<commit_before>// NOTE: The shared function that produces a disabled-cookies warning on
//       the signup and login pages is located in the sessions.js file.

// NOTE: The main/shared/sample stats pages are below.

$( ".stats-topic, .stats-sample_topic, .stats-shared_topic" )
    .ready( function() {

  // (check dd) > (check) > (dot) > (dot dd) > (x) > (empty) > (anything else)
  function sortSymbols( a, b ) {
    var sortOrder = ["", "✘", "• (dd)", "•", "✓", "✓ (dd)"];
    var indexA = sortOrder.indexOf( a );
    var indexB = sortOrder.indexOf( b );
    if ( indexB < indexA ) {
      return 1;
    } else if (indexB > indexA ) {
      return -1;
    } else {
      return 0;
    }
  }

  var $roundOneTable = $( "#roundOneTopicTable" );
  var $roundTwoTable = $( "#roundTwoTopicTable" );
  var $finalTable = $( "#finalTopicTable" );

  // Make the three tables on the topic-stats page sortable.
  // Initialize default sorts to [ date-played column, descending ].
  // Prevent meaningless attempts to sort by "Game" (edit) column.
  // To prevent a JS error, skip this if the table is empty.
  if ( !$roundOneTable.hasClass( "empty" ) ) {
    $roundOneTable.tablesorter({
      sortList: [[3,1]],
      sortInitialOrder: "desc",
      headers: {
        0: { sortInitialOrder: "asc" },   // Category title
        1: { sortInitialOrder: "asc" },   // Column number
        4: { sortInitialOrder: "asc" },   // Play type
        13: { sorter: false }             // Game (edit link)
      },
      textSorter: {
        5: sortSymbols,  // The clue-value columns
        6: sortSymbols,
        7: sortSymbols,
        8: sortSymbols,
        9: sortSymbols
      }
    })
  }

  if ( !$roundTwoTable.hasClass( "empty" ) ) {
    $roundTwoTable.tablesorter({
      sortList: [[3,1]],
      sortInitialOrder: "desc",
      headers: {
        0: { sortInitialOrder: "asc" },   // Category title
        1: { sortInitialOrder: "asc" },   // Column number
        4: { sortInitialOrder: "asc" },   // Play type
        13: { sorter: false }             // Game (edit link)
      },
      textSorter: {
        5: sortSymbols,  // The clue-value columns
        6: sortSymbols,
        7: sortSymbols,
        8: sortSymbols,
        9: sortSymbols
      }
    })

    if ( !$finalTable.hasClass( "empty" ) ) {
      $finalTable.tablesorter({
        sortList: [[2,1]],
        sortInitialOrder: "desc",
        headers: {
          0: { sortInitialOrder: "asc" },  // Category title
          3: { sortInitialOrder: "asc" },  // Play type
          7: { sorter: false }             // Game (edit link)
        },
        textSorter: {
          4: sortSymbols  // Result column
        }
      })
    }
  }
});


$( ".stats-show, .stats-shared, .stats-sample" ).ready( function() {

  var statsPageType;
  if ( $( this ).hasClass( "stats-show" ) ) {
    statsPageType = "stats";
  } else if ( $( this ).hasClass ( "stats-sample" ) ) {
    statsPageType = "sample";
  } else if ( $( this ).hasClass ( "stats-shared" ) ) {
    statsPageType = "shared";
  } else {
    alert ( "Invalid request" );
  }

  // Returns an array of play type abbreviations corresponding
  // to the checked boxes on the play types tab, or ['none']
  // if no boxes are checked.
  function getCheckedPlayTypeBoxes() {
    var types = $( "#typeTable :checked" ).map( function() {
      return this.id.slice(0, -4);
    }).get();

    if (types.length === 0) { return ['none']; }
    return types;
  }

  function getObjectFromSentences( dateType ) {
    var result = {};
    result.reverse = ( $( "#" + dateType + "-verb" ).val() === "hide" );
    result.preposition = $( "#" + dateType + "-preposition" ).val();
    switch (result.preposition) {
      case "sinceBeg":
        var beginDate = $( "#" + dateType + "-beginning-dropdown" ).val();
        result.beginning = ( beginDate || null );
        break;
      case "inLast":
        result.last_number = $( "#" + dateType + "-last-number" ).val();
        result.last_unit = $( "#" + dateType + "-last-unit" ).val();
        break;
      case "since":
        result.from = $( "#" + dateType + "-from input" ).val();
        break;
      case "from":
        result.from = $( "#" + dateType + "-from input" ).val();
        result.to = $( "#" + dateType + "-to input" ).val();
        break;
    }
    return result;
  }

  function makeDateFilterObject() {
    var result = {};
    var showDateObject = getObjectFromSentences( "show-date" ),
        datePlayedObject = getObjectFromSentences( "date-played" );
    for ( var key in showDateObject ) {
      result["show_date_" + key] = showDateObject[key];
    }
    for ( key in datePlayedObject ) {
      result["date_played_" + key] = datePlayedObject[key];
    }
    return result
  }

  function makeFilterObject() {
    return $.extend( makeDateFilterObject(),
                     { rerun_status: $( "#rerun-status" ).val(),
                       play_types: getCheckedPlayTypeBoxes() } );
  }

  function makeFilterQueryString() {
    return $.param( makeDateFilterObject() ) +
           "&rerun_status=" + $( "#rerun-status" ).val() +
           "&play_types=" + getCheckedPlayTypeBoxes().join( ',' );
  }

  function laterDate( date1, date2 ) {
    return date1 > date2 ? date1 : date2;
  }

  function updateFilterSentence( dateType ) {
    var preposition = $( "#" + dateType + "-preposition" ).val();
    $( "." + dateType + "-filter-object" ).hide();
    switch (preposition) {
      case "sinceBeg":
        $( "#" + dateType + "-beginning-span" ).show();
        break;
      case "inLast":
        var $options = $( "#" + dateType + "-last-unit option" ),
            num = parseFloat( $( "#" + dateType + "-last-number" ).val() );
        if ( num === 1 && $options.text().slice(-1) === "s" ) {
          $options.text( function( _, prevText ) {
            return prevText.slice(0, -1);
          });
        } else if ( num !== 1 && $options.text().slice(-1) !== "s" ) {
          $options.text( function( _, prevText ) {
            return prevText + "s";
          });
        }
        $( "#" + dateType + "-last-span" ).show();
        break;
      case "since":
        if (!storedToDates[dateType]) {
          var $toDatePicker = $( "#" + dateType + "-to-picker" );
          storedToDates[dateType] = $toDatePicker.find( "input" ).val();
          $toDatePicker.data( "DateTimePicker" ).date("9999-12-31");
        }
        $( "#" + dateType + "-from" ).show();
        break;
      case "from":
        if (storedToDates[dateType]) {
          var $toDatePicker = $( "#" + dateType + "-to-picker" ),
              fromDate = $( "#" + dateType + "-from-picker input" ).val(),
              newToDate = laterDate( fromDate, storedToDates[dateType] );
          $toDatePicker.data( "DateTimePicker" ).date( newToDate );
          storedToDates[dateType] = undefined;
        }
        $( "#" + dateType + "-from" ).show();
        $( "#" + dateType + "-to" ).show();
        break;
    }
  }

  var sortOrder = new Map();
  var defaultSortDirections =  {
    "pa": 1,  // "Played at", descending
    "rr": 1,  // "Rerun?", descending (check then dash)
    "sd": 1,  // "Show date", descending
    "pt": 0,  // "Play type", ascending
    "cs": 1,  // "Coryat score", descending
    "ro": 1,  // "Round one", descending
    "rt": 1,  // "Round two", descending
    "dr": 1,  // "DDs right", descending
    "dw": 1,  // "DDs wrong", descending
    "fi": 1   // "Final", descending (check then X)
  };

  function sortOrderString() {
    var result = "&sort_order=";
    sortOrder.forEach( function( dir, abbr, _map ) {
      result += ( abbr + dir + "," );
    });
    return ( result.length > 12 ? result.slice( 0, -1 ) : "" );
  }
  var currentPage = 1;

  function gamesTableHeaderSetup() {
    $( "#played-at-col, #rerun-col, #show-date-col, #play-type-col, " +
        "#coryat-col, #round-one-col, #round-two-col, #dds-right-col, " +
        "#dds-wrong-col, #final-col" ).on( "click", function( event ) {
      var abbr = $( this ).data( "abbr" );
      if ( event.shiftKey ) {
        // Shift-click: create a compound sort.
        // If the order exists in the list, reverse its direction.
        // (This will maintain its position in the ordering.)
        // Otherwise, add it to the end with its default direction.
        if ( sortOrder.has( abbr ) ) {
          sortOrder.set( abbr, 1 - sortOrder.get( abbr ) );
        } else {
          sortOrder.set( abbr, defaultSortDirections[abbr] );
        }
      } else {
        // Standard click: replace the existing sort.
        // If the column is currently sorted, reverse its direction.
        var sortDirection;
        if ( sortOrder.has ( abbr ) ) {
          sortDirection = 1 - sortOrder.get( abbr );
        } else {
          sortDirection = defaultSortDirections[abbr];
        }
        sortOrder.clear();
        sortOrder.set( abbr, sortDirection );<commit_msg>Add default sort order explicitly<commit_after>// NOTE: The shared function that produces a disabled-cookies warning on
//       the signup and login pages is located in the sessions.js file.

// NOTE: The main/shared/sample stats pages are below.

$( ".stats-topic, .stats-sample_topic, .stats-shared_topic" )
    .ready( function() {

  // (check dd) > (check) > (dot) > (dot dd) > (x) > (empty) > (anything else)
  function sortSymbols( a, b ) {
    var sortOrder = ["", "✘", "• (dd)", "•", "✓", "✓ (dd)"];
    var indexA = sortOrder.indexOf( a );
    var indexB = sortOrder.indexOf( b );
    if ( indexB < indexA ) {
      return 1;
    } else if (indexB > indexA ) {
      return -1;
    } else {
      return 0;
    }
  }

  var $roundOneTable = $( "#roundOneTopicTable" );
  var $roundTwoTable = $( "#roundTwoTopicTable" );
  var $finalTable = $( "#finalTopicTable" );

  // Make the three tables on the topic-stats page sortable.
  // Initialize default sorts to [ date-played column, descending ].
  // Prevent meaningless attempts to sort by "Game" (edit) column.
  // To prevent a JS error, skip this if the table is empty.
  if ( !$roundOneTable.hasClass( "empty" ) ) {
    $roundOneTable.tablesorter({
      sortList: [[3,1]],
      sortInitialOrder: "desc",
      headers: {
        0: { sortInitialOrder: "asc" },   // Category title
        1: { sortInitialOrder: "asc" },   // Column number
        4: { sortInitialOrder: "asc" },   // Play type
        13: { sorter: false }             // Game (edit link)
      },
      textSorter: {
        5: sortSymbols,  // The clue-value columns
        6: sortSymbols,
        7: sortSymbols,
        8: sortSymbols,
        9: sortSymbols
      }
    })
  }

  if ( !$roundTwoTable.hasClass( "empty" ) ) {
    $roundTwoTable.tablesorter({
      sortList: [[3,1]],
      sortInitialOrder: "desc",
      headers: {
        0: { sortInitialOrder: "asc" },   // Category title
        1: { sortInitialOrder: "asc" },   // Column number
        4: { sortInitialOrder: "asc" },   // Play type
        13: { sorter: false }             // Game (edit link)
      },
      textSorter: {
        5: sortSymbols,  // The clue-value columns
        6: sortSymbols,
        7: sortSymbols,
        8: sortSymbols,
        9: sortSymbols
      }
    })

    if ( !$finalTable.hasClass( "empty" ) ) {
      $finalTable.tablesorter({
        sortList: [[2,1]],
        sortInitialOrder: "desc",
        headers: {
          0: { sortInitialOrder: "asc" },  // Category title
          3: { sortInitialOrder: "asc" },  // Play type
          7: { sorter: false }             // Game (edit link)
        },
        textSorter: {
          4: sortSymbols  // Result column
        }
      })
    }
  }
});


$( ".stats-show, .stats-shared, .stats-sample" ).ready( function() {

  var statsPageType;
  if ( $( this ).hasClass( "stats-show" ) ) {
    statsPageType = "stats";
  } else if ( $( this ).hasClass ( "stats-sample" ) ) {
    statsPageType = "sample";
  } else if ( $( this ).hasClass ( "stats-shared" ) ) {
    statsPageType = "shared";
  } else {
    alert ( "Invalid request" );
  }

  // Returns an array of play type abbreviations corresponding
  // to the checked boxes on the play types tab, or ['none']
  // if no boxes are checked.
  function getCheckedPlayTypeBoxes() {
    var types = $( "#typeTable :checked" ).map( function() {
      return this.id.slice(0, -4);
    }).get();

    if (types.length === 0) { return ['none']; }
    return types;
  }

  function getObjectFromSentences( dateType ) {
    var result = {};
    result.reverse = ( $( "#" + dateType + "-verb" ).val() === "hide" );
    result.preposition = $( "#" + dateType + "-preposition" ).val();
    switch (result.preposition) {
      case "sinceBeg":
        var beginDate = $( "#" + dateType + "-beginning-dropdown" ).val();
        result.beginning = ( beginDate || null );
        break;
      case "inLast":
        result.last_number = $( "#" + dateType + "-last-number" ).val();
        result.last_unit = $( "#" + dateType + "-last-unit" ).val();
        break;
      case "since":
        result.from = $( "#" + dateType + "-from input" ).val();
        break;
      case "from":
        result.from = $( "#" + dateType + "-from input" ).val();
        result.to = $( "#" + dateType + "-to input" ).val();
        break;
    }
    return result;
  }

  function makeDateFilterObject() {
    var result = {};
    var showDateObject = getObjectFromSentences( "show-date" ),
        datePlayedObject = getObjectFromSentences( "date-played" );
    for ( var key in showDateObject ) {
      result["show_date_" + key] = showDateObject[key];
    }
    for ( key in datePlayedObject ) {
      result["date_played_" + key] = datePlayedObject[key];
    }
    return result
  }

  function makeFilterObject() {
    return $.extend( makeDateFilterObject(),
                     { rerun_status: $( "#rerun-status" ).val(),
                       play_types: getCheckedPlayTypeBoxes() } );
  }

  function makeFilterQueryString() {
    return $.param( makeDateFilterObject() ) +
           "&rerun_status=" + $( "#rerun-status" ).val() +
           "&play_types=" + getCheckedPlayTypeBoxes().join( ',' );
  }

  function laterDate( date1, date2 ) {
    return date1 > date2 ? date1 : date2;
  }

  function updateFilterSentence( dateType ) {
    var preposition = $( "#" + dateType + "-preposition" ).val();
    $( "." + dateType + "-filter-object" ).hide();
    switch (preposition) {
      case "sinceBeg":
        $( "#" + dateType + "-beginning-span" ).show();
        break;
      case "inLast":
        var $options = $( "#" + dateType + "-last-unit option" ),
            num = parseFloat( $( "#" + dateType + "-last-number" ).val() );
        if ( num === 1 && $options.text().slice(-1) === "s" ) {
          $options.text( function( _, prevText ) {
            return prevText.slice(0, -1);
          });
        } else if ( num !== 1 && $options.text().slice(-1) !== "s" ) {
          $options.text( function( _, prevText ) {
            return prevText + "s";
          });
        }
        $( "#" + dateType + "-last-span" ).show();
        break;
      case "since":
        if (!storedToDates[dateType]) {
          var $toDatePicker = $( "#" + dateType + "-to-picker" );
          storedToDates[dateType] = $toDatePicker.find( "input" ).val();
          $toDatePicker.data( "DateTimePicker" ).date("9999-12-31");
        }
        $( "#" + dateType + "-from" ).show();
        break;
      case "from":
        if (storedToDates[dateType]) {
          var $toDatePicker = $( "#" + dateType + "-to-picker" ),
              fromDate = $( "#" + dateType + "-from-picker input" ).val(),
              newToDate = laterDate( fromDate, storedToDates[dateType] );
          $toDatePicker.data( "DateTimePicker" ).date( newToDate );
          storedToDates[dateType] = undefined;
        }
        $( "#" + dateType + "-from" ).show();
        $( "#" + dateType + "-to" ).show();
        break;
    }
  }

  var sortOrder = new Map();
  var defaultSortDirections =  {
    "pa": 1,  // "Played at", descending
    "rr": 1,  // "Rerun?", descending (check then dash)
    "sd": 1,  // "Show date", descending
    "pt": 0,  // "Play type", ascending
    "cs": 1,  // "Coryat score", descending
    "ro": 1,  // "Round one", descending
    "rt": 1,  // "Round two", descending
    "dr": 1,  // "DDs right", descending
    "dw": 1,  // "DDs wrong", descending
    "fi": 1   // "Final", descending (check then X)
  };

  function sortOrderString() {
    var result = "&sort_order=";
    if ( sortOrder.size === 0 ) {
      return result + "pa1";
    }
    sortOrder.forEach(function (dir, abbr, _map) {
      result += (abbr + dir + ",");
    });
    return result.slice( 0, -1 );
  }
  var currentPage = 1;

  function gamesTableHeaderSetup() {
    $( "#played-at-col, #rerun-col, #show-date-col, #play-type-col, " +
        "#coryat-col, #round-one-col, #round-two-col, #dds-right-col, " +
        "#dds-wrong-col, #final-col" ).on( "click", function( event ) {
      var abbr = $( this ).data( "abbr" );
      if ( event.shiftKey ) {
        // Shift-click: create a compound sort.
        // If the order exists in the list, reverse its direction.
        // (This will maintain its position in the ordering.)
        // Otherwise, add it to the end with its default direction.
        if ( sortOrder.has( abbr ) ) {
          sortOrder.set( abbr, 1 - sortOrder.get( abbr ) );
        } else {
          sortOrder.set( abbr, defaultSortDirections[abbr] );
        }
      } else {
        // Standard click: replace the existing sort.
        // If the column is currently sorted, reverse its direction.
        var sortDirection;
        if ( sortOrder.has ( abbr ) ) {
          sortDirection = 1 - sortOrder.get( abbr );
        } else {
          sortDirection = defaultSortDirections[abbr];
        }
        sortOrder.clear();
        sortOrder.set( abbr, sortDirection );
{'fraction_non_alphanumeric': 0.16624909526195647, 'fraction_numerical': 0.008128723345025332, 'mean_word_length': 2.1124588459539075, 'pattern_counts': {'":': 36, '<': 5, '<?xml version=': 0, '>': 20, 'https://': 0, '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': '1062121', 'n_tokens_mistral': 5766, 'n_tokens_neox': 5618, 'n_words': 1455}