Merge branch 'master' into bug5773

# Conflicts:
#	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties
This commit is contained in:
Udo Wessels
2023-07-31 09:09:27 +02:00
71 changed files with 752 additions and 206 deletions
@@ -1,3 +1,4 @@
eclipse.preferences.version=1
encoding//resources/stringmessages/Sailing_StringMessages.properties=UTF-8
encoding//resources/stringmessages/Sailing_StringMessages_de.properties=UTF-8
encoding/<project>=UTF-8
@@ -133,6 +133,7 @@ RelativeDistanceToAdvantageousEndOfLineAtStartOfRace=Relative Distance to Advant
windFrom=True Wind Direction (TWD)
windSpeedKnots=True Wind Speed (kts)
speedInKnots=Speed (kts)
speedInFullKnots=Speed in Full Knots (kts)
bearing=Direction (°T)
WindTrack=Wind Track
timeSpentFoiling=Time spent foiling
@@ -131,6 +131,7 @@ WindSourceName=Name der Windmessreihe
windFrom=Wind aus Richtung (TWD)
windSpeedKnots=Wahre Windgeschwindigkeit (kn)
speedInKnots=Fahrt (kn)
speedInFullKnots=Fahrt in ganzen Knoten (kn)
bearing=Richtung (°)
WindTrack=Windmessreihe
timeSpentFoiling=Zeit auf Foils
@@ -32,7 +32,7 @@ public enum MaxPointsReason {
/** Disqualification for gross misconduct not excludable under rule 90.3 (b) */
DGM(/* discardable */ false, /* advanceCompetitorsTrackedWorse */ true, /* appliesAtStartOfRace */ false),
/** Redress given */
RDG(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ false, /* appliesAtStartOfRace */ false),
RDG(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ false, /* appliesAtStartOfRace */ true, /* calculateScoreDuringRace */ true),
/** Black Flag Disqualified */
BFD(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ true, /* appliesAtStartOfRace */ true),
/** Did Not Compete */
@@ -40,7 +40,7 @@ public enum MaxPointsReason {
/** Retired After Finishing */
RAF(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ true, /* appliesAtStartOfRace */ false),
/** Discretionary Penalty Imposed by the race committee */
DPI(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ false, /* appliesAtStartOfRace */ false),
DPI(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ false, /* appliesAtStartOfRace */ true, /* calculateScoreDuringRace */ true),
/** Retired */
RET(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ true, /* appliesAtStartOfRace */ false),
/** Uniform Flag Disqualification */
@@ -60,7 +60,7 @@ public enum MaxPointsReason {
* A9b: "points equal to the average, to the nearest tenth of a point (0.05 to be rounded upward), of her points in
* all the races before the race in question"
*/
SCA(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ false, /* appliesAtStartOfRace */ false)
SCA(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ false, /* appliesAtStartOfRace */ true)
;
private final boolean discardable;
@@ -42,6 +42,8 @@ public class LeaderboardEntryDTO implements Serializable {
public Double totalPoints;
public Double totalPointsUncorrected;
public Double incrementalScoreCorrectionInPoints;
/**
* Tells if the total points have been overridden by a score correction. Can be used to render differently in editing environment.
*/
@@ -653,6 +655,7 @@ public class LeaderboardEntryDTO implements Serializable {
result = prime * result + ((totalPoints == null) ? 0 : totalPoints.hashCode());
result = prime * result + (totalPointsCorrected ? 1231 : 1237);
result = prime * result + ((totalPointsUncorrected == null) ? 0 : totalPointsUncorrected.hashCode());
result = prime * result + ((incrementalScoreCorrectionInPoints == null) ? 0 : incrementalScoreCorrectionInPoints.hashCode());
result = prime * result + ((windwardDistanceToCompetitorFarthestAheadInMeters == null) ? 0
: windwardDistanceToCompetitorFarthestAheadInMeters.hashCode());
return result;
@@ -809,6 +812,11 @@ public class LeaderboardEntryDTO implements Serializable {
return false;
} else if (!totalPoints.equals(other.totalPoints))
return false;
if (incrementalScoreCorrectionInPoints == null) {
if (other.incrementalScoreCorrectionInPoints != null)
return false;
} else if (!incrementalScoreCorrectionInPoints.equals(other.incrementalScoreCorrectionInPoints))
return false;
if (totalPointsCorrected != other.totalPointsCorrected)
return false;
if (totalPointsUncorrected == null) {
@@ -87,7 +87,8 @@ public enum FieldNames {
LEADERBOARD_COLUMNS, LEADERBOARD_COLUMN_NAME, LEADERBOARD_COMPETITOR_DISPLAY_NAMES,
LEADERBOARD_IS_MEDAL_RACE_COLUMN, LEADERBOARD_CARRIED_POINTS, LEADERBOARD_CARRIED_POINTS_BY_ID,
LEADERBOARD_SCORE_CORRECTIONS, LEADERBOARD_DISCARDING_THRESHOLDS,
LEADERBOARD_SCORE_CORRECTION_MAX_POINTS_REASON, LEADERBOARD_CORRECTED_SCORE, LEADERBOARD_SCORE_CORRECTION_TIMESTAMP,
LEADERBOARD_SCORE_CORRECTION_MAX_POINTS_REASON, LEADERBOARD_CORRECTED_SCORE,
LEADERBOARD_INCREMENTAL_SCORE_CORRECTION_IN_POINTS, LEADERBOARD_SCORE_CORRECTION_TIMESTAMP,
LEADERBOARD_RANK, LEADERBOARD_SCORE_CORRECTION_COMMENT, LEADERBOARD_SCORE_CORRECTION_MERGE_STATE,
LEADERBOARD_COLUMN_FACTORS, WRAPPED_REGATTA_LEADERBOARD_NAME, OTHER_TIEBREAKING_LEADERBOARD_NAME,
ELMINATED_COMPETITORS,
@@ -769,6 +769,14 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
dbScoreCorrectionForCompetitorInRaceAsNumber.doubleValue();
correctionsToUpdate.correctScoreByID(competitorId, raceColumn, leaderboardCorrectedScore);
}
if (dbScoreCorrectionForCompetitorInRace
.containsKey(FieldNames.LEADERBOARD_INCREMENTAL_SCORE_CORRECTION_IN_POINTS.name())) {
final Number dbIncrementalScoreCorrectionForCompetitorInRaceAsNumberInPoints = (Number) dbScoreCorrectionForCompetitorInRace
.get(FieldNames.LEADERBOARD_INCREMENTAL_SCORE_CORRECTION_IN_POINTS.name());
final Double leaderboardIncrementalCorrectedScoreInPoints = dbIncrementalScoreCorrectionForCompetitorInRaceAsNumberInPoints == null ? null :
dbIncrementalScoreCorrectionForCompetitorInRaceAsNumberInPoints.doubleValue();
correctionsToUpdate.correctScoreIncrementallyByID(competitorId, raceColumn, leaderboardIncrementalCorrectedScoreInPoints);
}
}
} else {
logger.warning("Couldn't find race column " + MongoUtils.unescapeDollarAndDot(escapedRaceColumnName)
@@ -160,7 +160,6 @@ import com.sap.sse.common.TypeBasedServiceFinder;
import com.sap.sse.common.TypeBasedServiceFinderFactory;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.shared.json.JsonSerializer;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
@@ -476,26 +475,30 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
}
private void storeScoreCorrections(Leaderboard leaderboard, Document dbScoreCorrections) {
TimePoint now = MillisecondsTimePoint.now();
SettableScoreCorrection scoreCorrection = leaderboard.getScoreCorrection();
for (RaceColumn raceColumn : scoreCorrection.getRaceColumnsThatHaveCorrections()) {
BasicDBList dbCorrectionForRace = new BasicDBList();
final TimePoint now = TimePoint.now();
final SettableScoreCorrection scoreCorrection = leaderboard.getScoreCorrection();
for (final RaceColumn raceColumn : scoreCorrection.getRaceColumnsThatHaveCorrections()) {
final BasicDBList dbCorrectionForRace = new BasicDBList();
for (Competitor competitor : scoreCorrection.getCompetitorsThatHaveCorrectionsIn(raceColumn)) {
// TODO bug 655: make score corrections time dependent
if (scoreCorrection.isScoreCorrected(competitor, raceColumn, now)) {
Document dbCorrectionForCompetitor = new Document();
final Document dbCorrectionForCompetitor = new Document();
dbCorrectionForCompetitor.put(FieldNames.COMPETITOR_ID.name(), competitor.getId());
MaxPointsReason maxPointsReason = scoreCorrection.getMaxPointsReason(competitor, raceColumn, now);
final MaxPointsReason maxPointsReason = scoreCorrection.getMaxPointsReason(competitor, raceColumn, now);
if (maxPointsReason != MaxPointsReason.NONE) {
dbCorrectionForCompetitor.put(FieldNames.LEADERBOARD_SCORE_CORRECTION_MAX_POINTS_REASON.name(),
maxPointsReason.name());
}
Double explicitScoreCorrection = scoreCorrection
final Double explicitScoreCorrection = scoreCorrection
.getExplicitScoreCorrection(competitor, raceColumn);
if (explicitScoreCorrection != null) {
dbCorrectionForCompetitor.put(FieldNames.LEADERBOARD_CORRECTED_SCORE.name(),
explicitScoreCorrection);
}
final Double incrementalScoreCorrectionInPoints = scoreCorrection.getIncementalScoreCorrectionInPoints(competitor, raceColumn);
if (incrementalScoreCorrectionInPoints != null) {
dbCorrectionForCompetitor.put(FieldNames.LEADERBOARD_INCREMENTAL_SCORE_CORRECTION_IN_POINTS.name(), incrementalScoreCorrectionInPoints);
}
dbCorrectionForRace.add(dbCorrectionForCompetitor);
}
}
@@ -62,7 +62,7 @@ public abstract class AbstractTracTracLiveTest extends StoredTrackBasedTest {
*/
@Rule
public TestRule getTimeoutRule() {
return Timeout.millis(3 * 60 * 1000);
return Timeout.millis(5 * 60 * 1000);
}
protected AbstractTracTracLiveTest() throws URISyntaxException, MalformedURLException {
@@ -13,6 +13,12 @@ public abstract class AbstractScoreCorrectionListenerWithDefaultAction implement
defaultAction();
}
@Override
public void incrementalScoreCorrectionChanged(Competitor competitor, RaceColumn raceColumn,
Double oldScoreOffsetInPoints, Double newScoreOffsetInPoints) {
defaultAction();
}
@Override
public void maxPointsReasonChanged(Competitor competitor, RaceColumn raceColumn, MaxPointsReason oldMaxPointsReason,
MaxPointsReason newMaxPointsReason) {
@@ -34,6 +34,8 @@ public interface DelayedLeaderboardCorrections extends RaceColumnListener, Seria
void correctScoreByID(Serializable competitorId, RaceColumn raceColumn, double correctedScore);
void correctScoreIncrementallyByID(Serializable competitorId, RaceColumn raceColumn, double incrementalScoreCorrectionOffsetInPoints);
void setCarriedPointsByID(Serializable competitorId, double carriedPoints);
void setMaxPointsReasonByID(Serializable competitorId, RaceColumn raceColumn, MaxPointsReason maxPointsReason);
@@ -74,6 +74,7 @@ public interface Leaderboard extends LeaderboardBase, HasRaceColumns {
public interface Entry {
int getTrackedRank();
Double getTotalPoints();
Double getIncrementalScoreCorrectionInPoints();
Double getTotalPointsUncorrected();
Double getNetPoints();
MaxPointsReason getMaxPointsReason();
@@ -40,8 +40,12 @@ public interface ScoreCorrection extends Serializable {
MaxPointsReason getMaxPointsReason();
Double getIncrementalScoreCorrectionInPoints();
boolean isCorrected();
boolean isCorrectedIncrementally();
/**
* @return the time point for which this result is valid
*/
@@ -102,6 +106,10 @@ public interface ScoreCorrection extends Serializable {
*/
boolean isScoreCorrected(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint);
boolean isScoreCorrectedIncrementally(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint);
Double getIncementalScoreCorrectionInPoints(Competitor competitor, RaceColumn raceColumn);
/**
* Checks if this score correction object has any score corrections for any competitor valid at any time point for
* the race column specified by <code>raceInLeaderboard</code>.
@@ -8,6 +8,8 @@ import com.sap.sse.common.TimePoint;
public interface ScoreCorrectionListener {
void correctedScoreChanged(Competitor competitor, RaceColumn raceColumn, Double oldCorrectedScore, Double newCorrectedScore);
void incrementalScoreCorrectionChanged(Competitor competitor, RaceColumn raceColumn, Double oldScoreOffsetInPoints, Double newScoreOffsetInPoints);
void maxPointsReasonChanged(Competitor competitor, RaceColumn raceColumn, MaxPointsReason oldMaxPointsReason, MaxPointsReason newMaxPointsReason);
void carriedPointsChanged(Competitor competitor, Double oldCarriedPoints, Double newCarriedPoints);
@@ -90,7 +90,6 @@ public interface ScoringScheme extends Serializable {
* may be required in case a "penalty" such as a redress needs to inspect the scores of other race
* columns as well; implementations need to take great care not to cause endless recursions by
* naively asking the leaderboard for scores which would recurse into this method
* @param uncorrectedScoreProvider TODO
*/
Double getPenaltyScore(RaceColumn raceColumn, Competitor competitor, MaxPointsReason maxPointsReason,
Integer numberOfCompetitorsInRace, NumberOfCompetitorsInLeaderboardFetcher numberOfCompetitorsInLeaderboardFetcher,
@@ -3,6 +3,8 @@ package com.sap.sailing.domain.leaderboard;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.leaderboard.impl.HighPoint;
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
import com.sap.sse.common.TimePoint;
public interface SettableScoreCorrection extends ScoreCorrection {
@@ -31,6 +33,39 @@ public interface SettableScoreCorrection extends ScoreCorrection {
*/
void uncorrectScore(Competitor competitor, RaceColumn raceColumn);
/**
* An incremental score correction is applied when an absolute score correction set through
* {@link #correctScore(Competitor, RaceColumn, double)} is not available or not (yet) applied, e.g., because the
* {@link #getMaxPointsReason(Competitor, RaceColumn, TimePoint) invalid result marker (IRM)} suggests that the
* score correction should be applied only, e.g., after the race and the time point for which the score is requested
* is still before the competitor's finishing time.
* <p>
*
* For {@link LowPoint} schemes the {@code points} provided here will be <em>added</em> to a competitor's score as
* obtained by the scoring scheme from the competitor's rank in the race. For {@link HighPoint} schemes it will be
* subtracted.
* <p>
*
* Any {@link ScoreCorrectionListener} registered will be
* {@link ScoreCorrectionListener#incrementalScoreCorrectionChanged(Competitor, RaceColumn, Double, Double)
* notified}.
*/
void correctScoreIncrementally(Competitor competitor, RaceColumn raceColumn, double scoreOffsetInPoints);
/**
* Removes an incremental score correction set with
* {@link #correctScoreIncrementally(Competitor, RaceColumn, double)} which makes the competitor's live for
* <code>raceColumn</code> to fall back to the score determined by the tracking data, unless an absolute
* {@link #correctScore(Competitor, RaceColumn, double) score correction} has been provided that is to be applied
* already for the query time point.
* <p>
*
* Any {@link ScoreCorrectionListener} registered will be
* {@link ScoreCorrectionListener#incrementalScoreCorrectionChanged(Competitor, RaceColumn, Double, Double)
* notified}.
*/
void uncorrectScoreIncrementally(Competitor competitor, RaceColumn raceColumn);
/**
* @return <code>null</code> if not set for the competitor, e.g., because no correction was made or only a
* {@link MaxPointsReason} but no explicit score was provided for the competitor.
@@ -665,6 +665,7 @@ public abstract class AbstractLeaderboardWithCache implements Leaderboard {
if (fillTotalPointsUncorrected) {
entryDTO.totalPointsUncorrected = entry.getTotalPointsUncorrected();
}
entryDTO.incrementalScoreCorrectionInPoints = entry.getIncrementalScoreCorrectionInPoints();
entryDTO.totalPointsCorrected = entry.isTotalPointsCorrected();
entryDTO.netPoints = entry.getNetPoints();
entryDTO.reasonForMaxPoints = entry.getMaxPointsReason();
@@ -101,6 +101,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
private final Callable<Integer> trackedRankProvider;
private final Double totalPoints;
private final Callable<Double> totalPointsUncorrectedProvider;
private final Double incrementalScoreCorrectionInPoints;
private final boolean isTotalPointsCorrected;
private final Double netPoints;
private final MaxPointsReason maxPointsReason;
@@ -109,12 +110,13 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
private EntryImpl(Callable<Integer> trackedRankProvider, Double totalPoints,
Callable<Double> totalPointsUncorrectedProvider, boolean isTotalPointsCorrected, Double netPoints,
MaxPointsReason maxPointsReason, boolean discarded, Fleet fleet) {
MaxPointsReason maxPointsReason, Double incrementalScoreCorrectionInPoints, boolean discarded, Fleet fleet) {
super();
this.trackedRankProvider = trackedRankProvider;
this.totalPoints = totalPoints;
this.totalPointsUncorrectedProvider = totalPointsUncorrectedProvider;
this.isTotalPointsCorrected = isTotalPointsCorrected;
this.incrementalScoreCorrectionInPoints = incrementalScoreCorrectionInPoints;
this.netPoints = netPoints;
this.maxPointsReason = maxPointsReason;
this.discarded = discarded;
@@ -135,6 +137,11 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
return totalPoints;
}
@Override
public Double getIncrementalScoreCorrectionInPoints() {
return incrementalScoreCorrectionInPoints;
}
@Override
public boolean isTotalPointsCorrected() {
return isTotalPointsCorrected;
@@ -678,7 +685,8 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
return new EntryImpl(trackedRankProvider, correctedScoreScaledByColumnFactor, () -> correctedResults.getUncorrectedScore(),
correctedResults.isCorrected(),
discarded ? DOUBLE_0 : correctedScoreScaledByColumnFactor,
correctedResults.getMaxPointsReason(), discarded, race.getFleetOfCompetitor(competitor));
correctedResults.getMaxPointsReason(), correctedResults.getIncrementalScoreCorrectionInPoints(),
discarded, race.getFleetOfCompetitor(competitor));
}
@Override
@@ -753,7 +761,8 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
Entry entry = new EntryImpl(trackedRankProvider, correctedScoreScaledByColumnFactor,
() -> correctedResults.getUncorrectedScore(), correctedResults.isCorrected(),
discarded ? DOUBLE_0 : correctedScoreScaledByColumnFactor,
correctedResults.getMaxPointsReason(), discarded, raceColumn.getFleetOfCompetitor(competitor));
correctedResults.getMaxPointsReason(), correctedResults.getIncrementalScoreCorrectionInPoints(),
discarded, raceColumn.getFleetOfCompetitor(competitor));
result.put(new com.sap.sse.common.Util.Pair<Competitor, RaceColumn>(competitor, raceColumn), entry);
}
}
@@ -40,12 +40,13 @@ import com.sap.sse.common.IsManagedByCache;
*
*/
public class DelayedLeaderboardCorrectionsImpl implements RaceColumnListenerWithDefaultAction, DelayedLeaderboardCorrections, IsManagedByCache<SharedDomainFactory<?>> {
private static final long serialVersionUID = 8824782847677232275L;
private static final long serialVersionUID = 2652040937315024239L;
// structures that key corrections by competitor ID
private final Map<Serializable, Double> carriedPointsByCompetitorID;
private final Map<Serializable, Map<RaceColumn, MaxPointsReason>> maxPointsReasonsByCompetitorID;
private final Map<Serializable, Map<RaceColumn, Double>> correctedScoresByCompetitorID;
private final Map<Serializable, Map<RaceColumn, Double>> incrementalScoreCorrectionOffsetsInPointsByCompetitorID;
private final Map<Serializable, String> displayNamesByCompetitorID;
private final Set<Serializable> suppressedCompetitorIDs;
@@ -57,11 +58,12 @@ public class DelayedLeaderboardCorrectionsImpl implements RaceColumnListenerWith
public DelayedLeaderboardCorrectionsImpl(Leaderboard leaderboard, CompetitorFactory competitorFactory) {
this.competitorFactory = competitorFactory;
listeners = new HashSet<>();
carriedPointsByCompetitorID = new HashMap<Serializable, Double>();
maxPointsReasonsByCompetitorID = new HashMap<Serializable, Map<RaceColumn,MaxPointsReason>>();
correctedScoresByCompetitorID = new HashMap<Serializable, Map<RaceColumn, Double>>();
displayNamesByCompetitorID = new HashMap<Serializable, String>();
suppressedCompetitorIDs = new HashSet<Serializable>();
carriedPointsByCompetitorID = new HashMap<>();
maxPointsReasonsByCompetitorID = new HashMap<>();
correctedScoresByCompetitorID = new HashMap<>();
incrementalScoreCorrectionOffsetsInPointsByCompetitorID = new HashMap<>();
displayNamesByCompetitorID = new HashMap<>();
suppressedCompetitorIDs = new HashSet<>();
this.leaderboard = leaderboard;
leaderboard.addRaceColumnListener(this);
}
@@ -117,7 +119,7 @@ public class DelayedLeaderboardCorrectionsImpl implements RaceColumnListenerWith
synchronized (maxPointsReasonsByCompetitorID) {
Map<RaceColumn, MaxPointsReason> map = maxPointsReasonsByCompetitorID.get(competitorId);
if (map == null) {
map = new HashMap<RaceColumn, MaxPointsReason>();
map = new HashMap<>();
maxPointsReasonsByCompetitorID.put(competitorId, map);
}
map.put(raceColumn, maxPointsReason);
@@ -135,7 +137,7 @@ public class DelayedLeaderboardCorrectionsImpl implements RaceColumnListenerWith
synchronized (correctedScoresByCompetitorID) {
Map<RaceColumn, Double> map = correctedScoresByCompetitorID.get(competitorId);
if (map == null) {
map = new HashMap<RaceColumn, Double>();
map = new HashMap<>();
correctedScoresByCompetitorID.put(competitorId, map);
}
map.put(raceColumn, correctedScore);
@@ -143,6 +145,25 @@ public class DelayedLeaderboardCorrectionsImpl implements RaceColumnListenerWith
}
}
@Override
public void correctScoreIncrementallyByID(Serializable competitorId, RaceColumn raceColumn,
double incrementalScoreCorrectionOffsetInPoints) {
assertNoTrackedRaceAssociatedYet();
Competitor competitor = competitorFactory.getExistingCompetitorById(competitorId);
if (competitor != null) {
leaderboard.getScoreCorrection().correctScoreIncrementally(competitor, raceColumn, incrementalScoreCorrectionOffsetInPoints);
} else {
synchronized (incrementalScoreCorrectionOffsetsInPointsByCompetitorID) {
Map<RaceColumn, Double> map = incrementalScoreCorrectionOffsetsInPointsByCompetitorID.get(competitorId);
if (map == null) {
map = new HashMap<>();
incrementalScoreCorrectionOffsetsInPointsByCompetitorID.put(competitorId, map);
}
map.put(raceColumn, incrementalScoreCorrectionOffsetInPoints);
}
}
}
/**
* Checks if there are any carried points, max points reasons or corrected scores left over that may now receive
* their competitor record. If so, {@link #setCarriedPointsByName(com.sap.sailing.domain.base.Competitor, int)},
@@ -200,6 +221,20 @@ public class DelayedLeaderboardCorrectionsImpl implements RaceColumnListenerWith
}
}
}
synchronized (incrementalScoreCorrectionOffsetsInPointsByCompetitorID) {
for (Iterator<java.util.Map.Entry<Serializable, Map<RaceColumn, Double>>> incrementallyCorrectedScoresEntryIter = incrementalScoreCorrectionOffsetsInPointsByCompetitorID
.entrySet().iterator(); incrementallyCorrectedScoresEntryIter.hasNext();) {
java.util.Map.Entry<Serializable, Map<RaceColumn, Double>> incrementallyCorrectedScoresEntries = incrementallyCorrectedScoresEntryIter.next();
if (competitorsByID.containsKey(incrementallyCorrectedScoresEntries.getKey())) {
for (java.util.Map.Entry<RaceColumn, Double> incrementallyCorrectedScoreEntry : incrementallyCorrectedScoresEntries.getValue().entrySet()) {
leaderboard.getScoreCorrection().correctScoreIncrementally(
competitorsByID.get(incrementallyCorrectedScoresEntries.getKey()), incrementallyCorrectedScoreEntry.getKey(),
incrementallyCorrectedScoreEntry.getValue());
}
incrementallyCorrectedScoresEntryIter.remove();
}
}
}
synchronized (displayNamesByCompetitorID) {
for (Iterator<java.util.Map.Entry<Serializable, String>> displayNamesEntryIter = displayNamesByCompetitorID
.entrySet().iterator(); displayNamesEntryIter.hasNext();) {
@@ -66,7 +66,7 @@ public class LowPoint extends AbstractScoringSchemeImpl {
NumberOfCompetitorsInLeaderboardFetcher numberOfCompetitorsInLeaderboardFetcher, TimePoint timePoint,
Leaderboard leaderboard, Supplier<Double> uncorrectedScoreProvider) {
Double result;
if (maxPointsReason == MaxPointsReason.STP) {
if (maxPointsReason == MaxPointsReason.STP) { // TODO bug5873: this is where other incremental IRMs need to be considered, too, with configurable increments
final Double uncorrectedScore = uncorrectedScoreProvider.get();
result = uncorrectedScore == null ? null : uncorrectedScore + 1.0;
} else if (numberOfCompetitorsInRace == null || raceColumn.hasSplitFleetContiguousScoring()) {
@@ -8,12 +8,14 @@ import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.RaceColumnInSeries;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.NumberOfCompetitorsInLeaderboardFetcher;
@@ -26,6 +28,7 @@ import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingAndORCPerformanceCurveCache;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
/**
* Implements the basic logic of assigning a maximum score to a competitor in a race if that competitor was
@@ -43,12 +46,35 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
/**
* If no max point reason is provided for a competitor/race, {@link MaxPointsReason#NONE} should be the default.
*/
private final ConcurrentMap<com.sap.sse.common.Util.Pair<Competitor, RaceColumn>, MaxPointsReason> maxPointsReasons;
private final ConcurrentMap<Pair<Competitor, RaceColumn>, MaxPointsReason> maxPointsReasons;
/**
* If no score correction is provided here, the uncorrected points are the default.
*/
private final ConcurrentMap<com.sap.sse.common.Util.Pair<Competitor, RaceColumn>, Double> correctedScores;
private final ConcurrentMap<Pair<Competitor, RaceColumn>, Double> correctedScores;
/**
* If a {@link #correctedScores fixed corrected score} exists, it is used in
* {@link #getCorrectedScore(Callable, Competitor, RaceColumn, Leaderboard, TimePoint, NumberOfCompetitorsInLeaderboardFetcher, ScoringScheme, WindLegTypeAndLegBearingAndORCPerformanceCurveCache)}
* if any {@link #maxPointsReasons} suggests that the correction shall be applied (e.g., after the end of the race
* only). If no absolute {@link #correctedScores corrected score} is set for a competitor in a race column or the
* {@link #maxPointsReasons} suggests that it doesn't apply at the time point in question, an incremental score
* correction may apply.
* <p>
*
* Incremental score corrections are added to the score derived from the ranking at the given point in time, before
* applying a column factor. This is independent of the use of {@link LowPoint} or {@link HighPoint} scoring scheme
* variants, so for penalties in {@link HighPoint} schemes values should probably be negative. Column factor
* application may be contradicting the Notice of Race / Sailing Instructions for a specific event where it may
* read, e.g., that {@link MaxPointsReason#STP} penalties shall be applied <em>after</em> doubling a medal race's
* score. In such cases values divided by the column factor must be used so that the final result matches the
* expected incremental offset again.
* <p>
*
* @since 2023-07-25; this means that de-serializing an object written by an older version of this class will lead
* to serious problems, e.g., to {@link NullPointerException}s when trying to access this field.
*/
private final ConcurrentMap<Pair<Competitor, RaceColumn>, Double> incrementalScoreCorrection;
/**
* If <code>null</code>, despite a non-<code>null</code> {@link #timePointOfLastCorrectionsValidity} value the
@@ -72,6 +98,7 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
this.leaderboard = leaderboard;
this.maxPointsReasons = new ConcurrentHashMap<>();
this.correctedScores = new ConcurrentHashMap<>();
this.incrementalScoreCorrection = new ConcurrentHashMap<>();
this.scoreCorrectionListeners = new HashSet<ScoreCorrectionListener>();
}
@@ -106,6 +133,12 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
}
}
protected void notifyListenersAboutIncrementalScoreChange(Competitor competitor, RaceColumn raceColumn, Double oldScoreOffsetInPoints, Double newScoreOffsetInPoints) {
for (ScoreCorrectionListener listener : getScoreCorrectionListeners()) {
listener.incrementalScoreCorrectionChanged(competitor, raceColumn, oldScoreOffsetInPoints, newScoreOffsetInPoints);
}
}
protected void notifyListeners(Competitor competitor, RaceColumn raceColumn,
MaxPointsReason oldMaxPointsReason, MaxPointsReason newMaxPointsReason) {
for (ScoreCorrectionListener listener : getScoreCorrectionListeners()) {
@@ -144,7 +177,7 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
@Override
public void setMaxPointsReason(Competitor competitor, RaceColumn raceColumn, MaxPointsReason reason) {
com.sap.sse.common.Util.Pair<Competitor, RaceColumn> key = raceColumn.getKey(competitor);
Pair<Competitor, RaceColumn> key = raceColumn.getKey(competitor);
MaxPointsReason oldMaxPointsReason;
if (reason == null) {
oldMaxPointsReason = maxPointsReasons.remove(key);
@@ -162,17 +195,41 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
@Override
public boolean isScoreCorrected(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint) {
com.sap.sse.common.Util.Pair<Competitor, RaceColumn> key = raceColumn.getKey(competitor);
final Pair<Competitor, RaceColumn> key = raceColumn.getKey(competitor);
return (correctedScores.containsKey(key) && !isCertainlyBeforeRaceFinish(timePoint, raceColumn, competitor))
|| (maxPointsReasons.containsKey(key) && isMaxPointsReasonApplicable(maxPointsReasons.get(key), timePoint, raceColumn, competitor));
}
@Override
public void uncorrectScore(Competitor competitor, RaceColumn raceColumn) {
Double oldScore = correctedScores.remove(raceColumn.getKey(competitor));
final Double oldScore = correctedScores.remove(raceColumn.getKey(competitor));
notifyListeners(competitor, raceColumn, oldScore, null);
}
@Override
public void correctScoreIncrementally(Competitor competitor, RaceColumn raceColumn, double scoreOffsetInPoints) {
final Double oldScoreOffsetInPoints = incrementalScoreCorrection.put(raceColumn.getKey(competitor), scoreOffsetInPoints);
notifyListenersAboutIncrementalScoreChange(competitor, raceColumn, oldScoreOffsetInPoints, scoreOffsetInPoints);
}
@Override
public boolean isScoreCorrectedIncrementally(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint) {
final Pair<Competitor, RaceColumn> key = raceColumn.getKey(competitor);
return (incrementalScoreCorrection.containsKey(key) && !isCertainlyBeforeRaceFinish(timePoint, raceColumn, competitor))
|| (maxPointsReasons.containsKey(key) && isMaxPointsReasonApplicable(maxPointsReasons.get(key), timePoint, raceColumn, competitor));
}
@Override
public Double getIncementalScoreCorrectionInPoints(Competitor competitor, RaceColumn raceColumn) {
return incrementalScoreCorrection.get(raceColumn.getKey(competitor));
}
@Override
public void uncorrectScoreIncrementally(Competitor competitor, RaceColumn raceColumn) {
final Double oldScoreOffsetInPoints = incrementalScoreCorrection.remove(raceColumn.getKey(competitor));
notifyListenersAboutIncrementalScoreChange(competitor, raceColumn, oldScoreOffsetInPoints, null);
}
/**
* Based on the order of the {@link Leaderboard#getRaceColumns() race columns} in the {@link #getLeaderboard()
* leaderboard to which this score correction object belongs}, tries to determine whether the <code>timePoint</code>
@@ -417,10 +474,15 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
final Double correctedNonMaxedScore;
if ((maxPointsReason.isCalculateScoreDuringRace() && isCertainlyBeforeRaceFinish(timePoint, raceColumn, competitor))
|| (correctedNonMaxedScore = correctedScores.get(raceColumn.getKey(competitor))) == null) {
final Supplier<Double> uncorrectedScoreProvider = ()->getUncorrectedScore(competitor, raceColumn, trackedRankProvider, scoringScheme, numberOfCompetitorsInLeaderboardFetcher, timePoint, cache);
final Double incrementalScoreCorrectionForCompetitorInColumn = incrementalScoreCorrection.get(raceColumn.getKey(competitor));
if (incrementalScoreCorrectionForCompetitorInColumn != null) {
result = uncorrectedScoreProvider.get() + incrementalScoreCorrectionForCompetitorInColumn;
} else {
result = scoringScheme.getPenaltyScore(raceColumn, competitor, maxPointsReason.getMaxPointsReason(),
getNumberOfCompetitorsInRace(raceColumn, competitor, numberOfCompetitorsInLeaderboardFetcher),
numberOfCompetitorsInLeaderboardFetcher, timePoint, leaderboard,
/* uncorrectedScoreProvider */ ()->getUncorrectedScore(competitor, raceColumn, trackedRankProvider, scoringScheme, numberOfCompetitorsInLeaderboardFetcher, timePoint, cache));
numberOfCompetitorsInLeaderboardFetcher, timePoint, leaderboard, uncorrectedScoreProvider);
}
} else {
result = correctedNonMaxedScore;
}
@@ -437,11 +499,21 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
return correctedScore;
}
@Override
public Double getIncrementalScoreCorrectionInPoints() {
return incrementalScoreCorrection.get(raceColumn.getKey(competitor));
}
@Override
public boolean isCorrected() {
return isScoreCorrected(competitor, raceColumn, getTimePoint());
}
@Override
public boolean isCorrectedIncrementally() {
return isScoreCorrectedIncrementally(competitor, raceColumn, getTimePoint());
}
@Override
public TimePoint getTimePoint() {
return timePoint;
@@ -470,7 +542,16 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
Integer result;
final TrackedRace trackedRace = raceColumn.getTrackedRace(competitor);
if (trackedRace == null) {
result = numberOfCompetitorsInLeaderboardFetcher.getNumberOfCompetitorsInLeaderboard();
final int estimatedSizeOfLargestFleet;
final int numberOfCompetitorsInLeaderboard = numberOfCompetitorsInLeaderboardFetcher.getNumberOfCompetitorsInLeaderboard();
if (raceColumn instanceof RaceColumnInSeries) {
final int numberOfFleets = Util.size(((RaceColumnInSeries) raceColumn).getSeries().getFleets());
estimatedSizeOfLargestFleet = numberOfCompetitorsInLeaderboard / numberOfFleets
+ (int) Math.signum(numberOfCompetitorsInLeaderboard % numberOfFleets); // round up
} else {
estimatedSizeOfLargestFleet = numberOfCompetitorsInLeaderboard;
}
result = estimatedSizeOfLargestFleet;
} else {
result = Util.size(trackedRace.getRace().getCompetitors());
}
@@ -533,13 +614,13 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
}
private boolean internalHasScoreCorrectionFor(RaceColumn raceInLeaderboard, boolean considerOnlyUntrackedRaces) {
for (com.sap.sse.common.Util.Pair<Competitor, RaceColumn> correctedScoresKey : correctedScores.keySet()) {
for (Pair<Competitor, RaceColumn> correctedScoresKey : correctedScores.keySet()) {
if (correctedScoresKey.getB() == raceInLeaderboard &&
(!considerOnlyUntrackedRaces || raceInLeaderboard.getTrackedRace(correctedScoresKey.getA()) == null)) {
return true;
}
}
for (com.sap.sse.common.Util.Pair<Competitor, RaceColumn> maxPointsReasonsKey : maxPointsReasons.keySet()) {
for (Pair<Competitor, RaceColumn> maxPointsReasonsKey : maxPointsReasons.keySet()) {
if (maxPointsReasonsKey.getB() == raceInLeaderboard &&
(!considerOnlyUntrackedRaces || raceInLeaderboard.getTrackedRace(maxPointsReasonsKey.getA()) == null)) {
return true;
@@ -588,10 +669,10 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
@Override
public Iterable<RaceColumn> getRaceColumnsThatHaveCorrections() {
Set<RaceColumn> result = new HashSet<>();
for (com.sap.sse.common.Util.Pair<Competitor, RaceColumn> correctedScoresKey : correctedScores.keySet()) {
for (Pair<Competitor, RaceColumn> correctedScoresKey : correctedScores.keySet()) {
result.add(correctedScoresKey.getB());
}
for (com.sap.sse.common.Util.Pair<Competitor, RaceColumn> maxPointsReasonsKey : maxPointsReasons.keySet()) {
for (Pair<Competitor, RaceColumn> maxPointsReasonsKey : maxPointsReasons.keySet()) {
result.add(maxPointsReasonsKey.getB());
}
return result;
@@ -600,12 +681,12 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
@Override
public Iterable<Competitor> getCompetitorsThatHaveCorrectionsIn(RaceColumn raceColumn) {
Set<Competitor> result = new HashSet<>();
for (com.sap.sse.common.Util.Pair<Competitor, RaceColumn> correctedScoresKey : correctedScores.keySet()) {
for (Pair<Competitor, RaceColumn> correctedScoresKey : correctedScores.keySet()) {
if (raceColumn == correctedScoresKey.getB()) {
result.add(correctedScoresKey.getA());
}
}
for (com.sap.sse.common.Util.Pair<Competitor, RaceColumn> maxPointsReasonsKey : maxPointsReasons.keySet()) {
for (Pair<Competitor, RaceColumn> maxPointsReasonsKey : maxPointsReasons.keySet()) {
if (raceColumn == maxPointsReasonsKey.getB()) {
result.add(maxPointsReasonsKey.getA());
}
@@ -78,6 +78,13 @@ public abstract class AbstractMetaLeaderboard extends AbstractSimpleLeaderboardI
getScoreCorrection().notifyListeners(competitor, raceColumn, oldCorrectedScore, newCorrectedScore);
}
@Override
public void incrementalScoreCorrectionChanged(Competitor competitor, RaceColumn raceColumn,
Double oldScoreOffsetInPoints, Double newScoreOffsetInPoints) {
getScoreCorrection().notifyListenersAboutIncrementalScoreChange(competitor, raceColumn,
oldScoreOffsetInPoints, newScoreOffsetInPoints);
}
@Override
public void maxPointsReasonChanged(Competitor competitor, RaceColumn raceColumn,
MaxPointsReason oldMaxPointsReason, MaxPointsReason newMaxPointsReason) {
@@ -32,6 +32,16 @@ public class MetaLeaderboardScoreCorrection extends ScoreCorrectionImpl {
super.notifyListeners(competitor, raceColumn, oldCorrectedScore, newCorrectedScore);
}
/**
* These redefinitions are required for scoping reasons, to make the method visible also to other classes in this package.
*/
@Override
protected void notifyListenersAboutIncrementalScoreChange(Competitor competitor, RaceColumn raceColumn,
Double oldScoreOffsetInPoints, Double newScoreOffsetInPoints) {
super.notifyListenersAboutIncrementalScoreChange(competitor, raceColumn, oldScoreOffsetInPoints,
newScoreOffsetInPoints);
}
/**
* These redefinitions are required for scoping reasons, to make the method visible also to other classes in this package.
*/
@@ -587,6 +587,7 @@ public class MarkPassingCalculator {
// creation matches that of this mark passing calculator's race; load instead of compute
updateMarkPassingsFromRegistry();
queue.clear();
stop(); // ensures an end marker is written to queue to the queue.take() call in Listen.run() will always get unblocked after the queue.clear() above
suspended = false;
} else {
suspended = false;
@@ -15,6 +15,18 @@
<li>Bug fix: tracked races connected to more than one leaderboard column at the same time
will now send their competitor and race status updates to all those column's race logs.
This in particular fixes the special iQFOil set-up with their marathon races.</li>
<li>Added speed in full knots (rounded) as a dimension to the GPS fixes in Data Mining.
This can be used, e.g., to filter for outliers such as capsized or towed boats.</li>
<li>The invalid result markers (IRMs) <tt>SCP</tt>, <tt>STP</tt>, <tt>DPI</tt>, and <tt>RDG</tt> can now consider
optional incremental score corrections which are added to the points determined based on the competitor's rank
in the race and the scoring scheme that applied to the race. For example, a <tt>DPI</tt> penalty with <tt>+2.5</tt>
points may now be specified which applied during tracking the race. Absolute score corrections will be considered
for these IRMs at the end of the race, regardless the incremental score correction. Note that the increments
are subject to any column factors being applied; this may contradict an event's rules that may state that certain
penalties, such as <tt>STP</tt> are <em>not</em> subject to doubling for a medal race. In such cases, specify half
the penalty when editing the increment.</li>
<li>
Bug fix: It is now possible to subscribe to a plan and set a VAT number if previously subscribed to another plan.</li>
</ul>
<h5 class="articleSubheadline">June 2023</h5>
<ul class="bulletList">
@@ -345,9 +345,12 @@ public interface SailingServiceWrite extends FileStorageManagementGwtService, Sa
void updateLeaderboardScoreCorrectionMetadata(String leaderboardName, Date timePointOfLastCorrectionValidity,
String comment);
com.sap.sse.common.Util.Triple<Double, Double, Boolean> updateLeaderboardScoreCorrection(String leaderboardName,
Triple<Double, Double, Boolean> updateLeaderboardScoreCorrection(String leaderboardName,
String competitorIdAsString, String columnName, Double correctedScore, Date date) throws NoWindException;
Triple<Double, Double, Boolean> updateLeaderboardIncrementalScoreCorrection(
String leaderboardName, String competitorIdAsString, String columnName, Double scoringOffsetInPoints, Date date);
void updateLeaderboardCarryValue(String leaderboardName, String competitorIdAsString, Double carriedPoints);
void disconnectLeaderboardColumnFromTrackedRace(String leaderboardName, String raceColumnName, String fleetName)
@@ -383,13 +383,35 @@ public interface SailingServiceWriteAsync extends FileStorageManagementGwtServic
void updateLeaderboardCarryValue(String leaderboardName, String competitorIdAsString, Double carriedPoints,
AsyncCallback<Void> callback);
/**
* @param asyncCallback
* The result is a {@link Triple} with the new total points in {@link Triple#getA() a}, the new net
* points in {@link Triple#getB() b}, and whether or not the result is obtained from the correction
* ("isCorrected") as {@link Triple#getC() c}.
*/
void updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString, String raceColumnName,
MaxPointsReason maxPointsReason, Date date,
AsyncCallback<Util.Triple<Double, Double, Boolean>> asyncCallback);
/**
* @param asyncCallback
* The result is a {@link Triple} with the new total points in {@link Triple#getA() a}, the new net
* points in {@link Triple#getB() b}, and whether or not the result is obtained from the correction
* ("isCorrected") as {@link Triple#getC() c}.
*/
void updateLeaderboardScoreCorrection(String leaderboardName, String competitorIdAsString, String columnName,
Double correctedScore, Date date, AsyncCallback<Util.Triple<Double, Double, Boolean>> asyncCallback);
/**
* @param asyncCallback
* The result is a {@link Triple} with the new total points in {@link Triple#getA() a}, the new net
* points in {@link Triple#getB() b}, and whether or not the result is obtained from the correction
* ("isCorrected") as {@link Triple#getC() c}.
*/
void updateLeaderboardIncrementalScoreCorrection(String leaderboardName, String competitorIdAsString,
String columnName, Double scoringOffsetInPoints, Date date,
AsyncCallback<Triple<Double, Double, Boolean>> callback);
void updateLeaderboardScoreCorrectionMetadata(String leaderboardName, Date timePointOfLastCorrectionValidity,
String comment, AsyncCallback<Void> callback);
@@ -2436,4 +2436,5 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages,
String errorSettingUserPreference(String preferenceKey, String message);
String scoringSchemeLowPointWithEliminatingMedalSeriesPromotingOneToFinalAndTwoToSemifinal();
String scoringSchemeLowPointWithEliminatingMedalSeriesPromotingOneToFinalAndTwoToSemifinalDescription();
String incrementalScoreCorrectionInPoints();
}
@@ -2473,3 +2473,4 @@ errorFetchingUserPreference=Error fetching user preference with key "{0}": {1}
errorSettingUserPreference=Error setting user preference with key "{0}": {1}
scoringSchemeLowPointWithEliminatingMedalSeriesPromotingOneToFinalAndTwoToSemifinal=Low point system; Medal races as quarter final, semi final and grand final
scoringSchemeLowPointWithEliminatingMedalSeriesPromotingOneToFinalAndTwoToSemifinalDescription=Low point system; the best-ranked competitor of the opening series advances directly to the grand final; the second and third ranking competitors are promoted directly to the semi final.
incrementalScoreCorrectionInPoints=Incremental score correction (points)
@@ -475,7 +475,7 @@ scoringSchemeLowPointForLeagueOverallLeaderboard=Nízkobodový systém pro celko
scoringSchemeLowPointForLeagueOverallLeaderboardDescription=Namísto obvyklého způsobu, kdy rozhodují výsledky z určitého počtu odjetých rozjížděk, který se používá při rovnosti u nízkobodových hodnocení, se pořadí závodníků se stejným součtem bodů určuje podle součtu bodů získaných ve všech rozjížďkách. Pokud rovnost trvá, rozhoduje poslední rozjížďka.
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnly=Nízkobodový, při rovnosti rozhoduje poslední nefinálový závod
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnlyDescription=Namísto obvyklého způsobu, kdy rozhodují výsledky z určitého počtu odjetých rozjížděk, který se používá při rovnosti u nízkobodových hodnocení, se pořadí závodníků se stejným součtem bodů určuje podle posledního nefinálového závodu, aniž by se vylučovaly některé rozjížďky.
scoringSchemeLowPointWithAutomaticRdg=Nízkobodový, výchozí bodové hodnocení pro RDG na základě průměru všech bodových hodnocení bez RDG
scoringSchemeLowPointWithAutomaticRdg=Nízkobodový systém, výchozí bodové hodnocení pro RDG/SCA na základě průměru všech bodových hodnocení bez RDG/SCA
scoringSchemeHighPointFirstGetsOne=Vysokobodový systém, vítěz získává 1 bod, poražený 0 bodů
scoringSchemeHighPointFirstGetsOneDescription=Vysokobodový, vítěz získává bod, poražený 0 bodů; při rovnosti rozhoduje přímé porovnání s přímým porovnáním při rozhodování jiné rovnosti; pokud se přímé porovnání zacyklí, závodníci jsou hodnoceni na stejném místě; pořadí závodníků, kteří proti sobě (ještě) nestartovali, se určuje podle jejich polohy v grafu vítězství/porážky.
scoringSchemeHighPointFirstGetsTen=Vysokobodový systém, vítěz získává 10 bodů
@@ -2458,6 +2458,8 @@ scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Vysokobodový sy
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Vítěz závodu získává 1 bod, všichni ostatní 0; při shodě rozhoduje poslední rozjížďka, potom údaje jiné výsledkové tabule.
helptextLinkingRaces=Chcete-li propojit rozjížďky s trasovanými rozjížďkami, musíte kliknout levým tlačítkem na rozjížďku v tabulce níže a poté klikněte levým tlačítkem na odpovídající záznam v tabulce trasovaných rozjížděk vpravo.
scoringSchemeLowPointA82Only=Nízkobodový systém; shoda podle závodních pravidel jachtingu A8.2 (poslední rozjížďka)
scoringSchemeLowPointA82OnlyDescription=Nízkobodový systém; shoda podle závodních pravidel jachtingu A8.2; Pokud shoda přetrvá po kontrole účasti a skóre ve finálové rozjížďce, porovnejte skóre v poslední rozjížďce (včetně vyloučených skóre), potom v předposlední atd., dokud shoda nebude rozhodnuta.=scoringSchemeLowPointSystemFirstThreeWinsA82Only
scoringSchemeLowPointA82OnlyDescription=Nízkobodový systém; shoda podle závodních pravidel jachtingu A8.2; Pokud shoda přetrvá po kontrole účasti a skóre ve finálové rozjížďce, porovnejte skóre v poslední rozjížďce (včetně vyloučených skóre), potom v předposlední atd., dokud shoda nebude rozhodnuta.
scoringSchemeLowPointSystemFirstThreeWinsA82Only=Nízkobodový systém; první se třemi vítězstvími ve finálovém závodu je vítěz; shoda A8.2 (poslední rozjížďka)
scoringSchemeLowPointSystemFirstThreeWinsA82OnlyDescription=Nízkobodový systém. První ve finálovém závodu, který vyhraje tři rozjížďky, vyhrává finálový závod. Sloupec přenosu ve finálovém závodu lze použít k modelování přenášených vítězství. Shoda v úvodních závodech je založena na A8.2 (poslední rozjížďka, pak předposlední atd.).
errorFetchingUserPreference=Chyba při načítání uživatelských preferencí s klíčem „{0}“: {1}
errorSettingUserPreference=Chyba při načítání uživatelských preferencí s klíčem „{0}“: {1}
@@ -475,7 +475,7 @@ scoringSchemeLowPointForLeagueOverallLeaderboard=Lavpointsystem for samlet rangl
scoringSchemeLowPointForLeagueOverallLeaderboardDescription=I stedet for det normale nedtællingssystem, der bruges til at afgøre ved pointlighed i lavpointskemaer, sammenlignes deltagere med ens pointsum ved at se på de point, de har opnået på tværs af alle løb. Hvis der stadig er pointlighed, afgøres denne af sidste løb.
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnly=Lavpointsystem. Ved pointlighed afgøres sejladsen kun baseret på sidste serie uden medaljer
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnlyDescription=I stedet for det normale nedtællingssystem, der bruges til at afgøre ved pointlighed i lavpointskemaer, tages der hensyn til antallet af point i sidste serie uden medaljer, hvor ingen kapsejladser er udelukket, hvis to deltagere har samme antal point.
scoringSchemeLowPointWithAutomaticRdg=Lavpointsystem. RDG får standardpoint baseret på gennemsnittet af alle ikke-RDG-point
scoringSchemeLowPointWithAutomaticRdg=Lavpointsystem. RDG/SCA får standardpoint baseret på gennemsnittet af alle ikke-RDG-/SCA-point
scoringSchemeHighPointFirstGetsOne=Højpointsystem. Vinderen får 1 point, taberen får 0
scoringSchemeHighPointFirstGetsOneDescription=Højpointsystem. Vinderen får 1 point, taberen får 0. Ved pointlighed afgøres kapsejladsen baseret på direkte sammenligning, hvor sidste direkte sammenligning afgør pointligheden. Hvis cyklusser sker i direkte sammenligninger, behandles deltagere ens. Deltagere, der (endnu) ikke har sejlet mod hinanden, rangordnes baseret på deres placering i grafen over vundne/tabte.
scoringSchemeHighPointFirstGetsTen=Højpointsystem, vinderen får 10 point
@@ -2458,6 +2458,8 @@ scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Højpointsystem,
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Vinderen af en kapsejlads får 1 point, alle andre 0 point; uafgjort kapsejladser afgøres ved sidste løb og derefter på grundlag af en anden rangliste
helptextLinkingRaces=For at knytte kapsejladser til sporede kapsejladser skal du venstreklikke på en kapsejlads i tabellen nedenfor og derefter venstreklikke på den tilhørende entry i tabellen for sporede kapsejladser i højre side.
scoringSchemeLowPointA82Only=Lavpointsystem; tie-break iht. kapsejladsreglerne A8.2 (sidste kapsejlads)
scoringSchemeLowPointA82OnlyDescription=Lavpointsystem; tie-break iht. kapsejladsreglerne A8.2; hvis der stadig er pointlighed efter at have kigget på medaljesejladsdeltagelsen og pointene, skal du sammenligne pointene i den sidste kapsejlads (herunder udelukkede point); derefter den næstsidste kapsejlads osv., indtil pointligheden er afgjort.=scoringSchemeLowPointSystemFirstThreeWinsA82Only
scoringSchemeLowPointA82OnlyDescription=Lavpointsystem; tie-break iht. kapsejladsreglerne A8.2; hvis der stadig er pointlighed efter at have kigget på medaljesejladsdeltagelsen og pointene, skal du sammenligne pointene i den sidste kapsejlads (herunder udelukkede point); derefter den næstsidste kapsejlads osv., indtil pointligheden er afgjort.
scoringSchemeLowPointSystemFirstThreeWinsA82Only=Lavpointsystem, første med tre sejre i medaljekapsejladser er vinderen; A8.2 tie-break (sidste kapsejlads)
scoringSchemeLowPointSystemFirstThreeWinsA82OnlyDescription=Lavpointsystem. Den første i medaljeserien, der vinder tre kapsejladser, vinder medaljeserien. En kolonne til fremførsel i medaljeserien kan bruges til at modellere overførte sejre. Tie-break i åbningsserien er baseret på A8.2 (sidste kapsejlads, derefter næstsidste osv.).
errorFetchingUserPreference=Fejl ved hentning af brugerpræference med nøgle "{0}": {1}
errorSettingUserPreference=Fejl ved indstilling af brugerpræference med nøgle "{0}": {1}
@@ -2467,3 +2467,4 @@ errorFetchingUserPreference=Fehler beim Laden der Benutzereinstellung "{0}": {1}
errorSettingUserPreference=Fehler beim Speicher der Benutzereinstellung "{0}": {1}
scoringSchemeLowPointWithEliminatingMedalSeriesPromotingOneToFinalAndTwoToSemifinal=Low Point System; Medaillen-Rennen als Viertel-, Halb- und Großes Finale
scoringSchemeLowPointWithEliminatingMedalSeriesPromotingOneToFinalAndTwoToSemifinalDescription=Low Point System; der beste Teilnehmer der Eröffnungs-Serie ist direkt für das Große Finale qualifiziert; der zweit- und drittplazierte Teilnehmer der Eröffnungsserie ist direkt für das Halbfinale qualifiziert.
incrementalScoreCorrectionInPoints=Inkrementelle Punktestrafe
@@ -475,7 +475,7 @@ scoringSchemeLowPointForLeagueOverallLeaderboard=Puntuación baja para la tabla
scoringSchemeLowPointForLeagueOverallLeaderboardDescription=En lugar del sistema habitual de recuento hacia atrás que se utiliza para los esquemas de puntuación baja para romper empates, para clasificar los competidores que tienen los mismos totales de puntos se compara el total de los puntos que han obtenido en todas las pruebas. Si aún persiste el empate, el empate se resuelve con la última prueba.
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnly=Puntuación baja, los empates se resuelven por la última serie sin medalla
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnlyDescription=En lugar del sistema habitual de recuento para los esquemas de puntuación baja para romper empates, se tiene en cuenta la puntuación de la serie sin medalla sin regatas excluidas si dos competidores tienen los mismos puntos.
scoringSchemeLowPointWithAutomaticRdg=Sistema de puntuación baja, RDG obtiene una puntuación por defecto basada en la media de todas las puntuaciones que no sean de RDG
scoringSchemeLowPointWithAutomaticRdg=Sistema de puntuación baja, RDG/SCA obtiene una puntuación por defecto basada en la media de todas las puntuaciones que no sean de RDG/SGA
scoringSchemeHighPointFirstGetsOne=Puntuación alta, el ganador obtiene 1 punto; el perdedor, 0
scoringSchemeHighPointFirstGetsOneDescription=Puntuación alta, el ganador obtiene 1 punto; el perdedor, 0; los empates se han resuelto basándose en la comparación directa con la última comparación directa resolviendo otro empate; si se producen ciclos en la comparación directa, los competidores se han tratado por igual; los competidores que no hayan competido entre sí (aún) se clasificarán basándose en su posición en el gráfico de victorias/derrotas.
scoringSchemeHighPointFirstGetsTen=Puntuación alta, el ganador obtiene 10 puntos
@@ -2458,6 +2458,8 @@ scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Sistema de puntu
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=El ganador de una prueba obtiene 1 punto, todos los demás 0; se desempata en la última prueba, y luego se basan en otra tabla de clasificación
helptextLinkingRaces=Con el fin de enlazar las pruebas con las pruebas rastreadas, debe hacer clic con el botón izquierdo del ratón en una prueba de la tabla siguiente y, a continuación, hacer clic con el botón izquierdo del ratón en la entrada correspondiente de la tabla de pruebas rastreadas de la derecha.
scoringSchemeLowPointA82Only=Sistema de puntuación baja; desempate según RRS A8.2 (última prueba)
scoringSchemeLowPointA82OnlyDescription=Sistema de puntuación baja; desempate según RRS A8.2; Si el empate se mantiene tras la participación en la prueba de medalla y las puntuaciones, compare las puntuaciones de la última prueba (incluyendo puntuaciones excluidas), luego la penúltima prueba, etc. Hasta que el empate se deshaga.scoringSchemeLowPointSystemFirstThreeWinsA82Only
scoringSchemeLowPointA82OnlyDescription=Sistema de puntuación baja; desempate según RRS A8.2; Si el empate se mantiene tras la participación en la prueba de medalla y las puntuaciones, compare las puntuaciones de la última prueba (incluyendo puntuaciones excluidas), luego la penúltima prueba, etc. Hasta que el empate se deshaga.
scoringSchemeLowPointSystemFirstThreeWinsA82Only=Sistema de puntuación baja, el primero con tres victorias en medallas es el ganador; desempate A8.2 (última prueba)
scoringSchemeLowPointSystemFirstThreeWinsA82OnlyDescription=Sistema de puntuación baja. El primero de la serie de medallas en ganar tres pruebas gana la serie de medallas. Se puede utilizar una columna de arrastre en la serie de medallas para modelar las victorias arrastradas. El desempate en la serie inicial se basa en A8.2 (última prueba, luego la penúltima, etc.).
errorFetchingUserPreference=Error al obtener la preferencia de usuario con la clave "{0}": {1}
errorSettingUserPreference=Error al definir la preferencia de usuario con la clave "{0}": {1}
@@ -475,7 +475,7 @@ scoringSchemeLowPointForLeagueOverallLeaderboard=Système de points à minima po
scoringSchemeLowPointForLeagueOverallLeaderboardDescription=À la place du système habituel de comptage pour schémas à minima en cas d''égalité, les concurrents dont le total des points est égal sont départagés en comparant le total des points qu''ils ont obtenus dans tous les Act. Si l''égalité persiste, la victoire est accordée en fonction du classement dans le dernier Act.
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnly=Système de points a minima, en cas d''égalité, seule la dernière série non médaillée compte
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnlyDescription=À la place du système habituel de comptage pour schémas à minima en cas d''égalité, le score de la dernière série non médaillée sans exclusion de course est pris en compte si deux concurrents sont à égalité.
scoringSchemeLowPointWithAutomaticRdg=Système de points a minima, reclassement à une manche avec score par défaut basé sur la moyenne de tous les scores non reclassés.
scoringSchemeLowPointWithAutomaticRdg=Système de points a minima, reclassement à une manche/SCA avec score par défaut basé sur la moyenne de tous les scores non reclassés/SCA.
scoringSchemeHighPointFirstGetsOne=Système de points avec bonus, le vainqueur obtient 1 point, le perdant 0
scoringSchemeHighPointFirstGetsOneDescription=Système de points avec bonus, le vainqueur obtient 1 point, le perdant 0. En cas d''égalité, l''égalité est départagée par comparaison directe avec la dernière comparaison directe où des concurrents à égalité ont été départagés. Si des cycles avec comparaison directe existent, les concurrents sont traités à égalités ; les concurrents qui ne se sont pas (encore) affrontés sont classés en fonction de leur position dans le classement des courses gagnées/perdues.
scoringSchemeHighPointFirstGetsTen=Système de points avec bonus, le vainqueur obtient 10 points
@@ -2458,6 +2458,8 @@ scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Système de poin
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Le vainqueur d''une course obtient 1 point, tous les autres participants 0 ; en cas d''égalité, l''égalité est départagée en fonction du résultat de la dernière course, puis en fonction d''un autre palmarès.
helptextLinkingRaces=Pour relier des courses à des courses suivies, vous devez sélectionner une course (clic gauche) dans la table ci-dessous puis sélectionner l''entrée correspondante (clic gauche) dans la table des courses suivies sur la droite.
scoringSchemeLowPointA82Only=Système de points a minima ; égalité départagée selon RRS A8.2 (dernière course)
scoringSchemeLowPointA82OnlyDescription=Système de points a minima ; égalité départagée selon RRS A8.2 ; Si l''égalité subsiste après avoir pris en compte la participation et les scores obtenus à la course médaillée, comparez les scores de la dernière course (y compris les scores exclus), puis de l''avant-dernière course, etc., jusqu''à pouvoir départager l''égalité.=scoringSchemeLowPointSystemFirstThreeWinsA82Only
scoringSchemeLowPointA82OnlyDescription=Système de points a minima ; égalité départagée selon RRS A8.2 ; Si l''égalité subsiste après avoir pris en compte la participation et les scores obtenus à la course médaillée, comparez les scores de la dernière course (y compris les scores exclus), puis de l''avant-dernière course, etc., jusqu''à pouvoir départager l''égalité.
scoringSchemeLowPointSystemFirstThreeWinsA82Only=Système de points a minima ; le premier ayant gagné trois médailles gagne la compétition ; égalité départagé selon A8.2 (dernière course)
scoringSchemeLowPointSystemFirstThreeWinsA82OnlyDescription=Système de points a minima. Le premier ayant gagné trois courses gagne la série médaillée. Une colonne de report dans la série médaillée peut être utilisée pour modéliser un report de victoires. Égalité dans la première série départagée selon A8.2 (dernière course, puis avant-dernière, etc.).
errorFetchingUserPreference=Erreur lors de l''accès à la préférence utilisateur associée à la clé "{0}" : {1}
errorSettingUserPreference=Erreur lors de la définition de la préférence utilisateur associée à la clé "{0}" : {1}
@@ -475,7 +475,7 @@ scoringSchemeLowPointForLeagueOverallLeaderboard=Punteggio minimo per classifica
scoringSchemeLowPointForLeagueOverallLeaderboardDescription=Invece dell''usuale sistema di count-back utilizzato per il punteggio minimo per risolvere le parità, i concorrenti con uguali punti totali vengono confrontati in base al totale di punti accumulati in tutte le prove. Se il pareggio ancora permane, viene risolto in base all''ultima prova.
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnly=Punteggio minimo, parità risolta solo in base all''ultima non-medal series
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnlyDescription=Invece dell''usuale sistema di count-back degli schemi di punteggio minimo per risolvere i pareggi, il punteggio dell''ultima non-medal series senza esclusione di prove viene considerato se i concorrenti hanno pari punti.
scoringSchemeLowPointWithAutomaticRdg=Sistema di punteggio minimo, RDG ottiene un punteggio predefinito in base alla media di tutti i punteggi non RDG
scoringSchemeLowPointWithAutomaticRdg=Sistema di punteggio minimo, RDG/SCA ottiene un punteggio predefinito in base alla media di tutti i punteggi non RDG/SCA
scoringSchemeHighPointFirstGetsOne=Punteggio massimo, il vincitore ottiene 1 punto, il perdente 0
scoringSchemeHighPointFirstGetsOneDescription=Punteggio massimo, il vincitore ottiene 1 punto, il perdente 0; i pareggi vengono risolti in base al confronto diretto con l''ultimo confronto diretto che ha risolto un altro pareggio; in caso di catene nei confronti diretti, i concorrenti vengono trattati alla pari; i concorrenti che non hanno (ancora) gareggiato fra loro vengono classificati in base alla loro posizione nel grafico vittorie/sconfitte.
scoringSchemeHighPointFirstGetsTen=Punteggio massimo, il vincitore ottiene 10 punti
@@ -2458,6 +2458,8 @@ scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Sistema di punte
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Il vincitore della gara ottiene 1 punto, tutti gli altri 0; i pareggi vengono risolti nell''ultima gara, quindi in base a un''altra classifica
helptextLinkingRaces=Per collegare le gare a quelle tracciate, è necessario fare clic con il pulsante sinistro del mouse su una gara nella tabella sottostante e, successivamente, fare clic con il pulsante sinistro del mouse sulla voce corrispondente nella tabella delle gare tracciate a destra.
scoringSchemeLowPointA82Only=Sistema di punteggio minimo. Spareggio basato su RRS A8.2 (ultima gara)
scoringSchemeLowPointA82OnlyDescription=Sistema di punteggio minimo. Spareggio basato su RRS A8.2; se dopo l''esame della partecipazione e dei punteggi della Medal Race permane un pareggio, confrontare i punteggi dell''ultima gara (compresi i punteggi esclusi), quindi i punteggi della penultima gara, e così via, fino a che non si risolve il pareggio.=scoringSchemeLowPointSystemFirstThreeWinsA82Only
scoringSchemeLowPointA82OnlyDescription=Sistema di punteggio minimo. Spareggio basato su RRS A8.2; se dopo l''esame della partecipazione e dei punteggi della Medal Race permane un pareggio, confrontare i punteggi dell''ultima gara (compresi i punteggi esclusi), quindi i punteggi della penultima gara, e così via, fino a che non si risolve il pareggio.
scoringSchemeLowPointSystemFirstThreeWinsA82Only=Sistema di punteggio minimo; il primo a conseguire tre vittorie da medaglia è il vincitore; spareggio A8.2 (ultima gara)
scoringSchemeLowPointSystemFirstThreeWinsA82OnlyDescription=Sistema di punteggio minimo. Il primo nella Medal Series a conseguire tre vittorie vince la Medal Series. Una colonna di riporto nella Medal Series può essere utilizzata per modellare le vittorie riportate. Lo spareggio nella serie iniziale si basa su A8.2 (ultima gara, quindi penultima, e così via).
errorFetchingUserPreference=Errore nel recupero della preferenza utente con chiave "{0}": {1}
errorSettingUserPreference=Errore nell''impostazione della preferenza utente con chiave "{0}": {1}
@@ -475,7 +475,7 @@ scoringSchemeLowPointForLeagueOverallLeaderboard=全体リーダーボードに
scoringSchemeLowPointForLeagueOverallLeaderboardDescription=順位決定のための低得点方式に使用される通常のカウントダウン方式ではなく、総得点が同点の競技者が全アクト共通で得点した総得点で比較されます。これでも同順位となる場合は、最終アクトによって順位を決定します。
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnly=低得点方式、最後の非メダルシリーズのみに基づいて順位を決定
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnlyDescription=順序を決定するための低得点方式の通常のカウントダウン方式ではなく、2 艇の競技者の得点が同一の場合に、除外するレースなしに最後の非メダルシリーズの得点を考慮します。
scoringSchemeLowPointWithAutomaticRdg=低得点方式、RDG (救済を受けた艇) はすべての非 RDG (Redress give) スコアの平均に基づくデフォルトスコアを獲得
scoringSchemeLowPointWithAutomaticRdg=低得点方式、RDG/SCA はすべての非 RDG/SCA スコアの平均に基づくデフォルトスコアを獲得
scoringSchemeHighPointFirstGetsOne=高得点方式、勝者が 1 点、敗者が 0 点を獲得
scoringSchemeHighPointFirstGetsOneDescription=高得点方式、勝者が 1 点、敗者が 0 点を獲得します。順位の決定は、同順位が崩れた最終の直接比較に基づいて行われます。直接比較が繰り返されている場合、競技者は対等に扱われます。(まだ) 直接対戦していない競技者は勝敗グラフにおける位置に基づいて並べられます。
scoringSchemeHighPointFirstGetsTen=高得点方式、1 位が 10 点
@@ -2458,6 +2458,8 @@ scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=高得点方式
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=レースの勝者が 1 点を獲得し、その他はすべて 0 点。同順位はまず最終レース、次に別リーダーボードに基づいてタイブレーク
helptextLinkingRaces=レースを追跡レースにリンクするためには、下の表でレースを左クリックしてから、右側の追跡レース表で該当するエントリを左クリックする必要があります。
scoringSchemeLowPointA82Only=低得点方式、RRS A8.2 によるタイブレーク (最終レース)
scoringSchemeLowPointA82OnlyDescription=低得点方式、RRS A8.2 によるタイブレーク。メダルレースに参加しての得点を見ても同順位のままである場合は、最終レースの得点 (除外された得点を含む) を比較し、それでも同順位ならば最後から 2 番目のレースを比較するといったように、均衡が破れるまでこれを続けます。=scoringSchemeLowPointSystemFirstThreeWinsA82Only
scoringSchemeLowPointA82OnlyDescription=低得点方式、RRS A8.2 によるタイブレーク。メダルレースに参加しての得点を見ても同順位のままである場合は、最終レースの得点 (除外された得点を含む) を比較し、それでも同順位ならば最後から 2 番目のレースを比較するといったように、均衡が破れるまでこれを続けます。
scoringSchemeLowPointSystemFirstThreeWinsA82Only=低得点方式、メダルシリーズで最初に 3 勝した者が勝者、A8.2 タイブレーク (最終レース)
scoringSchemeLowPointSystemFirstThreeWinsA82OnlyDescription=低得点方式。メダルシリーズで最初に 3 レースに勝利した者をメダルシリーズの勝者とします。持ち越し列をメダルシリーズに使用して、持ち越される勝利のモデル化を行うことができます。オープニングシリーズでのタイブレークは A8.2 に基づきます (最終レース、次に最後から 2 番目のレース、など)。
errorFetchingUserPreference=キー "{0}" でのユーザプリファレンスのフェッチ中にエラーが発生: {1}
errorSettingUserPreference=キー "{0}" でのユーザプリファレンスの設定中にエラーが発生: {1}
@@ -475,7 +475,7 @@ scoringSchemeLowPointForLeagueOverallLeaderboard=Sistema linear para painel de c
scoringSchemeLowPointForLeagueOverallLeaderboardDescription=Em vez do habitual sistema de contagem regressiva utilizado para esquemas lineares para efetuar os desempates, os competidores com somas de pontos iguais são comparados comparando a soma dos pontos obtidos em todas as etapas. Se o empate continuar, o desempate é efetuado pela última etapa.
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnly=Sistema linear, desempates só com base na última série sem medalhas
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnlyDescription=Em vez do habitual sistema de contagem regressiva para esquemas lineares para efetuar os desempates, a pontuação da série final sem medalhas sem corridas excluídas é considerada se dois competidores tiverem pontuações iguais.
scoringSchemeLowPointWithAutomaticRdg=Sistema linear, a RDG recebe a pontuação padrão com base na média de todas as pontuações não RDG
scoringSchemeLowPointWithAutomaticRdg=Sistema linear, a RDG/SCA recebe a pontuação padrão com base na média de todas as pontuações não RDG/SCA
scoringSchemeHighPointFirstGetsOne=Sistema de bônus, o vencedor recebe 1 ponto, o perdedor 0
scoringSchemeHighPointFirstGetsOneDescription=Sistema de bônus, o vencedor recebe 1 ponto, o perdedor 0; os desempates são efetuados com base na comparação direta com a última comparação direta de outro desempate; se ocorrerem ciclos nas comparações diretas, os competidores são tratados da mesma forma; os competidores que (ainda) não competiram uns com os outros são ordenados com base na sua posição no diagrama de vitórias/derrotas.
scoringSchemeHighPointFirstGetsTen=Sistema de bônus, o vencedor recebe 10 pontos
@@ -2458,6 +2458,8 @@ scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Sistema de bônu
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=O vencedor de uma corrida obtém 1 ponto, todos os outros 0; os desempates são efetuados com base na última corrida, depois com base noutro painel de classificação
helptextLinkingRaces=Para vincular corridas a corridas rastreadas, deve clicar com o botão esquerdo em uma corrida na tabela embaixo e depois disso clicar com o botão esquerdo na entrada correspondente na tabela de corridas rastreadas à direita.
scoringSchemeLowPointA82Only=Sistema linear; tie-break de acordo com RRS A8.2 (última corrida)
scoringSchemeLowPointA82OnlyDescription=Sistema linear; tie-break de acordo com RRS A8.2; se continuar existindo um empate depois de consultar a participação e as pontuações da corrida para medalha, compare as pontuações na última corrida (incluindo pontuações excluídas), depois a penúltima corrida, etc., até chegar ao desempate.=scoringSchemeLowPointSystemFirstThreeWinsA82Only
scoringSchemeLowPointA82OnlyDescription=Sistema linear; tie-break de acordo com RRS A8.2; se continuar existindo um empate depois de consultar a participação e as pontuações da corrida para medalha, compare as pontuações na última corrida (incluindo pontuações excluídas), depois a penúltima corrida, etc., até chegar ao desempate.
scoringSchemeLowPointSystemFirstThreeWinsA82Only=Sistema linear, o primeiro com três vitórias em medalhas é o vencedor; A8.2 tie-break (última corrida)
scoringSchemeLowPointSystemFirstThreeWinsA82OnlyDescription=Sistema linear. O primeiro na série para medalha a vencer três corridas vence a série para medalha. É possível utilizar uma coluna de transferência na série para medalha para modelar vitórias transferidas. Um tie-break na série de abertura é baseado no A8.2 (última corrida, depois a penúltima, etc.).
errorFetchingUserPreference=Erro ao chamar preferência do usuário com a chave "{0}": {1}
errorSettingUserPreference=Erro ao definir preferência do usuário com a chave "{0}": {1}
@@ -475,7 +475,7 @@ scoringSchemeLowPointForLeagueOverallLeaderboard=Низкий балл по вс
scoringSchemeLowPointForLeagueOverallLeaderboardDescription=Вместо обычной системы обратного отсчета, используемой для разрешения равенства в схемах низких баллов, участники с равными суммами баллов сравниваются по сумме баллов, полученных за все акты. Если равенство сохраняется, оно разрешается по последнему акту.
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnly=Низкий балл, равенство разрешается только по последней не медальной серии
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnlyDescription=Вместо обычной системы обратного отсчета, используемой для разрешения равенства в системах низких баллов, при равенстве оценок двух участников учитывается оценка последней не медальной серии без исключенных гонок.
scoringSchemeLowPointWithAutomaticRdg=Система низких баллов, RDG получает оценку по умолчанию на основе среднего всех оценок без RDG
scoringSchemeLowPointWithAutomaticRdg=Система низких баллов, RDG/SCA получает оценку по умолчанию на основе среднего всех оценок без RDG/SCA
scoringSchemeHighPointFirstGetsOne=Высокий балл, победитель получает 1 балл, проигравший получает 0 баллов
scoringSchemeHighPointFirstGetsOneDescription=Высокий балл, победитель получает 1 балл, проигравший получает 0 баллов; равенство разрешается путем прямого сравнения с последним прямым сравнением при разрешении другого равенства; если в прямом сравнении обнаружен цикл, участники считаются равными; участники, (еще) не соревновавшиеся друг против друга, располагаются согласно позициям в графе побед/поражений.
scoringSchemeHighPointFirstGetsTen=Высокий балл, победитель получает 10 баллов
@@ -2458,6 +2458,8 @@ scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Система
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Победитель гонки получает 1 балл, остальные 0; при равенстве баллов победитель определяется в последней гонке, а затем на основе другой таблицы лидеров
helptextLinkingRaces=Чтобы соединить гонки с отслеживаемыми гонками, щелкните левой клавишей мыши гонку в таблице и после этого щелкните левой клавишей мыши соответствующую запись в таблице отслеживаемых гонок справа.
scoringSchemeLowPointA82Only=Система низких баллов; разрешение равенства по правилу парусных гонок A8.2 (последняя гонка)
scoringSchemeLowPointA82OnlyDescription=Система низких баллов; разрешение равенства по правилу парусных гонок A8.2. Если остаются равные очки у двух или более яхт, то они должны быть расположены в порядке их очков в последней гонке (включая исключенные); если все еще остаются равные очки, то преимущество должно быть отдано с использованием очков за предпоследнюю гонку и т.д. до тех пор, пока все равенства не будут разрешены.=scoringSchemeLowPointSystemFirstThreeWinsA82Only
scoringSchemeLowPointA82OnlyDescription=Система низких баллов; разрешение равенства по правилу парусных гонок A8.2. Если равенство сохраняется после учета баллов и участия в гонках на медали, то сравниваются баллы в последней гонке (включая исключенные); далее в предпоследней гонке и т.д. до тех пор, пока все равенства не будут разрешены.
scoringSchemeLowPointSystemFirstThreeWinsA82Only=Система низких баллов, первый с тремя победами в гонках на медали является победителем; разрешение равенства по правилу A8.2 (последняя гонка)
scoringSchemeLowPointSystemFirstThreeWinsA82OnlyDescription=Система низких баллов. Первый с тремя победами в гонках на медали, выигрывает серию на медали. Столбец для переноса в серии на медали можно использовать для переноса побед в гонках на медали. Разрешение равенства в открывающих сериях основано на правиле A8.2 (последняя гонка, предпоследняя гонка и т.д.).
errorFetchingUserPreference=Ошибка при вызове предпочтения пользователя с ключом "{0}": {1}
errorSettingUserPreference=Ошибка при настройке предпочтения пользователя с ключом "{0}": {1}
@@ -475,7 +475,7 @@ scoringSchemeLowPointForLeagueOverallLeaderboard=Enostavno točkovanje za skupno
scoringSchemeLowPointForLeagueOverallLeaderboardDescription=Namesto običajnega sistema štetja nazaj, ki se uporablja za odločanje o nedoločenem rezultatu pri enostavnem točkovanju, se za tekmovalce z enakim seštevkom točk primerja vsota točk, ki so jih zbrali z vsemi akti. Če je rezultat še vedno neodločen, odloči rezultat zadnjega akta.
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnly=Enostavno točkovanje, o neodločenih rezultatih odloča samo zadnja serija brez kolajn
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnlyDescription=Namesto običajnega sistema štetja nazaj, ki se uporablja za odločanje o nedoločenem rezultatu pri enostavnem točkovanju, se v primeru, da imata dva tekmovalca enak rezultat, upošteva rezultat zadnje serije brez kolajn brez izključenih plovov.
scoringSchemeLowPointWithAutomaticRdg=Enostavno točkovanje, dodeljeno nadomestilo je enako privzetemu rezultatu glede na povprečje vseh rezultatov brez dodeljenih nadomestil
scoringSchemeLowPointWithAutomaticRdg=Enostavno točkovanje, dodeljeno nadomestilo/SCA je enako privzetemu rezultatu glede na povprečje vseh rezultatov brez dodeljenih nadomestil/SCA
scoringSchemeHighPointFirstGetsOne=Napredno točkovanje, zmagovalec prejme 1, poraženec pa 0 točk
scoringSchemeHighPointFirstGetsOneDescription=Napredno točkovanje, zmagovalec prejme 1, poraženec pa 0 točk: v primeru neodločenega rezultata odloča primerjava z zadnjo neposredno primerjavo, ki je odločala o drugem neodločenem rezultatu; če se v neposrednih primerjavah pojavijo cikli, so tekmovalci izenačeni; tekmovalci, ki se (še) niso pomerili med sabo, so razvrščeni glede na njihov položaj na grafu zmag/porazov.
scoringSchemeHighPointFirstGetsTen=Napredno točkovanje, zmagovalec prejme 10 točk
@@ -2458,6 +2458,8 @@ scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Napredno točkov
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Zmagovalec plova prejme 1 točko, vsi ostali 0 točk; v primeru neodločenega rezultata odloča zadnji plov, nato pa na podlagi druge lestvice vodilnih
helptextLinkingRaces=Če želite plove povezati s sledenimi plovi, morate z levim gumbom miške klikniti plov v spodnji tabeli in nato ustrezen vnos v tabeli sledenih plovov na desni.
scoringSchemeLowPointA82Only=Enostavno točkovanje; neodločen rezultat glede na RRS A8.2 (zadnji plov)
scoringSchemeLowPointA82OnlyDescription=Enostavno točkovanje; neodločen rezultat glede na RRS A8.2; Če po pregledu udeležbe plova za kolajne in točk rezultat ostaja neodločen, se primerja točke zadnjega plova (vključno z odbitimi točkami), nato predzadnjega plova itn., dokler rezultat ni več neodločen.=scoringSchemeLowPointSystemFirstThreeWinsA82Only
scoringSchemeLowPointA82OnlyDescription=Enostavno točkovanje; neodločen rezultat v skladu z A8.2 jadralnih regatnih pravil. Če po pregledu udeležbe plova za kolajne in točk rezultat ostaja neodločen, primerjajte točke zadnjega plova (vključno z odbitimi točkami), nato predzadnjega plova itn., dokler rezultat ni več neodločen.
scoringSchemeLowPointSystemFirstThreeWinsA82Only=Enostavno točkovanje; prvi s tremi zmagami za kolajne je zmagovalec; A8.2 neodločen rezultat (zadnji plov)
scoringSchemeLowPointSystemFirstThreeWinsA82OnlyDescription=Enostavno točkovanje; prvi v seriji za kolajne, ki zmaga na treh plovih, je zmagovalec serije za kolajne. Stolpec za prenos v seriji za kolajne je mogoče uporabiti za prikaz prenesenih zmag. Neodločen rezultat v začetni seriji temelji na A8.2 (zadnji plov, nato predzadnji plov itn.).
errorFetchingUserPreference=Napaka pri priklicu nastavitev uporabnika s ključem "{0}": {1}
errorSettingUserPreference=Napaka pri nastavitvi nastavitev uporabnika s ključem "{0}": {1}
@@ -475,7 +475,7 @@ scoringSchemeLowPointForLeagueOverallLeaderboard=总积分榜的低分,分站
scoringSchemeLowPointForLeagueOverallLeaderboardDescription=与用于低分记分系统打破平局的常规倒算系统不同,对于总得分相同的参赛队,比较其在所有分站赛中的得分总和。 如果仍有平局,则以最后一个分站赛的得分打破平局。
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnly=低分,仅根据最后非奖牌轮系列赛打破平局。
scoringSchemeLowPointTieBreakBasedOnLastSeriesOnlyDescription=与用于低分记分系统打破平局的常规倒算系统不同,如果两支参赛队的得分相同,则考虑不排除比赛轮次的最后非奖牌轮系列赛的得分。
scoringSchemeLowPointWithAutomaticRdg=低分系统,RDG 根据所有非 RDG 得分的平均值获得默认得分
scoringSchemeLowPointWithAutomaticRdg=低分系统,RDG/SCA 根据所有非 RDG/SCA 得分的平均值获得默认得分
scoringSchemeHighPointFirstGetsOne=高分,获胜者得 1 分,败者 0 分
scoringSchemeHighPointFirstGetsOneDescription=高分,获胜者得 1 分,败者 0 分;根据与打破其他平局的上次直接比较进行直接比较打破平局;如果直接比较中出现循环赛,公平对待参赛队;根据输赢图中的位置将(尚未)互相比赛的参赛队排序。
scoringSchemeHighPointFirstGetsTen=高分,获胜者得 10 分
@@ -2458,6 +2458,8 @@ scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=高分系统,
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=比赛轮次的获胜者得 1 分,所有其他人得 0 分;在最后一个比赛轮次中打破平局,然后根据其他积分榜打破平局
helptextLinkingRaces=为了在比赛轮次之间建立链接,您必须左键点击下表中的比赛轮次,然后左键点击右侧跟踪比赛轮次表中的相应条目。
scoringSchemeLowPointA82Only=低分系统;基于 RRS A8.2 的决胜局(最后一个比赛轮次)
scoringSchemeLowPointA82OnlyDescription=低分系统;基于 RRS A8.2 的决胜局;如果在查看奖牌轮参与情况和得分后仍保持平局,则比较最后一个比赛轮次的得分(包括排除的得分),然后是倒数第二场比赛等,直到打破平局。=scoringSchemeLowPointSystemFirstThreeWinsA82Only
scoringSchemeLowPointA82OnlyDescription=低分系统;基于 RRS A8.2 的决胜局;如果在查看奖牌轮参与情况和得分后仍保持平局,则比较最后一个比赛轮次的得分(包括排除的得分),然后是倒数第二场比赛等,直到打破平局。
scoringSchemeLowPointSystemFirstThreeWinsA82Only=低分系统,奖牌轮中取得三场胜利的第一名为获胜者;A8.2 决胜局(最后一个比赛轮次)
scoringSchemeLowPointSystemFirstThreeWinsA82OnlyDescription=低分系统。在奖牌轮系列中,在三个比赛轮次中获胜的第一名在奖牌轮系列中获胜。奖牌轮系列中的得分列可用于为累计取得的胜利建模。开场系列赛的决胜局基于 A8.2(最后一个比赛轮次,然后是倒数第二场,依此类推)。
errorFetchingUserPreference=使用键值 "{0}" 获取用户首选项时出错:{1}
errorSettingUserPreference=使用键值 "{0}" 设置用户首选项时出错:{1}
@@ -9,17 +9,42 @@ import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sse.common.Util;
import com.sap.sailing.gwt.ui.leaderboardedit.EditScoreDialog.ScoreCorrectionUpdate;
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
import com.sap.sse.gwt.client.dialog.DoubleBox;
public class EditScoreDialog extends DataEntryDialog<Util.Pair<MaxPointsReason, Double>> {
public class EditScoreDialog extends DataEntryDialog<ScoreCorrectionUpdate> {
private final ListBox maxPointsBox;
private final DoubleBox totalPointsBox;
private final DoubleBox incrementalScoreOffsetInPointsBox;
private final StringMessages stringMessages;
public static class ScoreCorrectionUpdate {
private final Double correctedScore;
private final Double incrementalScoreCorrectionInPoints;
private final MaxPointsReason maxPointsReason;
public ScoreCorrectionUpdate(Double correctedScore, Double incrementalScoreCorrectionInPoints,
MaxPointsReason maxPointsReason) {
super();
this.correctedScore = correctedScore;
this.incrementalScoreCorrectionInPoints = incrementalScoreCorrectionInPoints;
this.maxPointsReason = maxPointsReason;
}
public Double getCorrectedScore() {
return correctedScore;
}
public Double getIncrementalScoreCorrectionInPoints() {
return incrementalScoreCorrectionInPoints;
}
public MaxPointsReason getMaxPointsReason() {
return maxPointsReason;
}
}
public EditScoreDialog(StringMessages stringMessages, String competitorName, String raceColumnName,
MaxPointsReason oldMaxPointsReason, Double oldTotalPoints, DialogCallback<Util.Pair<MaxPointsReason, Double>> callback) {
MaxPointsReason oldMaxPointsReason, Double oldTotalPoints, Double oldIncrementalScoreOffsetInPoints,
DialogCallback<ScoreCorrectionUpdate> callback) {
super(stringMessages.correctScore(), stringMessages.correctScoreFor(competitorName, raceColumnName),
stringMessages.ok(), stringMessages.cancel(), /* validator */ null, /* animationEnabled */ true,
callback);
@@ -39,10 +64,14 @@ public class EditScoreDialog extends DataEntryDialog<Util.Pair<MaxPointsReason,
if (oldTotalPoints != null) {
totalPointsBox.setValue(oldTotalPoints);
}
incrementalScoreOffsetInPointsBox = createDoubleBox(/* visibleLength */ 5);
if (oldIncrementalScoreOffsetInPoints != null) {
incrementalScoreOffsetInPointsBox.setValue(oldIncrementalScoreOffsetInPoints);
}
}
@Override
protected Util.Pair<MaxPointsReason, Double> getResult() {
protected ScoreCorrectionUpdate getResult() {
final MaxPointsReason maxPointsReason;
if ("".equals(maxPointsBox.getItemText(maxPointsBox.getSelectedIndex()))) {
maxPointsReason = null;
@@ -50,16 +79,19 @@ public class EditScoreDialog extends DataEntryDialog<Util.Pair<MaxPointsReason,
maxPointsReason = MaxPointsReason.valueOf(maxPointsBox.getItemText(maxPointsBox.getSelectedIndex()));
}
final Double totalScore = totalPointsBox.getValue();
return new Util.Pair<MaxPointsReason, Double>(maxPointsReason, totalScore);
final Double incrementalScoreCorrectionInPoints = incrementalScoreOffsetInPointsBox.getValue();
return new ScoreCorrectionUpdate(totalScore, incrementalScoreCorrectionInPoints, maxPointsReason);
}
@Override
protected Widget getAdditionalWidget() {
Grid grid = new Grid(2, 2);
Grid grid = new Grid(3, 2);
grid.setWidget(0, 0, new Label(stringMessages.penaltyOrRedress()));
grid.setWidget(0, 1, maxPointsBox);
grid.setWidget(1, 0, new Label(stringMessages.totalScore()));
grid.setWidget(1, 1, totalPointsBox);
grid.setWidget(2, 0, new Label(stringMessages.incrementalScoreCorrectionInPoints()));
grid.setWidget(2, 1, incrementalScoreOffsetInPointsBox);
return grid;
}
@@ -75,6 +75,7 @@ import com.sap.sailing.gwt.ui.leaderboard.ExpandableSortableColumn;
import com.sap.sailing.gwt.ui.leaderboard.ExplicitRaceColumnSelection;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSortableColumnWithMinMax;
import com.sap.sailing.gwt.ui.leaderboardedit.EditScoreDialog.ScoreCorrectionUpdate;
import com.sap.sse.common.InvertibleComparator;
import com.sap.sse.common.SortingOrder;
import com.sap.sse.common.Util;
@@ -481,6 +482,36 @@ public class EditableLeaderboardPanel extends LeaderboardPanel<EditableLeaderboa
}
}
private class IncrementalScoreCorrectionViewProvider
extends AbstractRowUpdateWhiteboardProducerThatHasCell<LeaderboardRowDTO, String> {
private final String raceColumnName;
protected IncrementalScoreCorrectionViewProvider(String raceColumnName) {
this.raceColumnName = raceColumnName;
}
@Override
public Cell<String> getCell() {
return new TextCell();
}
@Override
public FieldUpdater<LeaderboardRowDTO, String> getFieldUpdater() {
return null;
}
@Override
public String getValue(LeaderboardRowDTO object) {
final LeaderboardEntryDTO leaderboardEntryDTO = object.fieldsByRaceColumnName.get(raceColumnName);
String result = "";
if (leaderboardEntryDTO != null && leaderboardEntryDTO.incrementalScoreCorrectionInPoints != null) {
final char sign = Math.signum(leaderboardEntryDTO.incrementalScoreCorrectionInPoints) >= 0 ? '+' : '-';
result=" ["+sign+scoreFormat.format(leaderboardEntryDTO.incrementalScoreCorrectionInPoints)+"]";
}
return result;
}
}
private class TotalPointsEditCellProvider
extends AbstractRowUpdateWhiteboardProducerThatHasCell<LeaderboardRowDTO, String> {
private final EditTextCell totalPointsEditCell;
@@ -623,12 +654,13 @@ public class EditableLeaderboardPanel extends LeaderboardPanel<EditableLeaderboa
new EditScoreDialog(stringMessages, row.competitor.getName(), raceColumnName,
row.fieldsByRaceColumnName.get(raceColumnName).reasonForMaxPoints,
row.fieldsByRaceColumnName.get(raceColumnName).totalPoints,
new DialogCallback<Util.Pair<MaxPointsReason, Double>>() {
row.fieldsByRaceColumnName.get(raceColumnName).incrementalScoreCorrectionInPoints,
new DialogCallback<ScoreCorrectionUpdate>() {
@Override
public void ok(final Util.Pair<MaxPointsReason, Double> editedObject) {
public void ok(final ScoreCorrectionUpdate editedObject) {
addBusyTask();
getSailingService().updateLeaderboardScoreCorrection(getLeaderboardName(),
row.competitor.getIdAsString(), raceColumnName, editedObject.getB(),
row.competitor.getIdAsString(), raceColumnName, editedObject.getCorrectedScore(),
getLeaderboardDisplayDate(),
new AsyncCallback<Util.Triple<Double, Double, Boolean>>() {
@Override
@@ -641,11 +673,26 @@ public class EditableLeaderboardPanel extends LeaderboardPanel<EditableLeaderboa
}
@Override
public void onSuccess(
Util.Triple<Double, Double, Boolean> newTotalAndTotalPointsAndIsCorrected) {
public void onSuccess(Util.Triple<Double, Double, Boolean> newTotalAndNetPointsAndIsCorrected) {
getSailingService().updateLeaderboardIncrementalScoreCorrection(getLeaderboardName(),
row.competitor.getIdAsString(), raceColumnName, editedObject.getIncrementalScoreCorrectionInPoints(),
getLeaderboardDisplayDate(),
new AsyncCallback<Util.Triple<Double, Double, Boolean>>() {
@Override
public void onFailure(Throwable t) {
removeBusyTask();
getErrorReporter().reportError(stringMessages
.errorUpdatingLeaderboardScore(
row.competitor.getName(),
getLeaderboardName(),
raceColumnName, t.getMessage()));
}
@Override
public void onSuccess(Util.Triple<Double, Double, Boolean> newTotalAndNetPointsAndIsCorrected) {
getSailingService().updateLeaderboardMaxPointsReason(
getLeaderboardName(), row.competitor.getIdAsString(),
raceColumnName, editedObject.getA(),
raceColumnName, editedObject.getMaxPointsReason(),
getLeaderboardDisplayDate(),
new AsyncCallback<Util.Triple<Double, Double, Boolean>>() {
@Override
@@ -665,13 +712,15 @@ public class EditableLeaderboardPanel extends LeaderboardPanel<EditableLeaderboa
final LeaderboardEntryDTO leaderboardEntryDTO = row.fieldsByRaceColumnName
.get(raceColumnName);
leaderboardEntryDTO.reasonForMaxPoints = editedObject
.getA();
.getMaxPointsReason();
leaderboardEntryDTO.totalPoints = newTotalAndNetPointsAndIsCorrected
.getA();
leaderboardEntryDTO.netPoints = newTotalAndNetPointsAndIsCorrected
.getB();
leaderboardEntryDTO.totalPointsCorrected = newTotalAndNetPointsAndIsCorrected
.getC();
leaderboardEntryDTO.incrementalScoreCorrectionInPoints = editedObject
.getIncrementalScoreCorrectionInPoints();
maxPointsDropDownCellProvider.getCell()
.setViewData(row, null);
totalPointsEditCellProvider.getCell()
@@ -682,6 +731,8 @@ public class EditableLeaderboardPanel extends LeaderboardPanel<EditableLeaderboa
}
});
}
});
}
@Override
public void cancel() {
@@ -1216,13 +1267,15 @@ public class EditableLeaderboardPanel extends LeaderboardPanel<EditableLeaderboa
new ArrayList<RowUpdateWhiteboardProducerThatAlsoHasCell<LeaderboardRowDTO, ?>>();
final MaxPointsDropDownCellProvider maxPointsDropDownCellProvider = new MaxPointsDropDownCellProvider(
race.getRaceColumnName());
// list.add(maxPointsDropDownCellProvider);
final TotalPointsEditCellProvider totalPointsEditCellProvider = new TotalPointsEditCellProvider(
race.getRaceColumnName());
list.add(totalPointsEditCellProvider);
final ReasonForMaxPointsTextViewProvider testViewProvider = new ReasonForMaxPointsTextViewProvider(
final ReasonForMaxPointsTextViewProvider maxPointsReasonViewProvider = new ReasonForMaxPointsTextViewProvider(
race.getRaceColumnName());
list.add(testViewProvider);
list.add(maxPointsReasonViewProvider);
final IncrementalScoreCorrectionViewProvider incrementalScoreCorrectionViewProvider = new IncrementalScoreCorrectionViewProvider(
race.getRaceColumnName());
list.add(incrementalScoreCorrectionViewProvider);
final UncorrectedTotalPointsViewProvider uncorrectedViewProvider = new UncorrectedTotalPointsViewProvider(
race.getRaceColumnName());
list.add(uncorrectedViewProvider);
@@ -344,6 +344,7 @@ import com.sap.sailing.server.operationaltransformation.UpdateLeaderboard;
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardCarryValue;
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardColumnFactor;
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardGroup;
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardIncrementalScoreCorrection;
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardMaxPointsReason;
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardScoreCorrection;
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardScoreCorrectionMetadata;
@@ -1142,7 +1143,7 @@ public class SailingServiceWriteImpl extends SailingServiceImpl implements Saili
}
@Override
public com.sap.sse.common.Util.Triple<Double, Double, Boolean> updateLeaderboardMaxPointsReason(
public Triple<Double, Double, Boolean> updateLeaderboardMaxPointsReason(
String leaderboardName, String competitorIdAsString, String raceColumnName, MaxPointsReason maxPointsReason,
Date date) throws NoWindException {
SecurityUtils.getSubject().checkPermission(
@@ -1153,9 +1154,8 @@ public class SailingServiceWriteImpl extends SailingServiceImpl implements Saili
}
@Override
public com.sap.sse.common.Util.Triple<Double, Double, Boolean> updateLeaderboardScoreCorrection(
String leaderboardName, String competitorIdAsString, String columnName, Double correctedScore, Date date)
throws NoWindException {
public Triple<Double, Double, Boolean> updateLeaderboardScoreCorrection(
String leaderboardName, String competitorIdAsString, String columnName, Double correctedScore, Date date) {
SecurityUtils.getSubject().checkPermission(
SecuredDomainType.LEADERBOARD.getStringPermissionForTypeRelativeIdentifier(DefaultActions.UPDATE,
Leaderboard.getTypeRelativeObjectIdentifier(leaderboardName)));
@@ -1164,8 +1164,17 @@ public class SailingServiceWriteImpl extends SailingServiceImpl implements Saili
}
@Override
public void updateLeaderboardScoreCorrectionMetadata(String leaderboardName, Date timePointOfLastCorrectionValidity,
String comment) {
public Triple<Double, Double, Boolean> updateLeaderboardIncrementalScoreCorrection(
String leaderboardName, String competitorIdAsString, String columnName, Double scoringOffsetInPoints, Date date) {
SecurityUtils.getSubject().checkPermission(
SecuredDomainType.LEADERBOARD.getStringPermissionForTypeRelativeIdentifier(DefaultActions.UPDATE,
Leaderboard.getTypeRelativeObjectIdentifier(leaderboardName)));
return getService().apply(new UpdateLeaderboardIncrementalScoreCorrection(leaderboardName, columnName,
competitorIdAsString, scoringOffsetInPoints, new MillisecondsTimePoint(date)));
}
@Override
public void updateLeaderboardScoreCorrectionMetadata(String leaderboardName, Date timePointOfLastCorrectionValidity, String comment) {
SecurityUtils.getSubject().checkPermission(
SecuredDomainType.LEADERBOARD.getStringPermissionForTypeRelativeIdentifier(DefaultActions.UPDATE,
Leaderboard.getTypeRelativeObjectIdentifier(leaderboardName)));
@@ -2407,19 +2416,19 @@ public class SailingServiceWriteImpl extends SailingServiceImpl implements Saili
}
@Override
public void copyCourseToOtherRaceLogs(com.sap.sse.common.Util.Triple<String, String, String> fromTriple,
Set<com.sap.sse.common.Util.Triple<String, String, String>> toTriples, boolean copyMarkDeviceMappings, int priority)
public void copyCourseToOtherRaceLogs(Triple<String, String, String> fromTriple,
Set<Triple<String, String, String>> toTriples, boolean copyMarkDeviceMappings, int priority)
throws NotFoundException {
final LeaderboardThatHasRegattaLike fromLeaderboard = (LeaderboardThatHasRegattaLike) getLeaderboardByName(fromTriple.getA());
getSecurityService().checkCurrentUserReadPermission(fromLeaderboard);
LeaderboardThatHasRegattaLike toLeaderboard = null;
for (com.sap.sse.common.Util.Triple<String, String, String> toTriple : toTriples) {
for (Triple<String, String, String> toTriple : toTriples) {
toLeaderboard = (LeaderboardThatHasRegattaLike) getLeaderboardByName(toTriple.getA()); // they should all be the same
getSecurityService().checkCurrentUserUpdatePermission(toLeaderboard);
}
RaceLog fromRaceLog = getRaceLog(fromTriple);
Set<RaceLog> toRaceLogs = new HashSet<>();
for (com.sap.sse.common.Util.Triple<String, String, String> toTriple : toTriples) {
for (Triple<String, String, String> toTriple : toTriples) {
toRaceLogs.add(getRaceLog(toTriple));
}
getRaceLogTrackingAdapter().copyCourse(fromRaceLog, fromLeaderboard, toRaceLogs, toLeaderboard,
@@ -2427,15 +2436,15 @@ public class SailingServiceWriteImpl extends SailingServiceImpl implements Saili
}
@Override
public void copyCompetitorsToOtherRaceLogs(com.sap.sse.common.Util.Triple<String, String, String> fromTriple,
Set<com.sap.sse.common.Util.Triple<String, String, String>> toTriples) throws NotFoundException {
public void copyCompetitorsToOtherRaceLogs(Triple<String, String, String> fromTriple,
Set<Triple<String, String, String>> toTriples) throws NotFoundException {
getSecurityService().checkCurrentUserReadPermission(getLeaderboardByName(fromTriple.getA()));
for (com.sap.sse.common.Util.Triple<String, String, String> toTriple : toTriples) {
for (Triple<String, String, String> toTriple : toTriples) {
getSecurityService().checkCurrentUserUpdatePermission(getLeaderboardByName(toTriple.getA()));
}
final RaceColumn raceColumn = getRaceColumn(fromTriple.getA(), fromTriple.getB());
final Set<Pair<RaceColumn, Fleet>> toRaces = new HashSet<>();
for (com.sap.sse.common.Util.Triple<String, String, String> toTriple : toTriples) {
for (Triple<String, String, String> toTriple : toTriples) {
final RaceColumn toRaceColumn = getRaceColumn(toTriple.getA(), toTriple.getB());
final Fleet toFleet = getFleetByName(toRaceColumn, toTriple.getC());
toRaces.add(new Pair<>(toRaceColumn, toFleet));
@@ -153,3 +153,5 @@ moveTheFollowingMasterAndReplicaProcessesAway=Přesunování hlavních procesů
processOfReplicaSet=na portu {0} (aplikační sada replik {1})
successfullyMovedAllProcessesAwayFromHost=Všechny procesy byly úspěšně přesunuty z hostitele {0}
dnsNameAlreadyInUse=Název DNS se již používá
errorArchivingMongoDBTo=Chyba při archivaci MongoDB sady replik k sadě replik Mongo {0}: {1}
optionalSessionToken=Token relace (volitelný)
@@ -153,3 +153,5 @@ moveTheFollowingMasterAndReplicaProcessesAway=Flytter overordnede processer [{1}
processOfReplicaSet=på port {0} (applikationsreplikasæt {1})
successfullyMovedAllProcessesAwayFromHost=Alle processer blev flyttet væk fra vært {0} uden fejl
dnsNameAlreadyInUse=DNS-navn er allerede i brug
errorArchivingMongoDBTo=Fejl ved arkivering af replikasæts MongoDB til Monogo-replikasættet {0}: {1}
optionalSessionToken=Sessionstoken (valgfrit)
@@ -2,7 +2,7 @@ region=Región
images=Imágenes
imageType=Tipo de imagen
upgrade=Upgrade
replicaSet=Conjunto de réplicas
replicaSet=Conjunto de réplica
awsCredentials=Credenciales AWS
awsAccessKey=Clave de acceso AWS
awsSecret=Secreto AWS
@@ -53,7 +53,7 @@ loggedOutSuccessfully=Ha cerrado sesión correctamente.
instanceId=ID de instancia
port=Puerto
launchTimePoint=Iniciado a las
applicationReplicaSets=Conjuntos de réplicas de aplicación
applicationReplicaSets=Conjuntos de réplica de aplicación
masterHostName=Host maestro
masterPort=Puerto maestro
masterServerName=Nombre del servidor maestro
@@ -62,16 +62,16 @@ replicas=Réplicas
versionHeader=Versión
archive=Archivar
startTimePoint=Iniciado a las
createApplicationReplicaSet=Crear conjuntos de réplicas de aplicación
createApplicationReplicaSet=Crear conjunto de réplica de aplicación
useDynamicLoadBalancer=Utilizar ajuste de carga
bearerTokenForSecurityReplication=Token de portador para replicación de seguridad
successfullyCreatedReplicaSet=Conjunto de réplicas de aplicación {0} creado correctamente.
pleaseProvideApplicationReplicaSetName=Indique un nombre para el conjunto de réplicas de la aplicación
successfullyCreatedReplicaSet=Conjunto de réplica de aplicación {0} creado correctamente.
pleaseProvideApplicationReplicaSetName=Indique un nombre para el conjunto de réplica de la aplicación
pleaseSelectInstanceTypeForNewMaster=Seleccione un tipo de instancia para el host principal nuevo.
pleaseProvideBearerTokenForSecurityReplication=Indique el token de portador para la replicación del servicio de seguridad
domainName=Nombre de dominio DNS
release=Versión
reallyRemoveApplicationReplicaSet=¿Desea eliminar el conjunto de réplicas de aplicación {0} con todas las reglas de entrada?
reallyRemoveApplicationReplicaSet=¿Desea eliminar el conjunto de réplica de aplicación {0} con todas las reglas de entrada?
pleaseSelectSshKeyPair=Seleccione un par clave SSH
defineLandingPage=Definir página de llegada
successfullyUpdatedLandingPage=Página de llegada actualizada correctamente
@@ -83,32 +83,32 @@ redirectEvent=Evento específico
redirectEventSeries=Series de eventos específicos (por ejemplo, temporada de ligas)
pleaseProvideAValidId=Indique un ID válido
defaultRedirectPath=Redireccionamiento predeterminado
successfullyCreatedLoadBalancerMappingFor=Asignaciones del ajuste de carga creadas correctamente para el conjunto de réplicas de aplicación {0}.
successfullyCreatedLoadBalancerMappingFor=Asignaciones del ajuste de carga creadas correctamente para el conjunto de réplica de aplicación {0}.
createLoadBalancerMapping=Crear asignación de ajuste de carga
forceDNSUpdate=Forzar actualización DNS
latestMasterRelease=Versión de maestro más reciente
successfullyUpgradedApplicationReplicaSet=Conjunto de réplicas de aplicación actualizadas correctamente {0} a la versión {1}.
upgradingApplicationReplicaSetFailed=Actualización fallida de conjunto de réplicas de aplicación {0}.
upgradeApplicationReplicaSet=Actualizar conjuntos de réplicas de aplicación
successfullyArchivedReplicaSet=Conjunto de réplicas archivadas correctamente {0}.
removeArchivedReplicaSet=¿Desea eliminar el conjunto de réplicas archivadas tras la verificación correcta?
bearerTokenOrNullForApplicationReplicaSetToArchive=Token de portador para conjunto de réplicas de aplicación {0} (dejar en blanco para el usuario actual)
successfullyUpgradedApplicationReplicaSet=Conjunto de réplica de aplicación actualizado correctamente {0} a la versión {1}.
upgradingApplicationReplicaSetFailed=Actualización fallida de conjunto de réplica de aplicación {0}.
upgradeApplicationReplicaSet=Actualizar conjunto de réplica de aplicación
successfullyArchivedReplicaSet=Conjunto de réplica archivado correctamente {0}.
removeArchivedReplicaSet=¿Desea eliminar el conjunto de réplica archivado tras la verificación correcta?
bearerTokenOrNullForApplicationReplicaSetToArchive=Token de portador para conjunto de réplica de aplicación {0} (dejar en blanco para el usuario actual)
bearerTokenOrNullForArchive=Token de portador para archivo (dejar en blanco para el usuario actual)
numberOfMinutesBeforeAndBetweenCompareServers=Minutos antes de y entre los intentos de verificación
numberOfCompareServersAttempts=Número máximo de intentos de verificación
replicaReplicationBearerToken=Portador de token de réplicas para maestro de réplicas
memoryInMegabytes=Memoria (MB)
memoryTotalSizeFactor=Memoria como factor para la memoria total
launchAnotherReplicaSetOnThisMaster=Iniciar otro conjunto de réplicas en este maestro
launchAnotherReplicaSetOnThisMaster=Iniciar otro conjunto de réplica en este maestro
ensureAtLeastOneReplicaExistsStopReplicatingAndRemoveMasterFromTargetGroups=Asegúrese al menos que una réplica se esté ejecutando, luego detenga la replciación de todas las réplicas y elimine el maestro de ambos grupos objetivo.
successfullyStoppedReplicatingAndRemovedMasterFromTargetGroups=Se ha detenido correctamente la replicación y se ha eliminado el maestro de ambos grupos objetivo para el conjunto de réplicas {0}
successfullyStoppedReplicatingAndRemovedMasterFromTargetGroups=Se ha detenido correctamente la replicación y se ha eliminado el maestro de ambos grupos objetivo para el conjunto de réplica {0}
stopReplicating=Detener replicación
sameAsMaster=Igual que el maestro
firstReplicaOnSharedInstance=Primera réplica en instancia compartida
machineImageId=ID de AMI
updateAmiForAutoScalingReplicas=Actualizar imagen de máquina para réplicas de escalado automático
successfullyUpdatedMachineImageForAutoScalingReplicas=Grupo de escalado automático de {0} del conjunto de réplicas actualizado correctamente para la imagen de réplica {1}
updateSelectedReplicaSetAmisToo=¿Desea actualizar también los siguientes conjuntos de réplicas siguientes para la nueva imagen de la máquina?\{0}
successfullyUpdatedMachineImageForAutoScalingReplicas=Grupo de escalado automático de {0} del conjunto de réplica actualizado correctamente para la imagen de réplica {1}
updateSelectedReplicaSetAmisToo=¿Desea actualizar también los siguientes conjuntos de réplica siguientes para la nueva imagen de la máquina?\{0}
sharedMasterInstance=Utilice un instancia compartida para el proceso maestro
autoScalingReplicaInstanceType=Tipo de instancia para réplicas de escalado automático
dedicatedInstanceType=Tipo de instancia para instancias maestras/réplica especializadas
@@ -117,14 +117,14 @@ sharedMasterInstanceType=Tipo de instancia para instancia maestra compartida
sharedMasterAndReplicaInstanceType=Tipo de instancia para instancias maestras y de réplica compartidas
sharedReplicaInstanceType=Tipo de instancia para instancia de réplica compartida
switchToAutoScalingReplicasOnly=Cambiar a solo réplicas de escalado automático
problemSwitchingReplicaSetToAutoReplicasOnly=Problema al cambiar el conjunto de réplicas de la aplicación {0} para solo réplicas de escalado automático: {1}
successfullySwitchedReplicaSetToAutoReplicasOnly=Conjunto de réplicas de la aplicación {0} cambiadas correctamente para solo réplicas de escalado automático.
problemSwitchingReplicaSetToAutoReplicasOnly=Problema al cambiar el conjunto de réplica de la aplicación {0} para solo réplicas de escalado automático: {1}
successfullySwitchedReplicaSetToAutoReplicasOnly=Conjunto de réplica de la aplicación {0} cambiado correctamente para solo réplicas de escalado automático.
switchToReplicaOnSharedInstance=Cambiar a réplica en instancia compartida
moveMasterToOtherInstance=Mover proceso maestro a otra instancia
successfullyMovedMasterOfReplicaSet=Proceso maestro del conjunto de réplicas {0} movido correctamente
successfullyRemovedApplicationReplicaSet=Conjunto de réplicas {0} eliminadas correctamente
successfullyMovedMasterOfReplicaSet=Proceso maestro del conjunto de réplica {0} movido correctamente
successfullyRemovedApplicationReplicaSet=Conjunto de réplica {0} eliminado correctamente
scaleAutoScalingReplicasUpOrDown=Escalar réplicas de escalado automático arriba/abajo
successfullyScaledAutoScalingReplicasForReplicaSet=Réplicas de escalado automático correctamente escaladas para el conjunto de réplicas {0}
successfullyScaledAutoScalingReplicasForReplicaSet=Réplicas de escalado automático correctamente escaladas para el conjunto de réplica {0}
errorDuringImport=Error durante la importación: {0}
errorWhileComparingServerContent=Error al comparar el contenido del servidor
differencesInServerContentFound=Diferencias encontradas: el servidor {0} tiene {1}, mientras que el servidor {2} tiene {3}
@@ -147,9 +147,11 @@ shardCreatedSuccessfully=Partición "{0}" creada correctamente
deletedShard=Partición eliminada "{0}"
errorFetchingLeaderboardNames=Error al obtener los nombres de la tabla de clasificación: {0}
shardingDescription=Seleccione cero o más tablas de clasificación que todavía no estén en una partición; a continuación, haga clic en "Añadir partición" para crear una nueva partición que gestione las tablas de clasificación seleccionadas.\nUse los botones de flecha para añadir o quitar tablas de clasificación de una partición seleccionada.\nTenga en cuenta que los cambios se realizan inmediatamente, no cuando cierra este cuadro de diálogo.
moveAllApplicationProcessesAwayFromMaster=Mover todos los procesos de aplicación fuera del host principal de este conjunto de réplicas a otro host nuevo.
moveAllApplicationProcessesAwayFromMaster=Mover todos los procesos de aplicación fuera del host principal de este conjunto de réplica a otro host nuevo.
sameAsExistingHost=Igual que el host existente
moveTheFollowingMasterAndReplicaProcessesAway=Movimiento de procesos principales [{1}] y procesos de réplica [{2}] del host con ID {0} a un host nuevo.
processOfReplicaSet=en el puerto {0} (conjunto de réplicas de aplicación {1})
processOfReplicaSet=en el puerto {0} (conjunto de réplica de aplicación {1})
successfullyMovedAllProcessesAwayFromHost=Todos los procesos movidos correctamente fuera del host {0}
dnsNameAlreadyInUse=Nombre de DNS ya en uso
errorArchivingMongoDBTo=Error al archivar conjunto de réplica MongoDB en conjunto de réplica Mongo {0}: {1}
optionalSessionToken=Token de sesión (opcional)
@@ -147,9 +147,11 @@ shardCreatedSuccessfully=Éclat "{0}" correctement créé
deletedShard=Supprimer l''éclat "{0}"
errorFetchingLeaderboardNames=Erreur lors de l''accès aux noms de palmarès : {0}
shardingDescription=Sélectionnez un ou plusieurs palmarès qui ne sont pas encore dans un éclat ou n''en sélectionnez aucun, puis cliquez sur "Ajouter un éclat" pour créer un éclat traitant les palmarès sélectionnés.\nUtilisez les flèches pour ajouter des palmarès ou les supprimer d''un éclat sélectionné.\nNotez que les modifications sont appliquées immédiatement, pas quand vous fermez la boîte de dialogue.
moveAllApplicationProcessesAwayFromMaster=Déplacer tous les processus d''application de l''hôte principal de ce groupe de réplicas vers un nouvel hôte
moveAllApplicationProcessesAwayFromMaster=Déplacer tous les processus d''application de l''hôte principal de cet ensemble de réplicas vers un nouvel hôte
sameAsExistingHost=Identique à l''hôte existant
moveTheFollowingMasterAndReplicaProcessesAway=Déplacement des processus principaux [{1}] et des processus de réplicas [{2}) de l''hôte avec l''ID {0} vers un nouvel hôte.
processOfReplicaSet=sur le port {0} (ensemble de réplicas d''application {1})
successfullyMovedAllProcessesAwayFromHost=Processus correctement déplacés depuis l''hôte {0}
dnsNameAlreadyInUse=Nom DNS déjà utilisé
errorArchivingMongoDBTo=Erreur lors de l''archivage de l''ensemble de réplicas MongoDB dans l''ensemble de réplicas Mongo {0} : {1}
optionalSessionToken=Jeton de session (facultatif)
@@ -153,3 +153,5 @@ moveTheFollowingMasterAndReplicaProcessesAway=Spostamento in corso dei processi
processOfReplicaSet=sulla porta {0} (set di replica dell''applicazione {1})
successfullyMovedAllProcessesAwayFromHost=Spostamento di tutti i processi dall''host {0} avvenuto correttamente
dnsNameAlreadyInUse=Nome DNS già in uso
errorArchivingMongoDBTo=Errore di archiviazione del MongoDB del set di replica nel set di replica Mongo {0}: {1}
optionalSessionToken=Token di sessione (opzionale)
@@ -153,3 +153,5 @@ moveTheFollowingMasterAndReplicaProcessesAway=マスタプロセス [{1}] およ
processOfReplicaSet=ポート {0} (アプリケーション複製セット {1}) 上
successfullyMovedAllProcessesAwayFromHost=すべてのプロセスがホスト {0} から移動しました
dnsNameAlreadyInUse=DNS 名はすでに使用中です
errorArchivingMongoDBTo=複製セットの MongoDB を Mongo 複製セット {0} にアーカイブする際にエラーが発生: {1}
optionalSessionToken=セッショントークン (オプション)
@@ -153,3 +153,5 @@ moveTheFollowingMasterAndReplicaProcessesAway=Movendo processos mestre [{1}] e p
processOfReplicaSet=na porta {0} (conjunto de réplicas de aplicação {1})
successfullyMovedAllProcessesAwayFromHost=Todos os processos movidos com êxito do host {0}
dnsNameAlreadyInUse=Nome de DNS já em utilização
errorArchivingMongoDBTo=Erro ao arquivar MongoDB de conjunto de réplicas para o conjunto de réplicas Mongo {0}: {1}
optionalSessionToken=Token de sessão (opcional)
@@ -153,3 +153,5 @@ moveTheFollowingMasterAndReplicaProcessesAway=Перемещение основ
processOfReplicaSet=на порт {0} (набор реплик приложений {1})
successfullyMovedAllProcessesAwayFromHost=Все процессы успешно перемещены с хоста {0}
dnsNameAlreadyInUse=Имя DNS уже используется
errorArchivingMongoDBTo=Ошибка при архивации MongoDB набора реплик в набор реплик Mongo {0}: {1}
optionalSessionToken=Маркер сеанса (опциональный)
@@ -153,3 +153,5 @@ moveTheFollowingMasterAndReplicaProcessesAway=Premik glavnih procesov [{1}] in p
processOfReplicaSet=vrata {0} (niz replik aplikacije {1})
successfullyMovedAllProcessesAwayFromHost=Vsi procesi uspešno premaknjeni iz gostitelja {0}
dnsNameAlreadyInUse=Ime DNS je že v uporabi
errorArchivingMongoDBTo=Napaka pri arhiviranju MongoDB niza replik v niz replik Mongo {0}: {1}
optionalSessionToken=Žeton seje (izbirno)
@@ -153,3 +153,5 @@ moveTheFollowingMasterAndReplicaProcessesAway=将主流程 [{1}] 和复本流程
processOfReplicaSet=在端口 {0} 上(应用程序复本集 {1})
successfullyMovedAllProcessesAwayFromHost=已成功将所有流程移离主机 {0}
dnsNameAlreadyInUse=DNS 名称已在使用中
errorArchivingMongoDBTo=归档复本集的 MongoDB 到 Mongo 复本集 {0} 出错:{1}
optionalSessionToken=会话令牌(可选)
@@ -0,0 +1,83 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.server.interfaces.RacingEventService;
import com.sap.sailing.server.interfaces.RacingEventServiceOperation;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Triple;
/**
* The result is a {@link Triple} with the new total points in {@link Triple#getA() a}, the new net points in
* {@link Triple#getB() b}, and whether or not the result is obtained from the correction ("isCorrected") as
* {@link Triple#getC() c}.
*
* @author Axel Uhl (d043530)
*
*/
public abstract class AbstractLeaderboardScoreCorrectionUpdate extends AbstractLeaderboardColumnOperation<Util.Triple<Double, Double, Boolean>> {
private static final long serialVersionUID = -977025759476022993L;
private final String competitorIdAsString;
private final TimePoint timePoint;
/**
* @param timePoint the time point for which to deliver leaderboard results as the result of this operation
*/
public AbstractLeaderboardScoreCorrectionUpdate(String leaderboardName, String columnName, String competitorIdAsString, TimePoint timePoint) {
super(leaderboardName, columnName);
this.competitorIdAsString = competitorIdAsString;
this.timePoint = timePoint;
}
@Override
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
// TODO Auto-generated method stub
return null;
}
protected TimePoint getTimePoint() {
return timePoint;
}
protected String getCompetitorIdAsString() {
return competitorIdAsString;
}
@Override
public Util.Triple<Double, Double, Boolean> internalApplyTo(RacingEventService toState) throws NoWindException {
Leaderboard leaderboard = toState.getLeaderboardByName(getLeaderboardName());
Double newTotalPoints;
Double newNetPoints;
boolean isScoreCorrected;
if (leaderboard != null) {
Competitor competitor = leaderboard.getCompetitorByIdAsString(competitorIdAsString);
if (competitor != null) {
RaceColumn raceColumn = leaderboard.getRaceColumnByName(getColumnName());
newTotalPoints = updateScoreCorrection(leaderboard, competitor, raceColumn);
newNetPoints = leaderboard.getEntry(competitor, raceColumn, getTimePoint()).getNetPoints();
isScoreCorrected = leaderboard.getScoreCorrection().isScoreCorrected(competitor, raceColumn, getTimePoint());
} else {
throw new IllegalArgumentException("Didn't find competitor with ID "+competitorIdAsString+" in leaderboard "+getLeaderboardName());
}
} else {
throw new IllegalArgumentException("Didn't find leaderboard "+getLeaderboardName());
}
updateStoredLeaderboard(toState, leaderboard);
return new Util.Triple<Double, Double, Boolean>(newTotalPoints, newNetPoints, isScoreCorrected);
}
/**
* Perform the actual score correction update on the leaderboard and its {@link Leaderboard#getScoreCorrection() score corrections}
* and then return the competitor's new total points.
*/
protected abstract Double updateScoreCorrection(Leaderboard leaderboard, Competitor competitor, RaceColumn raceColumn);
}
@@ -0,0 +1,46 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.server.interfaces.RacingEventServiceOperation;
import com.sap.sse.common.TimePoint;
public class UpdateLeaderboardIncrementalScoreCorrection extends AbstractLeaderboardScoreCorrectionUpdate {
private static final long serialVersionUID = 9064307077124881657L;
private final Double scoreOffsetInPoints;
/**
* @param timePoint the time point for which to deliver leaderboard results as the result of this operation
*/
public UpdateLeaderboardIncrementalScoreCorrection(String leaderboardName, String columnName, String competitorIdAsString,
Double scoreOffsetInPoints, TimePoint timePoint) {
super(leaderboardName, columnName, competitorIdAsString, timePoint);
this.scoreOffsetInPoints = scoreOffsetInPoints;
}
@Override
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
// TODO Auto-generated method stub
return null;
}
@Override
protected Double updateScoreCorrection(Leaderboard leaderboard, Competitor competitor, RaceColumn raceColumn) {
final Double newTotalPoints;
if (scoreOffsetInPoints == null) {
leaderboard.getScoreCorrection().uncorrectScoreIncrementally(competitor, raceColumn);
} else {
leaderboard.getScoreCorrection().correctScoreIncrementally(competitor, raceColumn, scoreOffsetInPoints);
}
newTotalPoints = leaderboard.getTotalPoints(competitor, raceColumn, getTimePoint());
return newTotalPoints;
}
}
@@ -2,28 +2,21 @@ package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.server.interfaces.RacingEventService;
import com.sap.sailing.server.interfaces.RacingEventServiceOperation;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
public class UpdateLeaderboardScoreCorrection extends AbstractLeaderboardColumnOperation<Util.Triple<Double, Double, Boolean>> {
private static final long serialVersionUID = -977025759476022993L;
private final String competitorIdAsString;
public class UpdateLeaderboardScoreCorrection extends AbstractLeaderboardScoreCorrectionUpdate {
private static final long serialVersionUID = 697705655733594367L;
private final Double correctedScore;
private final TimePoint timePoint;
/**
* @param timePoint the time point for which to deliver leaderboard results as the result of this operation
*/
public UpdateLeaderboardScoreCorrection(String leaderboardName, String columnName, String competitorIdAsString,
Double correctedScore, TimePoint timePoint) {
super(leaderboardName, columnName);
this.competitorIdAsString = competitorIdAsString;
super(leaderboardName, columnName, competitorIdAsString, timePoint);
this.correctedScore = correctedScore;
this.timePoint = timePoint;
}
@Override
@@ -39,32 +32,15 @@ public class UpdateLeaderboardScoreCorrection extends AbstractLeaderboardColumnO
}
@Override
public Util.Triple<Double, Double, Boolean> internalApplyTo(RacingEventService toState) throws NoWindException {
Leaderboard leaderboard = toState.getLeaderboardByName(getLeaderboardName());
Double newTotalPoints;
Double newNetPoints;
boolean isScoreCorrected;
if (leaderboard != null) {
Competitor competitor = leaderboard.getCompetitorByIdAsString(competitorIdAsString);
if (competitor != null) {
RaceColumn raceColumn = leaderboard.getRaceColumnByName(getColumnName());
protected Double updateScoreCorrection(Leaderboard leaderboard, Competitor competitor, RaceColumn raceColumn) {
final Double newTotalPoints;
if (correctedScore == null) {
leaderboard.getScoreCorrection().uncorrectScore(competitor, raceColumn);
newTotalPoints = leaderboard.getTotalPoints(competitor, raceColumn, timePoint);
newTotalPoints = leaderboard.getTotalPoints(competitor, raceColumn, getTimePoint());
} else {
leaderboard.getScoreCorrection().correctScore(competitor, raceColumn, correctedScore);
newTotalPoints = correctedScore;
}
newNetPoints = leaderboard.getEntry(competitor, raceColumn, timePoint).getNetPoints();
isScoreCorrected = leaderboard.getScoreCorrection().isScoreCorrected(competitor, raceColumn, timePoint);
} else {
throw new IllegalArgumentException("Didn't find competitor with ID "+competitorIdAsString+" in leaderboard "+getLeaderboardName());
return newTotalPoints;
}
} else {
throw new IllegalArgumentException("Didn't find leaderboard "+getLeaderboardName());
}
updateStoredLeaderboard(toState, leaderboard);
return new Util.Triple<Double, Double, Boolean>(newTotalPoints, newNetPoints, isScoreCorrected);
}
}
@@ -2335,6 +2335,12 @@ Replicator {
notifyForCompetitorScoreCorrectionUpdateIfNotAlreadyNotifiedRecently(competitor, raceColumn);
}
@Override
public void incrementalScoreCorrectionChanged(Competitor competitor, RaceColumn raceColumn,
Double oldScoreOffsetInPoints, Double newScoreOffsetInPoints) {
notifyForCompetitorScoreCorrectionUpdateIfNotAlreadyNotifiedRecently(competitor, raceColumn);
}
@Override
public void maxPointsReasonChanged(Competitor competitor, RaceColumn raceColumn, MaxPointsReason oldMaxPointsReason, MaxPointsReason newMaxPointsReason) {
notifyForCompetitorScoreCorrectionUpdateIfNotAlreadyNotifiedRecently(competitor, raceColumn);
@@ -9,6 +9,6 @@
<classpathentry kind="lib" path="/com.sap.sailing.windestimation/lib/smile-math-1.5.2.jar"/>
<classpathentry kind="lib" path="lib/jcommon-1.0.23.jar"/>
<classpathentry kind="lib" path="lib/jfreechart-1.0.19.jar"/>
<classpathentry kind="lib" path="lib/trove-3.0.3.jar"/>
<classpathentry kind="lib" path="lib/trove-3.0.3.jar" sourcepath="/home/uhl/data/java/trove4j-3.0.3-sources.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
@@ -1,14 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/com.sap.sailing.windestimation.lab/src/com/sap/sailing/windestimation/model/SimpleModelsTrainingPart1.java"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="1"/>
</listAttribute>
<mapAttribute key="org.eclipse.debug.core.preferred_launchers">
<mapEntry key="[run]" value="org.eclipse.jdt.launching.localJavaApplication"/>
</mapAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_EXCLUDE_TEST_CODE" value="true"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.sap.sailing.windestimation.model.SimpleModelsTrainingPart1"/>
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="com.sap.sailing.windestimation.lab"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="${SAPSAILING_BEARER_TOKEN} 80 20 ../com.sap.sailing.windestimation.test/resources/trained_wind_estimation_models"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.windestimation.lab"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms16G -Xmx16G -Dmongo.dbName=windEstimation -Dmongo.port=10202"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms16G -Xmx16G -Dmongo.uri=&quot;mongodb://localhost/windestimation?uuidRepresentation=javaLegacy&amp;retryWrites=true&quot;"/>
</launchConfiguration>
@@ -7,9 +7,12 @@
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="1"/>
</listAttribute>
<mapAttribute key="org.eclipse.debug.core.preferred_launchers">
<mapEntry key="[run]" value="org.eclipse.jdt.launching.localJavaApplication"/>
</mapAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_EXCLUDE_TEST_CODE" value="true"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.sap.sailing.windestimation.model.SimpleModelsTrainingPart2"/>
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="com.sap.sailing.windestimation.lab"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.windestimation.lab"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Dmongo.port=10200 -Dmongo.dbName=windestimation"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Dmongo.uri=&quot;mongodb://localhost/windestimation?uuidRepresentation=javaLegacy&amp;retryWrites=true&quot;"/>
</launchConfiguration>
@@ -175,8 +175,8 @@ public class ManeuverAndWindImporter {
+ " competitor tracks\n\t" + importStatistics.maneuversCount
+ " complete maneuver curves with estimation data\n\t" + importStatistics.racesWithHighQualityWindData
+ " races with high quality wind data\n\t" + importStatistics.ignoredRegattas
+ " ignored regatta due to error\n\t" + importStatistics.ingoredRaces
+ " ingored races due to error\n--------------------------------------------\nTime passed: "
+ " ignored regatta due to error\n\t" + importStatistics.ignoredRaces
+ " ignored races due to error\n--------------------------------------------\nTime passed: "
+ duration.toHours() + "h " + (duration.toMinutes() - duration.toHours() * 60) + "m "
+ (duration.get(ChronoUnit.SECONDS) % 60) + "s");
}
@@ -216,7 +216,7 @@ public class ManeuverAndWindImporter {
importRace(regattaName, trackedRaceName, importStatistics, bearerToken);
} catch (Exception e) {
synchronized (importStatistics) {
importStatistics.ingoredRaces += 1;
importStatistics.ignoredRaces += 1;
}
String extraLog = "";
if (e instanceof HttpClientException) {
@@ -415,7 +415,7 @@ public class ManeuverAndWindImporter {
private int competitorTracksCount = 0;
private int maneuversCount = 0;
private int ignoredRegattas = 0;
private int ingoredRaces = 0;
private int ignoredRaces = 0;
private int racesWithHighQualityWindData = 0;
}
@@ -44,10 +44,14 @@ public class SingleDimensionTwdTransitionAggregationImporter {
.getIteratorSorted(); iterator.hasNext();) {
SingleDimensionBasedTwdTransition entry = iterator.next();
while (entry.getDimensionValue() > finalBucketThreshold) {
LoggingUtil.logInfo("Closing aggrgate for value "+currentBucketThreshold+
" because we arrived at a value outside the bucket: "+entry.getDimensionValue()+" > "+finalBucketThreshold);
if (entries.size() >= MIN_NUMBER_OF_VALUES_PER_BUCKET) {
AggregatedSingleDimensionBasedTwdTransition aggregate = computeAggregate(currentBucketThreshold,
entries);
aggregates.add(aggregate);
} else {
LoggingUtil.logInfo("Not writing aggregate because it has too few samples: "+entries.size()+" < "+MIN_NUMBER_OF_VALUES_PER_BUCKET);
}
currentBucketThreshold = nextBucketThreshold;
nextBucketThreshold = thresholdCalculator.getNextThresholdValue(nextBucketThreshold);
@@ -60,7 +64,7 @@ public class SingleDimensionTwdTransitionAggregationImporter {
twdChange = Math.abs(twdChange);
}
entries.add(twdChange);
if (entries.size() % 10000 == 0) {
if (entries.size() % 100000 == 0) {
LoggingUtil.logInfo(
(entries.size() + totalValuesCount) + " Entries aggregated for dimension " + dimensionType);
}
@@ -114,18 +114,14 @@ public class SimpleModelsTrainingPart1 {
awaitThreadPoolCompletion();
// The following code would open pop-up windows that display charts of original TWD regressions before cleansing:
final boolean showCharts = args.length > 4 && Boolean.valueOf(args[4]);
if (showCharts) {
AggregatedDurationDimensionPlot.main(args);
AggregatedDistanceDimensionPlot.main(args);
}
enforceMonotonicZeroMeanSigmaGrowth(AggregatedSingleDimensionType.DURATION);
enforceMonotonicZeroMeanSigmaGrowth(AggregatedSingleDimensionType.DISTANCE);
// The following code would open pop-up windows that display charts of original and "cleansed" TWD regressions:
if (showCharts) {
AggregatedDurationDimensionPlot.main(args);
showInfoAboutIntervalAdjustments(DurationBasedTwdTransitionRegressorModelContext.class, DurationValueRange.class);
AggregatedDistanceDimensionPlot.main(args);
showInfoAboutIntervalAdjustments(DistanceBasedTwdTransitionRegressorModelContext.class, DistanceValueRange.class);
} else {
enforceMonotonicZeroMeanSigmaGrowth(AggregatedSingleDimensionType.DURATION);
enforceMonotonicZeroMeanSigmaGrowth(AggregatedSingleDimensionType.DISTANCE);
}
DurationBasedTwdTransitionStdRegressorTrainer.train(modelStore);
DistanceBasedTwdTransitionStdRegressorTrainer.train(modelStore);
@@ -143,7 +139,9 @@ public class SimpleModelsTrainingPart1 {
if (aggregate.getZeroMeanStd() >= previousZeroMeanSigma) {
previousZeroMeanSigma = aggregate.getZeroMeanStd();
} else {
logger.info("Removing aggregate for dimension value "+aggregate.getDimensionValue()+" (dimension "+dimensionType.name()+") to achieve monotonic growth");
logger.info("Removing aggregate for dimension value "+aggregate.getDimensionValue()+" (dimension "+dimensionType.name()+
") to achieve monotonic growth. The previous zeroMeanSigma value was "+previousZeroMeanSigma+
"; the aggregate for "+aggregate.getDimensionValue()+" has "+aggregate.getZeroMeanStd());
persistenceManager.remove(aggregate);
}
}
@@ -52,6 +52,8 @@ import com.sap.sailing.windestimation.data.RaceWithEstimationData;
import com.sap.sailing.windestimation.data.WindQuality;
import com.sap.sailing.windestimation.data.transformer.CompleteManeuverCurveWithEstimationDataToManeuverForEstimationTransformer;
import com.sap.sailing.windestimation.model.exception.ModelPersistenceException;
import com.sap.sailing.windestimation.model.regressor.twdtransition.DistanceBasedTwdTransitionRegressorModelContext.DistanceValueRange;
import com.sap.sailing.windestimation.model.regressor.twdtransition.DurationBasedTwdTransitionRegressorModelContext.DurationValueRange;
import com.sap.sailing.windestimation.model.store.ClassPathReadOnlyModelStoreImpl;
import com.sap.sailing.windestimation.preprocessing.RaceElementsFilteringPreprocessingPipelineImpl;
import com.sap.sailing.windestimation.windinference.DummyBasedTwsCalculatorImpl;
@@ -74,11 +76,21 @@ public class IncrementalMstHmmWindEstimationForTrackedRaceTest extends OnlineTra
private static final double PERCENT_QUANTILE = 0.8;
/**
* These model file names must match up with the boundaries defined in the {@link DistanceValueRange} and {@link DurationValueRange}
* enumeration types. The files themselves are obtained by executing the training runs, particularly the launch configurations
* {@code AggregatedDurationBasedTwdTransitionImporter} and {@code AggregatedDistanceBasedTwdTransitionImporter} which, when provided
* with the argument {@code ../com.sap.sailing.windestimation.test/resources/trained_wind_estimation_models} will store the serialized
* versions of the wind regressor models there, using the boundaries as defined in the two enumeration types.<p>
*
* Failing to update these files and their names after making changes to either of the enumeration types will lead to exceptions
* during test runs.
*/
public static final String[] modelFilesNames = {
"SERIALIZATION.modelForDistanceBasedTwdDeltaStdRegressor.IncrementalSingleDimensionPolynomialRegressor.DistanceBasedTwdTransitionRegressorFrom0.0To10.0.clf",
"SERIALIZATION.modelForDistanceBasedTwdDeltaStdRegressor.IncrementalSingleDimensionPolynomialRegressor.DistanceBasedTwdTransitionRegressorFrom10.0To912.0.clf",
"SERIALIZATION.modelForDistanceBasedTwdDeltaStdRegressor.IncrementalSingleDimensionPolynomialRegressor.DistanceBasedTwdTransitionRegressorFrom1368.0ToMaximum.clf",
"SERIALIZATION.modelForDistanceBasedTwdDeltaStdRegressor.IncrementalSingleDimensionPolynomialRegressor.DistanceBasedTwdTransitionRegressorFrom912.0To1368.0.clf",
"SERIALIZATION.modelForDistanceBasedTwdDeltaStdRegressor.IncrementalSingleDimensionPolynomialRegressor.DistanceBasedTwdTransitionRegressorFrom1368.0ToMaximum.clf",
"SERIALIZATION.modelForDurationBasedTwdDeltaStdRegressor.IncrementalSingleDimensionPolynomialRegressor.DurationBasedTwdTransitionRegressorFrom0.0To1.0.clf",
"SERIALIZATION.modelForDurationBasedTwdDeltaStdRegressor.IncrementalSingleDimensionPolynomialRegressor.DurationBasedTwdTransitionRegressorFrom1.0To140.0.clf",
"SERIALIZATION.modelForDurationBasedTwdDeltaStdRegressor.IncrementalSingleDimensionPolynomialRegressor.DurationBasedTwdTransitionRegressorFrom140.0To5394.0.clf",
@@ -211,14 +223,16 @@ public class IncrementalMstHmmWindEstimationForTrackedRaceTest extends OnlineTra
foundCount++;
}
}
assertTrue((double) foundCount / (double) estimatedWindFixes.size() > PERCENT_QUANTILE);
assertTrue("Expected ratio of matching fixes to be at least "+PERCENT_QUANTILE+" but was only "+(double) foundCount / (double) estimatedWindFixes.size(),
(double) foundCount / (double) estimatedWindFixes.size() > PERCENT_QUANTILE);
foundCount = 0;
for (Wind wind : targetWindFixes) {
if (findWithinTolerance(estimatedWindFixesMap, new Pair<>(wind.getPosition(), wind.getTimePoint())) != null) {
foundCount++;
}
}
assertTrue((double) foundCount / (double) targetWindFixes.size() > PERCENT_QUANTILE);
assertTrue("Expected ratio of matching fixes to be at least "+PERCENT_QUANTILE+" but was only "+(double) foundCount / (double) estimatedWindFixes.size(),
(double) foundCount / (double) targetWindFixes.size() > PERCENT_QUANTILE);
}
/**
@@ -99,5 +99,4 @@ public class DistanceAndDurationAwareWindTransitionProbabilitiesCalculator
/ transitionProbabilitySum;
return new Pair<>(intersectedWindRangeUntilCurrentNode, normalizedTransitionProbabilityUntilCurrentNode);
}
}
@@ -37,7 +37,11 @@ public final class DistanceBasedTwdTransitionRegressorModelContext
* Input value intervals with corresponding model configurations for the distance dimension which is treated in
* meters. For each enum element, a separate model will be trained with polynomial degree and bias as specified by
* the enum element. Feel free to add/delete/modify enum elements as it is desired. The model training and discovery
* will still work. However, make sure that the specified intervals do not include holes between its transitions.
* will still work. However, make sure that the specified intervals do not include holes between its transitions.<p>
*
* Should you make changes here, also keep in mind that test cases and their test resources contains model files
* that must match these ranges. See {@code IncrementalMstHmmWindEstimationForTrackedRaceTest.modelFilesNames} for
* details.
*
* @author Vladislav Chumak (D069712)
*
@@ -77,7 +81,5 @@ public final class DistanceBasedTwdTransitionRegressorModelContext
public SupportedDimensionValueRange getSupportedDimensionValueRange() {
return supportedDimensionValueRange;
}
}
}
@@ -47,6 +47,18 @@
Semi Final, and Grand Final as a separate "Medal Series" with one race each. The scoring scheme understands
that the best competitor of the opening series advances to the last medal series (e.g., "Grand Final"), and
the second and third of the Opening Series advance straight to the Semi Final (last-but-one medal series).</li>
<li>The invalid result markers (IRMs) <tt>SCP</tt>, <tt>STP</tt>, <tt>DPI</tt>, and <tt>RDG</tt> can now consider
optional incremental score corrections which are added to the points determined based on the competitor's rank
in the race and the scoring scheme that applied to the race. For example, a <tt>DPI</tt> penalty with <tt>+2.5</tt>
points may now be specified which applied during tracking the race. Absolute score corrections will be considered
for these IRMs at the end of the race, regardless the incremental score correction. Note that the increments
are subject to any column factors being applied; this may contradict an event's rules that may state that certain
penalties, such as <tt>STP</tt> are <em>not</em> subject to doubling for a medal race. In such cases, specify half
the penalty when editing the increment. Specifying and incremental penalties can be done on the <tt>/gwt/LeaderboardEdit.html</tt>
reachable from the administration console's Leaderboards/Leaderboards tab (red dice symbol). They are displayed there
in brackets behind the score and an optional IRM code, as in "17 DPI [+1.5]". Clearing the corresponding field
in the editing popup dialog removes the incremental scoring offset, just like clearing the IRM code drop-down
or the absolute score correction removes the values there, respectively.</li>
</ul>
<h2 class="articleSubheadline">June 2023</h2>
<ul class="bulletList">
@@ -2,6 +2,7 @@ package com.sap.sse.common;
import java.io.Serializable;
import com.sap.sse.datamining.annotations.Dimension;
import com.sap.sse.datamining.annotations.Statistic;
/**
@@ -78,6 +79,11 @@ public interface Speed extends Comparable<Speed>, Serializable {
@Statistic(messageKey="speedInKnots", resultDecimals=2)
double getKnots();
@Dimension(messageKey="speedInFullKnots")
default int getKnotsFloored() {
return (int) Math.round(getKnots());
}
double getMetersPerSecond();
double getKilometersPerHour();
@@ -184,9 +184,7 @@ public class ChargebeeSubscriptionWriteServiceImpl extends ChargebeeSubscription
.subscriptionItemItemPriceId(0, priceId)
.subscriptionItemQuantity(0,1)
.customerId(user.getName()).customerEmail(user.getEmail())
.customerFirstName(usernames.getA()).customerLastName(usernames.getB())
.billingAddressFirstName(usernames.getA())
.billingAddressLastName(usernames.getB());
.customerFirstName(usernames.getA()).customerLastName(usernames.getB());
if (isChargebeeSupportedLocale(locale)) {
requestBuilder.customerLocale(locale);
}
+1 -1
View File
@@ -22,7 +22,7 @@ before:
after:
`TXT sapsailing.com "v=spf1 mx ip4:54.229.94.254 include:amazonses.com include:mail.zendesk.com include:servers.mcsv.net -all"`
There is a user created in WorkMail, ``support@sapsailing.com``. For this user we created a redirect for all incoming emails, using the [webmail access](https://sapsailing.awsapps.com/mail) and following the instructions provided here [Working with email rules](https://docs.aws.amazon.com/workmail/latest/userguide/email-rules.html).
There is a user created in WorkMail, ``support@sapsailing.com`` (simple username ``support``). For this user we created a redirect for all incoming emails, using the [webmail access](https://sapsailing.awsapps.com/mail) and following the instructions provided here [Working with email rules](https://docs.aws.amazon.com/workmail/latest/userguide/email-rules.html). Note that in order to modify an existing rule you have to double-click it. This will open the edit dialog. After confirming your changes with two OK buttons you still have to click on the "Save Changes" button at the top to make your changes take effect.
#### Create new user or change existing
Simply follow the instructions here: [Managing user accounts](https://docs.aws.amazon.com/workmail/latest/adminguide/manage-users.html).