text: 'use strict';
  
  const { isSupported, connect } = require('twilio-video');
  
  const { isMobile } = require('./browser');
  const joinRoom = require('./joinroom');
  const micLevel = require('./miclevel');
  const selectMedia = require('./selectmedia');
  const selectRoom = require('./selectroom');
  const showError = require('./showerror');
  
  const $modals = $('#modals');
  const $selectMicModal = $('#select-mic', $modals);
  const $selectCameraModal = $('#select-camera', $modals);
  const $showErrorModal = $('#show-error', $modals);
  const $joinRoomModal = $('#join-room', $modals);
  
  // ConnectOptions settings for a video web application.
  const connectOptions = {
    // Available only in Small Group or Group Rooms only. Please set "Room Type"
    // to "Group" or "Small Group" in your Twilio Console:
    // https://www.twilio.com/console/video/configure
    bandwidthProfile: {
      video: {
        dominantSpeakerPriority: 'high',
        mode: 'collaboration',
        clientTrackSwitchOffControl: 'auto',
        contentPreferencesMode: 'auto'
      }
    },
  
    // Available only in Small Group or Group Rooms only. Please set "Room Type"
    // to "Group" or "Small Group" in your Twilio Console:
    // https://www.twilio.com/console/video/configure
    dominantSpeaker: true,
  
    // Comment this line if you are playing music.
    maxAudioBitrate: 16000,
  
    // VP8 simulcast enables the media server in a Small Group or Group Room
    // to adapt your encoded video quality for each RemoteParticipant based on
    // their individual bandwidth constraints. This has no utility if you are
    // using Peer-to-Peer Rooms, so you can comment this line.
    preferredVideoCodecs: [{ codec: 'VP8', simulcast: false}],
  
    // Capture 720p video @ 24 fps.
    video: { height: 1080, frameRate: 24, width: 1920}
  };
  
  // For mobile browsers, limit the maximum incoming video bitrate to 2.5 Mbps.
  // if (isMobile) {
  //   connectOptions
  //     .bandwidthProfile
  //     .video;
  // }
  
  // On mobile browsers, there is the possibility of not getting any media even
  // after the user has given permission, most likely due to some other app reserving
  // the media device. So, we make sure users always test their media devices before
  // joining the Room. For more best practices, please refer to the following guide:
  // https://www.twilio.com/docs/video/build-js-video-application-recommendations-and-best-practices
  const deviceIds = {
    audio: isMobile ? null : localStorage.getItem('audioDeviceId'),
    video: isMobile ? null : localStorage.getItem('videoDeviceId')
  };
  
  /**
   * Select your Room name, your screen name and join.
   * @param [error=null] - Error from the previous Room session, if any
   */
  async function selectAndJoinRoom(error = null) {
  const formData = await selectRoom($joinRoomModal, error);
    if (!formData) {
      // User wants to change the camera and microphone.
      // So, show them the microphone selection modal.
      deviceIds.audio = null;
      deviceIds.video = null;
      return selectMicrophone();
    }
    const { roomName } = formData;
  
    try {
    // Fetch an AccessToken to join the Room.
      const urlSearchParams = new URLSearchParams(window.location.search);
      const params = Object.fromEntries(urlSearchParams.entries())
  
      // Extract the AccessToken from the Response.
      const token = params.token;
  
      // Add the specified audio device ID to ConnectOptions.
      connectOptions.audio = { deviceId: { exact: deviceIds.audio } };
  
      // Add the specified Room name to ConnectOptions.
      connectOptions.name = roomName;
  
      // Add the specified video device ID to ConnectOptions.
      connectOptions.video.deviceId = { exact: deviceIds.video };
      connectOptions.maxVideoBitrate = 8000000;
      connectOptions.video.width = 1920;
      connectOptions.video.height = 1080;
      connectOptions.video.frameRate = 30;
  
      // Join the Room.
      await joinRoom(token, connectOptions);
  
      // After the video session, display the room selection modal.
      return selectAndJoinRoom();
    } catch (error) {
      return selectAndJoinRoom(error);
    }
  }
  
  /**
   * Select your camera.
   */
  async function selectCamera() {
    if (deviceIds.video === null) {
      try {
        deviceIds.video = await selectMedia('video', $selectCameraModal, videoTrack => {
          const $video = $('video', $selectCameraModal);
          videoTrack.attach($video.get(0))
        });
      } catch (error) {
        showError($showErrorModal, error);
        return;
      }
    }
    return selectAndJoinRoom();
  }
  
  /**
   * Select your microphone.
   */
  async function selectMicrophone() {
    if (deviceIds.audio === null) {
      try {
        deviceIds.audio = await selectMedia('audio', $selectMicModal, audioTrack => {
          const $levelIndicator = $('svg rect', $selectMicModal);
          const maxLevel = Number($levelIndicator.attr('height'));
          micLevel(audioTrack, maxLevel, level => $levelIndicator.attr('y', maxLevel - level));
        });
      } catch (error) {
        showError($showErrorModal, error);
        return;
      }
    }
    return selectCamera();
  }
  
  // If the current browser is not supported by twilio-video.js, show an error
  // message. Otherwise, start the application.
  window.addEventListener('load', isSupported ? selectMicrophone : () => {
    showError($showErrorModal, new Error('This browser is not supported.'));
  });
  