@if (loading()) {
@for (s of skeletons; track s) {
}
} @else if (errored()) { error_outline

Could not load the report

The API request failed. Check that the backend is running and try again.

} @else if (!hasMatches()) { event_busy

No matches on this date

There are no fixtures scheduled for {{ dateControl.value | date: 'fullDate' }}.

} @else {
{{ report()!.matchCount }} match(es) on {{ report()!.date }} @if (selectedCount() > 0) { {{ selectedCount() }} selected }
@for (group of report()!.groups; track group.leagueId + '-' + group.seasonId) { emoji_events {{ group.leagueName }}  — {{ group.country }} Season {{ group.seasonName }} · {{ group.matches.length }} match(es) @if (group.modelParams) {
model_training Dixon-Coles model HA {{ group.modelParams.homeAdvantage }} ρ {{ group.modelParams.rho }} @if (group.modelParams.avgHomeGoals != null) { avg H {{ group.modelParams.avgHomeGoals }} } @if (group.modelParams.avgAwayGoals != null) { avg A {{ group.modelParams.avgAwayGoals }} } {{ group.modelParams.matchesUsed }} matches @if (group.modelParams.halfLifeDays) { · half-life {{ group.modelParams.halfLifeDays }}d } · trained {{ group.modelParams.trainedAt | date: 'mediumDate' }}
} @for (m of group.matches; track m.matchId) {
{{ m.kickoffAt | date: 'HH:mm' }}
{{ m.homeTeamName }} @if (m.hasScore) { {{ m.homeScoreFt }} : {{ m.awayScoreFt }} } @else { vs } {{ m.awayTeamName }}
{{ statusLabels[m.status] ?? m.status }}
@if (m.stadium || m.referee) {
@if (m.stadium) { stadium{{ m.stadium }} } @if (m.referee) { sports{{ m.referee }} } @if (m.hasScore) { scheduleHT {{ m.homeScoreHt }}:{{ m.awayScoreHt }} }
}
history_toggle_off{{ seasonsLabel(m) }}
@if (m.odds) {
casino Market 1X2 (avg {{ m.odds.bookmakerCount }} bookmaker{{ m.odds.bookmakerCount === 1 ? '' : 's' }})
Home {{ m.odds.avgHomeOdds | number: '1.2-2' }} {{ (m.odds.homeImplied * 100) | number: '1.1-1' }}%
Draw {{ m.odds.avgDrawOdds | number: '1.2-2' }} {{ (m.odds.drawImplied * 100) | number: '1.1-1' }}%
Away {{ m.odds.avgAwayOdds | number: '1.2-2' }} {{ (m.odds.awayImplied * 100) | number: '1.1-1' }}%
@if (m.odds.avgTotalLine != null || m.odds.avgOverOdds != null || m.odds.avgUnderOdds != null) {
Totals O/U @if (m.odds.avgTotalLine != null) { Line {{ m.odds.avgTotalLine }} } @if (m.odds.avgOverOdds != null) { Over {{ m.odds.avgOverOdds | number: '1.2-2' }} @if (m.odds.overImplied != null) { {{ (m.odds.overImplied * 100) | number: '1.1-1' }}% } } @if (m.odds.avgUnderOdds != null) { Under {{ m.odds.avgUnderOdds | number: '1.2-2' }} @if (m.odds.underImplied != null) { {{ (m.odds.underImplied * 100) | number: '1.1-1' }}% } }
}
} @if (m.extraOdds?.length) {
stacked_line_chart Extra markets @for (eo of m.extraOdds; track eo.market + eo.bookmaker) { }
Market Bookmaker Line Over Under
{{ extraMarketLabel(eo.market) }} {{ eo.bookmaker }} {{ eo.line }} {{ eo.overOdds | number: '1.2-2' }} {{ eo.underOdds | number: '1.2-2' }}
}
@for (t of [m.home, m.away]; track t.teamId) {
{{ t.teamName }} based on {{ t.matchesPlayed }} earlier match(es)
@if (t.strength) {
fitness_center Atk {{ t.strength.attackFactor }} · Def {{ t.strength.defenseFactor }} ({{ t.strength.matchesUsed }} matches)
} @if (t.oddsApiName) {
link Odds API: {{ t.oddsApiName }}
} @if (!t.hasHistory) {
info No historical data in the selected window.
} @else {
sports_soccer {{ goalsSummary(t) }}
@if (t.seasonAverages.hasData) {
Possession{{ t.seasonAverages.possession }}%
Shots{{ t.seasonAverages.shotsTotal }}
On target{{ t.seasonAverages.shotsOnTarget }}
Corners{{ t.seasonAverages.corners }}
Fouls{{ t.seasonAverages.fouls }}
Offsides{{ t.seasonAverages.offsides }}
Yellow{{ t.seasonAverages.yellowCards }}
Red{{ t.seasonAverages.redCards }}
} @else {
Detailed match stats: no data.
}
Form: @if (t.form.length) { @for (r of t.form; track $index) { } } @else { no data }
Top scorers (goals + assists so far) @if (t.topScorers.length) { @for (s of t.topScorers; track s.playerName) { }
{{ s.playerName }} {{ s.goals }}G {{ s.assists }}A
} @else {
no data
}
} @if (t.prediction || t.openAiPrediction || t.actual?.hasData) {
@if (t.actual?.hasData && (t.prediction || t.openAiPrediction)) { Predictions vs actual } @else if (t.actual?.hasData) { Match statistics } @else { Predictions (per this match) } @if (t.prediction) { } @if (t.openAiPrediction) { } @if (t.actual?.hasData) { } @if (t.prediction) { } @if (t.openAiPrediction) { } @if (t.actual?.hasData) { } @if (t.prediction || t.actual?.shotsTotal != null) { @if (t.prediction) { } @if (t.openAiPrediction) { } @if (t.actual?.hasData) { } } @if (t.prediction) { } @if (t.openAiPrediction) { } @if (t.actual?.hasData) { } @if (t.prediction) { } @if (t.openAiPrediction) { } @if (t.actual?.hasData) { } @if (t.prediction) { } @if (t.openAiPrediction) { } @if (t.actual?.hasData) { } @if (t.prediction) { } @if (t.openAiPrediction) { } @if (t.actual?.hasData) { } @if (t.openAiPrediction || t.actual?.hasData) { @if (t.prediction) { } @if (t.openAiPrediction) { } @if (t.actual?.hasData) { } }
MetricLLMOpenAIActual
Goals{{ t.prediction.predictedGoals ?? '—' }}{{ t.openAiPrediction.predictedGoals ?? '—' }}{{ t.actual!.goals ?? '—' }}
Shots{{ t.prediction.predictedShotsTotal ?? '—' }}{{ t.actual!.shotsTotal ?? '—' }}
On target{{ t.prediction.predictedShotsOnTarget ?? '—' }}{{ t.openAiPrediction.predictedShotsOnTarget ?? '—' }}{{ t.actual!.shotsOnTarget ?? '—' }}
Corners{{ t.prediction.predictedCorners ?? '—' }}{{ t.openAiPrediction.predictedCorners ?? '—' }}{{ t.actual!.corners ?? '—' }}
Fouls{{ t.prediction.predictedFouls ?? '—' }}{{ t.openAiPrediction.predictedFouls ?? '—' }}{{ t.actual!.fouls ?? '—' }}
Yellow cards{{ t.prediction.predictedYellowCards ?? '—' }}{{ t.openAiPrediction.predictedYellowCards ?? '—' }}{{ t.actual!.yellowCards }}
Red cards{{ t.openAiPrediction.predictedRedCards ?? '—' }}{{ t.actual!.redCards }}
@if (t.openAiPrediction) {
@if (t.openAiPrediction.model) { {{ t.openAiPrediction.model }} } @if (t.openAiPrediction.confidence) { · {{ t.openAiPrediction.confidence }} confidence } @if (t.openAiPrediction.predictedAt) { · {{ t.openAiPrediction.predictedAt | date: 'medium' }} }
} @if (t.prediction) {
LLM model @if (t.prediction.halfLifeDays) { · half-life {{ t.prediction.halfLifeDays }}d } · trained {{ t.prediction.modelTrainedAt | date: 'mediumDate' }} · saved {{ t.prediction.predictedAt | date: 'short' }}
}
}
}
}
} }