text: // _____________________________
  // Cross-Browser-Declarations.js
  
  // animation-frame used in WebM recording
  
  /*jshint -W079 */
  var requestAnimationFrame = window.requestAnimationFrame;
  if (typeof requestAnimationFrame === 'undefined') {
      if (typeof webkitRequestAnimationFrame !== 'undefined') {
          /*global requestAnimationFrame:true */
          requestAnimationFrame = webkitRequestAnimationFrame;
      }
  
      if (typeof mozRequestAnimationFrame !== 'undefined') {
          /*global requestAnimationFrame:true */
          requestAnimationFrame = mozRequestAnimationFrame;
      }
  }
  
  /*jshint -W079 */
  var cancelAnimationFrame = window.cancelAnimationFrame;
  if (typeof cancelAnimationFrame === 'undefined') {
      if (typeof webkitCancelAnimationFrame !== 'undefined') {
          /*global cancelAnimationFrame:true */
          cancelAnimationFrame = webkitCancelAnimationFrame;
      }
  
      if (typeof mozCancelAnimationFrame !== 'undefined') {
          /*global cancelAnimationFrame:true */
          cancelAnimationFrame = mozCancelAnimationFrame;
      }
  }
  
  // WebAudio API representer
  var AudioContext = window.AudioContext;
  
  if (typeof AudioContext === 'undefined') {
      if (typeof webkitAudioContext !== 'undefined') {
          /*global AudioContext:true */
          AudioContext = webkitAudioContext;
      }
  
      if (typeof mozAudioContext !== 'undefined') {
          /*global AudioContext:true */
          AudioContext = mozAudioContext;
      }
  }
  
  /*jshint -W079 */
  var URL = window.URL;
  
  if (typeof URL === 'undefined' && typeof webkitURL !== 'undefined') {
      /*global URL:true */
      URL = webkitURL;
  }
  
  if (typeof navigator !== 'undefined' && typeof navigator.getUserMedia === 'undefined') { // maybe window.navigator?
      if (typeof navigator.webkitGetUserMedia !== 'undefined') {
          navigator.getUserMedia = navigator.webkitGetUserMedia;
      }
  
      if (typeof navigator.mozGetUserMedia !== 'undefined') {
          navigator.getUserMedia = navigator.mozGetUserMedia;
      }
  }
  
  var isEdge = navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveBlob || !!navigator.msSaveOrOpenBlob);
  var isOpera = !!window.opera || navigator.userAgent.indexOf('OPR/') !== -1;
  var isChrome = !isOpera && !isEdge && !!navigator.webkitGetUserMedia;
  
  var MediaStream = window.MediaStream;
  
  if (typeof MediaStream === 'undefined' && typeof webkitMediaStream !== 'undefined') {
      MediaStream = webkitMediaStream;
  }
  
  /*global MediaStream:true */
  if (typeof MediaStream !== 'undefined') {
      if (!('getVideoTracks' in MediaStream.prototype)) {
          MediaStream.prototype.getVideoTracks = function() {
              if (!this.getTracks) {
                  return [];
              }
  
              var tracks = [];
              this.getTracks.forEach(function(track) {
                  if (track.kind.toString().indexOf('video') !== -1) {
                      tracks.push(track);
                  }
              });
              return tracks;
          };
  
          MediaStream.prototype.getAudioTracks = function() {
              if (!this.getTracks) {
                  return [];
              }
  
              var tracks = [];
              this.getTracks.forEach(function(track) {
                  if (track.kind.toString().indexOf('audio') !== -1) {
                      tracks.push(track);
                  }
              });
              return tracks;
          };
      }
  
      if (!('stop' in MediaStream.prototype)) {
          MediaStream.prototype.stop = function() {
              this.getAudioTracks().forEach(function(track) {
                  if (!!track.stop) {
                      track.stop();
                  }
              });
  
              this.getVideoTracks().forEach(function(track) {
                  if (!!track.stop) {
                      track.stop();
                  }
              });
          };
      }
  }
  
  // below function via: http://goo.gl/B3ae8c
  /**
   * @param {number} bytes - Pass bytes and get formafted string.
   * @returns {string} - formafted string
   * @example
   * bytesToSize(1024*1024*5) === '5 GB'
   * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
   */
  function bytesToSize(bytes) {
      var k = 1000;
      var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
      if (bytes === 0) {
          return '0 Bytes';
      }
      var i = parseInt(Math.floor(Math.log(bytes) / Math.log(k)), 10);
      return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
  }
  
  /**
   * @param {Blob} file - File or Blob object. This parameter is required.
   * @param {string} fileName - Optional file name e.g. "Recorded-Video.webm"
   * @example
   * invokeSaveAsDialog(blob or file, [optional] fileName);
   * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
   */
  function invokeSaveAsDialog(file, fileName) {
      if (!file) {
          throw 'Blob object is required.';
      }
  
      if (!file.type) {
          try {
              file.type = 'video/webm';
          } catch (e) {}
      }
  
      var fileExtension = (file.type || 'video/webm').split('/')[1];
  
      if (fileName && fileName.indexOf('.') !== -1) {
          var splitted = fileName.split('.');
          fileName = splitted[0];
          fileExtension = splitted[1];
      }
  
      var fileFullName = (fileName || (Math.round(Math.random() * 9999999999) + 888888888)) + '.' + fileExtension;
  
      if (typeof navigator.msSaveOrOpenBlob !== 'undefined') {
          return navigator.msSaveOrOpenBlob(file, fileFullName);
      } else if (typeof navigator.msSaveBlob !== 'undefined') {
          return navigator.msSaveBlob(file, fileFullName);
      }
  
      var hyperlink = document.createElement('a');
      hyperlink.href = URL.createObjectURL(file);
      hyperlink.target = '_blank';
      hyperlink.download = fileFullName;
  
      if (!!navigator.mozGetUserMedia) {
          hyperlink.onclick = function() {
              (document.body || document.documentElement).removeChild(hyperlink);
          };
          (document.body || document.documentElement).appendChild(hyperlink);
      }
  
      var evt = new MouseEvent('click', {
          view: window,
          bubbles: true,
          cancelable: true
      });
  
      hyperlink.dispatchEvent(evt);
  
      if (!navigator.mozGetUserMedia) {
          URL.revokeObjectURL(hyperlink.href);
      }
  }
  