diff --git a/bbb-client-check/src/org/bigbluebutton/clientcheck/service/RTMPTunnelingService.as b/bbb-client-check/src/org/bigbluebutton/clientcheck/service/RTMPTunnelingService.as
index a3e6803fc663bb4b09feae4ec2d5079b555f117e..30d5921ad8f502c60f50bbc5a55cd2004beb9d12 100644
--- a/bbb-client-check/src/org/bigbluebutton/clientcheck/service/RTMPTunnelingService.as
+++ b/bbb-client-check/src/org/bigbluebutton/clientcheck/service/RTMPTunnelingService.as
@@ -43,6 +43,7 @@ package org.bigbluebutton.clientcheck.service
 		private static var RECORD_MOCK:Boolean=false;
 		private static var EXTERNAL_USER_ID_MOCK:String="123456";
 		private static var INTERNAL_USER_ID_MOCK:String="654321";
+		private static var CLIENT_CONN_ID:String="client-conn-id";
 		private static var LOCK_ON_MOCK:Boolean=true;
 
 		public function init():void
@@ -60,7 +61,7 @@ package org.bigbluebutton.clientcheck.service
 						// sip has a different way of connecting to the red5 server, need to fake connection data.
 						if (systemConfiguration.rtmpApps[i].applicationUri.indexOf("sip") > 0)
 						{
-							_netConnection.connect(systemConfiguration.rtmpApps[i].applicationUri, ROOM_MOCK, EXTERNAL_USER_ID_MOCK, USER_NAME_MOCK, INTERNAL_USER_ID_MOCK);
+							_netConnection.connect(systemConfiguration.rtmpApps[i].applicationUri, ROOM_MOCK, EXTERNAL_USER_ID_MOCK, USER_NAME_MOCK, INTERNAL_USER_ID_MOCK, CLIENT_CONN_ID);
 							continue;
 						}
 						else
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/Application.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/Application.java
index 7521484f37852933891144bfdaa285266bb35561..42d7240014aeec2f69daf79c1898c616997e57c5 100755
--- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/Application.java
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/Application.java
@@ -86,7 +86,7 @@ public class Application extends MultiThreadedApplicationAdapter {
 	public boolean appConnect(IConnection conn, Object[] params) {
 
 		if(params.length != 5) {
-			log.error("Invalid number of parameters. param length=" + params.length);
+			log.error("Invalid number of parameters. Provided parameters={} .Required parameters=5", params.length);
 			return false;
 		}
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/assets/sounds/ScreenshareOff.mp3 b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/assets/sounds/ScreenshareOff.mp3
new file mode 100755
index 0000000000000000000000000000000000000000..9a64f01329ee0d8c92b7b16f331f7a3aecd46b68
Binary files /dev/null and b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/assets/sounds/ScreenshareOff.mp3 differ
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/ViewerWindowManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/ViewerWindowManager.as
index 16cfb0681833834c731d9fff50d1c70acc212ef8..939ec9f5a24e3e31f67c76f048b297e617d4a879 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/ViewerWindowManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/ViewerWindowManager.as
@@ -56,6 +56,7 @@ package org.bigbluebutton.modules.screenshare.managers {
             LOGGER.debug("ViewerWindowManager Received stop viewing command");
             if (viewWindow) {
                 closeWindow(viewWindow);
+                viewWindow = null;
                 isViewing = false;
             }
         }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/WebRTCPublishWindowManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/WebRTCPublishWindowManager.as
index 9580c607bfaa4700e4ec4293719f7fcd9b7a7f9d..11cbfc36aafce8be21d022da8dd302e5a60ddbbf 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/WebRTCPublishWindowManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/WebRTCPublishWindowManager.as
@@ -51,12 +51,11 @@ package org.bigbluebutton.modules.screenshare.managers
 			if (shareWindow != null) shareWindow.stopSharing();
 		}
 
-		private function autopublishTimerHandler(event:TimerEvent):void {
-			shareWindow.shareScreen(true);
-		}
-
 		public function handleShareWindowCloseEvent():void {
-			closeWindow(shareWindow);
+			if (shareWindow) {
+				closeWindow(shareWindow);
+				shareWindow = null;
+			}
 		}
 
 		private function openWindow(window:IBbbModuleWindow = null):void {
@@ -77,7 +76,6 @@ package org.bigbluebutton.modules.screenshare.managers
 			var event:CloseWindowEvent = new CloseWindowEvent(CloseWindowEvent.CLOSE_WINDOW_EVENT);
 			event.window = window;
 			globalDispatcher.dispatchEvent(event);
-			shareWindow = null;
 		}
 
 		public function startSharing():void {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/WebRTCViewerWindowManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/WebRTCViewerWindowManager.as
index 37e73b854fdef8d7bb38309a0d376b77c58d28c3..b6c4a42041c6121cd1f71b05dc17d76c6ce51399 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/WebRTCViewerWindowManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/WebRTCViewerWindowManager.as
@@ -50,8 +50,10 @@ package org.bigbluebutton.modules.screenshare.managers
 
 		public function handleViewWindowCloseEvent():void {
 			LOGGER.debug("Received close view window event");
-			closeWindow(viewWindow);
-			isViewing = false;
+			if (viewWindow) {
+				closeWindow(viewWindow);
+				isViewing = false;
+			}
 		}
 
 		private function closeWindow(window:IBbbModuleWindow):void {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreensharePublishWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreensharePublishWindow.mxml
index 219264b853929c3c388cb7afd26f90bc7efc46f9..eaa4be18ad91c98c1f61b3910ba5ebecf8b6887b 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreensharePublishWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreensharePublishWindow.mxml
@@ -107,6 +107,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
       [Bindable]
       private var shareTypeProvider:Array;
+      
+      [Embed(source="../../assets/sounds/ScreenshareOff.mp3")]
+      private var noticeSoundClass:Class;
+      private var noticeSound:Sound = new noticeSoundClass() as Sound;
+      private var soundPlayed:Boolean = false;
 
       private function init():void {
         dsOptions = Options.getOptions(ScreenshareOptions) as ScreenshareOptions;
@@ -431,6 +436,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
       private function closeWindow():void {
         dispatchEvent(new ShareWindowEvent(ShareWindowEvent.CLOSE));
+        
+        if (!soundPlayed) {
+          trace("playing from java publish window");
+          var tSC:SoundChannel = noticeSound.play(0, 0, new SoundTransform(0.25));
+          soundPlayed = true;
+        }
       }
 
       private function restartJava():void {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/WebRTCDesktopPublishWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/WebRTCDesktopPublishWindow.mxml
index fc87c8b734eb64be1e0edd992da1e719e5f87c20..c6805e0c7075d5fb9e341cf67032901e54f76372 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/WebRTCDesktopPublishWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/WebRTCDesktopPublishWindow.mxml
@@ -97,6 +97,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			private var globalDispatcher:Dispatcher = new Dispatcher();
 
 			[Bindable] private var dsOptions:ScreenshareOptions;
+			
+			[Embed(source="../../assets/sounds/ScreenshareOff.mp3")]
+			private var noticeSoundClass:Class;
+			private var noticeSound:Sound = new noticeSoundClass() as Sound;
+			private var soundPlayed:Boolean = false;
 
 			private function displayInstall():void {
 				setCurrentState("displayInstall");
@@ -115,9 +120,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				if (ExternalInterface.available) {
 					var isIncognito:Function = function(args:Object):void {
 						incognitoLbl.visible = true;
+						ExternalInterface.addCallback("isIncognito", null);
+						ExternalInterface.addCallback("isNotIncognito", null);
 					};
 
-					var isNotIncognito:Function = function(args:Object):void {};
+					var isNotIncognito:Function = function(args:Object):void {
+						ExternalInterface.addCallback("isIncognito", null);
+						ExternalInterface.addCallback("isNotIncognito", null);
+					};
 
 					ExternalInterface.addCallback("isIncognito", isIncognito);
 					ExternalInterface.addCallback("isNotIncognito", isNotIncognito);
@@ -145,6 +155,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				ExternalInterface.addCallback("onSuccess", onSuccess);
 				ExternalInterface.call("checkChromeExtInstalled", "onSuccess", dsOptions.chromeExtensionKey);
 			}
+			
+			
 
 			private function init():void {
 				dsOptions = Options.getOptions(ScreenshareOptions) as ScreenshareOptions;
@@ -248,24 +260,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			 */
 			public function resetWidthAndHeight():void{/* do nothing */}
 
-			public function initWindow(connection:NetConnection, uri:String, useTLS:Boolean , room:String):void {
-				this.connection = connection;
-				this.uri = uri;
-				this.useTLS = useTLS;
-				this.room = room;
-			}
-
-			public function shareScreen(fullScreen:Boolean):void {
-				LOGGER.debug("Calling shareScreen");
-				startSharing(connection, uri, useTLS , room, fullScreen);
-			}
-
-			private function startSharing(connection:NetConnection, uri:String , useTLS:Boolean , room:String, fullScreen:Boolean):void {
-				var captureX:Number = 0;
-				var captureY:Number = 0;
-
-			}
-
 			public function stopSharing():void{
 				if (streaming) {
 					stopStream();
@@ -273,7 +267,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 					dispatchEvent(streamEvent);
 				}
 				streaming = false;
-				closeWindow();
+				//closeWindow();
 			}
 
 			public function stopSharingEvent(evt:StopSharingButtonEvent):void{
@@ -427,12 +421,15 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				video.y = videoHolder.y = (this.height - VID_HEIGHT_PAD - vidH) / 2;
 			}
 
-			private function stopStream():void{
+			private function stopStream():void {
 				streaming = false;
 				
 				if (ns != null) {
 					ns.close();
 				}
+				if (connection != null) {
+					connection.close();
+				}
 			}
 
 			private function onAsyncError(e:AsyncErrorEvent):void{
@@ -479,9 +476,18 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			}
 
 			private function closeWindow():void {
+				// Have to remove the callback so we can garbage collect
+				ExternalInterface.addCallback("onFail", null);
+				
 				// LOGGER.debug("Calling stopApplet in closeWindow()");
 				dispatchEvent(new WebRTCShareWindowEvent(WebRTCShareWindowEvent.CLOSE));
-        globalDispatcher.dispatchEvent(new DeskshareToolbarEvent(DeskshareToolbarEvent.STOP));
+				globalDispatcher.dispatchEvent(new DeskshareToolbarEvent(DeskshareToolbarEvent.STOP));
+				
+				if (!soundPlayed) {
+					trace("playing from webrtc publish window");
+					var tSC:SoundChannel = noticeSound.play(0, 0, new SoundTransform(0.25));
+					soundPlayed = true;
+				}
 			}
 
 			/*
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as
index cc95493b8b7e5d36ec7ad533364ee96d7f2c9cfc..3d39fcc3f852d687f3561bdd3c318ef9d6c63c9e 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as
@@ -970,6 +970,9 @@ package org.bigbluebutton.modules.users.services
       if (UsersUtil.isMe(userId)) {
         LiveMeeting.inst().me.role = role;
         dispatcher.dispatchEvent(new ChangeMyRole(role));
+        
+        // need to fake a new lock settings so that the lock state gets revalidated
+        UsersUtil.applyLockSettings();
       }
 
       dispatcher.dispatchEvent(new UserStatusChangedEvent(userId));
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/MediaItemRenderer.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/MediaItemRenderer.mxml
index b072a08437a072cc184ffeb885e9ab836841d4a7..cca024a7915c3640497d2df3bac4713e3d30d107 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/MediaItemRenderer.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/MediaItemRenderer.mxml
@@ -193,12 +193,13 @@
 				muteImg.filters = null;
 
 				var ls:LockSettingsVO = UsersUtil.getLockSettings();
+				var amIMod:Boolean = UsersUtil.amIModerator();
 				
 				if (data != null) {
 					var allowModeratorToSeeOwnSettings: Boolean = !data.me || (data.me && UsersUtil.amIModerator());
 					settingsBtn.visible = rolledOver && allowModeratorToSeeOwnSettings && !UsersUtil.isBreakout();
 
-					if (!data.inVoiceConf) {
+					if ( !data.inVoiceConf || ( options.moderatorUnmute == false && amIMod && !UsersUtil.isMe(data.userId) ) ) {
 						muteImg.visible = false;
 						muteImg.includeInLayout = false;
 						muteBtn.visible = false;
@@ -210,7 +211,7 @@
 							muteImg.includeInLayout = true;
 							muteBtn.visible = false;
 							muteBtn.includeInLayout = false;
-						} else if (data.locked && ls.getDisableMic()) {
+						} else if (!amIMod && data.locked && ls.getDisableMic()) {
 							muteImg.visible = true;
 							muteImg.includeInLayout = true;
 							muteBtn.visible = false;
diff --git a/bigbluebutton-config/bin/bbb-conf b/bigbluebutton-config/bin/bbb-conf
index ed13fd42c75b6dba05b124613d6dae62b4720047..394f69004cfed62a763f4ea7ea2e424b8f5fa69c 100755
--- a/bigbluebutton-config/bin/bbb-conf
+++ b/bigbluebutton-config/bin/bbb-conf
@@ -1792,11 +1792,12 @@ if [ -n "$HOST" ]; then
         #
 
         echo "Assigning $HOST for http[s]:// in /var/www/bigbluebutton/client/conf/config.xml"
-        chromeExtensionLinkURL=$(cat /var/www/bigbluebutton/client/conf/config.xml | sed -n '/chromeExtensionLink/{s/.*https*:\/\///;s/\/.*//;p}')
-        sudo sed -i "s/http[s]*:\/\/\([^\"\/]*\)\([\"\/]\)/$PROTOCOL_HTTP:\/\/$HOST\2/g"  \
-		/var/www/bigbluebutton/client/conf/config.xml
-        sudo sed -i "s/chromeExtensionLink=\"https:\/\/[^\/]*/chromeExtensionLink=\"https:\/\/$chromeExtensionLinkURL/g" \ 
-		/var/www/bigbluebutton/client/conf/config.xml
+        sudo sed -i "s/http[s]*:\/\/\([^\"\/]*\)\([\"\/]\)/$PROTOCOL_HTTP:\/\/$HOST\2/g"  /var/www/bigbluebutton/client/conf/config.xml
+        if ! echo "$chromeExtensionLinkURL" | grep -q '""'; then
+          sudo sed -i "s/chromeExtensionLink=\"https:\/\/[^\/]*/chromeExtensionLink=\"https:\/\/$chromeExtensionLinkURL/g" \
+                /var/www/bigbluebutton/client/conf/config.xml
+        fi
+
 
         echo "Assigning $HOST for publishURI in /var/www/bigbluebutton/client/conf/config.xml"
         sudo sed -i "s/publishURI=\"[^\"]*\"/publishURI=\"$HOST\"/" /var/www/bigbluebutton/client/conf/config.xml
diff --git a/bigbluebutton-html5/client/main.html b/bigbluebutton-html5/client/main.html
old mode 100644
new mode 100755
index f0dc4c57bcf700ca2cf6b17d49cea0595c59eb5f..732f35244c3b09cc1d724c4d45fabc4e5f371d08
--- a/bigbluebutton-html5/client/main.html
+++ b/bigbluebutton-html5/client/main.html
@@ -1,5 +1,5 @@
 <head>
-  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
   <style>
     html {
       box-sizing: border-box;
diff --git a/bigbluebutton-html5/imports/api/audio/client/bridge/base.js b/bigbluebutton-html5/imports/api/audio/client/bridge/base.js
old mode 100644
new mode 100755
index 69e256274f1c44a6468168fb41d85cba8b4c352f..a9c63969a29328327d4ad2cd06a1ec4e2b1ffbf6
--- a/bigbluebutton-html5/imports/api/audio/client/bridge/base.js
+++ b/bigbluebutton-html5/imports/api/audio/client/bridge/base.js
@@ -8,6 +8,8 @@ export default class BaseAudioBridge {
       REQUEST_TIMEOUT: 'REQUEST_TIMEOUT',
       GENERIC_ERROR: 'GENERIC_ERROR',
       MEDIA_ERROR: 'MEDIA_ERROR',
+      WEBRTC_NOT_SUPPORTED: 'WEBRTC_NOT_SUPPORTED',
+      ICE_NEGOTIATION_FAILED: 'ICE_NEGOTIATION_FAILED',
     };
 
     this.baseCallStates = {
diff --git a/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js b/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js
old mode 100644
new mode 100755
index b3678cf46e202799604746a74bb15058ee2a2b9c..e16be8fdc569844e32fd73ca918d947206076aa4
--- a/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js
+++ b/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js
@@ -9,6 +9,7 @@ const MEDIA_TAG = MEDIA.mediaTag;
 const CALL_TRANSFER_TIMEOUT = MEDIA.callTransferTimeout;
 const CALL_HANGUP_TIMEOUT = MEDIA.callHangupTimeout;
 const CALL_HANGUP_MAX_RETRIES = MEDIA.callHangupMaximumRetries;
+const CONNECTION_TERMINATED_EVENTS = ['iceConnectionFailed', 'iceConnectionClosed'];
 
 const fetchStunTurnServers = (sessionToken) => {
   const handleStunTurnResponse = ({ stunServers, turnServers }) => {
@@ -76,6 +77,20 @@ export default class SIPBridge extends BaseAudioBridge {
       [causes.REQUEST_TIMEOUT]: this.baseErrorCodes.REQUEST_TIMEOUT,
       [causes.INVALID_TARGET]: this.baseErrorCodes.INVALID_TARGET,
       [causes.CONNECTION_ERROR]: this.baseErrorCodes.CONNECTION_ERROR,
+      [causes.WEBRTC_NOT_SUPPORTED]: this.baseErrorCodes.WEBRTC_NOT_SUPPORTED,
+    };
+    this.webRtcError = {
+      1001: '1001',
+      1002: '1002',
+      1003: '1003',
+      1004: '1004',
+      1005: '1005',
+      1006: '1006',
+      1007: '1007',
+      1008: '1008',
+      1009: '1009',
+      1010: '1010',
+      1011: '1011',
     };
   }
 
@@ -168,6 +183,10 @@ export default class SIPBridge extends BaseAudioBridge {
     return new Promise((resolve, reject) => {
       let hangupRetries = 0;
       let hangup = false;
+      const { mediaHandler } = this.currentSession;
+
+      // Removing termination events to avoid triggering an error
+      CONNECTION_TERMINATED_EVENTS.forEach(e => mediaHandler.off(e));
       const tryHangup = () => {
         this.currentSession.bye();
         hangupRetries += 1;
@@ -229,19 +248,22 @@ export default class SIPBridge extends BaseAudioBridge {
         resolve(userAgent);
       };
 
-      const handleUserAgentDisconnection = () => {
+      const handleUserAgentDisconnection = (event) => {
         userAgent.stop();
         userAgent = null;
+        const { lastTransportError } = event.transport;
+        const errorCode = lastTransportError.code;
+        const error = this.webRtcError[errorCode] || this.baseErrorCodes.CONNECTION_ERROR;
         this.callback({
           status: this.baseCallStates.failed,
-          error: this.baseErrorCodes.CONNECTION_ERROR,
+          error,
           bridgeError: 'User Agent Disconnected',
         });
         reject(this.baseErrorCodes.CONNECTION_ERROR);
       };
 
       userAgent.on('connected', handleUserAgentConnection);
-      userAgent.on('disconnected', handleUserAgentDisconnection);
+      userAgent.on('disconnected', handleUserAgentDisconnection); 
 
       userAgent.start();
     });
@@ -311,16 +333,15 @@ export default class SIPBridge extends BaseAudioBridge {
       };
       currentSession.on('terminated', handleSessionTerminated);
 
-      const connectionTerminatedEvents = ['iceConnectionFailed', 'iceConnectionDisconnected'];
       const handleConnectionTerminated = (peer) => {
-        connectionTerminatedEvents.forEach(e => mediaHandler.off(e, handleConnectionTerminated));
+        CONNECTION_TERMINATED_EVENTS.forEach(e => mediaHandler.off(e, handleConnectionTerminated));
         this.callback({
           status: this.baseCallStates.failed,
-          error: this.baseErrorCodes.CONNECTION_ERROR,
+          error: this.baseErrorCodes.ICE_NEGOTIATION_FAILED,
           bridgeError: peer,
         });
       };
-      connectionTerminatedEvents.forEach(e => mediaHandler.on(e, handleConnectionTerminated));
+      CONNECTION_TERMINATED_EVENTS.forEach(e => mediaHandler.on(e, handleConnectionTerminated));
 
       this.currentSession = currentSession;
     });
diff --git a/bigbluebutton-html5/imports/api/users/server/handlers/validateAuthToken.js b/bigbluebutton-html5/imports/api/users/server/handlers/validateAuthToken.js
index 0cc164f2ae12ff158db1591fba3af6d248abcc0f..9fdd768003d311d9dab6274183419d9da07c56d7 100644
--- a/bigbluebutton-html5/imports/api/users/server/handlers/validateAuthToken.js
+++ b/bigbluebutton-html5/imports/api/users/server/handlers/validateAuthToken.js
@@ -1,31 +1,9 @@
 import { check } from 'meteor/check';
 import Logger from '/imports/startup/server/logger';
-import Meetings from '/imports/api/meetings';
 import Users from '/imports/api/users';
 
-import addChat from '/imports/api/chat/server/modifiers/addChat';
-import clearUserSystemMessages from '/imports/api/chat/server/modifiers/clearUserSystemMessages';
-
 import userJoin from '../methods/userJoin';
 
-const addWelcomeChatMessage = (meetingId, userId) => {
-  const CHAT_CONFIG = Meteor.settings.public.chat;
-
-  const Meeting = Meetings.findOne({ meetingId });
-
-  const message = {
-    message: Meeting.welcomeProp.welcomeMsg,
-    fromColor: '0x3399FF',
-    toUserId: userId,
-    toUsername: CHAT_CONFIG.type_system,
-    fromUserId: CHAT_CONFIG.type_system,
-    fromUsername: '',
-    fromTime: (new Date()).getTime(),
-  };
-
-  addChat(meetingId, message);
-};
-
 const clearOtherSessions = (sessionUserId, current = false) => {
   const serverSessions = Meteor.server.sessions;
   Object.keys(serverSessions)
@@ -72,9 +50,6 @@ export default function handleValidateAuthToken({ body }, meetingId) {
 
     if (numChanged) {
       if (valid) {
-        clearUserSystemMessages(meetingId, userId);
-        addWelcomeChatMessage(meetingId, userId);
-
         const sessionUserId = `${meetingId}-${userId}`;
         const currentConnectionId = User.connectionId ? User.connectionId : false;
         clearOtherSessions(sessionUserId, currentConnectionId);
diff --git a/bigbluebutton-html5/imports/api/users/server/modifiers/addUser.js b/bigbluebutton-html5/imports/api/users/server/modifiers/addUser.js
index 972380ec39528234bfbbccc400455eaf125f821b..c0c165feffe47e44ea0a69122cb27fbf9f42abd5 100755
--- a/bigbluebutton-html5/imports/api/users/server/modifiers/addUser.js
+++ b/bigbluebutton-html5/imports/api/users/server/modifiers/addUser.js
@@ -8,12 +8,33 @@ import flat from 'flat';
 import addVoiceUser from '/imports/api/voice-users/server/modifiers/addVoiceUser';
 import changeRole from '/imports/api/users/server/modifiers/changeRole';
 
+import Meetings from '/imports/api/meetings';
+import addChat from '/imports/api/chat/server/modifiers/addChat';
+import clearUserSystemMessages from '/imports/api/chat/server/modifiers/clearUserSystemMessages';
+
 const COLOR_LIST = [
   '#7b1fa2', '#6a1b9a', '#4a148c', '#5e35b1', '#512da8', '#4527a0',
   '#311b92', '#3949ab', '#303f9f', '#283593', '#1a237e', '#1976d2', '#1565c0',
   '#0d47a1', '#0277bd', '#01579b',
 ];
 
+// add some default welcoming message to the chat (welcome / mod only)
+const addWelcomingChatMessage = (messageText, meetingId, userId) => {
+  const CHAT_CONFIG = Meteor.settings.public.chat;
+
+  const message = {
+    message: messageText,
+    fromColor: '0x3399FF',
+    toUserId: userId,
+    toUsername: CHAT_CONFIG.type_system,
+    fromUserId: CHAT_CONFIG.type_system,
+    fromUsername: '',
+    fromTime: (new Date()).getTime(),
+  };
+
+  addChat(meetingId, message);
+};
+
 export default function addUser(meetingId, user) {
   check(meetingId, String);
 
@@ -95,12 +116,26 @@ export default function addUser(meetingId, user) {
       return Logger.error(`Adding user to collection: ${err}`);
     }
 
+    clearUserSystemMessages(meetingId, userId);
+
+    const Meeting = Meetings.findOne({ meetingId });
+    addWelcomingChatMessage(
+      Meeting.welcomeProp.welcomeMsg,
+      meetingId, userId,
+    );
+
     if (user.presenter) {
       changeRole(ROLE_PRESENTER, true, userId, meetingId);
     }
 
     if (userRole === ROLE_MODERATOR) {
       changeRole(ROLE_MODERATOR, true, userId, meetingId);
+      if (Meeting.welcomeProp.modOnlyMessage) {
+        addWelcomingChatMessage(
+          Meeting.welcomeProp.modOnlyMessage,
+          meetingId, userId,
+        );
+      }
     }
 
     const { insertedId } = numChanged;
diff --git a/bigbluebutton-html5/imports/startup/client/base.jsx b/bigbluebutton-html5/imports/startup/client/base.jsx
index ef39c274e209cf81ec42e5b257a3ec7e5ffd0ec9..46d5e1b9e21aae213dbed903baefc894f35dc65e 100755
--- a/bigbluebutton-html5/imports/startup/client/base.jsx
+++ b/bigbluebutton-html5/imports/startup/client/base.jsx
@@ -127,11 +127,12 @@ const BaseContainer = withRouter(withTracker(({ params, router }) => {
 
   const annotationsHandler = Meteor.subscribe('annotations', credentials, {
     onReady: () => {
-      Annotations.find({}, { reactive: false }).forEach(a => {
+      AnnotationsLocal.remove({});
+      Annotations.find({}, { reactive: false }).forEach((a) => {
         try {
-          AnnotationsLocal.insert(a)
+          AnnotationsLocal.insert(a);
         } catch (e) {
-            // who cares.
+          // who cares.
         }
       });
       annotationsHandler.stop();
diff --git a/bigbluebutton-html5/imports/ui/components/audio/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/container.jsx
old mode 100644
new mode 100755
index 874667d8274e7c464be17a80439f12a7c0fc4e9e..f00e27e077e496c9b87441b20a8c5d9adbcf0886
--- a/bigbluebutton-html5/imports/ui/components/audio/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/container.jsx
@@ -2,6 +2,7 @@ import React from 'react';
 import { withTracker } from 'meteor/react-meteor-data';
 import { withModalMounter } from '/imports/ui/components/modal/service';
 import { injectIntl, defineMessages } from 'react-intl';
+import _ from 'lodash';
 import Breakouts from '/imports/api/breakouts';
 import Service from './service';
 import AudioModalContainer from './audio-modal/container';
@@ -39,6 +40,14 @@ const intlMessages = defineMessages({
     id: 'app.audioManager.mediaError',
     description: 'Media error message',
   },
+  BrowserNotSupported: {
+    id: 'app.audioNotification.audioFailedError1003',
+    description: 'browser not supported error messsage',
+  },
+  iceNegotiationError: {
+    id: 'app.audioNotification.audioFailedError1007',
+    description: 'ice negociation error messsage',
+  },
 });
 
 
@@ -81,6 +90,12 @@ export default withModalMounter(injectIntl(withTracker(({ mountModal, intl }) =>
     },
   });
 
+  const webRtcError = _.range(1001, 1012)
+    .reduce((acc, value) => ({
+      ...acc,
+      [value]: intl.formatMessage({ id: `app.audioNotification.audioFailedError${value}` }),
+    }), {});
+
   const messages = {
     info: {
       JOINED_AUDIO: intl.formatMessage(intlMessages.joinedAudio),
@@ -93,6 +108,9 @@ export default withModalMounter(injectIntl(withTracker(({ mountModal, intl }) =>
       REQUEST_TIMEOUT: intl.formatMessage(intlMessages.requestTimeout),
       INVALID_TARGET: intl.formatMessage(intlMessages.invalidTarget),
       MEDIA_ERROR: intl.formatMessage(intlMessages.mediaError),
+      WEBRTC_NOT_SUPPORTED: intl.formatMessage(intlMessages.BrowserNotSupported),
+      ICE_NEGOTIATION_FAILED: intl.formatMessage(intlMessages.iceNegotiationError),
+      ...webRtcError,
     },
   };
 
diff --git a/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx
old mode 100644
new mode 100755
index 98716c98ee166b7555f5246028247c8dc593cafe..a4c569b573fc742cd3a5e8243a10075317e30fb8
--- a/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx
@@ -80,13 +80,17 @@ class MessageForm extends Component {
     const { minMessageLength, maxMessageLength } = this.props;
 
     if (message.length < minMessageLength) {
-      error = intl.formatMessage(messages.errorMinMessageLength,
-        { 0: minMessageLength - message.length });
+      error = intl.formatMessage(
+        messages.errorMinMessageLength,
+        { 0: minMessageLength - message.length },
+      );
     }
 
     if (message.length > maxMessageLength) {
-      error = intl.formatMessage(messages.errorMaxMessageLength,
-        { 0: message.length - maxMessageLength });
+      error = intl.formatMessage(
+        messages.errorMaxMessageLength,
+        { 0: message.length - maxMessageLength },
+      );
     }
 
     this.setState({
@@ -123,8 +127,10 @@ class MessageForm extends Component {
   }
 
   render() {
-    const { intl, chatTitle, chatName, disabled,
-      minMessageLength, maxMessageLength } = this.props;
+    const {
+      intl, chatTitle, chatName, disabled,
+      minMessageLength, maxMessageLength,
+    } = this.props;
 
     const { hasErrors, error } = this.state;
 
diff --git a/bigbluebutton-html5/imports/ui/components/chat/message-form/styles.scss b/bigbluebutton-html5/imports/ui/components/chat/message-form/styles.scss
old mode 100644
new mode 100755
index caebbfd4d10ae68f6a78755598643c56084422c8..f02d35fb1d66c68a63d59babaf9b49823119f3a4
--- a/bigbluebutton-html5/imports/ui/components/chat/message-form/styles.scss
+++ b/bigbluebutton-html5/imports/ui/components/chat/message-form/styles.scss
@@ -56,7 +56,7 @@
   resize: none;
   transition: none;
   border-radius: $border-radius;
-  font-size: $font-size-base * .90;
+  font-size: $font-size-base;
   min-height: 2.5rem;
   max-height: 10rem;
   border: 1px solid $color-gray-lighter;
diff --git a/bigbluebutton-html5/imports/ui/components/cursor/presentation-overlay/component.jsx b/bigbluebutton-html5/imports/ui/components/cursor/presentation-overlay/component.jsx
index ecaf2efb4e6b522267d5055ecf969406d4ce2b0e..e3a5a505ce742f519ad237df5834d063fbd9ebd7 100755
--- a/bigbluebutton-html5/imports/ui/components/cursor/presentation-overlay/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/cursor/presentation-overlay/component.jsx
@@ -92,6 +92,7 @@ export default class PresentationOverlay extends Component {
   }
 
   handleTouchMove(event) {
+    event.preventDefault();
     const { clientX, clientY } = event.changedTouches[0];
 
     this.currentClientX = clientX;
diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-overlay/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/presentation-overlay/component.jsx
index 66f7867ca4685469c1da896a27f39666b97d3483..74422d6de4af58b550616ad8b4186b8b5c402bf2 100755
--- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-overlay/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-overlay/component.jsx
@@ -97,6 +97,8 @@ export default class PresentationOverlay extends Component {
   }
 
   handleTouchMove(event) {
+    event.preventDefault();
+
     const { clientX, clientY } = event.changedTouches[0];
 
     this.currentClientX = clientX;
@@ -187,6 +189,8 @@ export default class PresentationOverlay extends Component {
         y="0"
         width={this.props.slideWidth}
         height={this.props.slideHeight}
+        // maximun value of z-index to prevent other things from overlapping
+        style={{ zIndex: 2 ** 31 - 1 }}
       >
         <div
           onTouchStart={this.handleTouchStart}
diff --git a/bigbluebutton-html5/imports/ui/components/settings/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/component.jsx
index d2a77b2ced7f3e4f1ee3d257842ffcef910b850c..bd499f6835bd8ecc81f384205120221619d8d55b 100644
--- a/bigbluebutton-html5/imports/ui/components/settings/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/settings/component.jsx
@@ -210,6 +210,7 @@ class Settings extends Component {
       intl,
       router,
       location,
+      mountModal,
     } = this.props;
 
     return (
@@ -218,17 +219,20 @@ class Settings extends Component {
         confirm={{
           callback: () => {
             this.updateSettings(this.state.current);
-            this.props.router.push(location.pathname);
+            router.push(location.pathname);
             /* We need to use mountModal(null) here to prevent submenu state updates,
             *  from re-opening the modal.
             */
-            this.props.mountModal(null);
+            mountModal(null);
           },
           label: intl.formatMessage(intlMessages.SaveLabel),
           description: intl.formatMessage(intlMessages.SaveLabelDesc),
         }}
         dismiss={{
-          callback: () => Settings.setHtmlFontSize(this.state.saved.application.fontSize),
+          callback: () => {
+            Settings.setHtmlFontSize(this.state.saved.application.fontSize);
+            mountModal(null);
+          },
           label: intl.formatMessage(intlMessages.CancelLabel),
           description: intl.formatMessage(intlMessages.CancelLabelDesc),
         }}
diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/service.js b/bigbluebutton-html5/imports/ui/components/whiteboard/service.js
index 9bf6879cf087083de113c58e5cec3b378a34a8bf..c9795aa06e6c363c41a663262cedfadcc85a7c2e 100755
--- a/bigbluebutton-html5/imports/ui/components/whiteboard/service.js
+++ b/bigbluebutton-html5/imports/ui/components/whiteboard/service.js
@@ -1,14 +1,15 @@
 import Users from '/imports/api/users';
 import Auth from '/imports/ui/services/auth';
+import WhiteboardMultiUser from '/imports/api/whiteboard-multi-user/';
 import { AnnotationsStreamer } from '/imports/api/annotations';
 import addAnnotationQuery from '/imports/api/annotations/addAnnotation';
-import { isEqual, isArray } from 'lodash';
+import { isEqual } from 'lodash';
 
 const Annotations = new Mongo.Collection(null);
-const Logger = {
-  info: console.log,
-  error: console.error,
-};
+
+function clearFakeAnnotations() {
+  Annotations.remove({ id: /-fake/g });
+}
 
 function handleAddedAnnotation({
   meetingId, whiteboardId, userId, annotation,
@@ -71,7 +72,7 @@ function handleRemovedAnnotation({
   }
 
   if (shapeId) {
-    query.id = shapeId;
+    query.id = { $in: [shapeId, `${shapeId}-fake`] };
   }
 
   Annotations.remove(query);
@@ -83,23 +84,25 @@ AnnotationsStreamer.on('added', ({ annotations }) => {
   annotations.forEach(annotation => handleAddedAnnotation(annotation));
 });
 
-function increase_brightness(hex, percent) {
-  hex = parseInt(hex, 10).toString(16).padStart(6, 0);
+function increaseBrightness(realHex, percent) {
+  let hex = parseInt(realHex, 10).toString(16).padStart(6, 0);
   // strip the leading # if it's there
   hex = hex.replace(/^\s*#|\s*$/g, '');
 
   // convert 3 char codes --> 6, e.g. `E0F` --> `EE00FF`
-  if (hex.length == 3) {
+  if (hex.length === 3) {
     hex = hex.replace(/(.)/g, '$1$1');
   }
 
-  let r = parseInt(hex.substr(0, 2), 16),
-    g = parseInt(hex.substr(2, 2), 16),
-    b = parseInt(hex.substr(4, 2), 16);
+  const r = parseInt(hex.substr(0, 2), 16);
+  const g = parseInt(hex.substr(2, 2), 16);
+  const b = parseInt(hex.substr(4, 2), 16);
 
-  return parseInt(((0 | (1 << 8) + r + (256 - r) * percent / 100).toString(16)).substr(1) +
-     ((0 | (1 << 8) + g + (256 - g) * percent / 100).toString(16)).substr(1) +
-     ((0 | (1 << 8) + b + (256 - b) * percent / 100).toString(16)).substr(1), 16);
+  /* eslint-disable no-bitwise, no-mixed-operators */
+  return parseInt(((0 | (1 << 8) + r + ((256 - r) * percent) / 100).toString(16)).substr(1) +
+     ((0 | (1 << 8) + g + ((256 - g) * percent) / 100).toString(16)).substr(1) +
+     ((0 | (1 << 8) + b + ((256 - b) * percent) / 100).toString(16)).substr(1), 16);
+  /* eslint-enable no-bitwise, no-mixed-operators */
 }
 
 let annotationsQueue = [];
@@ -124,13 +127,17 @@ const proccessAnnotationsQueue = () => {
   AnnotationsStreamer.emit('publish', { credentials: Auth.credentials, payload: annotationsQueue });
   annotationsQueue = [];
   // ask tiago
-  const delayPerc = Math.min(annotationsMaxDelayQueueSize, queueSize) / annotationsMaxDelayQueueSize;
+  const delayPerc =
+    Math.min(annotationsMaxDelayQueueSize, queueSize) / annotationsMaxDelayQueueSize;
   const delayDelta = annotationsBufferTimeMax - annotationsBufferTimeMin;
   const delayTime = annotationsBufferTimeMin + (delayDelta * delayPerc);
   setTimeout(proccessAnnotationsQueue, delayTime);
 };
 
 export function sendAnnotation(annotation) {
+  // Prevent sending annotations while disconnected
+  if (!Meteor.status().connected) return;
+
   annotationsQueue.push(annotation);
   if (!annotationsSenderIsRunning) setTimeout(proccessAnnotationsQueue, annotationsBufferTimeMin);
 
@@ -146,11 +153,23 @@ export function sendAnnotation(annotation) {
       position: Number.MAX_SAFE_INTEGER,
       annotationInfo: {
         ...annotation.annotationInfo,
-        color: increase_brightness(annotation.annotationInfo.color, 40),
+        color: increaseBrightness(annotation.annotationInfo.color, 40),
       },
     },
   );
-  return Annotations.upsert(queryFake.selector, queryFake.modifier);
+
+  Annotations.upsert(queryFake.selector, queryFake.modifier);
 }
 
+WhiteboardMultiUser.find({ meetingId: Auth.meetingID }).observeChanges({
+  changed: clearFakeAnnotations,
+});
+
+Users.find({ userId: Auth.userID }).observeChanges({
+  changed(id, { presenter }) {
+    console.log(presenter);
+    if (presenter === false) clearFakeAnnotations();
+  },
+});
+
 export default Annotations;
diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/pencil-draw-listener/component.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/pencil-draw-listener/component.jsx
index 01c66d37a366f72f89e717d6270a6a5760aba5a7..2297f6b8f7c600e98d5de2e47433a75bffbe13bd 100755
--- a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/pencil-draw-listener/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/pencil-draw-listener/component.jsx
@@ -102,6 +102,7 @@ export default class PencilDrawListener extends Component {
   }
 
   handleTouchMove(event) {
+    event.preventDefault();
     const { clientX, clientY } = event.changedTouches[0];
     this.commonDrawMoveHandler(clientX, clientY);
   }
@@ -213,6 +214,7 @@ export default class PencilDrawListener extends Component {
       width: '100%',
       height: '100%',
       touchAction: 'none',
+      zIndex: 2 ** 31 - 1, // maximun value of z-index to prevent other things from overlapping
       cursor: `url('${baseName}/resources/images/whiteboard-cursor/pencil.png') 2 22, default`,
     };
     return (
diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/shape-draw-listener/component.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/shape-draw-listener/component.jsx
index 5c9f7c130fcbcbb9ef75c70d821bffbd8c11de0e..2992fe43e489c67cc5e0f8558d330e23b0835c79 100755
--- a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/shape-draw-listener/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/shape-draw-listener/component.jsx
@@ -133,6 +133,7 @@ export default class ShapeDrawListener extends Component {
   }
 
   handleTouchMove(event) {
+    event.preventDefault();
     const { clientX, clientY } = event.changedTouches[0];
     this.commonDrawMoveHandler(clientX, clientY);
   }
@@ -284,6 +285,7 @@ export default class ShapeDrawListener extends Component {
       width: '100%',
       height: '100%',
       touchAction: 'none',
+      zIndex: 2 ** 31 - 1, // maximun value of z-index to prevent other things from overlapping
       cursor: `url('${baseName}/resources/images/whiteboard-cursor/${tool !== 'rectangle' ? tool : 'square'}.png'), default`,
     };
     return (
diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/text-draw-listener/component.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/text-draw-listener/component.jsx
old mode 100644
new mode 100755
index d68288a6cd4712626ba1edcc54b674da8a401701..f615c81b198d975e3678bd1fed72f7feb8e5e753
--- a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/text-draw-listener/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/text-draw-listener/component.jsx
@@ -151,6 +151,7 @@ export default class TextDrawListener extends Component {
   }
 
   handleTouchMove(event) {
+    event.preventDefault();
     const { clientX, clientY } = event.changedTouches[0];
     this.commonDrawMoveHandler(clientX, clientY);
   }
@@ -373,6 +374,7 @@ export default class TextDrawListener extends Component {
       width: '100%',
       height: '100%',
       touchAction: 'none',
+      zIndex: 2 ** 31 - 1, // maximun value of z-index to prevent other things from overlapping
       cursor: `url('${baseName}/resources/images/whiteboard-cursor/text.png'), default`,
     };
     return (
diff --git a/bigbluebutton-html5/imports/ui/services/audio-manager/index.js b/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
index d432835a0e68325edd684ad3829fd5dbef4615ad..5d79563e5260aabc0bbb5425a4de4efd0f33e165 100755
--- a/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
+++ b/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
@@ -171,7 +171,7 @@ class AudioManager {
   exitAudio() {
     if (!this.isConnected) return Promise.resolve();
 
-    const bridge  = USE_KURENTO? this.listenOnlyBridge : this.bridge;
+    const bridge  = (USE_KURENTO && this.isListenOnly) ? this.listenOnlyBridge : this.bridge;
 
     this.isHangingUp = true;
     this.isEchoTest = false;
@@ -260,9 +260,10 @@ class AudioManager {
         this.onAudioExit();
       } else if (status === FAILED) {
         this.error = error;
-        this.notify(this.messages.error[error], true);
+        this.notify(this.messages.error[error] || this.messages.error.GENERIC_ERROR, true);
         makeCall('failed callStateCallback audio', response);
         console.error('Audio Error:', error, bridgeError);
+        this.exitAudio();
         this.onAudioExit();
       }
     });
diff --git a/bigbluebutton-html5/private/locales/fr.json b/bigbluebutton-html5/private/locales/fr.json
index 8684b99ff757159acf42456173404e85cc107f8a..a88eeb123f417e3ed14c12b9eda7ff8cadef63eb 100644
--- a/bigbluebutton-html5/private/locales/fr.json
+++ b/bigbluebutton-html5/private/locales/fr.json
@@ -40,7 +40,7 @@
     "app.userList.menu.promoteUser.label": "Promouvoir {0} modérateur",
     "app.userList.menu.demoteUser.label": "Redéfinir {0} comme participant",
     "app.media.label": "Média",
-    "app.media.screenshare.start": "Le Partage d'écran à débuté",
+    "app.media.screenshare.start": "Le Partage d'écran à commencé",
     "app.media.screenshare.end": "Le Partage d'écran s'est terminé",
     "app.media.screenshare.safariNotSupported": "Le Partage d'écran n'est pour le moment pas supporté par Safari. Veuillez utiliser Firefox ou Google Chrome.",
     "app.meeting.ended": "Cette session s'est terminée",
@@ -136,7 +136,7 @@
     "app.submenu.application.languageOptionLabel": "Choisir la langue",
     "app.submenu.application.noLocaleOptionLabel": "Pas de lieu actif",
     "app.submenu.audio.micSourceLabel": "Source du Micro",
-    "app.submenu.audio.speakerSourceLabel": "Source des diffuseurs",
+    "app.submenu.audio.speakerSourceLabel": "Source du haut-parleur",
     "app.submenu.audio.streamVolumeLabel": "Volume de votre flux audio",
     "app.submenu.video.title": "Vidéo",
     "app.submenu.video.videoSourceLabel": "Voir la source",
@@ -162,17 +162,17 @@
     "app.submenu.participants.lockCamDesc": "Désactiver la webcam de tous les participants verrouillés",
     "app.submenu.participants.lockPublicChatDesc": "Désactiver la discussion publique pour tous les participants verrouillés",
     "app.submenu.participants.lockPrivateChatDesc": "Désactiver la discussion privée pour tous les participants verrouillés",
-    "app.submenu.participants.lockLayoutDesc": "Verrouiller les mise en page pour tous les participants verrouillés",
+    "app.submenu.participants.lockLayoutDesc": "Verrouiller la disposition pour tous les participants verrouillés",
     "app.submenu.participants.lockMicAriaLabel": "Verrouillage du micro",
     "app.submenu.participants.lockCamAriaLabel": "Verrouillage de la webcam",
     "app.submenu.participants.lockPublicChatAriaLabel": "Discussion publique verrouillée",
     "app.submenu.participants.lockPrivateChatAriaLabel": "Discussion privée verrouillée",
-    "app.submenu.participants.lockLayoutAriaLabel": "Mise en page verrouillée",
+    "app.submenu.participants.lockLayoutAriaLabel": "Disposition verrouillée",
     "app.submenu.participants.lockMicLabel": "Microphone",
     "app.submenu.participants.lockCamLabel": "Webcam",
     "app.submenu.participants.lockPublicChatLabel": "Discussion Publique",
     "app.submenu.participants.lockPrivateChatLabel": "Discussion Privée",
-    "app.submenu.participants.lockLayoutLabel": "Mise en page",
+    "app.submenu.participants.lockLayoutLabel": "Disposition",
     "app.settings.applicationTab.label": "Application",
     "app.settings.audioTab.label": "Audio",
     "app.settings.videoTab.label": "Vidéo",
@@ -316,6 +316,9 @@
     "app.video.iceCandidateError": "Erreur lors de l'ajout d'un candidat ICE",
     "app.video.permissionError": "Erreur lors du partage de la webcam. Veuillez vérifier les permissions.",
     "app.video.sharingError": "Erreur lors du partage de la Webcam",
+    "app.video.notFoundError": "Webcam introuvable. Assurez-vous qu'elle soit bien connectée",
+    "app.video.notAllowed": "Permission manquante pour partager la Webcam. Veuillez vérifier les permissions dans votre navigateur",
+    "app.video.mediaServerOffline": "Le serveur de médias est hors ligne. Veuillez ré-essayer plus tard.",
     "app.video.swapCam": "Échanger",
     "app.video.swapCamDesc": "Permuter les Webcams",
     "app.video.videoMenu": "Menu Vidéo",
@@ -327,11 +330,13 @@
     "app.video.stats.packetsReceived": "Paquets reçus",
     "app.video.stats.packetsSent": "Paquets envoyés",
     "app.video.stats.packetsLost": "Paquets perdus",
+    "app.video.stats.bitrate": "Bitrate",
     "app.video.stats.lostPercentage": "Pourcentage perdu total",
     "app.video.stats.lostRecentPercentage": "Pourcentage perdu récent",
     "app.video.stats.dimensions": "Dimensions",
     "app.video.stats.codec": "Codec",
     "app.video.stats.decodeDelay": "Délai de décodage",
+    "app.video.stats.rtt": "RTT",
     "app.video.stats.encodeUsagePercent": "Usage de l'encodage",
     "app.video.stats.currentDelay": "Délai actuel",
     "app.meeting.endNotification.ok.label": "OK",
@@ -366,7 +371,9 @@
     "app.whiteboard.toolbar.fontSize": "Liste des Tailles de Police",
     "app.feedback.title": "Vous avez quitté la conférence",
     "app.feedback.subtitle": "Nous aimerions connaitre votre expérience avec BigBlueButton (optionnel)",
-    "app.feedback.textarea": "Comment pouvons nous améliorer BigBlueButton ?"
+    "app.feedback.textarea": "Comment pouvons nous améliorer BigBlueButton ?",
+    "app.videoDock.webcamFocusLabel": "Focus",
+    "app.videoDock.webcamFocusDesc": "Focus sur la webcam sélectionnée"
 
 }
 
diff --git a/bigbluebutton-html5/private/locales/ja.json b/bigbluebutton-html5/private/locales/ja.json
index 4162b7d681359126b9528381f7c8451413c88133..b1aad8ba7fc1bddda6ef5c6349f008d73db6a11f 100644
--- a/bigbluebutton-html5/private/locales/ja.json
+++ b/bigbluebutton-html5/private/locales/ja.json
@@ -346,7 +346,7 @@
     "app.whiteboard.toolbar.tools.pencil": "ペン",
     "app.whiteboard.toolbar.tools.rectangle": "長方形",
     "app.whiteboard.toolbar.tools.triangle": "三角形",
-    "app.whiteboard.toolbar.tools.ellipse": "長方形",
+    "app.whiteboard.toolbar.tools.ellipse": "楕円",
     "app.whiteboard.toolbar.tools.line": "ç·š",
     "app.whiteboard.toolbar.tools.text": "テキスト",
     "app.whiteboard.toolbar.thickness": "線の太さ",
@@ -371,7 +371,7 @@
     "app.whiteboard.toolbar.multiUserOff": "マルチユーザーモードを外す",
     "app.whiteboard.toolbar.fontSize": "フォントサイズ",
     "app.feedback.title": "セッションからログアウトしました",
-    "app.feedback.subtitle": "BigBlueButtonの感想は? (任意)\"",
+    "app.feedback.subtitle": "BigBlueButtonの感想は? (任意)",
     "app.feedback.textarea": "BigBlueButtonに何が欲しいですか?",
     "app.feedback.sendFeedback": "フィードバックを送る",
     "app.feedback.sendFeedbackDesc": "フィードバックを送ってセッションから退席する",
diff --git a/bigbluebutton-html5/private/locales/ja_JP.json b/bigbluebutton-html5/private/locales/ja_JP.json
index 4162b7d681359126b9528381f7c8451413c88133..b1aad8ba7fc1bddda6ef5c6349f008d73db6a11f 100644
--- a/bigbluebutton-html5/private/locales/ja_JP.json
+++ b/bigbluebutton-html5/private/locales/ja_JP.json
@@ -346,7 +346,7 @@
     "app.whiteboard.toolbar.tools.pencil": "ペン",
     "app.whiteboard.toolbar.tools.rectangle": "長方形",
     "app.whiteboard.toolbar.tools.triangle": "三角形",
-    "app.whiteboard.toolbar.tools.ellipse": "長方形",
+    "app.whiteboard.toolbar.tools.ellipse": "楕円",
     "app.whiteboard.toolbar.tools.line": "ç·š",
     "app.whiteboard.toolbar.tools.text": "テキスト",
     "app.whiteboard.toolbar.thickness": "線の太さ",
@@ -371,7 +371,7 @@
     "app.whiteboard.toolbar.multiUserOff": "マルチユーザーモードを外す",
     "app.whiteboard.toolbar.fontSize": "フォントサイズ",
     "app.feedback.title": "セッションからログアウトしました",
-    "app.feedback.subtitle": "BigBlueButtonの感想は? (任意)\"",
+    "app.feedback.subtitle": "BigBlueButtonの感想は? (任意)",
     "app.feedback.textarea": "BigBlueButtonに何が欲しいですか?",
     "app.feedback.sendFeedback": "フィードバックを送る",
     "app.feedback.sendFeedbackDesc": "フィードバックを送ってセッションから退席する",
diff --git a/bigbluebutton-html5/private/locales/pt_BR.json b/bigbluebutton-html5/private/locales/pt_BR.json
index 78b0b6cc29ad266e7f6722e806ac4af59e3f7bf0..2248f585e1461f92a66680e71ddae7a68212eb4e 100644
--- a/bigbluebutton-html5/private/locales/pt_BR.json
+++ b/bigbluebutton-html5/private/locales/pt_BR.json
@@ -69,7 +69,9 @@
     "app.presentationUploder.fileToUpload": "Carregar arquivo...",
     "app.presentationUploder.currentBadge": "Atual",
     "app.presentationUploder.genericError": "Ops, algo deu errado",
+    "app.presentationUploder.upload.progress": "Carregando ({0}%)",
     "app.presentationUploder.upload.413": "O arquivo é muito grande",
+    "app.presentationUploder.conversion.conversionProcessingSlides": "Página de processamento {0} de {1}",
     "app.presentationUploder.conversion.genericConversionStatus": "Convertendo arquivo...",
     "app.presentationUploder.conversion.generatingThumbnail": "Gerando miniaturas...",
     "app.presentationUploder.conversion.generatedSlides": "Slides gerados...",
@@ -294,6 +296,9 @@
     "app.error.leaveLabel": "Faça o login novamente",
     "app.guest.waiting": "Esperando aprovação para participar",
     "app.toast.breakoutRoomEnded": "A sala de apoio terminou. Clique no ícone do microfone para reingressar a conferência de áudio na sala principal",
+    "app.toast.chat.public": "Nova mensagem de Bate-papo público",
+    "app.toast.chat.private": "Nova mensagem de Bate-papo privado",
+    "app.toast.chat.system": "Sistema",
     "app.notification.recordingStart": "Esta reunião está sendo gravada",
     "app.notification.recordingStop": "Esta reunião não está mais sendo gravada",
     "app.shortcut-help.title": "Atalhos de teclado",
@@ -327,6 +332,19 @@
     "app.video.videoMenuDesc": "Abra o menu de vídeo",
     "app.video.chromeExtensionError": "Você deve instalar o seguinte:",
     "app.video.chromeExtensionErrorLink": "esta extensão do Chrome",
+    "app.video.stats.title": "Estatísticas de conexão",
+    "app.video.stats.packetsReceived": "Pacotes recebidos",
+    "app.video.stats.packetsSent": "Pacotes enviados",
+    "app.video.stats.packetsLost": "Pacotes perdidos",
+    "app.video.stats.bitrate": "Taxa de bits",
+    "app.video.stats.lostPercentage": "Percentuais de perda total",
+    "app.video.stats.lostRecentPercentage": "Percentuais de perda recentemente",
+    "app.video.stats.dimensions": "Dimensões",
+    "app.video.stats.codec": "Codec",
+    "app.video.stats.decodeDelay": "Atraso de decodificação",
+    "app.video.stats.rtt": "RTT",
+    "app.video.stats.encodeUsagePercent": "Uso de codificação",
+    "app.video.stats.currentDelay": "Atraso atual",
     "app.meeting.endNotification.ok.label": "OK",
     "app.whiteboard.toolbar.tools": "Ferramentas",
     "app.whiteboard.toolbar.tools.pointer": "Cursor",
@@ -344,6 +362,7 @@
     "app.whiteboard.toolbar.color.white": "Branco",
     "app.whiteboard.toolbar.color.red": "Vermelho",
     "app.whiteboard.toolbar.color.orange": "Laranja",
+    "app.whiteboard.toolbar.color.eletricLime": "Verde limão",
     "app.whiteboard.toolbar.color.lime": "Verde",
     "app.whiteboard.toolbar.color.cyan": "Ciano",
     "app.whiteboard.toolbar.color.dodgerBlue": "Azul Dodger",
diff --git a/bigbluebutton-html5/private/locales/ru_RU.json b/bigbluebutton-html5/private/locales/ru_RU.json
index c767de27ba850d720d802ca3748c28ae702407c5..f277f07ebc4ecccb1b443ca56f71a2448bba7305 100644
--- a/bigbluebutton-html5/private/locales/ru_RU.json
+++ b/bigbluebutton-html5/private/locales/ru_RU.json
@@ -1,9 +1,9 @@
 {
     "app.home.greeting": "Добро пожаловать {0}! Ваша презентация начнётся в ближайшее время... ",
     "app.chat.submitLabel": "Отправить сообщение",
-    "app.chat.errorMinMessageLength": "Сообщение слишком короткое ({0} символов)",
-    "app.chat.errorMaxMessageLength": "Сообщение слишком длинное ({0} символов)",
-    "app.chat.inputLabel": "Поле ввода сообщения для {0}",
+    "app.chat.errorMinMessageLength": "Сообщение из {0} символа(-ов) слишком короткое",
+    "app.chat.errorMaxMessageLength": "Сообщение из {0} символа(-ов) слишком длинное",
+    "app.chat.inputLabel": "Ввод сообщений для чата {0}",
     "app.chat.inputPlaceholder": "Сообщение {0}",
     "app.chat.titlePublic": "Общий чат",
     "app.chat.titlePrivate": "Приватный чат с {0}",
@@ -33,12 +33,16 @@
     "app.userList.menu.chat.label": "Чат",
     "app.userList.menu.clearStatus.label": "Очистить статус",
     "app.userList.menu.makePresenter.label": "Сделать ведущим",
-    "app.userList.menu.removeUser.label": "Удалить пользователя",
+    "app.userList.menu.removeUser.label": "Исключить пользователя",
     "app.userList.menu.muteUserAudio.label": "Выключить микрофон пользователя",
     "app.userList.menu.unmuteUserAudio.label": "Включить микрофон пользователя",
+    "app.userList.userAriaLabel": "{0} {1} {2}  Статус {3}",
     "app.userList.menu.promoteUser.label": "Повысить {0} до модератора",
     "app.userList.menu.demoteUser.label": "Понизить {0} до зрителя",
     "app.media.label": "Медиа",
+    "app.media.screenshare.start": "Демонстрация экрана началась",
+    "app.media.screenshare.end": "Демонстрация экрана закончилась",
+    "app.media.screenshare.safariNotSupported": "Демонстрация экрана на данный момент не поддерживается Safari. Пожалуйста, используйте Firefox или Google Chrome.",
     "app.meeting.ended": "Сеанс окончен",
     "app.meeting.endedMessage": "Вы будете перенаправлены назад на главный экран",
     "app.presentation.presentationToolbar.prevSlideLabel": "Предыдущий слайд",
@@ -47,9 +51,9 @@
     "app.presentation.presentationToolbar.nextSlideDesc": "Переключить презентацию на следующий слайд",
     "app.presentation.presentationToolbar.skipSlideLabel": "Пропустить слайд",
     "app.presentation.presentationToolbar.skipSlideDesc": "Переключить презентацию на указанный слайд",
-    "app.presentation.presentationToolbar.fitWidthLabel": "По ширине",
+    "app.presentation.presentationToolbar.fitWidthLabel": "Подогнать по ширине",
     "app.presentation.presentationToolbar.fitWidthDesc": "Уместить по ширине слайда",
-    "app.presentation.presentationToolbar.fitScreenLabel": "По размеру экрана",
+    "app.presentation.presentationToolbar.fitScreenLabel": "Подогнать к экрану",
     "app.presentation.presentationToolbar.fitScreenDesc": "Уместить слайд целиком",
     "app.presentation.presentationToolbar.zoomLabel": "Масштаб",
     "app.presentation.presentationToolbar.zoomDesc": "Изменить масштаб презетации",
@@ -59,21 +63,25 @@
     "app.presentationUploder.confirmLabel": "Начать",
     "app.presentationUploder.confirmDesc": "Сохранить изменения и начать презентацию",
     "app.presentationUploder.dismissLabel": "Отменить",
-    "app.presentationUploder.dismissDesc": "Закрыть всплывающее окно и отменить изменения",
+    "app.presentationUploder.dismissDesc": "Закрыть окно изображения и отменить изменения",
     "app.presentationUploder.dropzoneLabel": "Перетащите сюда файлы, чтобы загрузить их",
     "app.presentationUploder.browseFilesLabel": "или выберите файл",
     "app.presentationUploder.fileToUpload": "Чтобы загрузить...",
     "app.presentationUploder.currentBadge": "Текущий",
     "app.presentationUploder.genericError": "Ой, что-то пошло не так",
+    "app.presentationUploder.upload.progress": "Загрузка ({0}%)",
     "app.presentationUploder.upload.413": "Файл слишком большой",
+    "app.presentationUploder.conversion.conversionProcessingSlides": "Обработка страницы {0} из {1}",
     "app.presentationUploder.conversion.genericConversionStatus": "Файл конвертируется...",
     "app.presentationUploder.conversion.generatingThumbnail": "Генерируются миниатюры...",
-    "app.presentationUploder.conversion.generatedSlides": "Слайды сгенерированы...",
+    "app.presentationUploder.conversion.generatedSlides": "Слайды генерируются...",
     "app.presentationUploder.conversion.generatingSvg": "Генерация изображений SVG...",
     "app.presentationUploder.conversion.pageCountExceeded": "Ой, достигнут предел количества страниц",
     "app.presentationUploder.conversion.timeout": "Ой, конвертация занимает слишком много времени",
     "app.polling.pollingTitle": "Варианты голосования",
-    "app.failedMessage": "Apologies, trouble connecting to the server.",
+    "app.polling.pollAnswerLabel": "Результат опроса {0}",
+    "app.polling.pollAnswerDesc": "Выберите этот вариант, чтобы проголосовать за {0}",
+    "app.failedMessage": "Извините, проблемы с подключением к серверу.",
     "app.connectingMessage": "Подключение...",
     "app.waitingMessage": "Соединение потеряно. Попытка переподключения через {0} секунд...",
     "app.navBar.settingsDropdown.optionsLabel": "Опции",
@@ -87,9 +95,12 @@
     "app.navBar.settingsDropdown.aboutDesc": "Показать информацию о клиенте",
     "app.navBar.settingsDropdown.leaveSessionDesc": "Покинуть конференцию",
     "app.navBar.settingsDropdown.exitFullscreenDesc": "Выйти из полноэкранного режима",
+    "app.navBar.settingsDropdown.hotkeysLabel": "Быстрые клавиши",
+    "app.navBar.settingsDropdown.hotkeysDesc": "Список доступных быстрых клавиш",
     "app.navBar.userListToggleBtnLabel": "Включить/выключить список пользователей",
+    "app.navBar.toggleUserList.ariaLabel": "Включить/выключить Пользователей и Сообщения",
     "app.navBar.toggleUserList.newMessages": "с уведомлением о новых сообщениях",
-    "app.navBar.recording": "Этот сеанс будет записан",
+    "app.navBar.recording": "Этот сеанс записывается",
     "app.navBar.recording.on": "Записывается",
     "app.navBar.recording.off": "Не записывается",
     "app.leaveConfirmation.title": "Покинуть сеанс",
@@ -97,8 +108,9 @@
     "app.leaveConfirmation.confirmLabel": "Выйти",
     "app.leaveConfirmation.confirmDesc": "Выйти из конференции",
     "app.leaveConfirmation.dismissLabel": "Отмена",
-    "app.leaveConfirmation.dismissDesc": "Не выходить из конференции",
+    "app.leaveConfirmation.dismissDesc": "Закрывает и отклоняет подтверждение о выходе",
     "app.leaveConfirmation.endMeetingLabel": "Да, завершить сеанс",
+    "app.leaveConfirmation.endMeetingAriaLabel": "Покинуть и завершить сеанс",
     "app.leaveConfirmation.endMeetingDesc": "Подтвердить завершение конференции",
     "app.about.title": "О программе",
     "app.about.version": "Сборка клиента:",
@@ -115,7 +127,7 @@
     "app.actionsBar.label": "Панель действий",
     "app.submenu.application.applicationSectionTitle": "Приложение",
     "app.submenu.application.audioNotifyLabel": "Звуковые уведомления чата",
-    "app.submenu.application.pushNotifyLabel": "Пуш уведомления чата",
+    "app.submenu.application.pushNotifyLabel": "Push-уведомления для чата",
     "app.submenu.application.fontSizeControlLabel": "Размер шрифта",
     "app.submenu.application.increaseFontBtnLabel": "Увеличить шрифт приложения",
     "app.submenu.application.decreaseFontBtnLabel": "Уменьшить шрифт приложения",
@@ -123,8 +135,8 @@
     "app.submenu.application.ariaLanguageLabel": "Изменить язык приложения",
     "app.submenu.application.languageOptionLabel": "Выберите язык",
     "app.submenu.application.noLocaleOptionLabel": "Нет доступных переводов",
-    "app.submenu.audio.micSourceLabel": "Микрофон",
-    "app.submenu.audio.speakerSourceLabel": "Динамики",
+    "app.submenu.audio.micSourceLabel": "Источник микрофона",
+    "app.submenu.audio.speakerSourceLabel": "Источник динамиков",
     "app.submenu.audio.streamVolumeLabel": "Громкость аудио-потока",
     "app.submenu.video.title": "Видео",
     "app.submenu.video.videoSourceLabel": "Видео-источник",
@@ -171,7 +183,9 @@
     "app.settings.main.cancel.label.description": "Сбрасывает изменения и закрывает меню настроек",
     "app.settings.main.save.label": "Сохранить",
     "app.settings.main.save.label.description": "Сохраняет изменения и закрывает меню настроек",
-    "app.settings.dataSavingTab.label": "Экономия данных",
+    "app.settings.dataSavingTab.label": "Сохранение данных",
+    "app.settings.dataSavingTab.webcam": "Включить веб камеры",
+    "app.settings.dataSavingTab.screenShare": "Включить демонстрацию рабочего стола",
     "app.settings.dataSavingTab.description": "Чтобы сохранить устойчивую скорость соединения, выберите, что будет отображаться",
     "app.switch.onLabel": "ВКЛ",
     "app.switch.offLabel": "ВЫКЛ",
@@ -179,63 +193,71 @@
     "app.actionsBar.actionsDropdown.presentationLabel": "Загрузить презентацию",
     "app.actionsBar.actionsDropdown.initPollLabel": "Начать опрос",
     "app.actionsBar.actionsDropdown.desktopShareLabel": "Демонстировать ваш экран",
-    "app.actionsBar.actionsDropdown.stopDesktopShareLabel": "Оставить демонстрацию экрана",
+    "app.actionsBar.actionsDropdown.stopDesktopShareLabel": "Остановить демонстрацию экрана",
     "app.actionsBar.actionsDropdown.presentationDesc": "Загрузите вашу презентацию",
     "app.actionsBar.actionsDropdown.initPollDesc": "Начать опрос",
     "app.actionsBar.actionsDropdown.desktopShareDesc": "Демонстрировать ваш экран другим участникам",
-    "app.actionsBar.actionsDropdown.stopDesktopShareDesc": "Не демонстрировать ваш экран ",
+    "app.actionsBar.actionsDropdown.stopDesktopShareDesc": "Остановить демонстрацию экрана ",
     "app.actionsBar.actionsDropdown.startRecording": "Начать запись",
     "app.actionsBar.actionsDropdown.stopRecording": "Остановить запись",
+    "app.actionsBar.emojiMenu.statusTriggerLabel": "Установить статус",
     "app.actionsBar.emojiMenu.awayLabel": "Отошел",
-    "app.actionsBar.emojiMenu.awayDesc": "Изменить ваш статус на \"Отошел\"",
+    "app.actionsBar.emojiMenu.awayDesc": "Изменяет ваш статус на \"Отошел\"",
     "app.actionsBar.emojiMenu.raiseHandLabel": "Поднять руку",
     "app.actionsBar.emojiMenu.raiseHandDesc": "Поднять руку, чтобы задать вопрос",
     "app.actionsBar.emojiMenu.neutralLabel": "Нерешительный",
-    "app.actionsBar.emojiMenu.neutralDesc": "Изменить ваш статус на \"Нерешительный\"",
+    "app.actionsBar.emojiMenu.neutralDesc": "Изменяет ваш статус на \"Нерешительный\"",
     "app.actionsBar.emojiMenu.confusedLabel": "Смущен",
-    "app.actionsBar.emojiMenu.confusedDesc": "Изменить ваш статус на \"Смущен\"",
+    "app.actionsBar.emojiMenu.confusedDesc": "Изменяет ваш статус на \"Смущен\"",
     "app.actionsBar.emojiMenu.sadLabel": "Грустный",
-    "app.actionsBar.emojiMenu.sadDesc": "Изменить ваш статус на \"Грустный\"",
+    "app.actionsBar.emojiMenu.sadDesc": "Изменяет ваш статус на \"Грустный\"",
     "app.actionsBar.emojiMenu.happyLabel": "Счастливый",
-    "app.actionsBar.emojiMenu.happyDesc": "Изменить ваш статус на \"Счастливый\"",
-    "app.actionsBar.emojiMenu.noneDesc": "Очистить ваш статус",
+    "app.actionsBar.emojiMenu.happyDesc": "Изменяет ваш статус на \"Счастливый\"",
+    "app.actionsBar.emojiMenu.noneLabel": "Очистить статус",
+    "app.actionsBar.emojiMenu.noneDesc": "Очищает ваш статус",
     "app.actionsBar.emojiMenu.applauseLabel": "Апплодисменты",
-    "app.actionsBar.emojiMenu.applauseDesc": "Изменить ваш статус на \"Аплодисменты\"",
+    "app.actionsBar.emojiMenu.applauseDesc": "Изменяет ваш статус на \"Аплодисменты\"",
     "app.actionsBar.emojiMenu.thumbsUpLabel": "Нравится",
-    "app.actionsBar.emojiMenu.thumbsUpDesc": "Изменить ваш статус на \"Нравится\"",
+    "app.actionsBar.emojiMenu.thumbsUpDesc": "Изменяет ваш статус на \"Нравится\"",
     "app.actionsBar.emojiMenu.thumbsDownLabel": "Не нравится",
-    "app.actionsBar.emojiMenu.thumbsDownDesc": "Изменить ваш статус на \"Не нравится\"",
+    "app.actionsBar.emojiMenu.thumbsDownDesc": "Изменяет ваш статус на \"Не нравится\"",
     "app.actionsBar.currentStatusDesc": "текущий статус {0}",
-    "app.audioNotification.audioFailedError1001": "Ошибка 1001: Соединение закрыто",
-    "app.audioNotification.audioFailedError1002": "Ошибка 1002: невозможно установить соединение",
-    "app.audioNotification.audioFailedError1003": "Ошибка 1003: версия браузера не поддерживается",
-    "app.audioNotification.audioFailedError1004": "Ошибка 1004: Failure on call",
-    "app.audioNotification.audioFailedError1005": "Ошибка 1005: Call ended unexpectedly",
-    "app.audioNotification.audioFailedError1006": "Ошибка 1006: Call timed out",
-    "app.audioNotification.audioFailedError1007": "Ошибка 1007: ICE negotiation failed",
-    "app.audioNotification.audioFailedError1008": "Ошибка 1008: сбой передачи",
+    "app.audioNotification.audioFailedError1001": "Ошибка 1001: WebSocket отключен",
+    "app.audioNotification.audioFailedError1002": "Ошибка 1002: Не удалось установить соединение WebSocket",
+    "app.audioNotification.audioFailedError1003": "Ошибка 1003: Версия браузера не поддерживается",
+    "app.audioNotification.audioFailedError1004": "Ошибка 1004: Сбой вызова",
+    "app.audioNotification.audioFailedError1005": "Ошибка 1005: Вызов внезапно прервался",
+    "app.audioNotification.audioFailedError1006": "Ошибка 1006: Время вызова истекло",
+    "app.audioNotification.audioFailedError1007": "Ошибка 1007: Согласование ICE не состоялось",
+    "app.audioNotification.audioFailedError1008": "Ошибка 1008: Сбой передачи",
     "app.audioNotification.audioFailedError1009": "Ошибка 1009: не удалось получить информацию STUN/TURN сервера",
-    "app.audioNotification.audioFailedError1010": "Ошибка 1010: ICE negotiation timeout",
-    "app.audioNotification.audioFailedError1011": "Ошибка 1011: ICE gathering timeout",
+    "app.audioNotification.audioFailedError1010": "Ошибка 1010: Время согласования ICE истекло ",
+    "app.audioNotification.audioFailedError1011": "Ошибка 1011: Превышено время сбора ICE",
     "app.audioNotification.audioFailedMessage": "Не удалось установить аудио-соединение",
     "app.audioNotification.mediaFailedMessage": "Ошибка getUserMicMedia, разрешены только безопасные источники",
     "app.audioNotification.closeLabel": "Закрыть",
     "app.breakoutJoinConfirmation.title": "Присоединиться к комнате групповой работы",
     "app.breakoutJoinConfirmation.message": "Вы хотите присоединиться к ",
     "app.breakoutJoinConfirmation.confirmLabel": "Присоединиться",
-    "app.breakoutJoinConfirmation.confirmDesc": "Join you to the Breakout Room",
+    "app.breakoutJoinConfirmation.confirmDesc": "Присоединяет вас к конференции",
     "app.breakoutJoinConfirmation.dismissLabel": "Отмена",
-    "app.breakoutJoinConfirmation.dismissDesc": "Закрыть и отменить присоединение",
+    "app.breakoutJoinConfirmation.dismissDesc": "Закрывает и отклоняет присоединение к конференции",
+    "app.breakoutTimeRemainingMessage": "Оставшееся время конференции: {0}",
     "app.breakoutWillCloseMessage": "Время вышло. Комната групповой работы скоро закроется.",
     "app.calculatingBreakoutTimeRemaining": "Подсчёт оставшегося времени...",
     "app.audioModal.microphoneLabel": "Микрофон",
     "app.audioModal.listenOnlyLabel": "Только слушать",
-    "app.audioModal.audioChoiceLabel": "Как вы хотите использовать звуковое соединение?",
+    "app.audioModal.audioChoiceLabel": "Как вы хотите войти в аудио-конференцию?",
+    "app.audioModal.iOSBrowser": "Аудио/Видео не поддерживается",
+    "app.audioModal.iOSErrorDescription": "В настоящее время аудио и видео не поддерживаются в Chrome для iOS.",
+    "app.audioModal.iOSErrorRecommendation": "Мы рекомендуем использовать Safari для iOS.",
     "app.audioModal.audioChoiceDesc": "Выберите, как участвовать в аудио-конференции",
     "app.audioModal.closeLabel": "Закрыть",
     "app.audioModal.yes": "Да",
     "app.audioModal.no": "Нет",
-    "app.audioModal.echoTestTitle": "Это тестирование звука, его слышите только вы. Скажите несколько слов в микрофон: слышите ли вы себя в динамиках?",
+    "app.audioModal.yes.arialabel" : "Звучит эхо",
+    "app.audioModal.no.arialabel" : "Эхо не звучит",
+    "app.audioModal.echoTestTitle": "Это тестирование звука, его слышите только вы. Скажите несколько слов в микрофон. Слышите ли вы себя в динамиках?",
     "app.audioModal.settingsTitle": "Изменить настройки звука",
     "app.audioModal.helpTitle": "Возникли проблемы с вашими аудио-устройствами",
     "app.audioModal.helpText": "Дали ли вы BigBlueButton разрешение на использование вашего микрофона? Когда вы подключаете аудио, вы должны увидеть диалог запроса доступа к аудио-устройствам - вы должны предоставить доступ, чтобы учавствовать в аудио-конференции. Если этого не произошло, попробуйте изменить настройки доступа к микрофону в настройках вашего браузера.",
@@ -247,9 +269,10 @@
     "app.audioManager.genericError": "Ошибка: что-то пошло не так, пожалуйста, попробуйте еще раз",
     "app.audioManager.connectionError": "Ошибка: подключение не удалось",
     "app.audioManager.requestTimeout": "Ошибка: время ожидания подключения истекло",
+    "app.audioManager.invalidTarget": "Ошибка: Попытка запросить что-то от неверной цели",
     "app.audioManager.mediaError": "Ошибка: возникла проблема с вашими аудио-устройствами",
-    "app.audio.joinAudio": "Подключиться к аудио",
-    "app.audio.leaveAudio": "Покинуть аудио",
+    "app.audio.joinAudio": "Присоединиться к аудио-конференции",
+    "app.audio.leaveAudio": "Покинуть аудио-конференцию",
     "app.audio.enterSessionLabel": "Подключиться к сеансу",
     "app.audio.playSoundLabel": "Проиграть звук",
     "app.audio.backLabel": "Назад",
@@ -272,16 +295,45 @@
     "app.error.403": "Доступ запрещен",
     "app.error.leaveLabel": "Зайдите снова",
     "app.guest.waiting": "Ожидание одобрения входа",
+    "app.toast.breakoutRoomEnded": "Конференция закончилась. Пожалуйста, присоединитесь снова к аудио конференции.",
+    "app.toast.chat.public": "Новое сообщение в публичном чате",
+    "app.toast.chat.private": "Новое сообщение в приватном чате",
+    "app.toast.chat.system": "Система",
     "app.notification.recordingStart": "Этот сеанс записывается",
     "app.notification.recordingStop": "Этот сеанс больше не будет записан",
-    "app.video.joinVideo": "Включить веб-камеру",
-    "app.video.leaveVideo": "Отключить веб-камеру",
+    "app.shortcut-help.title": "Клавиши быстрого доступа",
+    "app.shortcut-help.accessKeyNotAvailable": "Доступ к ключам недоступен.",
+    "app.shortcut-help.comboLabel": "Комбо",
+    "app.shortcut-help.functionLabel": "Функция",
+    "app.shortcut-help.closeLabel": "Закрыть",
+    "app.shortcut-help.closeDesc": "Закрывает модальные клавиши быстрого доступа",
+    "app.shortcut-help.openOptions": "Открывает параметры",
+    "app.shortcut-help.toggleUserList": "Включает список пользователей",
+    "app.shortcut-help.toggleMute": "Включает / Выключает микрофон",
+    "app.shortcut-help.togglePublicChat": "Включает публичный чат (Список пользователей должен быть открыт)",
+    "app.shortcut-help.hidePrivateChat": "Прячет приватный чат",
+    "app.shortcut-help.closePrivateChat": "Закрывает приватный чат",
+    "app.shortcut-help.openActions": "Открывает меню действий",
+    "app.shortcut-help.openStatus": "Открывает меню статуса",
+    "app.video.joinVideo": "Транслировать веб-камеру",
+    "app.video.leaveVideo": "Не транслировать веб-камеру",
+    "app.video.iceCandidateError": "Щшибка добавления ice кандидата",
     "app.video.permissionError": "Ошибка. Проверьте разрешение на доступ к веб-камере.",
     "app.video.sharingError": "Ошибка трансляции веб-камеры",
+    "app.video.notFoundError": "Невозможно найти веб-камеру. Пожалуйста, проверте присоединена ли она",
+    "app.video.notAllowed": "Отсутствует разрешение на трансляцию веб-камеры, пожалуйста, убедитесь, что ваш браузер имеет необходиміе разрешения",
+    "app.video.notSupportedError": "Можна транслировать видео с веб-камеры только с безопасных источников, убедитесь, что ваш сертификат SSL действителен",
+    "app.video.notReadableError": "Не удалось получить видео с веб-камеры. Убедитесь, что другая программа не использует веб-камеру",
+    "app.video.mediaServerOffline": "Медиа-сервер отключен. Пожалуйста, повторите попытку позже.",
+    "app.video.swapCam": "Заменить",
+    "app.video.swapCamDesc": "поменять направление веб-камер",
     "app.video.videoMenu": "Меню видео",
+    "app.video.videoMenuDisabled": "Меню видео веб-камеры отключено в настройках",
     "app.video.videoMenuDesc": "Открыть выпадающее меню видео",
     "app.video.chromeExtensionError": "Вы должны установить",
     "app.video.chromeExtensionErrorLink": "это расширение Chrome",
+    "app.video.stats.title": "Статистика подключений",
+    "app.video.stats.packetsReceived": "Полученные пакеты",
     "app.meeting.endNotification.ok.label": "ОК",
     "app.whiteboard.toolbar.tools": "Инструменты",
     "app.whiteboard.toolbar.tools.pencil": "Карандаш",
diff --git a/bigbluebutton-html5/private/locales/uk_UA.json b/bigbluebutton-html5/private/locales/uk_UA.json
index b662006f61f57751dbefaa8b99fcf9b37adf7c61..0c4ff779cc9a57cf7e6ec694685a971ba55d9a99 100644
--- a/bigbluebutton-html5/private/locales/uk_UA.json
+++ b/bigbluebutton-html5/private/locales/uk_UA.json
@@ -3,7 +3,7 @@
     "app.chat.submitLabel": "Надіслати повідомлення",
     "app.chat.errorMinMessageLength": "Повідомлення із {0} символа(-ів) занадто коротке",
     "app.chat.errorMaxMessageLength": "Повідомлення із {0} символа(-ів) занадто довге",
-    "app.chat.inputLabel": "Message input for chat {0}",
+    "app.chat.inputLabel": "Введення повідомлення для чату {0}",
     "app.chat.inputPlaceholder": "Повідомлення {0}",
     "app.chat.titlePublic": "Загальний чат",
     "app.chat.titlePrivate": "Приватний чат з {0}",
@@ -25,28 +25,315 @@
     "app.userList.you": "Ви",
     "app.userList.locked": "Заблокований",
     "app.userList.label": "Список користувачів",
+    "app.userList.toggleCompactView.label": "Увімкнути/вимкнути компактний вид",
+    "app.userList.guest": "Гість",
+    "app.userList.menuTitleContext": "Доступні опції",
+    "app.userList.chatListItem.unreadSingular": "{0} нове повідомлення",
+    "app.userList.chatListItem.unreadPlural": "{0} нових повідомлень",
+    "app.userList.menu.chat.label": "Чат",
+    "app.userList.menu.clearStatus.label": "Очистити статус",
+    "app.userList.menu.makePresenter.label": "Зробити ведучим",
+    "app.userList.menu.removeUser.label": "Виключити користувача",
+    "app.userList.menu.muteUserAudio.label": "Вимкнути мікрофон користувача",
+    "app.userList.menu.unmuteUserAudio.label": "Увімкнути мікрофон користувача",
+    "app.userList.userAriaLabel": "{0} {1} {2}  Статус {3}",
+    "app.userList.menu.promoteUser.label": "Підвищити {0} до модератора",
+    "app.userList.menu.demoteUser.label": "Понизити {0} до глядача",
+    "app.media.label": "Медія",
+    "app.media.screenshare.start": "Демонстрація екрану розпочалася",
+    "app.media.screenshare.end": "Демонстрацію екрану закінчено",
+    "app.media.screenshare.safariNotSupported": "Демонстрація екрану наразі не підтримується Safari. Будь ласка, використовуйте Firefox або Google Chrome.",
+    "app.meeting.ended": "Ця сесія завершилася",
+    "app.meeting.endedMessage": "Ви будете перенаправлені на головний екран",
     "app.presentation.presentationToolbar.prevSlideLabel": "Попередній слайд",
+    "app.presentation.presentationToolbar.prevSlideDesc": "Перемкнути презентацію на попередній слайд",
     "app.presentation.presentationToolbar.nextSlideLabel": "Наступний слайд",
-    "app.presentation.presentationToolbar.zoomLabel": "Масштаб презентації",
+    "app.presentation.presentationToolbar.nextSlideDesc": "Перемкнути презентацію на наступний слайд",
+    "app.presentation.presentationToolbar.skipSlideLabel": "Пропустити слайд",
+    "app.presentation.presentationToolbar.skipSlideDesc": "Перемкнути презентацію на вказаний слайд",
+    "app.presentation.presentationToolbar.fitWidthLabel": "Підігнати по ширині",
+    "app.presentation.presentationToolbar.fitWidthDesc": "Показати всю ширину слайда",
+    "app.presentation.presentationToolbar.fitScreenLabel": "Підігнати до екрана",
+    "app.presentation.presentationToolbar.fitScreenDesc": "Показати весь слайд",
+    "app.presentation.presentationToolbar.zoomLabel": "Масштаб",
+    "app.presentation.presentationToolbar.zoomDesc": "Змінити масштаб презентації",
+    "app.presentation.presentationToolbar.goToSlide": "Слайд {0}",
+    "app.presentationUploder.title": "Презентація",
+    "app.presentationUploder.message": "Як ведучий у BigBlueButton, ви маєте можливість завантажувати будь-який офісний документ або файл PDF. Ми рекомендуємо завантажувати файл PDF для отримання найкращих результатів.",
+    "app.presentationUploder.confirmLabel": "Почати",
+    "app.presentationUploder.confirmDesc": "Зберегти зміни та розпочати презентацію",
+    "app.presentationUploder.dismissLabel": "Відмінити",
+    "app.presentationUploder.dismissDesc": "Закрити вікно зображення та скасувати зміни",
+    "app.presentationUploder.dropzoneLabel": "Перетягніть файли сюди, щоб завантажити",
+    "app.presentationUploder.browseFilesLabel": "або виберіть файл",
+    "app.presentationUploder.fileToUpload": "Щоб завантажити",
+    "app.presentationUploder.currentBadge": "Поточний",
+    "app.presentationUploder.genericError": "Ой, щось пішло не так",
+    "app.presentationUploder.upload.progress": "Завантаження ({0}%)",
+    "app.presentationUploder.upload.413": "Файл занадто великий",
+    "app.presentationUploder.conversion.conversionProcessingSlides": "Обробка сторінки {0} з {1}",
+    "app.presentationUploder.conversion.genericConversionStatus": "Файл конвертується...",
+    "app.presentationUploder.conversion.generatingThumbnail": "Генерування мініатюр...",
+    "app.presentationUploder.conversion.generatedSlides": "Слайди генеруються...",
+    "app.presentationUploder.conversion.generatingSvg": "Генерація слайдів SVG...",
+    "app.presentationUploder.conversion.pageCountExceeded": "Ой, кількість сторінок перевищила ліміт",
+    "app.presentationUploder.conversion.timeout": "Ой, перетворення займає надто багато часу",
+    "app.polling.pollingTitle": "Варіанти опитування",
+    "app.polling.pollAnswerLabel": "Результат опитування {0}",
+    "app.polling.pollAnswerDesc": "Виберіть цей варіант щоб проголосувати за {0}",
+    "app.failedMessage": "Вибачте, проблеми з підключенням до сервера.",
     "app.connectingMessage": "З'єднання...",
+    "app.waitingMessage": "Втрачено з'еднання. Спроба повторного підключення через {0} секунд...",
     "app.navBar.settingsDropdown.optionsLabel": "Опції",
-    "app.navBar.settingsDropdown.settingsLabel": "Відкрити настройки",
+    "app.navBar.settingsDropdown.fullscreenLabel": "Розгорнути на весь екран",
+    "app.navBar.settingsDropdown.settingsLabel": "Відкрити параметри",
     "app.navBar.settingsDropdown.aboutLabel": "Про програму",
     "app.navBar.settingsDropdown.leaveSessionLabel": "Вихід",
-    "app.navBar.settingsDropdown.settingsDesc": "Змінити загальні настройки",
-    "app.navBar.settingsDropdown.aboutDesc": "Show information about the client",
+    "app.navBar.settingsDropdown.exitFullscreenLabel": "Вийти з повноекранного режиму",
+    "app.navBar.settingsDropdown.fullscreenDesc": "Розгорнути меню параметрів на весь екран",
+    "app.navBar.settingsDropdown.settingsDesc": "Змінити загальні параметри",
+    "app.navBar.settingsDropdown.aboutDesc": "Показати інформацію про клієнта",
     "app.navBar.settingsDropdown.leaveSessionDesc": "Залишити конференцію",
+    "app.navBar.settingsDropdown.exitFullscreenDesc": "Вийти з повноекранного режиму",
+    "app.navBar.settingsDropdown.hotkeysLabel": "Швидкі клавіши",
+    "app.navBar.settingsDropdown.hotkeysDesc": "Перелік наявних швидких клавіш",
+    "app.navBar.userListToggleBtnLabel": "Увімкнути/вимкнути список користувачів",
+    "app.navBar.toggleUserList.ariaLabel": "Увімкнути/вимкнути Користувачів та Повідомлення",
+    "app.navBar.toggleUserList.newMessages": "зі сповіщенням про нове повідомлення",
+    "app.navBar.recording": "Ця сесія записується",
+    "app.navBar.recording.on": "Записується",
+    "app.navBar.recording.off": "Не записується",
     "app.leaveConfirmation.title": "Залишити сесію",
     "app.leaveConfirmation.message": "Ви впевнені, що хочете залишити цю конференцію?",
-    "app.leaveConfirmation.confirmLabel": "Вихід",
+    "app.leaveConfirmation.confirmLabel": "Вийти",
+    "app.leaveConfirmation.confirmDesc": "Вийти з конференції",
     "app.leaveConfirmation.dismissLabel": "Відміна",
+    "app.leaveConfirmation.dismissDesc": "Закриває та відхиляє підтвердження про вихід",
+    "app.leaveConfirmation.endMeetingLabel": "Так, залишити сесію",
+    "app.leaveConfirmation.endMeetingAriaLabel": "Покинути та завершити сесію",
+    "app.leaveConfirmation.endMeetingDesc": "Підтвердити завершення конференції",
     "app.about.title": "Про програму",
+    "app.about.version": "Збірка клієнта:",
     "app.about.copyright": "Авторське право:",
+    "app.about.confirmLabel": "OK",
+    "app.about.confirmDesc": "OK",
     "app.about.dismissLabel": "Відміна",
+    "app.about.dismissDesc": "Закрити інформацію про клієнта",
     "app.actionsBar.changeStatusLabel": "Змінити статус",
     "app.actionsBar.muteLabel": "Вимкнути мікрофон",
     "app.actionsBar.unmuteLabel": "Увімкнути мікрофон",
-    "app.actionsBar.camOffLabel": "Вимкнути камеру"
+    "app.actionsBar.camOffLabel": "Вимкнути камеру",
+    "app.actionsBar.raiseLabel": "Підняти",
+    "app.actionsBar.label": "Панель дій",
+    "app.submenu.application.applicationSectionTitle": "Застосунок",
+    "app.submenu.application.audioNotifyLabel": "Аудіо сповіщення чату",
+    "app.submenu.application.pushNotifyLabel": "Push-сповіщення для чату",
+    "app.submenu.application.fontSizeControlLabel": "Розмір шрифту",
+    "app.submenu.application.increaseFontBtnLabel": "Збільшити шрифт застосунку",
+    "app.submenu.application.decreaseFontBtnLabel": "Зменшити шрифт застосунку",
+    "app.submenu.application.languageLabel": "Мова застосунку",
+    "app.submenu.application.ariaLanguageLabel": "Змінити мову застосунку",
+    "app.submenu.application.languageOptionLabel": "Вибрати мову",
+    "app.submenu.application.noLocaleOptionLabel": "Відсутні доступні переклади",
+    "app.submenu.audio.micSourceLabel": "Джерело мікрофона",
+    "app.submenu.audio.speakerSourceLabel": "Джерело динаміків",
+    "app.submenu.audio.streamVolumeLabel": "Гучність аудіо потоку",
+    "app.submenu.video.title": "Відео",
+    "app.submenu.video.videoSourceLabel": "Джерело відео",
+    "app.submenu.video.videoOptionLabel": "Виберіть джерело відео",
+    "app.submenu.video.videoQualityLabel": "Якість відео",
+    "app.submenu.video.qualityOptionLabel": "Виберіть якість відео",
+    "app.submenu.video.participantsCamLabel": "Перегляд веб-камер учасників",
+    "app.submenu.closedCaptions.closedCaptionsLabel": "Субтитри",
+    "app.submenu.closedCaptions.takeOwnershipLabel": "Перехопити",
+    "app.submenu.closedCaptions.languageLabel": "Мова",
+    "app.submenu.closedCaptions.localeOptionLabel": "Виберіть мову",
+    "app.submenu.closedCaptions.noLocaleOptionLabel": "Відсутні доступні переклади",
+    "app.submenu.closedCaptions.fontFamilyLabel": "Шрифт",
+    "app.submenu.closedCaptions.fontFamilyOptionLabel": "Виберіть шрифт",
+    "app.submenu.closedCaptions.fontSizeLabel": "Розмір шрифту",
+    "app.submenu.closedCaptions.fontSizeOptionLabel": "Виберіть розмір шрифту",
+    "app.submenu.closedCaptions.backgroundColorLabel": "Колір фону",
+    "app.submenu.closedCaptions.fontColorLabel": "Колір шрифта",
+    "app.submenu.participants.muteAllLabel": "Вимкнути мікрофони у всіх окрім ведучого",
+    "app.submenu.participants.lockAllLabel": "Заблокувати всіх учасників",
+    "app.submenu.participants.lockItemLabel": "Учасники {0}",
+    "app.submenu.participants.lockMicDesc": "Вимикає мікрофони усіх заблокованих учасників",
+    "app.submenu.participants.lockCamDesc": "Вимикає веб-камери усіх заблокованих учасників",
+    "app.submenu.participants.lockPublicChatDesc": "Вимикає загальний чат для усіх заблокованих учасників",
+    "app.submenu.participants.lockPrivateChatDesc": "Вимикає приватний чат для усіх заблокованих учасників",
+    "app.submenu.participants.lockLayoutDesc": "Блокує розміщення вікон для усіх заблокованих учасників",
+    "app.submenu.participants.lockMicAriaLabel": "Блокувати мікрофон",
+    "app.submenu.participants.lockCamAriaLabel": "Блокувати веб-камеру",
+    "app.submenu.participants.lockPublicChatAriaLabel": "Блокувати публічний чат",
+    "app.submenu.participants.lockPrivateChatAriaLabel": "Блокувати приватний чат",
+    "app.submenu.participants.lockLayoutAriaLabel": "Блокувати розміщення вікон",
+    "app.submenu.participants.lockMicLabel": "Мікрофон",
+    "app.submenu.participants.lockCamLabel": "Веб-камера",
+    "app.submenu.participants.lockPublicChatLabel": "Публічний чат",
+    "app.submenu.participants.lockPrivateChatLabel": "Приватний чат",
+    "app.submenu.participants.lockLayoutLabel": "Розміщення вікон",
+    "app.settings.applicationTab.label": "Застосунок",
+    "app.settings.audioTab.label": "Аудіо",
+    "app.settings.videoTab.label": "Відео",
+    "app.settings.closedcaptionTab.label": "Субтитри",
+    "app.settings.usersTab.label": "Учасники",
+    "app.settings.main.label": "Налаштування",
+    "app.settings.main.cancel.label": "Відмінити",
+    "app.settings.main.cancel.label.description": "Відміняє зміни та закриває меню налаштувань",
+    "app.settings.main.save.label": "Зберегти",
+    "app.settings.main.save.label.description": "Зберігає зміни та закриває меню налаштувань",
+    "app.settings.dataSavingTab.label": "Збереження даних",
+    "app.settings.dataSavingTab.webcam": "Увімкнути веб-камери",
+    "app.settings.dataSavingTab.screenShare": "Увімкнути демонстрацію робочого столу",
+    "app.settings.dataSavingTab.description": "Щоб зберегти пропускну здатність, виберіть що зараз буде відображатись.",
+    "app.switch.onLabel": "УВІМК.",
+    "app.switch.offLabel": "ВИМК.",
+    "app.actionsBar.actionsDropdown.actionsLabel": "Дії",
+    "app.actionsBar.actionsDropdown.presentationLabel": "Завантажити презентацію",
+    "app.actionsBar.actionsDropdown.initPollLabel": "Розпочати опитування",
+    "app.actionsBar.actionsDropdown.desktopShareLabel": "Демонструвати ваш екран",
+    "app.actionsBar.actionsDropdown.stopDesktopShareLabel": "Зупинити демонстрацію екрану",
+    "app.actionsBar.actionsDropdown.presentationDesc": "Завантажити вашу презентацію",
+    "app.actionsBar.actionsDropdown.initPollDesc": "Розпочати опитування",
+    "app.actionsBar.actionsDropdown.desktopShareDesc": "Демонструвати ваш екран іншим учасникам",
+    "app.actionsBar.actionsDropdown.stopDesktopShareDesc": "Зупинити демонстрацію екрану",
+    "app.actionsBar.actionsDropdown.startRecording": "Почати запис",
+    "app.actionsBar.actionsDropdown.stopRecording": "Зупинити запис",
+    "app.actionsBar.emojiMenu.statusTriggerLabel": "Встановити статус",
+    "app.actionsBar.emojiMenu.awayLabel": "Відійшов",
+    "app.actionsBar.emojiMenu.awayDesc": "Змінює ваш статус на \"Відійшов\"",
+    "app.actionsBar.emojiMenu.raiseHandLabel": "Підняти руку",
+    "app.actionsBar.emojiMenu.raiseHandDesc": "Підняти руку щоб поставити питання",
+    "app.actionsBar.emojiMenu.neutralLabel": "Не визначився",
+    "app.actionsBar.emojiMenu.neutralDesc": "Змінює ваш статус на \"Не визначився\"",
+    "app.actionsBar.emojiMenu.confusedLabel": "Збентежений",
+    "app.actionsBar.emojiMenu.confusedDesc": "Змінює ваш статус на \"Збентежений\"",
+    "app.actionsBar.emojiMenu.sadLabel": "Сумний",
+    "app.actionsBar.emojiMenu.sadDesc": "Змінює ваш статус на \"Сумний\"",
+    "app.actionsBar.emojiMenu.happyLabel": "Щасливий",
+    "app.actionsBar.emojiMenu.happyDesc": "Змінює ваш статус на \"Щасливий\"",
+    "app.actionsBar.emojiMenu.noneLabel": "Очистити статус",
+    "app.actionsBar.emojiMenu.noneDesc": "Очищує ваш статус",
+    "app.actionsBar.emojiMenu.applauseLabel": "Оплески",
+    "app.actionsBar.emojiMenu.applauseDesc": "Змінює ваш статус на \"Оплески\"",
+    "app.actionsBar.emojiMenu.thumbsUpLabel": "Подобається",
+    "app.actionsBar.emojiMenu.thumbsUpDesc": "Змінює ваш статус на \"Подобається\"",
+    "app.actionsBar.emojiMenu.thumbsDownLabel": "Не подобається",
+    "app.actionsBar.emojiMenu.thumbsDownDesc": "Змінює ваш статус на \"Не подобається\"",
+    "app.actionsBar.currentStatusDesc": "нинішній статус {0}",
+    "app.audioNotification.audioFailedError1001": "Помилка 1001: WebSocket відключено",
+    "app.audioNotification.audioFailedError1002": "Помилка 1002: Не вдалось встановити з'єднання WebSocket",
+    "app.audioNotification.audioFailedError1003": "Помилка 1003: Версія браузера не підтримується",
+    "app.audioNotification.audioFailedError1004": "Помилка 1004: Збій виклика",
+    "app.audioNotification.audioFailedError1005": "Помилка 1005: Виклик раптово перервався",
+    "app.audioNotification.audioFailedError1006": "Помилка 1006: Час дзвінка минув",
+    "app.audioNotification.audioFailedError1007": "Помилка 1007: Узгодження ICE не відбулось",
+    "app.audioNotification.audioFailedError1008": "Помилка 1008: Передача не вдалась",
+    "app.audioNotification.audioFailedError1009": "Помилка 1009: Не вдалось отримати STUN/TURN інформацію з серверу",
+    "app.audioNotification.audioFailedError1010": "Помилка 1010: Час узгодження ICE вичерпано",
+    "app.audioNotification.audioFailedError1011": "Помилка 1011: Перевищено час збору ICE",
+    "app.audioNotification.audioFailedMessage": "Не вдалося встановити аудіо з'єднання",
+    "app.audioNotification.mediaFailedMessage": "Помилка getUserMicMedia, дозволені тільки безпечні джерела",
+    "app.audioNotification.closeLabel": "Закрити",
+    "app.breakoutJoinConfirmation.title": "Приєднатись до зустрічі",
+    "app.breakoutJoinConfirmation.message": "Чи хочете ви приєднатися до",
+    "app.breakoutJoinConfirmation.confirmLabel": "Приєднатися",
+    "app.breakoutJoinConfirmation.confirmDesc": "Приєднує вас до зустрічі",
+    "app.breakoutJoinConfirmation.dismissLabel": "Скасувати",
+    "app.breakoutJoinConfirmation.dismissDesc": "Закриває та відмовляє в приєднанні до зустрічі",
+    "app.breakoutTimeRemainingMessage": "Час до закінчення конференції: {0}",
+    "app.breakoutWillCloseMessage": "Час вичерпано. Конференцію невдовзі буде закрито",
+    "app.calculatingBreakoutTimeRemaining": "Підрахунок часу що залишився...",
+    "app.audioModal.microphoneLabel": "Мікрофон",
+    "app.audioModal.listenOnlyLabel": "Тільки слухати",
+    "app.audioModal.audioChoiceLabel": "Як ви хочете увійти в аудіо-конференцію?",
+    "app.audioModal.iOSBrowser": "Аудіо/Відео не підтримується",
+    "app.audioModal.iOSErrorDescription": "Наразі аудіо та відео в Chrome для iOS не підтримуються.",
+    "app.audioModal.iOSErrorRecommendation": "Ми рекомендуємо використовувати Safari для iOS.",
+    "app.audioModal.audioChoiceDesc": "Виберіть як брати участь в аудіоконференції",
+    "app.audioModal.closeLabel": "Закрити",
+    "app.audioModal.yes": "Так",
+    "app.audioModal.no": "Ні",
+    "app.audioModal.yes.arialabel" : "Звучить ехо",
+    "app.audioModal.no.arialabel" : "Ехо не звучить",
+    "app.audioModal.echoTestTitle": "Це приватний ехо-тест. Промовте кілька слів. Чи чуєте ви себе в динаміках?",
+    "app.audioModal.settingsTitle": "Змінити налаштування аудіо",
+    "app.audioModal.helpTitle": "З'явилися проблеми з вашими аудіоприладами",
+    "app.audioModal.helpText": "Чи надали ви BigBlueButton дозвіл на доступ до мікрофона? Зверніть увагу що коли ви намагаєтеся приєднатися до аудіоконференції має з'явитися діалогове вікно запитуючи дозволи на підключення медіа-пристрою, будь ласка, прийміть це, щоб приєднатися до аудіоконференції. Якщо цього не відбулося спробуйте змінити дозволи мікрофона у налаштуваннях вашого веб-переглядача.",
+    "app.audioModal.connecting": "Підключення",
+    "app.audioModal.connectingEchoTest": "Підключення до ехо тесту",
+    "app.audioManager.joinedAudio": "Ви приєдналися до аудіоконференції",
+    "app.audioManager.joinedEcho": "Ви приєдналися до ехо тесту",
+    "app.audioManager.leftAudio": "Ви покинули аудіо конференцію",
+    "app.audioManager.genericError": "Помилка: Щось пішло не так, будь ласка, спробуйте ще раз",
+    "app.audioManager.connectionError": "Помилка: Підключення не вдалося",
+    "app.audioManager.requestTimeout": "Помилка: Час очікування підключення вичерпано",
+    "app.audioManager.invalidTarget": "Помилка: Спроба запросити що-небудь від невірної цілі",
+    "app.audioManager.mediaError": "Помилка: Виникли проблеми з вашими аудіопристроями",
+    "app.audio.joinAudio": "Приєднатися до аудіоконференції",
+    "app.audio.leaveAudio": "Залишити аудіоконференцію",
+    "app.audio.enterSessionLabel": "Підключитися до сеансу",
+    "app.audio.playSoundLabel": "Програти звук",
+    "app.audio.backLabel": "Назад",
+    "app.audio.audioSettings.titleLabel": "Виберіть налаштування звуку",
+    "app.audio.audioSettings.descriptionLabel": "Зверніть увагу, що в вашому браузері з'явиться діалогове вікно, що вимагає дозволу вашого мікрофона.",
+    "app.audio.audioSettings.microphoneSourceLabel": "Джерело мікрофона",
+    "app.audio.audioSettings.speakerSourceLabel": "Джерело динаміків",
+    "app.audio.audioSettings.microphoneStreamLabel": "Гучність вашого аудіопотоку",
+    "app.audio.audioSettings.retryLabel": "Повторити",
+    "app.audio.listenOnly.backLabel": "Незад",
+    "app.audio.listenOnly.closeLabel": "Закрити",
+    "app.audio.permissionsOverlay.title": "Дозволити BigBlueButton використовувати ваші медіа-пристрої",
+    "app.audio.permissionsOverlay.hint": "Нам потрібно, щоб ви дозволили нам використовувати свої медіа-пристрої, щоб приєднатись до голосової конференції :)",
+    "app.error.removed": "Ви були вилучені з конференції",
+    "app.error.meeting.ended": "Ви вийшли з конференції",
+    "app.dropdown.close": "Закрити",
+    "app.error.500": "Ой, щось пішло не так",
+    "app.error.404": "Не знайдено",
+    "app.error.401": "Неавторизований",
+    "app.error.403": "Заборонено",
+    "app.error.leaveLabel": "Увійдіть знову",
+    "app.guest.waiting": "Очікування схвалення для приєднання",
+    "app.toast.breakoutRoomEnded": "Конференція закінчилася. Будь ласка, приєднайтесь знову до аудіо конференції.",
+    "app.toast.chat.public": "Нове повідомлення в публічному чаті",
+    "app.toast.chat.private": "Нове повідомлення в приватному чаті",
+    "app.toast.chat.system": "Система",
+    "app.notification.recordingStart": "Цей сеанс наразі записується",
+    "app.notification.recordingStop": "Цей сеанс більше не записується",
+    "app.shortcut-help.title": "Клавіші швидкого доступу",
+    "app.shortcut-help.accessKeyNotAvailable": "Ключі доступу недоступні.",
+    "app.shortcut-help.comboLabel": "Комбо",
+    "app.shortcut-help.functionLabel": "Функція",
+    "app.shortcut-help.closeLabel": "Закрити",
+    "app.shortcut-help.closeDesc": "Закриває модальні клавіші швидкого доступу",
+    "app.shortcut-help.openOptions": "Відкриває параметри",
+    "app.shortcut-help.toggleUserList": "Вмикає список користувачів",
+    "app.shortcut-help.toggleMute": "Вмикає / Вимикає мікрофон",
+    "app.shortcut-help.togglePublicChat": "Вмикає публічеий чат (Список користувачів має бути відкитим)",
+    "app.shortcut-help.hidePrivateChat": "Приховує приватний чат",
+    "app.shortcut-help.closePrivateChat": "Закриває приватний чат",
+    "app.shortcut-help.openActions": "Відкриває меню дій",
+    "app.shortcut-help.openStatus": "Відкриває меню статусу",
+    "app.video.joinVideo": "Транслювати веб-камеру",
+    "app.video.leaveVideo": "Припинити транслювати веб-камеру",
+    "app.video.iceCandidateError": "Помилка при додаванні ice кандидата",
+    "app.video.permissionError": "Помилка при трансляції веб-камерию Будь ласка перевірте дозволи",
+    "app.video.sharingError": "Помилка при трансляції веб-камери",
+    "app.video.notFoundError": "Не вдалося знайти веб-камеру. Переконайтеся, що вона під'єднана",
+    "app.video.notAllowed": "Відсутній дозвіл на трансляцію веб-камери, будь ласка, переконайтеся, що ваш браузер має необхідні дозволи",
+    "app.video.notSupportedError": "Можна транслювати веб-камеру лише з безпечних джерел, переконайтеся, що сертифікат SSL дійсний",
+    "app.video.notReadableError": "Не вдалося отримати відео з веб-камери. Будь ласка, переконайтеся, що інша програма не використовує веб-камеру",
+    "app.video.mediaServerOffline": "Медіасервер відключено. Будь-ласка спробуйте ще раз пізніше.",
+    "app.video.swapCam": "Змінити",
+    "app.video.swapCamDesc": "поміняти напрямок веб-камер",
+    "app.video.videoMenu": "Меню відео",
+    "app.video.videoMenuDisabled": "Меню відео веб-камера відключено в налаштуваннях",
+    "app.video.videoMenuDesc": "Відкрити контекстне меню відео",
+    "app.video.chromeExtensionError": "Ви маєте встановити",
+    "app.video.chromeExtensionErrorLink": "Це розширення Chrome",
+    "app.video.stats.title": "Статистика з'єднань",
+    "app.video.stats.packetsReceived": "Пакети отримані"
 
 }