<commit_before>/* This Source Code Form is subject to the terms of the MIT license
 * If a copy of the MIT license was not distributed with this file, you can
 * obtain one at https://raw.github.com/mozilla/butter/master/LICENSE */

define( [ "util/mediatypes", "editor/editor", "util/time",
          "util/uri", "ui/widget/textbox", "text!layouts/sequencer-editor.html"  ],
  function( MediaUtils, Editor, Time, URI, Textbox, LAYOUT_SRC ) {

  Editor.register( "sequencer", LAYOUT_SRC,
    function( rootElement, butter ) {
    var _this = this;

    var _rootElement = rootElement,
        _trackEvent,
        _butter,
        _manifest,
        _popcornOptions,
        _mediaType;

    var _fields = {};

      // Creates an "off-on" toggler
      function Toggler( el, property, isReverse, customUpdateUI ) {
        var hiddenInput = el.querySelector( "input" );

        function updateUI() {
          var val = _popcornOptions[ property ];
          if ( val && !isReverse || !val && isReverse ) {
            el.classList.add( "on" );
          } else {
            el.classList.remove( "on" );
          }
          hiddenInput.checked = val;
          if ( customUpdateUI ) {
            customUpdateUI( el );
          }
        }

        function updateTrackEvent( val ) {
          var properties = {};
          properties[ property ] = val;
          updateUI( val );
          _this.updateTrackEventSafe( _trackEvent, properties );
        }

        el.addEventListener( "click", function() {
          // Toggle the state
          updateTrackEvent( !hiddenInput.checked );
        }, false );

        updateUI( _popcornOptions[ property ] );

        return {
          el: el,
          updateUI: updateUI,
        };

      }

      // Creates a standard input
      function Input( el, property, callback, customUpdate ) {
        _this.attachInputChangeHandler( el, _trackEvent, property, callback );

        function updateUI() {
          var val = _popcornOptions[ property ];
          el.value = val;
          if ( customUpdate ) {
            customUpdate( el );
          }
        }

        updateUI( _popcornOptions[ property ] );

        return {
          el: el,
          updateUI: updateUI
        };
      }

      function StartEnd( el ) {
        var container = _this.createStartEndInputs( _trackEvent, _this.updateTrackEventSafe ),
            startEl = container.querySelector( "[data-manifest-key=start]" ),
            endEl = container.querySelector( "[data-manifest-key=end]" );

        el.appendChild( container );

        function updateUI() {
          startEl.value = Time.toTimecode( _popcornOptions.start );
          endEl.value = Time.toTimecode( _popcornOptions.end );
        }

        updateUI();

        return {
          el: el,
          updateUI: updateUI
        };
      }

      // Our custom trimmer thingy
      function Trimmer( el ) {

        var MIN_VISUAL_WIDTH = 5;

        var rightHandle = el.querySelector( ".trimmer-resizable-e" ),
            leftHandle = el.querySelector( ".trimmer-resizable-w" ),
            outInput = _rootElement.querySelector( ".trimmer-input-right" ),
            inInput = _rootElement.querySelector( ".trimmer-input-left" ),
            clipSection = el.querySelector( ".clip-section" ),
            clipEndLable = el.querySelector( ".clip-end" );

        var firstX,
            startLeft,
            startWidth,
            activeHandle,
            updateOptions = {};

        // Converting px <=> time, normalizing
        function positionToTime( pos ) {
          var max1 = _popcornOptions.duration,
              max2 = el.offsetWidth;
          return ( pos / max2 ) * max1;
        }

        function timeToPosition( time ) {
          var max1 = _popcornOptions.duration,
              max2 = el.offsetWidth;
          return ( time / max1 ) * max2;
        }

        // Updating functions
        function updateUI( options ) {
          options = options || _popcornOptions;

          var start = ( options.start || options.start === 0 ) && options.start || _popcornOptions.start,
              end = options.end || ( options.end || options.end === 0 ) && options.end || _popcornOptions.end,
              from = options.from || ( options.from || options.from === 0 ) && options.from || _popcornOptions.from;

          // Adjust UI to account for very small durations
          if ( timeToPosition( end - start ) < MIN_VISUAL_WIDTH ) {
            clipSection.classList.add( "small" );
          } else {
            clipSection.classList.remove( "small" );
          }

          if ( options.from || options.from === 0 ) {
            clipSection.style.left = timeToPosition( from ) + "px";
            inInput.value = Time.toTimecode( from );
            outInput.value = Time.toTimecode( from + end - start );
          }

          if ( options.end || options.start ) {
            clipSection.style.width = timeToPosition( end - start ) + "px";
            outInput.value = Time.toTimecode( from + end - start );
          }

          if ( options.duration ) {
            clipEndLable.innerHTML = Time.toTimecode( options.duration );
          }

        }

        function updateEndAfterExpand() {
          var track = _trackEvent.track;
          track.removeTrackEvent( _trackEvent );
          track.addTrackEvent( _trackEvent );
          _this.updateTrackEventSafe( _trackEvent, updateOptions );
          _butter.unlisten( "mediaready", updateEndAfterExpand );
          _butter.currentTime = _popcornOptions.start;
          updateUI();
          updateOptions = {};
        }

        function updateTrackEvent( options ) {
          if ( !_butter.currentMedia.paused ) {
            _butter.currentMedia.pause();
          }
          // If the end time is greater than the duration of the video, expand it to fit.
          // We have to set an event listener on "mediaready" to update the trackevent after the base duration has been changed
          if ( options.end && options.end > _butter.duration ) {
            _butter.currentMedia.url = "#t=," + options.end;
            _butter.listen( "mediaready", updateEndAfterExpand );
          } else {
            _this.updateTrackEventSafe( _trackEvent, options );
            updateOptions = {};
            updateUI();
          }
        }

        function onResizeStop() {
          var accuracy,
              start = updateOptions.start || _popcornOptions.start,
              end = updateOptions.end || _popcornOptions.end;

          el.classList.remove( "editing" );

          if ( activeHandle === "left" ) {
            accuracy = start * Math.pow( 10, Time.timeAccuracy - 1 );
            butter.currentTime = start === 0 ? start : Math.ceil( start * accuracy ) / accuracy;
          } else if ( activeHandle === "right" ) {
            accuracy = end * Math.pow( 10, Time.timeAccuracy - 1 );
            butter.currentTime = Math.floor( end * accuracy ) / accuracy;
          }

          updateTrackEvent( updateOptions );
          activeHandle = "";

          document.removeEventListener( "mousemove", onResizingRight, false );
          document.removeEventListener( "mousemove", onResizingLeft, false );
          document.removeEventListener( "mouseup", onResizeStop, false );
        }


        function onResizingLeft( e ) {
          e.preventDefault();
          var left = startLeft + e.clientX - firstX,
              width = startWidth - ( e.clientX - firstX );

          if ( left < 0 || width < 0 ) {
            return;
          }

          updateOptions.end = _popcornOptions.start + positionToTime( width );
          updateOptions.from = positionToTime( left );

          updateUI({
            from: updateOptions.from,
            end: updateOptions.end
          });

        }

        function onResizingRight( e ) {
          e.preventDefault();
          var left = clipSection.offsetLeft,
              width = startWidth + e.clientX - firstX;

          if ( left + width > el.offsetWidth || width < 0 ) {
            return;
          }

          updateOptions.end = _popcornOptions.start + positionToTime( width );
          updateUI({
            end: updateOptions.end
          });

        }

        function onResizeStart( e ) {
          e.preventDefault(); // Prevent selection
          el.classList.add( "editing" );

          firstX = e.clientX;
          startLeft = clipSection.offsetLeft;
          startWidth = clipSection.offsetWidth;

          if ( this === rightHandle ) {
            document.addEventListener( "mousemove", onResizingRight, false );
            activeHandle = "right";
          } else if ( this === leftHandle ) {
            activeHandle = "left";
            document.addEventListener( "mousemove", onResizingLeft, false );
          }
          document.addEventListener( "mouseup", onResizeStop, false );
        }


        function onDragStop() {
          el.classList.remove( "editing" );
          updateTrackEvent( updateOptions );
          document.removeEventListener( "mouseup", onDragStop, false );
          document.removeEventListener( "mousemove", onDragging, false );
        }

        function onDragging( e ) {
          e.preventDefault(); // Prevent selection
          var left = startLeft + e.clientX - firstX,
              width = clipSection.offsetWidth;

          if ( left < 0 || ( left + width ) > el.offsetWidth ) {
            return;<commit_msg>[#3286] Validate media editor trimmer and fix if out of bounds during a drag.<commit_after>/* This Source Code Form is subject to the terms of the MIT license
 * If a copy of the MIT license was not distributed with this file, you can
 * obtain one at https://raw.github.com/mozilla/butter/master/LICENSE */

define( [ "util/mediatypes", "editor/editor", "util/time",
          "util/uri", "ui/widget/textbox", "text!layouts/sequencer-editor.html"  ],
  function( MediaUtils, Editor, Time, URI, Textbox, LAYOUT_SRC ) {

  Editor.register( "sequencer", LAYOUT_SRC,
    function( rootElement, butter ) {
    var _this = this;

    var _rootElement = rootElement,
        _trackEvent,
        _butter,
        _manifest,
        _popcornOptions,
        _mediaType;

    var _fields = {};

      // Creates an "off-on" toggler
      function Toggler( el, property, isReverse, customUpdateUI ) {
        var hiddenInput = el.querySelector( "input" );

        function updateUI() {
          var val = _popcornOptions[ property ];
          if ( val && !isReverse || !val && isReverse ) {
            el.classList.add( "on" );
          } else {
            el.classList.remove( "on" );
          }
          hiddenInput.checked = val;
          if ( customUpdateUI ) {
            customUpdateUI( el );
          }
        }

        function updateTrackEvent( val ) {
          var properties = {};
          properties[ property ] = val;
          updateUI( val );
          _this.updateTrackEventSafe( _trackEvent, properties );
        }

        el.addEventListener( "click", function() {
          // Toggle the state
          updateTrackEvent( !hiddenInput.checked );
        }, false );

        updateUI( _popcornOptions[ property ] );

        return {
          el: el,
          updateUI: updateUI,
        };

      }

      // Creates a standard input
      function Input( el, property, callback, customUpdate ) {
        _this.attachInputChangeHandler( el, _trackEvent, property, callback );

        function updateUI() {
          var val = _popcornOptions[ property ];
          el.value = val;
          if ( customUpdate ) {
            customUpdate( el );
          }
        }

        updateUI( _popcornOptions[ property ] );

        return {
          el: el,
          updateUI: updateUI
        };
      }

      function StartEnd( el ) {
        var container = _this.createStartEndInputs( _trackEvent, _this.updateTrackEventSafe ),
            startEl = container.querySelector( "[data-manifest-key=start]" ),
            endEl = container.querySelector( "[data-manifest-key=end]" );

        el.appendChild( container );

        function updateUI() {
          startEl.value = Time.toTimecode( _popcornOptions.start );
          endEl.value = Time.toTimecode( _popcornOptions.end );
        }

        updateUI();

        return {
          el: el,
          updateUI: updateUI
        };
      }

      // Our custom trimmer thingy
      function Trimmer( el ) {

        var MIN_VISUAL_WIDTH = 5;

        var rightHandle = el.querySelector( ".trimmer-resizable-e" ),
            leftHandle = el.querySelector( ".trimmer-resizable-w" ),
            outInput = _rootElement.querySelector( ".trimmer-input-right" ),
            inInput = _rootElement.querySelector( ".trimmer-input-left" ),
            clipSection = el.querySelector( ".clip-section" ),
            clipEndLable = el.querySelector( ".clip-end" );

        var firstX,
            startLeft,
            startWidth,
            activeHandle,
            updateOptions = {};

        // Converting px <=> time, normalizing
        function positionToTime( pos ) {
          var max1 = _popcornOptions.duration,
              max2 = el.offsetWidth;
          return ( pos / max2 ) * max1;
        }

        function timeToPosition( time ) {
          var max1 = _popcornOptions.duration,
              max2 = el.offsetWidth;
          return ( time / max1 ) * max2;
        }

        // Updating functions
        function updateUI( options ) {
          var start,
              end,
              from;

          options = options || _popcornOptions;
          start = options.start;
          end = options.end;
          from = options.from;

          if ( !from && from !== 0 ) {
            from = _popcornOptions.from;
          }

          if ( !end && end !== 0 ) {
            end = _popcornOptions.end;
          }

          if ( !start && start !== 0 ) {
            start = _popcornOptions.start;
          }

          // Adjust UI to account for very small durations
          if ( timeToPosition( end - start ) < MIN_VISUAL_WIDTH ) {
            clipSection.classList.add( "small" );
          } else {
            clipSection.classList.remove( "small" );
          }

          clipSection.style.left = timeToPosition( from ) + "px";
          inInput.value = Time.toTimecode( from );

          clipSection.style.width = timeToPosition( end - start ) + "px";
          outInput.value = Time.toTimecode( from + end - start );

          if ( options.duration ) {
            clipEndLable.innerHTML = Time.toTimecode( options.duration );
          }

        }

        function updateEndAfterExpand() {
          var track = _trackEvent.track;
          track.removeTrackEvent( _trackEvent );
          track.addTrackEvent( _trackEvent );
          _this.updateTrackEventSafe( _trackEvent, updateOptions );
          _butter.unlisten( "mediaready", updateEndAfterExpand );
          _butter.currentTime = _popcornOptions.start;
          updateUI();
          updateOptions = {};
        }

        function updateTrackEvent( options ) {
          if ( !_butter.currentMedia.paused ) {
            _butter.currentMedia.pause();
          }
          // If the end time is greater than the duration of the video, expand it to fit.
          // We have to set an event listener on "mediaready" to update the trackevent after the base duration has been changed
          if ( options.end && options.end > _butter.duration ) {
            _butter.currentMedia.url = "#t=," + options.end;
            _butter.listen( "mediaready", updateEndAfterExpand );
          } else {
            _this.updateTrackEventSafe( _trackEvent, options );
            updateOptions = {};
            updateUI();
          }
        }

        function onResizeStop() {
          var accuracy,
              start = updateOptions.start || _popcornOptions.start,
              end = updateOptions.end || _popcornOptions.end;

          el.classList.remove( "editing" );

          if ( activeHandle === "left" ) {
            accuracy = start * Math.pow( 10, Time.timeAccuracy - 1 );
            butter.currentTime = start === 0 ? start : Math.ceil( start * accuracy ) / accuracy;
          } else if ( activeHandle === "right" ) {
            accuracy = end * Math.pow( 10, Time.timeAccuracy - 1 );
            butter.currentTime = Math.floor( end * accuracy ) / accuracy;
          }

          updateTrackEvent( updateOptions );
          activeHandle = "";

          document.removeEventListener( "mousemove", onResizingRight, false );
          document.removeEventListener( "mousemove", onResizingLeft, false );
          document.removeEventListener( "mouseup", onResizeStop, false );
        }


        function onResizingLeft( e ) {
          e.preventDefault();
          var left = startLeft + e.clientX - firstX,
              width = startWidth - ( e.clientX - firstX );

          if ( left < 0 ) {
            width += left;
            left = 0;
          }

          if ( width < 0 ) {
            return;
          }

          updateOptions.end = _popcornOptions.start + positionToTime( width );
          updateOptions.from = positionToTime( left );
          updateUI({
            from: updateOptions.from,
            end: updateOptions.end
          });

        }

        function onResizingRight( e ) {
          e.preventDefault();
          var left = clipSection.offsetLeft,
              width = startWidth + e.clientX - firstX;

          if ( left + width > el.offsetWidth ) {
            width = el.offsetWidth - left;
          }

          if ( width < 0 ) {
            return;
          }

          updateOptions.end = _popcornOptions.start + positionToTime( width );
          updateUI({
            end: updateOptions.end
          });

        }

        function onResizeStart( e ) {
          e.preventDefault(); // Prevent selection
          el.classList.add( "editing" );

          firstX = e.clientX;
          startLeft = clipSection.offsetLeft;
          startWidth = clipSection.offsetWidth;

          if ( this === rightHandle ) {
            document.addEventListener( "mousemove", onResizingRight, false );
            activeHandle = "right";
          } else if ( this === leftHandle ) {
            activeHandle = "left";
            document.addEventListener( "mousemove", onResizingLeft, false );
          }
          document.addEventListener( "mouseup", onResizeStop, false );
        }


        function onDragStop() {
          el.classList.remove( "editing" );
          updateTrackEvent( updateOptions );
          document.removeEventListener( "mouseup", onDragStop, false );
          document.removeEventListener( "mousemove", onDragging, false );
        }

        function onDragging( e ) {
          e.preventDefault(); // Prevent selection
          var left = startLeft + e.clientX - firstX,
              width = clipSection.offsetWidth;

          if ( left < 0 ) {
            left = 0;
          }

          if ( left + width > el.offsetWidth ) {
            left = el.offsetWidth - width;
          }

          if ( width < 0 ) {
            return;
{'fraction_non_alphanumeric': 0.10599989592548265, 'fraction_numerical': 0.0028100119685694957, 'mean_word_length': 1.7454285714285713, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 11, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4108124', 'n_tokens_mistral': 5219, 'n_tokens_neox': 5043, 'n_words': 1233}