+var waypoints = 0;
+var omitted_optional = 0;
+
/* Get the table element. */
function get_table() {
var div = document.getElementById('laps');
return has_class(table.rows[i].cells[0], 'finish_line');
}
+/* Is this station optional? */
+function optional(table, i) {
+ if (! omitted_optional) return false;
+ if (i == last_row(table)) return false;
+ if (i < last_row(table) - omitted_optional) return false;
+ return true;
+}
+
/* Get name of (station, lap) pair. */
function get_cell_name(i, j) {
return 'lap' + String(j) + 'station' + String(i);
var input = get_cell_input(i, j);
if (! input) continue;
input.setCustomValidity("");
+ /* Last row is mandatory. Others may be optional. */
+ if (optional(table, i)) input.style.backgroundImage = 'repeating-linear-gradient(-30deg, transparent, rgba(32, 128, 160, 0.25) 8px, rgba(32, 128, 160, 0.25) 8px, transparent 16px)';
+ else input.style.backgroundImage = 'inherit';
input.style.color = 'inherit';
}
}
var all_stations_visited = true;
/* Ensure station times are sequential. */
for (var i = first_row(table); valid_row(table, i); i++) {
+ if (optional(table, i)) continue;
var input = get_cell_input(i, j);
var text = input.value;
if (text.match(input.pattern)) {
for (var i = first_row(table); valid_row(table, i); i++) {
var input = get_cell_input(i, j);
if (input.value.match(input.pattern)) continue;
+ if (optional(table, i)) continue;
input.setCustomValidity('Lap ' + String(lap) + ' incomplete');
break;
}
for (var i = last_row(table); valid_row(table, i); i--) {
var input = get_cell_input(i, j);
if (! input.value.match(input.pattern)) continue;
+ if (optional(table, i)) continue;
last = i;
break;
}
for (var i = first_row(table); i < last; i++) {
var input = get_cell_input(i, j);
if (input.value.match(input.pattern)) continue;
+ if (optional(table, i)) continue;
valid = false;
/* First lap (only) can be reordered. */
if (j == first_column(table) && i > first_row(table) && i < last_row(table)) {
if (station_orders.length) {
var stations = [];
for (var i = first_row(table); valid_row(table, i); i++) {
+ if (optional(table, i)) continue;
var station_id = get_station_id(table, i);
if (station_id) stations.push(station_id);
}
}
else {
/* Revalidate if row is reordered. */
- for (var i = first_row(table); valid_row(table, i); i++) {
+ for (var i = first_row(table); valid_row(table, i, omitted_optional); i++) {
if (i == cloned) continue;
if (reorder_row(table, i)) return validate(table);
}
var joker = get_joker();
if (joker) joker.addEventListener('change', changed_joker, true);
if (typeof distances != 'undefined') update_raikogram(table);
+ var total_waypoints = last_row(table) - first_row(table);
+ if (typeof optional_waypoints == 'number' && optional_waypoints) waypoints = optional_waypoints;
+ else waypoints = total_waypoints;
+ omitted_optional = total_waypoints - waypoints - 1;
validate(table);
do_plot(table, document.getElementById('plot'));
var stats = document.getElementById('stats').getElementsByTagName('table')[0];
if ($leg->getFinishLine()) $flags |= Course::FinishFlag();
$legs[$station_name] = array($flags, $station->getId(), $system_id, $leg->getStationOrder());
}
+ $waypoints = $race->getWaypoints();
+ if (! $waypoints) $waypoints = count($station_order);
uasort($legs, 'sort_legs');
$system_ids = array_unique($system_ids);
$rq = new RaikogramQuery;
echo "<script type=\"text/javascript\"><!--\n";
echo "var distances = " . json_encode($distances) . ";\n";
echo "var allotted_time = $allotted_time;\n";
+ echo "var optional_waypoints = $waypoints;\n";
if ($entry) retrieve_entry($entry);
if ($_POST['lap1station1']) {
/*