function listCompetitions()
{
    #----------------------------------------------------------------------
    global $chosenEventId, $chosenYears, $chosenRegionId, $chosenPatternHtml;
    global $chosenList, $chosenMap;
    global $chosenCompetitions;
    $chosenCompetitions = getCompetitions($chosenList);
    tableBegin('results', 5);
    tableCaption(false, spaced(array(eventName($chosenEventId), chosenRegionName(), $chosenYears, $chosenPatternHtml ? "\"{$chosenPatternHtml}\"" : '')));
    if ($chosenList) {
        tableHeader(explode('|', 'Year|Date|Name|Country, City|Venue'), array(4 => 'class="f"'));
        foreach ($chosenCompetitions as $competition) {
            extract($competition);
            if (isset($previousYear) && $year != $previousYear) {
                tableRowEmpty();
            }
            $previousYear = $year;
            $isPast = wcaDate('Ymd') > 10000 * $year + 100 * $month + $day;
            tableRow(array($year, competitionDate($competition), $isPast ? competitionLink($id, $cellName) : ($showPreregForm || $showPreregList ? competitionLinkClassed('rg', $id, $cellName) : competitionLinkClassed('fc', $id, $cellName)), "<b>{$countryName}</b>, {$cityName}", processLinks($venue)));
        }
    }
    tableEnd();
    if ($chosenMap) {
        // create map markers
        $markers = array();
        foreach ($chosenCompetitions as $comp) {
            $markers[$comp['id']] = array();
            $markers[$comp['id']]['latitude'] = $comp['latitude'];
            $markers[$comp['id']]['longitude'] = $comp['longitude'];
            $markers[$comp['id']]['info'] = "<a href='c.php?i=" . $comp['id'] . "'>" . o($comp['cellName']) . "</a><br />" . date("M j, Y", mktime(0, 0, 0, $comp['month'], $comp['day'], $comp['year'])) . " - " . o($comp['cityName']);
        }
        displayMap($markers);
    }
}
function analyzeChoices()
{
    #----------------------------------------------------------------------
    global $chosenYears, $chosenRegionId, $chosenOrder;
    $chosenYears = getNormalParam('years');
    $chosenRegionId = getNormalParam('regionId');
    $chosenOrder = getNormalParam('order');
    if (getNormalParam('filter') == '') {
        $chosenYears = "only " . wcaDate('Y');
    }
    if (!preg_match('/^(date|submission)$/', $chosenOrder)) {
        $chosenOrder = 'submission';
    }
}
function defineAllLists()
{
    #----------------------------------------------------------------------
    #--- Compute some helpers.
    global $WHERE, $sinceDateHtml, $sinceDateMysql, $sinceDateCondition;
    $WHERE = "WHERE " . randomDebug() . " AND";
    list($year, $month, $day) = explode(' ', wcaDate("Y m d"));
    $year = intval($year) - 1;
    $month = intval($month);
    $day = intval($day);
    $monthName = getMonthName($month);
    $sinceDateHtml = "{$monthName} {$day}, {$year}";
    $sinceDateMysql = $year * 10000 + $month * 100 + $day;
    $sinceDateCondition = "(year*10000 + month*100 + day) >= {$sinceDateMysql}";
    #--- Import the list definitions.
    require 'includes/statistics/ALL_LISTS.php';
}
function doTheDarnChecking()
{
    #----------------------------------------------------------------------
    global $differencesWereFound;
    #--- Begin form and table.
    echo "<form action='check_regional_record_markers_ACTION.php' method='post'>\n";
    tableBegin('results', 12);
    #--- Do the checking.
    computeRegionalRecordMarkers('best', 'Single');
    computeRegionalRecordMarkers('average', 'Average');
    #--- End table.
    tableEnd();
    #--- Tell the result.
    $date = wcaDate();
    noticeBox2(!$differencesWereFound, "We completely agree.<br />{$date}", "<p>Darn! We disagree!<br />{$date}</p>\n     <p>Choose the changes you agree with above, then click the 'Execute...' button below. It will result in something like the following.\n        If you then go back in your browser and refresh the page, the changes should be visible.</p>\n        \n<pre>\n            Queries similar to the following will be executed:\n              UPDATE Results SET regionalSingleRecord = ? WHERE id = ?\n              UPDATE Results SET regionalAverageRecord = ? WHERE id = ?\n          </pre>");
    #--- If differences were found, offer to fix them.
    if ($differencesWereFound) {
        echo "<center><input type='submit' value='Execute the agreed changes!' /></center>\n";
    }
    #--- Finish the form.
    echo "</form>\n";
}
adminHeadline( 'Compute auxiliary data' );
showDescription();
showChoices();

if( $chosenDoIt ){
  noticeBox3( 0, "Note: At the end of this, when this page is completed, you should see a green success box at the bottom of the page. If not, something went wrong (like an out-of-memory error we recently had, which killed the script)." );

  // Adding best-3 mean computations, for 2014 mean/3 recognition.
  computeBest3();

  computeConciseRecords();
  computeRanks( 'best', 'Single' );
  computeRanks( 'average', 'Average' );
  computeCachedDatabase('../generated/cachedDatabase.php');
  deleteCaches();
  noticeBox3( 1, "Ok, finished.<br />" . wcaDate() );
}

require( '../includes/_footer.php' );

#----------------------------------------------------------------------
function showDescription () {
#----------------------------------------------------------------------

  echo "<p>This computes means for 3x3 bld, the auxiliary tables ConciseSingleResults, ConciseAverageResults, RanksSingle and RanksAverage, as well as the cachedDatabase.php script, and clears the caches.</p>\n";

  echo "<p>Do it after changes to the database data so that these things are up-to-date.</p><hr />\n";
}

#----------------------------------------------------------------------
function analyzeChoices () {
function checkSimilarResults()
{
    #----------------------------------------------------------------------
    global $competitionCondition, $chosenWhich;
    echo "<hr /><p>Checking <b>" . $chosenWhich . " similar results</b>... (wait for the result message box at the end)</p>\n";
    #--- Get all similar results (except old-new multiblind)
    $rows = pdo_query("\n      SELECT\n          Results.competitionId AS competitionId,\n          Results.personId AS personIdA, Results.personName AS personNameA, Results.eventId AS eventIdA, Results.roundId AS roundIdA,\n          h.personId AS personIdB, h.personName AS personNameB, h.eventId AS eventIdB, h.roundId AS roundIdB,\n          Results.value1 AS value1A, Results.value2 AS value2A, Results.value3 AS value3A, Results.value4 AS value4A, Results.value5 AS value5A,\n          h.value1 AS value1B, h.value2 AS value2B, h.value3 AS value3B, h.value4 AS value4B, h.value5 AS value5B\n      FROM Results\n      JOIN (\n          SELECT competitionId, eventId, roundId, personId, personName, value1, value2, value3, value4, value5\n          FROM Results " . ($competitionCondition ? "JOIN Competitions ON Competitions.id = competitionId " : "") . "WHERE best > 0 " . ($competitionCondition ? $competitionCondition : "") . " AND value3 <> 0\n              AND eventId <> '333mbo'\n      ) h ON Results.competitionId = h.competitionId\n          AND Results.eventId <> '333mbo'\n          AND Results.personId < h.personId\n          AND (\n              (Results.value1 = h.value1 AND h.value1 > 0) +\n              (Results.value2 = h.value2 AND h.value2 > 0) +\n              (Results.value3 = h.value3 AND h.value3 > 0) +\n              (Results.value4 = h.value4 AND h.value4 > 0) +\n              (Results.value5 = h.value5 AND h.value5 > 0) > 2\n              )\n  ");
    tableBegin('results', 4);
    foreach ($rows as $row) {
        $competition = getCompetition($row['competitionId']);
        $competitionName = $competition['cellName'];
        tableCaption(false, competitionLink($row['competitionId'], $competitionName));
        tableHeader(explode('|', "Person|Event|Round|Result Details"), array(3 => 'class="f"'));
        foreach (array('A', 'B') as $letter) {
            $otherLetter = chr(65 + 66 - ord($letter));
            $resultStr = '';
            for ($i = 1; $i <= 5; $i++) {
                $value = $row['value' . $i . $letter];
                if (!$value) {
                    break;
                }
                $resultStr .= "<span class='label label-" . ($value == $row['value' . $i . $otherLetter] ? "danger" : "success") . "'>" . formatValue($value, valueFormat($row['eventId' . $letter])) . "</span> ";
            }
            tableRow(array(personLink($row['personId' . $letter], $row['personName' . $letter]), eventCellName($row['eventId' . $letter]), roundCellName($row['roundId' . $letter]), $resultStr));
        }
    }
    tableEnd();
    #--- Tell the result.
    $date = wcaDate();
    noticeBox2(count($rows) == 0, "No similar results were found.<br />{$date}", "Similar results were found.<br />{$date}");
}
function checkRounds()
{
    #----------------------------------------------------------------------
    global $competitionCondition, $competitionDescription;
    echo "<hr /><p>Checking <b> rounds for {$competitionDescription}</b>... (wait for the result message box at the end)</p>\n";
    #--- Get the number of competitors per round
    $roundRows = dbQuery("\n    SELECT   count(result.id) nbPersons, result.competitionId, competition.year, competition.month, competition.day, result.eventId, result.roundId, round.cellName, result.formatId,\n             CASE result.formatId WHEN '2' THEN BIT_AND( IF( result.value2,1,0)) WHEN '3' THEN BIT_AND( IF( result.value3,1,0)) WHEN 'm' THEN BIT_AND( IF( result.value3,1,0)) WHEN 'a' THEN BIT_AND( IF( result.value5 <> 0,1,0)) ELSE 1 END isNotCombined\n    FROM     Results result, Competitions competition, Rounds round\n    WHERE    competition.id = competitionId\n      {$competitionCondition}\n      AND    (( eventId <> '333mbf' ) OR (( competition.year = 2009 ) AND ( competition.month > 1 )) OR ( competition.year > 2009 ))\n      AND    result.roundId <> 'b'\n      AND    result.roundId = round.id\n    GROUP BY competitionId, eventId, roundId\n    ORDER BY year desc, month desc, day desc, competitionId, eventId, round.rank\n  ");
    #--- Get the number of competitors per event
    $eventRows = dbQuery("\n    SELECT   count(distinct result.personId) nbPersons, competitionId, eventId\n    FROM     Results result, Competitions competition\n    WHERE    competition.id = competitionId\n      {$competitionCondition}\n      AND    (( eventId <> '333mbf' ) OR (( competition.year = 2009 ) AND ( competition.month > 1 )) OR ( competition.year > 2009 ))\n      AND    result.roundId <> 'b'\n    GROUP BY competitionId, eventId\n    ORDER BY year desc, month desc, day desc, competitionId, eventId\n  ");
    #--- Begin the form
    echo "<form action='check_rounds_ACTION.php' method='post'>\n";
    $prevEvent = '';
    $wrongs = 0;
    foreach ($roundRows as $i => $roundRow) {
        list($nbPersons, $competitionId, $year, $month, $day, $eventId, $roundId, $roundCellName, $formatId, $isNotCombined) = $roundRow;
        $event = "{$competitionId}|{$eventId}";
        #--- First round
        if ($event != $prevEvent) {
            $nbRounds = 1;
            $eventRow = array_shift($eventRows);
            list($nbTotalPersons, $eventCompetitionId, $eventEventId) = $eventRow;
            assert($eventCompetitionId == $competitionId);
            assert($eventEventId == $eventId);
            #--- Checks round names
            if ($prevEvent) {
                list($prevCompetitionId, $prevEventId) = explode('|', $prevEvent);
                $wrongs += checkRoundNames($roundInfos, $prevCompetitionId, $prevEventId);
            }
            $roundInfos = array();
            #--- Checks for qualification round
            $isThisRoundQuals = ($roundId == '0' or $roundId == 'h');
            if ($nbTotalPersons != $nbPersons and !$isThisRoundQuals) {
                echo "<p style='margin-top:2em; margin-bottom:0'><a href='https://www.worldcubeassociation.org/results/c.php?i={$competitionId}&allResults=1#e{$eventId}_{$roundId}'>{$competitionId} - {$eventId} - {$roundId}</a></p>";
                #--- Peek at next roundId
                if ($i + 1 < count($roundRows)) {
                    #--- Should be true.
                    $nextRoundId = $roundRows[$i + 1]['roundId'];
                    showQualifications($competitionId, $eventId, $roundId, $nextRoundId);
                }
                echo "<p>Not all persons that competed in {$eventId} are in {$roundCellName}. It should thus be indicated as Qualification round<p/>";
                addQuals($competitionId, $eventId);
                echo "<br /><hr />";
                $isThisRoundQuals = true;
                $wrongs++;
            }
            if ($nbTotalPersons == $nbPersons and $isThisRoundQuals) {
                echo "<p style='margin-top:2em; margin-bottom:0'><a href='https://www.worldcubeassociation.org/results/c.php?i={$competitionId}&allResults=1#e{$eventId}_{$roundId}'>{$competitionId} - {$eventId} - {$roundId}</a></p>";
                #--- Peek at next roundId
                if ($i + 1 < count($roundRows)) {
                    #--- Is not always true.
                    if ($roundRows[$i + 1]['competitionId'] == $competitionId && $roundRows[$i + 1]['eventId'] == $eventId) {
                        #--- Idem
                        $nextRoundId = $roundRows[$i + 1]['roundId'];
                        showQualifications($competitionId, $eventId, $roundId, $nextRoundId);
                    }
                }
                echo "<p>All persons that competed in {$eventId} are in {$roundCellName}. It should thus not be indicated as Qualification round</p>";
                removeQuals($competitionId, $eventId);
                echo "<br /><hr />";
                $isThisRoundQuals = false;
                $wrongs++;
            }
        } else {
            $isThisRoundQuals = false;
            # Article 9m, since April 9, 2008
            if (mktime(0, 0, 0, $month, $day, $year) >= mktime(0, 0, 0, 4, 9, 2008)) {
                if ($nbRounds > 1 and $nbTotalPersons < 8 or $nbRounds > 2 and $nbTotalPersons < 16 or $nbRounds > 3 and $nbTotalPersons < 100 or $nbRounds > 4) {
                    echo "<p style='margin-top:2em; margin-bottom:0'><a href='https://www.worldcubeassociation.org/results/c.php?i={$competitionId}&allResults=1#e{$eventId}_{$roundId}'>{$competitionId} - {$eventId} - {$roundId}</a></p>";
                    echo "<p>There are {$nbRounds} rounds for event {$eventId}, but only {$nbTotalPersons} competitors in total</p>";
                    removeRound($competitionId, $eventId, $nbRounds);
                    echo "<br /><hr />";
                    $wrongs++;
                }
            }
            # Article 9m/n/o, since July 20, 2006 until April 8, 2008
            if (mktime(0, 0, 0, $month, $day, $year) >= mktime(0, 0, 0, 7, 20, 2006) and mktime(0, 0, 0, $month, $day, $year) < mktime(0, 0, 0, 4, 9, 2008)) {
                if ($nbRounds > 2 and $nbTotalPersons < 16 or $nbRounds > 3 and $nbTotalPersons < 100 or $nbRounds > 4) {
                    echo "<p style='margin-top:2em; margin-bottom:0'><a href='https://www.worldcubeassociation.org/results/c.php?i={$competitionId}&allResults=1#e{$eventId}_{$roundId}'>{$competitionId} - {$eventId} - {$roundId}</a></p>";
                    echo "<p>There are {$nbRounds} rounds for event {$eventId}, but only {$nbTotalPersons} competitors in total</p>";
                    removeRound($competitionId, $eventId, $nbRounds);
                    echo "<br /><hr />";
                    $wrongs++;
                }
            }
            $nbQualPersons = $isPrevRoundQuals ? getQualifications($competitionId, $eventId, $prevRoundId, $roundId) : $nbPersons;
            # Article 9p1, since April 14, 2010
            if (mktime(0, 0, 0, $month, $day, $year) >= mktime(0, 0, 0, 4, 14, 2010)) {
                if ($nbQualPersons > 3 * $prevNbPersons / 4) {
                    echo "<p style='margin-top:2em; margin-bottom:0'><a href='https://www.worldcubeassociation.org/results/c.php?i={$competitionId}&allResults=1#e{$eventId}'>{$competitionId} - {$eventId}</a></p>";
                    showQualifications($competitionId, $eventId, $prevRoundId, $roundId);
                    echo "<p>From round {$prevRoundCellName} with {$prevNbPersons} competitors, {$nbQualPersons} were qualified to round {$roundCellName} which is more than 75%</p>";
                    echo "<br /><hr />";
                    $wrongs++;
                }
            }
            # Article 9p, since July 20, 2006 until April 13, 2010
            if (mktime(0, 0, 0, $month, $day, $year) >= mktime(0, 0, 0, 7, 20, 2006) and mktime(0, 0, 0, $month, $day, $year) < mktime(0, 0, 0, 4, 14, 2010)) {
                if ($nbQualPersons >= $prevNbPersons) {
                    echo "<p style='margin-top:2em; margin-bottom:0'><a href='https://www.worldcubeassociation.org/results/c.php?i={$competitionId}&allResults=1#e{$eventId}'>{$competitionId} - {$eventId}</a></p>";
                    showQualifications($competitionId, $eventId, $prevRoundId, $roundId);
                    echo "<p>From round {$prevRoundCellName} to round {$roundCellName}, at least one competitor must not proceed</p>";
                    echo "<br /><hr />";
                    $wrongs++;
                }
            }
        }
        $nbRounds += 1;
        $prevNbPersons = $nbPersons;
        $prevEvent = $event;
        $prevRoundId = $roundId;
        $prevRoundCellName = $roundCellName;
        $isPrevRoundQuals = $isThisRoundQuals;
        $roundInfos[] = array($roundId, $roundCellName, $formatId, $isNotCombined);
    }
    #--- Tell the result.
    $date = wcaDate();
    noticeBox2(!$wrongs, "We didn't find any mistake.<br />{$date}", "<p>Darn! We disagree: {$wrongs} incorrect rounds found<br /><br />{$date}</p>" . "<p>Choose the changes you agree with above, then click the 'Execute...' button below. It will result in something like the following.</p>" . "<pre>I'm doing this:\n" . "UPDATE Results SET pos=111 WHERE id=11111\n" . "UPDATE Results SET pos=222 WHERE id=22222\n" . "UPDATE Results SET pos=333 WHERE id=33333\n" . "</pre>");
    #--- If differences were found, offer to fix them.
    if ($wrongs) {
        echo "<center><input type='submit' value='Execute the agreed changes!' /></center>\n";
    }
    #--- Finish the form.
    echo "</form>\n";
}
function yearCondition()
{
    global $chosenYears;
    #--- current = 90 days into the past + all future
    if ($chosenYears == 'current') {
        return "AND (10000*year+100*month+day)>" . wcaDate('Ymd', time() - 90 * 24 * 60 * 60);
    }
    if (preg_match('/^until (\\d+)$/', $chosenYears, $match)) {
        return " AND year <= {$match['1']} ";
    }
    if (preg_match('/^only (\\d+)$/', $chosenYears, $match)) {
        return " AND year = {$match['1']} ";
    }
    return '';
}
function adminHeadline($title, $scriptIfExecution = false)
{
    if ($scriptIfExecution) {
        $crumb = '<a href="' . $scriptIfExecution . '.php?forceReload=' . time() . '">' . $title . '</a> &gt;&gt; <strong>Execution</strong>';
    } else {
        $crumb = '<strong>' . $title . '</strong>';
    }
    print '<div class="adminHeadline">' . '<a href="' . pathToRoot() . 'admin/">Administration</a> &gt;&gt; ' . $crumb . ' &nbsp;(' . wcaDate() . ')</div>';
}
personId	success	rounds	accuracy
2004GALL02	36	65	50.04%
2007HABE01	14	17	70.83%
2008AURO01	14	44	25.28%
2005KOCZ01	11	33	28.73%
2007HUGH01	10	30	25.11%
2004LOLE01	10	47	19.84%
2006BUUS01	7	33	35.86%
2004MAOT02	7	48	14.87%
2009LIAN03	7	21	24.62%
2004CHAN04	5	61	6.80%
*/
#--- Output the page header.
echo "<h1>Missing Averages</h1>\n\n";
echo "<p style='padding-left:20px;padding-right:20px;font-weight:bold'>Some events don't have official averages, only singles. They have best-of-3 rounds, though, so we can compute mean-of-3. This page does that. Since mean-of-3 is pretty hard for 4x4 and 5x5 blindfolded, means of 2 (out of 2 or 3) are shown instead for those who don't have a mean-of-3 yet. Note this is just for fun, officially we only rank by best-of-X single results. </p>";
echo "<p style='padding-left:20px;padding-right:20px;color:gray;font-size:10px'>Generated on " . wcaDate() . ".</p>";
#--- Tabbing div and links
$tabLinks = '';
foreach (array('444bf', '555bf') as $eventId) {
    $tabLinks .= "<li><a href=\"#container_{$eventId}\">{$eventId}</a></li>\n";
}
echo "\n<div id=\"tabs\" style=\"font-size:1.0em; width:980px; margin:auto; background:white \">\n<ul>\n{$tabLinks}</ul>\n";
#--- Tabbing contents
foreach (array('444bf', '555bf') as $eventId) {
    echo "<div id=\"container_{$eventId}\">";
    showBody($eventId);
    echo "</div>\n";
}
#--- Finish/store/show the page
echo "</div>";
require '../../includes/_footer.php';
function exportPublic ( $sources ) {
#----------------------------------------------------------------------

  #--- No time limit
  set_time_limit( 0 );

  #--- We'll work in the /admin/export directory
  chdir( 'export' );

  #------------------------------------------
  # PREPARATION
  #------------------------------------------

  #--- Get old and new serial number
  $oldSerial = file_get_contents( 'serial.txt' );
  $serial = $oldSerial + 1;
  file_put_contents( 'serial.txt', $serial );

  #--- Build the file basename
  $basename         = sprintf( 'WCA_export%03d_%s', $serial,    wcaDate( 'Ymd' ) );
  $oldBasenameStart = sprintf( 'WCA_export%03d_', $oldSerial );

  #------------------------------------------
  # SQL + TSVs
  #------------------------------------------

  #--- Build SQL and TSV files
  echo "<p><b>Build SQL and TSV files</b></p>";

  #--- Start the SQL file
  $sqlFile = "WCA_export.sql";
  file_put_contents( $sqlFile, "--\n-- $basename\n-- Also read the README.txt\n--\n" );

  #--- Walk the tables, create SQL file and TSV files
  foreach ( $sources as $tableName => $tableSource ) {
    startTimer();
    echo "$tableName ";

    #--- Get the query
    $query = ($tableSource != '*') ? $tableSource : "SELECT * FROM $tableName";

    #--- Add the SQL for creating the table
    file_put_contents( $sqlFile, getTableCreationSql( $tableName, $query ), FILE_APPEND );

    #--- Do the query
    $dbResult = mysql_unbuffered_query( $query )
      or die( '<p>Unable to perform database query.<br/>\n(' . mysql_error() . ')</p>\n' );

    #--- Start the TSV file
    $tsvFile = "WCA_export_$tableName.tsv";
    file_put_contents( $tsvFile, getTsvHeader( $dbResult ) );

    #--- Add data rows
    $sqlStart = "INSERT INTO `$tableName` VALUES ";
    $tsv = '';
    $sqlInserts = array();
    while ( $row = mysql_fetch_array( $dbResult, MYSQL_NUM ) ) {
      // Polish the whitespace (especially remove characters that would break the tsv file format)
      $niceValues = preg_replace( '/\s+/', ' ', array_map( 'trim', $row ) );

      // Data to write
      $tsv .= implode( "\t", $niceValues ) . "\n";
      $sqlInserts[] = "('" . implode( "','", array_map( 'addslashes', $niceValues ) ) . "')";

      // Periodically write data so variable size doesn't explode
      if ( strlen($tsv) > 200000 ) {
        $sql = $sqlStart . implode( ",\n", $sqlInserts ) . ";\n";
        file_put_contents( $tsvFile, $tsv, FILE_APPEND );
        file_put_contents( $sqlFile, $sql, FILE_APPEND );
        $tsv = '';
        $sqlInserts = array();
        echo '.';  # shows both Apache and the user that the script is doing stuff and not hanging
      }
    }
    //Check if any sql need to be exported
    if ($sqlInserts !== array()) {
      $sql = $sqlStart . "\n" . implode( ",\n", $sqlInserts ) . ";\n";
      file_put_contents( $tsvFile, $tsv, FILE_APPEND );
      file_put_contents( $sqlFile, $sql, FILE_APPEND );
    }

    #--- Free the query result
    mysql_free_result( $dbResult );

    echo "<br />\n";
    stopTimer( $tableName );
  }

  #------------------------------------------
  # README
  #------------------------------------------

  #--- Build the README file
  echo "<p><b>Build the README file</b></p>";
  instantiateTemplate( 'README.txt', array( 'longDate' => wcaDate( 'F j, Y' ) ) );

  #------------------------------------------
  # ZIPs
  #------------------------------------------

  #--- Build the ZIP files
  echo "<p><b>Build the ZIP files</b></p>";
  $sqlZipFile  = "$basename.sql.zip";
  $tsvZipFile  = "$basename.tsv.zip";
  mySystem( "zip $sqlZipFile README.txt $sqlFile" );
  mySystem( "zip $tsvZipFile README.txt *.tsv" );

  #------------------------------------------
  # HTML
  #------------------------------------------

  #--- Build the HTML file
  echo '<p><b>Build the HTML file</b></p>';
  instantiateTemplate( 'export.html', array(
                       'sqlZipFile'     => $sqlZipFile,
                       'sqlZipFileSize' => sprintf( '%.1f MB', filesize( $sqlZipFile ) / 1000000 ),
                       'tsvZipFile'     => $tsvZipFile,
                       'tsvZipFileSize' => sprintf( '%.1f MB', filesize( $tsvZipFile ) / 1000000 ),
                       'README'         => file_get_contents( 'README.txt' ) ) );

  #------------------------------------------
  # DEPLOY
  #------------------------------------------

  #--- Move new files to public directory
  echo '<p><b>Move new files to public directory</b></p>';
  mySystem( "mv $sqlZipFile $tsvZipFile ../../misc/" );
  mySystem( "mv export.html ../../misc/" );

  #------------------------------------------
  # CLEAN UP
  #------------------------------------------

  #--- Delete temporary and old stuff we don't need anymore
  echo "<p><b>Delete temporary and old stuff we don't need anymore</b></p>";
  mySystem( "rm README.txt $sqlFile *.tsv" );
  mySystem( "rm ../../misc/$oldBasenameStart*" );

  #------------------------------------------
  # FINISHED
  #------------------------------------------

  #--- Tell the result
  noticeBox ( true, "Finished $basename.<br />Have a look at <a href='../misc/export.html'>the results</a>." );

  #--- Return to /admin
  chdir( '..' );
}
$currentSection = 'competitions';
require 'includes/_header.php';
#--- Get the parameters.
analyzeChoices();
#--- Get all competition infos.
$competition = getFullCompetitionInfos($chosenCompetitionId);
#--- If competition not found, say so and stop.
if (!$competition || !$competition['showAtAll']) {
    noticeBox(false, "Unknown competition ID \"{$chosenCompetitionId}\"");
    require 'includes/_footer.php';
    exit(0);
}
#--- Show competition infos.
require 'includes/competition_infos.php';
showCompetitionInfos();
if (wcaDate('Ymd') >= 10000 * $competition['year'] + 100 * $competition['month'] + $competition['day']) {
    #--- Try the cache
    # tryCache( 'competition', $chosenCompetitionId, $chosenByPerson, $chosenAllResults, $chosenTop3, $chosenWinners );
    #--- Show competition results...
    offerChoicesResults();
    require 'includes/competition_results.php';
    if ($chosenByPerson) {
        showCompetitionResultsByPerson();
    } else {
        showCompetitionResults();
    }
} else {
    if ($competition['use_wca_registration']) {
        #--- Show the prereg form.
        offerChoicesPrereg();
    }
function checkRounds () {
#----------------------------------------------------------------------
  global $competitionCondition, $competitionDescription;

  echo "<hr /><p>Checking <b> rounds for $competitionDescription</b>... (wait for the result message box at the end)</p>\n";

  #--- Get the number of competitors per round
  $roundRows = dbQuery("
    SELECT   count(result.id) nbPersons, result.competitionId, competition.year, competition.month, competition.day, result.eventId, result.roundId, round.cellName, result.formatId,
             CASE result.formatId WHEN '2' THEN BIT_AND( IF( result.value2,1,0)) WHEN '3' THEN BIT_AND( IF( result.value3,1,0)) WHEN 'm' THEN BIT_AND( IF( result.value3,1,0)) WHEN 'a' THEN BIT_AND( IF( result.value5 <> 0,1,0)) ELSE 1 END isNotCombined
    FROM     Results result, Competitions competition, Rounds round
    WHERE    competition.id = competitionId
      $competitionCondition
      AND    (( eventId <> '333mbf' ) OR (( competition.year = 2009 ) AND ( competition.month > 1 )) OR ( competition.year > 2009 ))
      AND    result.roundId <> 'b'
      AND    result.roundId = round.id
    GROUP BY competitionId, eventId, roundId
    ORDER BY year desc, month desc, day desc, competitionId, eventId, round.rank
  ");

  #--- Get the number of competitors per event
  $eventRows = dbQuery("
    SELECT   count(distinct result.personId) nbPersons, competitionId, eventId
    FROM     Results result, Competitions competition
    WHERE    competition.id = competitionId
      $competitionCondition
      AND    (( eventId <> '333mbf' ) OR (( competition.year = 2009 ) AND ( competition.month > 1 )) OR ( competition.year > 2009 ))
      AND    result.roundId <> 'b'
    GROUP BY competitionId, eventId
    ORDER BY year desc, month desc, day desc, competitionId, eventId
  ");

  #--- Begin the form
  echo "<form action='check_rounds_ACTION.php' method='post'>\n";

  $prevEvent = '';
  $wrongs = 0;
  foreach( $roundRows as $i => $roundRow ){
    list( $nbPersons, $competitionId, $year, $month, $day, $eventId, $roundId, $roundCellName, $formatId, $isNotCombined ) = $roundRow;
    $event = "$competitionId|$eventId";
    $competitionDate = mktime( 0, 0, 0, $month, $day, $year );

    $subsequentRoundCount = 0;
    while(true) {
      $nextRoundIndex = $i + $subsequentRoundCount + 1;
      if($nextRoundIndex >= count($roundRows)) {
        break;
      }
      $nextRoundRow = $roundRows[$nextRoundIndex];
      if($nextRoundRow['competitionId'] != $competitionId || $nextRoundRow['eventId'] != $eventId) {
        break;
      }
      $subsequentRoundCount++;
    }

    # Expanded Article 9m, since April 18, 2016
    if (mktime( 0, 0, 0, 4, 18, 2016 ) <= $competitionDate) {
      if($nbPersons <= 7) {
        # https://www.worldcubeassociation.org/regulations/#9m3: Rounds with 7 or fewer competitors must not have subsequent rounds.
        $maxAllowedSubsequentRoundCount = 0;
      } else if($nbPersons <= 15) {
        # https://www.worldcubeassociation.org/regulations/#9m2: Rounds with 15 or fewer competitors must have at most one subsequent round.
        $maxAllowedSubsequentRoundCount = 1;
      } else if($nbPersons <= 99) {
        # https://www.worldcubeassociation.org/regulations/#9m1: Rounds with 99 or fewer competitors must have at most two subsequent rounds.
        $maxAllowedSubsequentRoundCount = 2;
      } else {
        # https://www.worldcubeassociation.org/regulations/#9m: Events must have at most four rounds.
        $maxAllowedSubsequentRoundCount = 3;
      }

      if($subsequentRoundCount > $maxAllowedSubsequentRoundCount) {
        echo "<p style='margin-top:2em; margin-bottom:0'><a href='/competitions/$competitionId/results/all#e{$eventId}_$roundId'>$competitionId - $eventId - $roundId</a></p>";
        echo "<p>There were $nbPersons competitors in this round, and $subsequentRoundCount subsequent round(s), which is more than the allowed $maxAllowedSubsequentRoundCount subsequent round(s).</p>";
        echo "<br /><hr />";
        $wrongs++;
      }
    }

    #--- First round
    if ( $event != $prevEvent ) {
      $nbRounds = 1;
      $eventRow = array_shift( $eventRows );
      list( $nbTotalPersons, $eventCompetitionId, $eventEventId ) = $eventRow;
      assert( $eventCompetitionId == $competitionId );
      assert( $eventEventId == $eventId );

      #--- Checks round names
      if( $prevEvent ){
        list( $prevCompetitionId, $prevEventId ) = explode('|', $prevEvent);
        $wrongs += checkRoundNames ( $roundInfos, $prevCompetitionId, $prevEventId );
      }

      $roundInfos = array();

      #--- Checks for qualification round
      $isThisRoundQuals = (( $roundId == '0' or $roundId == 'h' ));

      if (( $nbTotalPersons != $nbPersons ) and ( ! $isThisRoundQuals )) {
        echo "<p style='margin-top:2em; margin-bottom:0'><a href='/competitions/$competitionId/results/all#e{$eventId}_$roundId'>$competitionId - $eventId - $roundId</a></p>";

        #--- Peek at next roundId
        if($subsequentRoundCount > 0) {
          $nextRoundId = $roundRows[$i+1]['roundId'];
          showQualifications( $competitionId, $eventId, $roundId, $nextRoundId );
        }

        echo "<p>Not all persons that competed in $eventId are in $roundCellName. It should thus be indicated as Qualification round<p/>";
        addQuals( $competitionId, $eventId );
        echo "<br /><hr />";
        $isThisRoundQuals = true;
        $wrongs++;
      }

      if (( $nbTotalPersons == $nbPersons ) and ( $isThisRoundQuals )) {
        echo "<p style='margin-top:2em; margin-bottom:0'><a href='/competitions/$competitionId/results/all#e{$eventId}_$roundId'>$competitionId - $eventId - $roundId</a></p>";

        #--- Peek at next roundId
        if($subsequentRoundCount > 0) {
          $nextRoundId = $roundRows[$i+1]['roundId'];
          showQualifications( $competitionId, $eventId, $roundId, $nextRoundId );
        }

        echo "<p>All persons that competed in $eventId are in $roundCellName. It should thus not be indicated as Qualification round</p>";
        removeQuals( $competitionId, $eventId );
        echo "<br /><hr />";
        $isThisRoundQuals = false;
        $wrongs++;
      }
    }

    # Following rounds
    else {
      $isThisRoundQuals = false;

      # Article 9m, since April 9, 2008 until April 17, 2016
      if (mktime( 0, 0, 0, 4, 9, 2008 ) <= $competitionDate and $competitionDate <= mktime( 0, 0, 0, 4, 17, 2016 )) {
        if ((( $nbRounds > 1 ) and ( $nbTotalPersons < 8 )) or (( $nbRounds > 2 ) and ( $nbTotalPersons < 16 )) or (( $nbRounds > 3 ) and ( $nbTotalPersons < 100 )) or ( $nbRounds > 4 )) {
          echo "<p style='margin-top:2em; margin-bottom:0'><a href='/competitions/$competitionId/results/all#e{$eventId}_$roundId'>$competitionId - $eventId - $roundId</a></p>";
          echo "<p>There are $nbRounds rounds for event $eventId, but only $nbTotalPersons competitors in total</p>";
          removeRound( $competitionId, $eventId, $nbRounds );
          echo "<br /><hr />";
          $wrongs++;
        }
      }

      # Article 9m/n/o, since July 20, 2006 until April 8, 2008
      if ( mktime( 0, 0, 0, 7, 20, 2006 ) <= $competitionDate and $competitionDate <= mktime( 0, 0, 0, 4, 8, 2008 )) {
        if ((( $nbRounds > 2 ) and ( $nbTotalPersons < 16 )) or (( $nbRounds > 3 ) and ( $nbTotalPersons < 100 )) or ( $nbRounds > 4 )) {
          echo "<p style='margin-top:2em; margin-bottom:0'><a href='/competitions/$competitionId/results/all#e{$eventId}_$roundId'>$competitionId - $eventId - $roundId</a></p>";
          echo "<p>There are $nbRounds rounds for event $eventId, but only $nbTotalPersons competitors in total</p>";
          removeRound( $competitionId, $eventId, $nbRounds );
          echo "<br /><hr />";
          $wrongs++;
        }
      }

      $nbQualPersons = $isPrevRoundQuals ? getQualifications( $competitionId, $eventId, $prevRoundId, $roundId ) : $nbPersons;

      # Article 9p1, since April 14, 2010
      if ( mktime( 0, 0, 0, 4, 14, 2010 ) <= $competitionDate ) {
        if ( $nbQualPersons > ( 3*$prevNbPersons/4 )) {
          echo "<p style='margin-top:2em; margin-bottom:0'><a href='/competitions/$competitionId/results/all#e{$eventId}_$roundId'>$competitionId - $eventId</a></p>";
          showQualifications( $competitionId, $eventId, $prevRoundId, $roundId );
          echo "<p>From round $prevRoundCellName with $prevNbPersons competitors, $nbQualPersons were qualified to round $roundCellName which is more than 75%</p>";
          echo "<br /><hr />";
          $wrongs++;
        }
      }

      # Article 9p, since July 20, 2006 until April 13, 2010
      if (mktime( 0, 0, 0, 7, 20, 2006 ) <= $competitionDate and $competitionDate <= mktime( 0, 0, 0, 4, 13, 2010 )) {
        if ( $nbQualPersons >= $prevNbPersons ) {
          echo "<p style='margin-top:2em; margin-bottom:0'><a href='/competitions/$competitionId/results/all#e{$eventId}_$roundId'>$competitionId - $eventId</a></p>";
          showQualifications( $competitionId, $eventId, $prevRoundId, $roundId );
          echo "<p>From round $prevRoundCellName to round $roundCellName, at least one competitor must not proceed</p>";
          echo "<br /><hr />";
          $wrongs++;
        }
      }
    }
    $nbRounds += 1;
    $prevNbPersons = $nbPersons;
    $prevEvent = $event;
    $prevRoundId = $roundId;
    $prevRoundCellName = $roundCellName;
    $isPrevRoundQuals = $isThisRoundQuals;
    $roundInfos[] = array( $roundId, $roundCellName, $formatId, $isNotCombined );

  }

  #--- Tell the result.
  $date = wcaDate();
  noticeBox2(
    ! ( $wrongs ),
    "We didn't find any mistake.<br />$date",
    "<p>Darn! We disagree: $wrongs incorrect rounds found<br /><br />$date</p>"
    ."<p>Choose the changes you agree with above, then click the 'Execute...' button below. It will result in something like the following.</p>"
    ."<pre>I'm doing this:\n"
    ."UPDATE Results SET pos=111 WHERE id=11111\n"
    ."UPDATE Results SET pos=222 WHERE id=22222\n"
    ."UPDATE Results SET pos=333 WHERE id=33333\n"
    ."</pre>"
  );

  #--- If differences were found, offer to fix them.
  if( $wrongs )
    echo "<center><input type='submit' value='Execute the agreed changes!' /></center>\n";

  #--- Finish the form.
  echo "</form>\n";
}
#--- Get all competition infos.
$competition = getFullCompetitionInfos( $chosenCompetitionId );

#--- If competition not found, say so and stop.
if( ! $competition || ! $competition['showAtAll'] ){
  noticeBox( false, "Unknown competition ID \"$chosenCompetitionId\"" );
  require( 'includes/_footer.php' );
  exit( 0 );
}

#--- Show competition infos.
require( 'includes/competition_infos.php' );
showCompetitionInfos();

if( wcaDate( 'Ymd' ) >= (10000*$competition['year'] + 
                           100*$competition['month'] + 
                               $competition['day']) ){

  #--- Try the cache
  # tryCache( 'competition', $chosenCompetitionId, $chosenByPerson, $chosenAllResults, $chosenTop3, $chosenWinners );

  #--- Show competition results...
  offerChoicesResults();
  require( 'includes/competition_results.php' );
  if( $chosenByPerson )
    showCompetitionResultsByPerson();
  else
    showCompetitionResults();
}
adminHeadline('Check finished persons');
showDescription();
showChoices();
if ($chosenCheck) {
    echo "<hr /><p>Checking... (wait for the result message box at the end)</p>\n";
    #--- Prepare the data
    getPersonsFromPersons();
    getPersonsFromResults();
    #--- Run the checks
    $success = true;
    checkSpacesInPersons();
    checkSpacesInResults();
    checkTooMuchInResults();
    checkDuplicatesInCompetition();
    #--- Tell the result
    noticeBox2($success, "Finished. All checks successful.<br />" . wcaDate(), "Finished. Some errors found.<br />" . wcaDate());
}
require '../includes/_footer.php';
#----------------------------------------------------------------------
function showDescription()
{
    #----------------------------------------------------------------------
    echo "<p>In this script, a \"person\" always means a triple of id/name/countryId, and \"similar\" always means just name similarity.</p>\n\n";
    echo "<p>I run several phases, listed below. You should always work from top to bottom, i.e. don't work on one phase before all previous phases report \"OK\".</p>\n\n";
    echo "<ul>\n";
    echo "<li><p>Find persons in <strong>Persons</strong> whose name starts or ends with space or has double spaces.</p></li>\n";
    echo "<li><p>Find persons in <strong>Results</strong> whose name starts or ends with space or has double spaces.</p></li>\n";
    echo "<li><p>Find persons in <strong>Results</strong> who have ids but who don't appear in <strong>Persons</strong>. Can be caused by organizers telling you incorrect persons. I show similar persons from <strong>Persons</strong> and offer you to adopt their data. Can also be caused by a person really changing name or countryId, in this case please add this person to the <strong>Persons</strong> table with new subId.</p></li>\n";
    echo "<li><p>Find persons in <strong>Results</strong> that appear more than once in the same round, event and competition. This is the most easily detected case of where an organizer should've added numbers to otherwise equal persons but didn't. Or for example when like in CaltechWinter2007, the roundIds are wrong. <b>Warning:</b> Currently this is only checks the last three months, to prevent a timeout problem.</p></li>\n";
    echo "</ul>";
    echo "<hr />";
function generateNewPassword($id, $randomString)
{
    #----------------------------------------------------------------------
    return sha1($id . "foobidoo" . $randomString . wcaDate());
}