@ethlete/cdk 4.45.0 → 4.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/esm2022/lib/components/bracket/components/new-bracket/bracket-new.mjs +782 -0
  3. package/esm2022/lib/components/bracket/components/new-bracket/draw-man.mjs +66 -0
  4. package/esm2022/lib/components/bracket/components/new-bracket/grid-definitions.mjs +47 -0
  5. package/esm2022/lib/components/bracket/components/new-bracket/grid-placements.mjs +97 -0
  6. package/esm2022/lib/components/bracket/components/new-bracket/index.mjs +8 -0
  7. package/esm2022/lib/components/bracket/components/new-bracket/new-bracket-default-match.component.mjs +17 -0
  8. package/esm2022/lib/components/bracket/components/new-bracket/new-bracket-default-round-header.component.mjs +16 -0
  9. package/esm2022/lib/components/bracket/components/new-bracket/new-bracket.component.mjs +54 -0
  10. package/esm2022/lib/components/bracket/public-api/index.mjs +2 -1
  11. package/fesm2022/ethlete-cdk.mjs +1096 -3
  12. package/fesm2022/ethlete-cdk.mjs.map +1 -1
  13. package/lib/components/bracket/components/new-bracket/bracket-new.d.ts +238 -0
  14. package/lib/components/bracket/components/new-bracket/draw-man.d.ts +12 -0
  15. package/lib/components/bracket/components/new-bracket/grid-definitions.d.ts +9 -0
  16. package/lib/components/bracket/components/new-bracket/grid-placements.d.ts +56 -0
  17. package/lib/components/bracket/components/new-bracket/index.d.ts +7 -0
  18. package/lib/components/bracket/components/new-bracket/new-bracket-default-match.component.d.ts +8 -0
  19. package/lib/components/bracket/components/new-bracket/new-bracket-default-round-header.component.d.ts +7 -0
  20. package/lib/components/bracket/components/new-bracket/new-bracket.component.d.ts +26 -0
  21. package/lib/components/bracket/public-api/index.d.ts +1 -0
  22. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import * as i1 from '@angular/cdk/portal';
2
2
  import { CdkPortal, PortalModule, ComponentPortal, TemplatePortal, CdkPortalOutlet } from '@angular/cdk/portal';
3
- import { AsyncPipe, NgClass, NgTemplateOutlet, JsonPipe, NgComponentOutlet, DOCUMENT, Location } from '@angular/common';
3
+ import { AsyncPipe, NgClass, NgTemplateOutlet, NgComponentOutlet, JsonPipe, DOCUMENT, Location } from '@angular/common';
4
4
  import * as i0 from '@angular/core';
5
5
  import { Component, ViewEncapsulation, ChangeDetectionStrategy, InjectionToken, Directive, booleanAttribute, Input, ContentChild, ContentChildren, inject, ElementRef, Injector, HostBinding, input, numberAttribute, computed, signal, contentChildren, viewChild, viewChildren, isDevMode, Injectable, ChangeDetectorRef, TemplateRef, ViewContainerRef, ViewChild, assertInInjectionContext, forwardRef, EventEmitter, Output, ViewChildren, runInInjectionContext, Optional, Inject, SkipSelf, HostListener, contentChild, effect, untracked, NgZone, NgModule, DestroyRef, isSignal, Attribute } from '@angular/core';
6
6
  import * as i1$1 from '@ethlete/core';
@@ -8,6 +8,7 @@ import { LetDirective, createDestroy, Memo, signalHostAttributes, signalHostClas
8
8
  import { BehaviorSubject, startWith, map, switchMap, combineLatest, pairwise, tap, takeUntil, skip, of, merge, timer, takeWhile, filter, fromEvent, Subject, Observable, debounceTime, withLatestFrom, distinctUntilChanged, take, skipUntil, skipWhile, catchError, throwError, defer, partition, from, finalize, Subscription } from 'rxjs';
9
9
  import { trigger, state, style, transition, animate } from '@angular/animations';
10
10
  import { __decorate, __metadata } from 'tslib';
11
+ import { DomSanitizer, Title } from '@angular/platform-browser';
11
12
  import { toSignal, toObservable, takeUntilDestroyed, outputFromObservable } from '@angular/core/rxjs-interop';
12
13
  import { extractQuery, isQueryStateSuccess, isQueryStateFailure, isQueryStateLoading, QueryDirective, queryComputed, switchQueryState, shouldRetryRequest, isClassValidatorError, isSymfonyFormViolationListError, isSymfonyListError } from '@ethlete/query';
13
14
  import * as i1$2 from '@angular/cdk/a11y';
@@ -28,7 +29,6 @@ import { startWith as startWith$1, debounceTime as debounceTime$1, distinctUntil
28
29
  import { UniqueSelectionDispatcher, _VIEW_REPEATER_STRATEGY, _DisposeViewRepeaterStrategy, _RecycleViewRepeaterStrategy, DataSource } from '@angular/cdk/collections';
29
30
  import * as i1$3 from '@angular/router';
30
31
  import { Router, RouterLink, RouterLinkActive, NavigationEnd } from '@angular/router';
31
- import { Title } from '@angular/platform-browser';
32
32
  import * as i1$4 from '@angular/cdk/table';
33
33
  import { CdkColumnDef, CDK_TABLE, CdkTable, _COALESCED_STYLE_SCHEDULER, _CoalescedStyleScheduler, STICKY_POSITIONING_LISTENER, HeaderRowOutlet, DataRowOutlet, NoDataRowOutlet, FooterRowOutlet, CdkCell, CdkCellDef, CdkFooterCell, CdkFooterCellDef, CdkHeaderCell, CdkHeaderCellDef, CdkTextColumn, TEXT_COLUMN_OPTIONS, CdkFooterRow, CdkTableModule, CDK_ROW_TEMPLATE, CdkFooterRowDef, CdkHeaderRow, CdkHeaderRowDef, CdkNoDataRow, CdkRow, CdkRowDef } from '@angular/cdk/table';
34
34
  import * as i1$5 from '@angular/cdk/scrolling';
@@ -1010,6 +1010,1099 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImpo
1010
1010
 
1011
1011
  const BracketImports = [BracketComponent, BracketMatchComponent, BracketRoundHeaderComponent];
1012
1012
 
1013
+ const FALLBACK_MATCH_POSITION = -1;
1014
+ const TOURNAMENT_MODE = {
1015
+ SINGLE_ELIMINATION: 'single-elimination',
1016
+ DOUBLE_ELIMINATION: 'double-elimination',
1017
+ GROUP: 'group',
1018
+ SWISS: 'swiss',
1019
+ SWISS_WITH_ELIMINATION: 'swiss-with-elimination',
1020
+ };
1021
+ const COMMON_BRACKET_ROUND_TYPE = {
1022
+ THIRD_PLACE: 'third-place',
1023
+ FINAL: 'final',
1024
+ };
1025
+ const SINGLE_ELIMINATION_BRACKET_ROUND_TYPE = {
1026
+ SINGLE_ELIMINATION_BRACKET: 'single-elimination-bracket',
1027
+ };
1028
+ const DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE = {
1029
+ UPPER_BRACKET: 'upper-bracket',
1030
+ LOWER_BRACKET: 'lower-bracket',
1031
+ REVERSE_FINAL: 'reverse-final',
1032
+ };
1033
+ const SWISS_BRACKET_ROUND_TYPE = {
1034
+ SWISS: 'swiss',
1035
+ };
1036
+ const GROUP_BRACKET_ROUND_TYPE = {
1037
+ GROUP: 'group',
1038
+ };
1039
+ const generateRoundTypeFromEthleteRoundType = (type, tournamentMode) => {
1040
+ switch (type) {
1041
+ case 'normal':
1042
+ switch (tournamentMode) {
1043
+ case 'single-elimination':
1044
+ return SINGLE_ELIMINATION_BRACKET_ROUND_TYPE.SINGLE_ELIMINATION_BRACKET;
1045
+ case 'group':
1046
+ return GROUP_BRACKET_ROUND_TYPE.GROUP;
1047
+ case 'swiss':
1048
+ return SWISS_BRACKET_ROUND_TYPE.SWISS;
1049
+ default:
1050
+ throw new Error(`Unsupported tournament mode for a normal type round: ${tournamentMode}`);
1051
+ }
1052
+ case 'third_place':
1053
+ return COMMON_BRACKET_ROUND_TYPE.THIRD_PLACE;
1054
+ case 'final':
1055
+ return COMMON_BRACKET_ROUND_TYPE.FINAL;
1056
+ case 'reverse_final':
1057
+ return DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.REVERSE_FINAL;
1058
+ case 'winner_bracket':
1059
+ return DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.UPPER_BRACKET;
1060
+ case 'loser_bracket':
1061
+ return DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.LOWER_BRACKET;
1062
+ }
1063
+ };
1064
+ const generateTournamentModeFormEthleteRounds = (source) => {
1065
+ const firstRound = source[0];
1066
+ const firstMatch = firstRound?.matches[0];
1067
+ if (!firstRound)
1068
+ throw new Error('No rounds found');
1069
+ if (!firstMatch)
1070
+ throw new Error('No matches found');
1071
+ switch (firstMatch.matchType) {
1072
+ case 'groups':
1073
+ return TOURNAMENT_MODE.GROUP;
1074
+ case 'fifa_swiss': {
1075
+ const lastRound = source[source.length - 1];
1076
+ if (!lastRound)
1077
+ throw new Error('No last round found');
1078
+ if (lastRound.matches.length !== firstRound.matches.length) {
1079
+ return TOURNAMENT_MODE.SWISS_WITH_ELIMINATION;
1080
+ }
1081
+ else {
1082
+ return TOURNAMENT_MODE.SWISS;
1083
+ }
1084
+ }
1085
+ case 'double_elimination':
1086
+ return TOURNAMENT_MODE.DOUBLE_ELIMINATION;
1087
+ case 'single_elimination':
1088
+ return TOURNAMENT_MODE.SINGLE_ELIMINATION;
1089
+ default:
1090
+ throw new Error(`Unsupported tournament mode: ${firstMatch.matchType}`);
1091
+ }
1092
+ };
1093
+ const generateBracketDataForEthlete = (source) => {
1094
+ const tournamentMode = generateTournamentModeFormEthleteRounds(source);
1095
+ const bracketData = {
1096
+ rounds: new Map(),
1097
+ matches: new Map(),
1098
+ participants: new Map(),
1099
+ mode: tournamentMode,
1100
+ };
1101
+ let currentUpperBracketIndex = 0;
1102
+ let currentLowerBracketIndex = 0;
1103
+ for (const currentItem of source) {
1104
+ if (bracketData.rounds.has(currentItem.round.id)) {
1105
+ throw new Error(`Round with id ${currentItem.round.id} already exists in the bracket data.`);
1106
+ }
1107
+ const roundType = generateRoundTypeFromEthleteRoundType(currentItem.round.type, tournamentMode);
1108
+ const isLowerBracket = roundType === DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.LOWER_BRACKET;
1109
+ const bracketRound = {
1110
+ type: roundType,
1111
+ id: currentItem.round.id,
1112
+ index: isLowerBracket ? currentLowerBracketIndex : currentUpperBracketIndex,
1113
+ data: currentItem.round,
1114
+ position: currentItem.round.number,
1115
+ name: currentItem.round.name || currentItem.round.type,
1116
+ matchCount: currentItem.matches.length,
1117
+ matches: new Map(),
1118
+ };
1119
+ bracketData.rounds.set(currentItem.round.id, bracketRound);
1120
+ for (const [matchIndex, match] of currentItem.matches.entries()) {
1121
+ if (bracketData.matches.has(match.id)) {
1122
+ throw new Error(`Match with id ${match.id} already exists in the bracket data.`);
1123
+ }
1124
+ const bracketMatch = {
1125
+ id: match.id,
1126
+ indexInRound: matchIndex,
1127
+ position: (matchIndex + 1),
1128
+ data: match,
1129
+ round: bracketRound,
1130
+ home: match.home?.id || null,
1131
+ away: match.away?.id || null,
1132
+ winner: match.winningSide,
1133
+ status: match.status === 'published' ? 'completed' : 'pending',
1134
+ };
1135
+ bracketData.matches.set(match.id, bracketMatch);
1136
+ bracketRound.matches.set(match.id, bracketMatch);
1137
+ const participants = [match.home, match.away];
1138
+ for (const participant of participants) {
1139
+ if (!participant)
1140
+ continue;
1141
+ const participantId = participant.id;
1142
+ if (!bracketData.participants.has(participantId)) {
1143
+ bracketData.participants.set(participantId, {
1144
+ id: participantId,
1145
+ name: participant.name || 'Unknown',
1146
+ matches: new Map(),
1147
+ });
1148
+ }
1149
+ const participantData = bracketData.participants.get(participantId);
1150
+ if (!participantData.matches.has(match.id)) {
1151
+ participantData.matches.set(match.id, {
1152
+ side: match.home?.id === participantId ? 'home' : 'away',
1153
+ bracketMatch,
1154
+ });
1155
+ }
1156
+ }
1157
+ }
1158
+ if (isLowerBracket) {
1159
+ currentLowerBracketIndex++;
1160
+ }
1161
+ else {
1162
+ currentUpperBracketIndex++;
1163
+ }
1164
+ }
1165
+ return bracketData;
1166
+ };
1167
+ const generateMatchPositionMaps = (bracketData) => {
1168
+ const matchPositionMaps = new Map();
1169
+ for (const round of bracketData.rounds.values()) {
1170
+ const matchMap = new Map([...round.matches.values()].map((m) => [m.position, m]));
1171
+ matchPositionMaps.set(round.id, matchMap);
1172
+ }
1173
+ return matchPositionMaps;
1174
+ };
1175
+ const generateBracketRoundTypeMap = (bracketData) => {
1176
+ const roundAmountMap = new Map();
1177
+ for (const round of bracketData.rounds.values()) {
1178
+ if (!roundAmountMap.has(round.type)) {
1179
+ roundAmountMap.set(round.type, new Map([[round.id, round]]));
1180
+ }
1181
+ else {
1182
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1183
+ roundAmountMap.set(round.type, roundAmountMap.get(round.type).set(round.id, round));
1184
+ }
1185
+ }
1186
+ return roundAmountMap;
1187
+ };
1188
+ const UPPER_LOOP_ORDER = [
1189
+ SINGLE_ELIMINATION_BRACKET_ROUND_TYPE.SINGLE_ELIMINATION_BRACKET,
1190
+ DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.UPPER_BRACKET,
1191
+ SWISS_BRACKET_ROUND_TYPE.SWISS,
1192
+ GROUP_BRACKET_ROUND_TYPE.GROUP,
1193
+ COMMON_BRACKET_ROUND_TYPE.FINAL,
1194
+ DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.REVERSE_FINAL,
1195
+ COMMON_BRACKET_ROUND_TYPE.THIRD_PLACE,
1196
+ ];
1197
+ const LOWER_LOOP_ORDER = [DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.LOWER_BRACKET];
1198
+ const generateRoundRelations = (bracketData) => {
1199
+ const roundRelations = new Map();
1200
+ const sortedRoundsByType = new Map();
1201
+ for (const round of bracketData.rounds.values()) {
1202
+ if (!sortedRoundsByType.has(round.type)) {
1203
+ sortedRoundsByType.set(round.type, [round]);
1204
+ }
1205
+ else {
1206
+ sortedRoundsByType.get(round.type)?.push(round);
1207
+ }
1208
+ }
1209
+ for (const rounds of sortedRoundsByType.values()) {
1210
+ if (rounds.length === 1)
1211
+ continue;
1212
+ rounds.sort((a, b) => a.position - b.position);
1213
+ }
1214
+ const sortedUpperRounds = UPPER_LOOP_ORDER.map((t) => sortedRoundsByType.get(t))
1215
+ .filter((r) => !!r)
1216
+ .flat();
1217
+ const sortedLowerRounds = LOWER_LOOP_ORDER.map((t) => sortedRoundsByType.get(t))
1218
+ .filter((r) => !!r)
1219
+ .flat();
1220
+ const firstUpperRound = sortedUpperRounds[0] || null;
1221
+ const firstLowerRound = sortedLowerRounds[0] || null;
1222
+ if (!firstUpperRound)
1223
+ throw new Error('firstUpperRound is null');
1224
+ const hasLowerRounds = sortedLowerRounds.length > 0;
1225
+ const lastLowerRound = sortedLowerRounds[sortedLowerRounds.length - 1] || null;
1226
+ for (const [currentUpperRoundIndex, currentUpperRound] of sortedUpperRounds.entries()) {
1227
+ const previousUpperRound = sortedUpperRounds[currentUpperRoundIndex - 1] || null;
1228
+ const nextUpperRound = sortedUpperRounds[currentUpperRoundIndex + 1] || null;
1229
+ const currentLowerRound = sortedLowerRounds[currentUpperRoundIndex] || null;
1230
+ const previousLowerRound = sortedLowerRounds[currentUpperRoundIndex - 1] || null;
1231
+ const nextLowerRound = sortedLowerRounds[currentUpperRoundIndex + 1] || null;
1232
+ const isFirstRound = currentUpperRoundIndex === 0;
1233
+ const isLastUpperRound = currentUpperRoundIndex === sortedUpperRounds.length - 1;
1234
+ const isFinal = currentUpperRound.type === COMMON_BRACKET_ROUND_TYPE.FINAL;
1235
+ if (isFinal && hasLowerRounds) {
1236
+ // two to one relation
1237
+ if (!lastLowerRound || !currentLowerRound || !previousUpperRound)
1238
+ throw new Error('lastLowerRound or currentLowerRound or previousUpperRound is null');
1239
+ // in a sync double elimination bracket, the final round has the same index as the last lower round
1240
+ // in an async one, there is always one more round in the lower bracket since we only display a section of the whole tournament
1241
+ const isAsyncBracket = currentLowerRound.id !== lastLowerRound.id;
1242
+ const finalLowerRound = isAsyncBracket ? nextLowerRound : currentLowerRound;
1243
+ if (!finalLowerRound)
1244
+ throw new Error('finalLowerRound is null');
1245
+ if (!firstLowerRound)
1246
+ throw new Error('firstLowerRound is null');
1247
+ if (finalLowerRound.id !== lastLowerRound.id)
1248
+ throw new Error('finalLowerRound is not the last lower round');
1249
+ // if we have a reverse final
1250
+ if (nextUpperRound) {
1251
+ // for the final
1252
+ roundRelations.set(currentUpperRound.id, {
1253
+ type: 'two-to-one',
1254
+ previousUpperRound: previousUpperRound,
1255
+ previousLowerRound: finalLowerRound,
1256
+ nextRound: nextUpperRound,
1257
+ currentRound: currentUpperRound,
1258
+ nextRoundMatchFactor: nextUpperRound.matchCount / currentUpperRound.matchCount,
1259
+ previousUpperRoundMatchFactor: previousUpperRound.matchCount / currentUpperRound.matchCount,
1260
+ previousLowerRoundMatchFactor: finalLowerRound.matchCount / currentUpperRound.matchCount,
1261
+ upperRootRoundMatchFactor: firstUpperRound.matchCount / currentUpperRound.matchCount,
1262
+ lowerRootRoundMatchFactor: firstLowerRound.matchCount / currentUpperRound.matchCount,
1263
+ });
1264
+ }
1265
+ else {
1266
+ // no reverse final means the final is the last round
1267
+ // for the final
1268
+ roundRelations.set(currentUpperRound.id, {
1269
+ type: 'two-to-nothing',
1270
+ previousUpperRound: previousUpperRound,
1271
+ previousLowerRound: finalLowerRound,
1272
+ currentRound: currentUpperRound,
1273
+ previousLowerRoundMatchFactor: finalLowerRound.matchCount / currentUpperRound.matchCount,
1274
+ previousUpperRoundMatchFactor: previousUpperRound.matchCount / currentUpperRound.matchCount,
1275
+ lowerRootRoundMatchFactor: firstLowerRound.matchCount / currentUpperRound.matchCount,
1276
+ upperRootRoundMatchFactor: firstUpperRound.matchCount / currentUpperRound.matchCount,
1277
+ });
1278
+ }
1279
+ if (isAsyncBracket) {
1280
+ // if this is an async bracket, we need to set the relations for the 2 last lower rounds since they will be skipped by the default one to one logic
1281
+ const preFinalLowerRound = sortedLowerRounds[sortedLowerRounds.length - 2] || null;
1282
+ const prePreFinalLowerRound = sortedLowerRounds[sortedLowerRounds.length - 3] || null;
1283
+ if (!preFinalLowerRound)
1284
+ throw new Error('preFinalLowerRound is null');
1285
+ if (!firstLowerRound)
1286
+ throw new Error('firstLowerRound is null');
1287
+ // for the last lower round
1288
+ roundRelations.set(finalLowerRound.id, {
1289
+ type: 'one-to-one',
1290
+ previousRound: preFinalLowerRound,
1291
+ nextRound: currentUpperRound,
1292
+ currentRound: finalLowerRound,
1293
+ nextRoundMatchFactor: currentUpperRound.matchCount / finalLowerRound.matchCount,
1294
+ previousRoundMatchFactor: preFinalLowerRound.matchCount / finalLowerRound.matchCount,
1295
+ rootRoundMatchFactor: firstLowerRound.matchCount / finalLowerRound.matchCount,
1296
+ });
1297
+ if (prePreFinalLowerRound) {
1298
+ // for the pre final lower round
1299
+ roundRelations.set(preFinalLowerRound.id, {
1300
+ type: 'one-to-one',
1301
+ previousRound: prePreFinalLowerRound,
1302
+ nextRound: finalLowerRound,
1303
+ currentRound: preFinalLowerRound,
1304
+ nextRoundMatchFactor: finalLowerRound.matchCount / preFinalLowerRound.matchCount,
1305
+ previousRoundMatchFactor: prePreFinalLowerRound.matchCount / preFinalLowerRound.matchCount,
1306
+ rootRoundMatchFactor: firstLowerRound.matchCount / preFinalLowerRound.matchCount,
1307
+ });
1308
+ }
1309
+ else {
1310
+ // for the first lower round
1311
+ roundRelations.set(preFinalLowerRound.id, {
1312
+ type: 'nothing-to-one',
1313
+ nextRound: finalLowerRound,
1314
+ currentRound: preFinalLowerRound,
1315
+ nextRoundMatchFactor: finalLowerRound.matchCount / preFinalLowerRound.matchCount,
1316
+ });
1317
+ }
1318
+ }
1319
+ else {
1320
+ // this is a sync bracket, we only need to set the relation for the last lower round
1321
+ if (!previousLowerRound)
1322
+ throw new Error('previousLowerRound is null');
1323
+ if (!firstLowerRound)
1324
+ throw new Error('firstLowerRound is null');
1325
+ // for the last lower round
1326
+ roundRelations.set(finalLowerRound.id, {
1327
+ type: 'one-to-one',
1328
+ previousRound: previousLowerRound,
1329
+ nextRound: currentUpperRound,
1330
+ currentRound: finalLowerRound,
1331
+ nextRoundMatchFactor: currentUpperRound.matchCount / finalLowerRound.matchCount,
1332
+ previousRoundMatchFactor: previousLowerRound.matchCount / finalLowerRound.matchCount,
1333
+ rootRoundMatchFactor: firstLowerRound.matchCount / finalLowerRound.matchCount,
1334
+ });
1335
+ }
1336
+ }
1337
+ else if (isLastUpperRound) {
1338
+ // one to nothing relation
1339
+ if (!previousUpperRound)
1340
+ throw new Error('previousUpperRound is null');
1341
+ roundRelations.set(currentUpperRound.id, {
1342
+ type: 'one-to-nothing',
1343
+ previousRound: previousUpperRound,
1344
+ currentRound: currentUpperRound,
1345
+ previousRoundMatchFactor: previousUpperRound.matchCount / currentUpperRound.matchCount,
1346
+ rootRoundMatchFactor: firstUpperRound.matchCount / currentUpperRound.matchCount,
1347
+ });
1348
+ }
1349
+ else if (isFirstRound) {
1350
+ // nothing to one relation
1351
+ if (!nextUpperRound)
1352
+ throw new Error('nextUpperRound is null');
1353
+ roundRelations.set(currentUpperRound.id, {
1354
+ type: 'nothing-to-one',
1355
+ nextRound: nextUpperRound,
1356
+ currentRound: currentUpperRound,
1357
+ nextRoundMatchFactor: nextUpperRound.matchCount / currentUpperRound.matchCount,
1358
+ });
1359
+ if (currentLowerRound) {
1360
+ if (!nextLowerRound)
1361
+ throw new Error('nextLowerRound is null');
1362
+ roundRelations.set(currentLowerRound.id, {
1363
+ type: 'nothing-to-one',
1364
+ nextRound: nextLowerRound,
1365
+ currentRound: currentLowerRound,
1366
+ nextRoundMatchFactor: nextLowerRound.matchCount / currentLowerRound.matchCount,
1367
+ });
1368
+ }
1369
+ }
1370
+ else {
1371
+ // one to one relation
1372
+ if (!previousUpperRound)
1373
+ throw new Error('previousUpperRound is null');
1374
+ if (!nextUpperRound)
1375
+ throw new Error('nextUpperRound is null');
1376
+ roundRelations.set(currentUpperRound.id, {
1377
+ type: 'one-to-one',
1378
+ previousRound: previousUpperRound,
1379
+ nextRound: nextUpperRound,
1380
+ currentRound: currentUpperRound,
1381
+ nextRoundMatchFactor: nextUpperRound.matchCount / currentUpperRound.matchCount,
1382
+ previousRoundMatchFactor: previousUpperRound.matchCount / currentUpperRound.matchCount,
1383
+ rootRoundMatchFactor: firstUpperRound.matchCount / currentUpperRound.matchCount,
1384
+ });
1385
+ // we only want to set lower rounds here until the special merging point of the final.
1386
+ // lower bracket rounds after and including the final will be set in the final round block
1387
+ if (currentLowerRound && currentUpperRound.type === DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.UPPER_BRACKET) {
1388
+ if (!previousLowerRound)
1389
+ throw new Error('previousLowerRound is null');
1390
+ if (!nextLowerRound)
1391
+ throw new Error('nextLowerRound is null');
1392
+ if (!firstLowerRound)
1393
+ throw new Error('firstLowerRound is null');
1394
+ roundRelations.set(currentLowerRound.id, {
1395
+ type: 'one-to-one',
1396
+ previousRound: previousLowerRound,
1397
+ nextRound: nextLowerRound,
1398
+ currentRound: currentLowerRound,
1399
+ nextRoundMatchFactor: nextLowerRound.matchCount / currentLowerRound.matchCount,
1400
+ previousRoundMatchFactor: previousLowerRound.matchCount / currentLowerRound.matchCount,
1401
+ rootRoundMatchFactor: firstLowerRound.matchCount / currentLowerRound.matchCount,
1402
+ });
1403
+ }
1404
+ }
1405
+ }
1406
+ return roundRelations;
1407
+ };
1408
+ const generateMatchRelations = (bracketData, roundRelations, matchPositionMaps) => {
1409
+ const matchRelations = new Map();
1410
+ for (const match of bracketData.matches.values()) {
1411
+ const currentRelation = roundRelations.get(match.round.id);
1412
+ if (!currentRelation)
1413
+ throw new Error('Match round not found');
1414
+ const { nextRoundMatchPosition, previousLowerRoundMatchPosition, previousUpperRoundMatchPosition } = generateMatchRelationPositions(currentRelation, match);
1415
+ switch (currentRelation.type) {
1416
+ case 'nothing-to-one': {
1417
+ const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextRoundMatchPosition);
1418
+ if (!nextMatch)
1419
+ throw new Error('Next round match not found');
1420
+ // means left is nothing. right is one
1421
+ matchRelations.set(match.id, {
1422
+ type: 'nothing-to-one',
1423
+ currentMatch: match,
1424
+ currentRound: currentRelation.currentRound,
1425
+ nextRound: currentRelation.nextRound,
1426
+ nextMatch,
1427
+ });
1428
+ break;
1429
+ }
1430
+ case 'one-to-nothing': {
1431
+ const previousUpperMatch = matchPositionMaps
1432
+ .get(currentRelation.previousRound.id)
1433
+ ?.get(previousUpperRoundMatchPosition);
1434
+ const previousLowerMatch = matchPositionMaps
1435
+ .get(currentRelation.previousRound.id)
1436
+ ?.get(previousLowerRoundMatchPosition);
1437
+ if (!previousUpperMatch)
1438
+ throw new Error('Previous round match not found');
1439
+ if (previousUpperRoundMatchPosition !== previousLowerRoundMatchPosition) {
1440
+ // means left is two. right is one
1441
+ if (!previousLowerMatch)
1442
+ throw new Error('Previous lower round match not found');
1443
+ matchRelations.set(match.id, {
1444
+ type: 'two-to-nothing',
1445
+ currentMatch: match,
1446
+ currentRound: currentRelation.currentRound,
1447
+ previousUpperMatch,
1448
+ previousUpperRound: currentRelation.previousRound,
1449
+ previousLowerMatch,
1450
+ previousLowerRound: currentRelation.previousRound,
1451
+ });
1452
+ }
1453
+ else {
1454
+ // means left is one. right is nothing
1455
+ matchRelations.set(match.id, {
1456
+ type: 'one-to-nothing',
1457
+ currentMatch: match,
1458
+ currentRound: currentRelation.currentRound,
1459
+ previousMatch: previousUpperMatch,
1460
+ previousRound: currentRelation.previousRound,
1461
+ });
1462
+ }
1463
+ break;
1464
+ }
1465
+ case 'one-to-one': {
1466
+ const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextRoundMatchPosition);
1467
+ const previousUpperMatch = matchPositionMaps
1468
+ .get(currentRelation.previousRound.id)
1469
+ ?.get(previousUpperRoundMatchPosition);
1470
+ const previousLowerMatch = matchPositionMaps
1471
+ .get(currentRelation.previousRound.id)
1472
+ ?.get(previousLowerRoundMatchPosition);
1473
+ if (!nextMatch)
1474
+ throw new Error('Next round match not found');
1475
+ if (!previousUpperMatch)
1476
+ throw new Error(`Previous upper round match not found`);
1477
+ if (!previousLowerMatch)
1478
+ throw new Error('Previous lower round match not found');
1479
+ // can be either one to one or two to one
1480
+ const isLeftOne = previousUpperRoundMatchPosition === previousLowerRoundMatchPosition;
1481
+ if (isLeftOne) {
1482
+ // one-to-one
1483
+ matchRelations.set(match.id, {
1484
+ type: 'one-to-one',
1485
+ currentMatch: match,
1486
+ currentRound: currentRelation.currentRound,
1487
+ previousMatch: previousUpperMatch,
1488
+ previousRound: currentRelation.previousRound,
1489
+ nextMatch,
1490
+ nextRound: currentRelation.nextRound,
1491
+ });
1492
+ }
1493
+ else {
1494
+ // two-to-one
1495
+ matchRelations.set(match.id, {
1496
+ type: 'two-to-one',
1497
+ currentMatch: match,
1498
+ currentRound: currentRelation.currentRound,
1499
+ previousUpperMatch,
1500
+ previousUpperRound: currentRelation.previousRound,
1501
+ previousLowerMatch,
1502
+ previousLowerRound: currentRelation.previousRound,
1503
+ nextMatch,
1504
+ nextRound: currentRelation.nextRound,
1505
+ });
1506
+ }
1507
+ break;
1508
+ }
1509
+ case 'two-to-one': {
1510
+ const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextRoundMatchPosition);
1511
+ const previousUpperMatch = matchPositionMaps
1512
+ .get(currentRelation.previousUpperRound.id)
1513
+ ?.get(previousUpperRoundMatchPosition);
1514
+ const previousLowerMatch = matchPositionMaps
1515
+ .get(currentRelation.previousLowerRound.id)
1516
+ ?.get(previousLowerRoundMatchPosition);
1517
+ if (!nextMatch)
1518
+ throw new Error('Next round match not found');
1519
+ if (!previousUpperMatch)
1520
+ throw new Error(`Previous upper round match not found`);
1521
+ if (!previousLowerMatch)
1522
+ throw new Error('Previous lower round match not found');
1523
+ matchRelations.set(match.id, {
1524
+ type: 'two-to-one',
1525
+ currentMatch: match,
1526
+ currentRound: currentRelation.currentRound,
1527
+ previousUpperMatch,
1528
+ previousUpperRound: currentRelation.previousUpperRound,
1529
+ previousLowerMatch,
1530
+ previousLowerRound: currentRelation.previousLowerRound,
1531
+ nextMatch,
1532
+ nextRound: currentRelation.nextRound,
1533
+ });
1534
+ break;
1535
+ }
1536
+ case 'two-to-nothing': {
1537
+ const previousUpperMatch = matchPositionMaps
1538
+ .get(currentRelation.previousUpperRound.id)
1539
+ ?.get(previousUpperRoundMatchPosition);
1540
+ const previousLowerMatch = matchPositionMaps
1541
+ .get(currentRelation.previousUpperRound.id)
1542
+ ?.get(previousLowerRoundMatchPosition);
1543
+ if (!previousUpperMatch)
1544
+ throw new Error(`Previous upper round match not found`);
1545
+ if (!previousLowerMatch)
1546
+ throw new Error('Previous lower round match not found');
1547
+ matchRelations.set(match.id, {
1548
+ type: 'two-to-nothing',
1549
+ currentMatch: match,
1550
+ currentRound: currentRelation.currentRound,
1551
+ previousUpperMatch,
1552
+ previousUpperRound: currentRelation.previousUpperRound,
1553
+ previousLowerMatch,
1554
+ previousLowerRound: currentRelation.previousUpperRound,
1555
+ });
1556
+ break;
1557
+ }
1558
+ }
1559
+ }
1560
+ return matchRelations;
1561
+ };
1562
+ const generateMatchRelationPositions = (currentRelation, match) => {
1563
+ switch (currentRelation.type) {
1564
+ case 'nothing-to-one': {
1565
+ return {
1566
+ nextRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
1567
+ previousUpperRoundMatchPosition: FALLBACK_MATCH_POSITION,
1568
+ previousLowerRoundMatchPosition: FALLBACK_MATCH_POSITION,
1569
+ };
1570
+ }
1571
+ case 'one-to-nothing': {
1572
+ const previousRoundHasDoubleTheMatchCount = currentRelation.previousRoundMatchFactor === 2;
1573
+ const doubleUpperMatchCountShift = previousRoundHasDoubleTheMatchCount ? 1 : 0;
1574
+ return {
1575
+ nextRoundMatchPosition: FALLBACK_MATCH_POSITION,
1576
+ previousUpperRoundMatchPosition: (generateMatchPosition(match, currentRelation.previousRoundMatchFactor) -
1577
+ doubleUpperMatchCountShift),
1578
+ previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousRoundMatchFactor),
1579
+ };
1580
+ }
1581
+ case 'one-to-one': {
1582
+ const previousRoundHasDoubleTheMatchCount = currentRelation.previousRoundMatchFactor === 2;
1583
+ const doubleUpperMatchCountShift = previousRoundHasDoubleTheMatchCount ? 1 : 0;
1584
+ return {
1585
+ nextRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
1586
+ previousUpperRoundMatchPosition: (generateMatchPosition(match, currentRelation.previousRoundMatchFactor) -
1587
+ doubleUpperMatchCountShift),
1588
+ previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousRoundMatchFactor),
1589
+ };
1590
+ }
1591
+ case 'two-to-one': {
1592
+ return {
1593
+ nextRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
1594
+ previousUpperRoundMatchPosition: generateMatchPosition(match, currentRelation.previousUpperRoundMatchFactor),
1595
+ previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousLowerRoundMatchFactor),
1596
+ };
1597
+ }
1598
+ case 'two-to-nothing': {
1599
+ return {
1600
+ nextRoundMatchPosition: FALLBACK_MATCH_POSITION,
1601
+ previousUpperRoundMatchPosition: generateMatchPosition(match, currentRelation.previousUpperRoundMatchFactor),
1602
+ previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousLowerRoundMatchFactor),
1603
+ };
1604
+ }
1605
+ }
1606
+ };
1607
+ const generateMatchPosition = (match, factor) => {
1608
+ return Math.ceil(match.position * factor);
1609
+ };
1610
+ const logRoundRelations = (roundRelations, bracketData) => {
1611
+ for (const [roundId, relation] of roundRelations.entries()) {
1612
+ const round = bracketData.rounds.get(roundId);
1613
+ if (!round) {
1614
+ console.error(`Round with id ${roundId} not found in bracket data. The bracket will be malformed.`);
1615
+ continue;
1616
+ }
1617
+ switch (relation.type) {
1618
+ case 'nothing-to-one':
1619
+ console.log(`START: ${round.name} -> ${relation.nextRound.name} (F: ${relation.nextRoundMatchFactor})`);
1620
+ break;
1621
+ case 'one-to-nothing':
1622
+ console.log(`${relation.previousRound.name} (F: ${relation.previousRoundMatchFactor}) <- ENDING: ${round.name}`);
1623
+ break;
1624
+ case 'one-to-one':
1625
+ console.log(`${relation.previousRound.name} (F: ${relation.previousRoundMatchFactor}) <- ${round.name} -> ${relation.nextRound.name} (F: ${relation.nextRoundMatchFactor})`);
1626
+ break;
1627
+ case 'two-to-one':
1628
+ console.log(`MERGER: ${relation.previousUpperRound.name} (F: ${relation.previousUpperRoundMatchFactor}) AND ${relation.previousLowerRound.name} (F: ${relation.previousLowerRoundMatchFactor}) <- ${round.name} -> ${relation.nextRound.name} (F: ${relation.nextRoundMatchFactor})`);
1629
+ break;
1630
+ case 'two-to-nothing':
1631
+ console.log(`MERGER: ${relation.previousUpperRound.name} (F: ${relation.previousUpperRoundMatchFactor}) AND ${relation.previousLowerRound.name} (F: ${relation.previousLowerRoundMatchFactor}) <- ENDING: ${round.name}`);
1632
+ break;
1633
+ }
1634
+ }
1635
+ };
1636
+ const generateMatchParticipantMap = (bracketData) => {
1637
+ const matchParticipantMap = new Map();
1638
+ const hasElimination = bracketData.mode === TOURNAMENT_MODE.SINGLE_ELIMINATION ||
1639
+ bracketData.mode === TOURNAMENT_MODE.DOUBLE_ELIMINATION ||
1640
+ bracketData.mode === TOURNAMENT_MODE.SWISS_WITH_ELIMINATION;
1641
+ for (const participant of bracketData.participants.values()) {
1642
+ let winsTilNow = 0;
1643
+ let lossesTilNow = 0;
1644
+ let tiesTilNow = 0;
1645
+ for (const matchParticipantMatch of participant.matches.values()) {
1646
+ const isWinner = matchParticipantMatch.bracketMatch.winner === matchParticipantMatch.side;
1647
+ const isLooser = matchParticipantMatch.bracketMatch.winner &&
1648
+ matchParticipantMatch.bracketMatch.winner !== matchParticipantMatch.side;
1649
+ const isTie = matchParticipantMatch.bracketMatch.status === 'completed' && !matchParticipantMatch.bracketMatch.winner;
1650
+ if (isWinner) {
1651
+ winsTilNow++;
1652
+ }
1653
+ else if (isLooser) {
1654
+ lossesTilNow++;
1655
+ }
1656
+ else if (isTie) {
1657
+ tiesTilNow++;
1658
+ }
1659
+ let isEliminated = false;
1660
+ let isEliminationMatch = false;
1661
+ if (hasElimination) {
1662
+ // TODO: Implement elimination logic
1663
+ // Means the current match is loss and it's the last match of the participant
1664
+ isEliminated = false;
1665
+ // Always true for single elimination, never for e.g. groups, depends on the round for double elimination, depends on the loss count for swiss with elimination
1666
+ isEliminationMatch = false;
1667
+ }
1668
+ // TODO: Implement round logic
1669
+ // true if its the first round of the bracket
1670
+ const isFirstRound = false;
1671
+ // true if its the last round of the bracket (eg. final for single elimination)
1672
+ const isLastRound = false;
1673
+ const participantMatchData = {
1674
+ bracketMatch: matchParticipantMatch.bracketMatch,
1675
+ result: isWinner ? 'win' : isLooser ? 'loss' : isTie ? 'tie' : null,
1676
+ isEliminated,
1677
+ isEliminationMatch,
1678
+ isFirstRound,
1679
+ isLastRound,
1680
+ tieCount: tiesTilNow,
1681
+ winCount: winsTilNow,
1682
+ lossCount: lossesTilNow,
1683
+ };
1684
+ if (!matchParticipantMap.has(participant.id)) {
1685
+ matchParticipantMap.set(participant.id, {
1686
+ id: participant.id,
1687
+ name: participant.name,
1688
+ matches: new Map(),
1689
+ });
1690
+ }
1691
+ const participantData = matchParticipantMap.get(participant.id);
1692
+ participantData.matches.set(matchParticipantMatch.bracketMatch.id, participantMatchData);
1693
+ }
1694
+ }
1695
+ return matchParticipantMap;
1696
+ };
1697
+ const factorialCache = new Map();
1698
+ const getAvailableSwissGroupsForRound = (roundNumber, totalMatchesInRound) => {
1699
+ const ADVANCE_WINS = 3;
1700
+ const ELIMINATE_LOSSES = 3;
1701
+ // Cache factorial calculations
1702
+ const getFactorial = (n) => {
1703
+ if (n <= 1)
1704
+ return 1;
1705
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1706
+ if (factorialCache.has(n))
1707
+ return factorialCache.get(n);
1708
+ const result = n * getFactorial(n - 1);
1709
+ factorialCache.set(n, result);
1710
+ return result;
1711
+ };
1712
+ // Pre-calculate roundFactorial
1713
+ const roundFact = getFactorial(roundNumber);
1714
+ let totalCombinations = 0;
1715
+ const validGroups = [];
1716
+ // Single loop to gather valid groups and total combinations
1717
+ for (let wins = roundNumber; wins >= 0; wins--) {
1718
+ const losses = roundNumber - wins;
1719
+ const remainingGames = ADVANCE_WINS + ELIMINATE_LOSSES - (wins + losses) - 1;
1720
+ const notYetEliminated = losses < ELIMINATE_LOSSES;
1721
+ const canStillAdvance = wins < ADVANCE_WINS && remainingGames >= 0;
1722
+ if (!canStillAdvance || !notYetEliminated)
1723
+ continue;
1724
+ const combinations = roundFact / (getFactorial(wins) * getFactorial(losses));
1725
+ totalCombinations += combinations;
1726
+ validGroups.push({ wins, losses, combinations });
1727
+ }
1728
+ // Create final groups with calculated proportions
1729
+ return validGroups.map(({ wins, losses, combinations }) => ({
1730
+ id: `${wins}-${losses}`,
1731
+ name: `${wins}-${losses}`,
1732
+ matchesInGroup: Math.round((combinations / totalCombinations) * totalMatchesInRound),
1733
+ }));
1734
+ };
1735
+ const generateBracketRoundSwissGroupMaps = (bracketData, matchParticipantMap) => {
1736
+ if (bracketData.mode !== TOURNAMENT_MODE.SWISS_WITH_ELIMINATION) {
1737
+ return null;
1738
+ }
1739
+ const roundsWithSwissGroups = new Map();
1740
+ let roundNumber = 0;
1741
+ for (const bracketRound of bracketData.rounds.values()) {
1742
+ const availableGroups = getAvailableSwissGroupsForRound(roundNumber, bracketRound.matchCount);
1743
+ const roundSwissData = {
1744
+ groups: new Map(),
1745
+ };
1746
+ for (const group of availableGroups) {
1747
+ const subGroup = {
1748
+ id: group.id,
1749
+ name: group.name,
1750
+ matches: new Map(),
1751
+ allowedMatchCount: group.matchesInGroup,
1752
+ };
1753
+ roundSwissData.groups.set(group.id, subGroup);
1754
+ }
1755
+ const emptyMatchIds = [];
1756
+ for (const match of bracketRound.matches.values()) {
1757
+ const participantHome = match.home ? (matchParticipantMap.get(match.home) ?? null) : null;
1758
+ const participantAway = match.away ? (matchParticipantMap.get(match.away) ?? null) : null;
1759
+ const anyParticipant = participantHome || participantAway;
1760
+ if (!anyParticipant) {
1761
+ emptyMatchIds.push(match.id);
1762
+ continue;
1763
+ }
1764
+ const matchParticipantMatch = anyParticipant.matches.get(match.id);
1765
+ if (!matchParticipantMatch)
1766
+ throw new Error('Match participant match not found');
1767
+ const wins = matchParticipantMatch.winCount;
1768
+ const losses = matchParticipantMatch.lossCount;
1769
+ const group = roundSwissData.groups.get(`${wins}-${losses}`);
1770
+ if (!group)
1771
+ throw new Error('Group not found for match: ' + match.id);
1772
+ group.matches.set(match.id, match);
1773
+ }
1774
+ for (const emptyMatchId of emptyMatchIds) {
1775
+ const match = bracketRound.matches.get(emptyMatchId);
1776
+ if (!match)
1777
+ throw new Error('Empty match not found');
1778
+ let groupFound = false;
1779
+ for (const group of roundSwissData.groups.values()) {
1780
+ if (group.matches.size < group.allowedMatchCount) {
1781
+ group.matches.set(match.id, match);
1782
+ groupFound = true;
1783
+ break;
1784
+ }
1785
+ }
1786
+ if (!groupFound) {
1787
+ throw new Error('No group found for empty match');
1788
+ }
1789
+ }
1790
+ roundNumber++;
1791
+ }
1792
+ return roundsWithSwissGroups;
1793
+ };
1794
+
1795
+ const LINE_WIDTH = 1;
1796
+ const path = (d) => `<path d="${d}" stroke="red" fill="none" stroke-width="${LINE_WIDTH}" />`;
1797
+ const drawMan = (items, roundRelations, dimensions) => {
1798
+ const { columnWidth, matchHeight, rowGap, columnGap, roundHeaderHeight, gridDefinitions } = dimensions;
1799
+ const roundHeaderRowGap = roundHeaderHeight ? rowGap : 0;
1800
+ const baseOffsetY = roundHeaderHeight + roundHeaderRowGap;
1801
+ const columnGapCenter = columnGap / 2;
1802
+ const totalHeight = (gridDefinitions.rowCount - 1) * matchHeight + (gridDefinitions.rowCount - 1) * rowGap + roundHeaderHeight; // TODO: This is not correct in double elimination
1803
+ const svgParts = [];
1804
+ // a nothing to one draws nothing
1805
+ // a one to nothing draws nothing
1806
+ // a one to one draws a line
1807
+ // a one to two draws a line that splits into in the middle
1808
+ // a two to one draws two lines that merge into one in the middle
1809
+ // WE ONLY EVER DRAW THE LEFT SIDE (on-to, nothing-to, two-to)
1810
+ for (const round of items.values()) {
1811
+ const rows = round.roundRelation.currentRound.matchCount;
1812
+ const rowGaps = rows - 1;
1813
+ const rowHeight = (totalHeight - baseOffsetY) / rows - rowGaps * rowGap;
1814
+ const rowWhitespace = (rowHeight - matchHeight) / 2;
1815
+ const matchHeightOffset = rowWhitespace + matchHeight / 2; // the vertical middle of a match in this row
1816
+ for (const item of round.items.values()) {
1817
+ if (item.type === 'round')
1818
+ continue; // we don't draw lines for round headers
1819
+ switch (item.matchRelation.type) {
1820
+ case 'nothing-to-one': {
1821
+ continue;
1822
+ }
1823
+ case 'one-to-nothing':
1824
+ case 'one-to-one': {
1825
+ // draw a straight line
1826
+ const previousRound = items.get(item.matchRelation.previousRound.id);
1827
+ if (!previousRound)
1828
+ throw new Error('Previous round or match is missing');
1829
+ const previousMatch = previousRound.items.get(item.matchRelation.previousMatch.id);
1830
+ if (!previousMatch || previousMatch.type !== 'match')
1831
+ throw new Error('Previous round or match is missing');
1832
+ const previousRoundRows = previousRound.roundRelation.currentRound.matchCount;
1833
+ const previousRoundRowGaps = previousRoundRows - 1;
1834
+ const previousRoundRowHeight = (totalHeight - baseOffsetY) / previousRoundRows - previousRoundRowGaps * rowGap;
1835
+ const previousRoundRowWhitespace = (previousRoundRowHeight - matchHeight) / 2;
1836
+ const previousRoundMatchHeightOffset = previousRoundRowWhitespace + matchHeight / 2;
1837
+ const fromX = previousRound.columnStart * columnWidth + (round.columnStart - 2) * columnGap;
1838
+ const toX = (round.columnStart - 1) * columnWidth + (round.columnStart - 1) * columnGap;
1839
+ const fromY = previousMatch.matchRelation.currentMatch.indexInRound * previousRoundRowWhitespace +
1840
+ previousMatch.matchRelation.currentMatch.indexInRound * rowGap +
1841
+ baseOffsetY +
1842
+ previousRoundMatchHeightOffset;
1843
+ const toY = item.matchRelation.currentMatch.indexInRound * rowWhitespace +
1844
+ item.matchRelation.currentMatch.indexInRound * rowGap +
1845
+ baseOffsetY +
1846
+ matchHeightOffset;
1847
+ svgParts.push(path(`M ${fromX} ${fromY} L ${toX} ${toY}`));
1848
+ break;
1849
+ }
1850
+ case 'two-to-nothing':
1851
+ case 'two-to-one': {
1852
+ // draw two lines that merge into one in the middle
1853
+ break;
1854
+ }
1855
+ }
1856
+ }
1857
+ }
1858
+ return svgParts.join(' /n');
1859
+ };
1860
+
1861
+ const generateColumnCount = (bracketData, roundTypeMap) => {
1862
+ const thirdPlaceRoundSize = roundTypeMap.get(COMMON_BRACKET_ROUND_TYPE.THIRD_PLACE)?.size || 0;
1863
+ switch (bracketData.mode) {
1864
+ case TOURNAMENT_MODE.DOUBLE_ELIMINATION: {
1865
+ const upperBracketSize = roundTypeMap.get(DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.UPPER_BRACKET)?.size || 0;
1866
+ const lowerBracketSize = roundTypeMap.get(DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.LOWER_BRACKET)?.size || 0;
1867
+ // the total columns are the bigger number of winner bracket rounds vs looser bracket rounds + all other rounds excluding third place
1868
+ return bracketData.rounds.size - thirdPlaceRoundSize + Math.max(upperBracketSize, lowerBracketSize);
1869
+ }
1870
+ default: {
1871
+ // the total columns are the amount of rounds excluding third place
1872
+ return bracketData.rounds.size - thirdPlaceRoundSize;
1873
+ }
1874
+ }
1875
+ };
1876
+ const generateRowCount = (bracketData, roundTypeMap, options) => {
1877
+ switch (bracketData.mode) {
1878
+ case TOURNAMENT_MODE.DOUBLE_ELIMINATION: {
1879
+ const upperBracketSize = roundTypeMap.get(DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.UPPER_BRACKET)?.values().next()
1880
+ .value?.matchCount;
1881
+ const lowerBracketSize = roundTypeMap.get(DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.LOWER_BRACKET)?.values().next()
1882
+ .value?.matchCount;
1883
+ const roundHeadersCount = options.includeRoundHeaders ? 2 : 0;
1884
+ if (upperBracketSize === undefined || lowerBracketSize === undefined) {
1885
+ throw new Error('Upper or lower bracket size is undefined');
1886
+ }
1887
+ // the total rows the amount of matches in the first upper bracket round + first lower bracket round + if true, the round header row for both
1888
+ return upperBracketSize + lowerBracketSize + roundHeadersCount;
1889
+ }
1890
+ default: {
1891
+ const firstRoundSize = bracketData.rounds.values().next().value?.matchCount;
1892
+ const roundHeadersCount = options.includeRoundHeaders ? 1 : 0;
1893
+ if (firstRoundSize === undefined) {
1894
+ throw new Error('First round size is undefined');
1895
+ }
1896
+ // the total rows are the amount of matches in the first round + if true, the round header row
1897
+ return firstRoundSize + roundHeadersCount;
1898
+ }
1899
+ }
1900
+ };
1901
+ const generateBracketGridDefinitions = (bracketData, roundTypeMap, options) => {
1902
+ const columnCount = generateColumnCount(bracketData, roundTypeMap);
1903
+ const rowCount = generateRowCount(bracketData, roundTypeMap, options);
1904
+ return { columnCount, rowCount };
1905
+ };
1906
+
1907
+ class NewBracketDefaultMatchComponent {
1908
+ constructor() {
1909
+ this.bracketRound = input.required();
1910
+ this.bracketMatch = input.required();
1911
+ }
1912
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: NewBracketDefaultMatchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1913
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.11", type: NewBracketDefaultMatchComponent, isStandalone: true, selector: "et-new-bracket-default-match", inputs: { bracketRound: { classPropertyName: "bracketRound", publicName: "bracketRound", isSignal: true, isRequired: true, transformFunction: null }, bracketMatch: { classPropertyName: "bracketMatch", publicName: "bracketMatch", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "et-new-bracket-default-match-host" }, ngImport: i0, template: ` {{ bracketMatch().id }} `, isInline: true, styles: [".et-new-bracket-default-match-host{display:block;padding:8px;border:1px solid yellow;inline-size:250px;block-size:75px;display:flex;justify-content:center;align-items:center;box-sizing:border-box;font-size:12px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1914
+ }
1915
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: NewBracketDefaultMatchComponent, decorators: [{
1916
+ type: Component,
1917
+ args: [{ selector: 'et-new-bracket-default-match', template: ` {{ bracketMatch().id }} `, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
1918
+ class: 'et-new-bracket-default-match-host',
1919
+ }, styles: [".et-new-bracket-default-match-host{display:block;padding:8px;border:1px solid yellow;inline-size:250px;block-size:75px;display:flex;justify-content:center;align-items:center;box-sizing:border-box;font-size:12px}\n"] }]
1920
+ }] });
1921
+
1922
+ class NewBracketDefaultRoundHeaderComponent {
1923
+ constructor() {
1924
+ this.bracketRound = input.required();
1925
+ }
1926
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: NewBracketDefaultRoundHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1927
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.11", type: NewBracketDefaultRoundHeaderComponent, isStandalone: true, selector: "et-new-bracket-default-round-header", inputs: { bracketRound: { classPropertyName: "bracketRound", publicName: "bracketRound", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "et-new-bracket-default-round-header-host" }, ngImport: i0, template: ` {{ bracketRound().name }} `, isInline: true, styles: [".et-new-bracket-default-round-header-host{display:block;padding:8px;border:1px solid green;inline-size:250px;block-size:50px;display:flex;justify-content:center;align-items:center;box-sizing:border-box}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1928
+ }
1929
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: NewBracketDefaultRoundHeaderComponent, decorators: [{
1930
+ type: Component,
1931
+ args: [{ selector: 'et-new-bracket-default-round-header', template: ` {{ bracketRound().name }} `, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
1932
+ class: 'et-new-bracket-default-round-header-host',
1933
+ }, styles: [".et-new-bracket-default-round-header-host{display:block;padding:8px;border:1px solid green;inline-size:250px;block-size:50px;display:flex;justify-content:center;align-items:center;box-sizing:border-box}\n"] }]
1934
+ }] });
1935
+
1936
+ const generateBracketGridItems = (bracketData, roundTypeMap, swissGroups, roundRelations, matchRelations, options) => {
1937
+ const roundHeaderComponent = options.headerComponent ?? NewBracketDefaultRoundHeaderComponent;
1938
+ const matchComponent = options.matchComponent ?? NewBracketDefaultMatchComponent;
1939
+ const optionsWithDefaults = {
1940
+ ...options,
1941
+ headerComponent: roundHeaderComponent,
1942
+ matchComponent: matchComponent,
1943
+ };
1944
+ switch (bracketData.mode) {
1945
+ case TOURNAMENT_MODE.DOUBLE_ELIMINATION:
1946
+ return generateDoubleEliminationGridPlacements(bracketData, roundTypeMap, roundRelations, matchRelations, optionsWithDefaults);
1947
+ case TOURNAMENT_MODE.SWISS_WITH_ELIMINATION: {
1948
+ if (!swissGroups)
1949
+ throw new Error('Swiss groups are required for swiss with elimination mode');
1950
+ return generateSwissWithEliminationGridPlacements(bracketData, roundTypeMap, swissGroups, roundRelations, matchRelations, optionsWithDefaults);
1951
+ }
1952
+ default:
1953
+ return generateGenericGridPlacements(bracketData, roundTypeMap, roundRelations, matchRelations, optionsWithDefaults);
1954
+ }
1955
+ };
1956
+ const generateGenericGridPlacements = (bracketData, roundTypeMap, roundRelations, matchRelations, options) => {
1957
+ const gridItems = new Map();
1958
+ const firstRound = bracketData.rounds.values().next().value;
1959
+ if (!firstRound) {
1960
+ throw new Error('First round is missing');
1961
+ }
1962
+ for (const round of bracketData.rounds.values()) {
1963
+ const roundRelation = roundRelations.get(round.id);
1964
+ let currentMatchRow = 1;
1965
+ const columnStart = round.index + 1;
1966
+ const columnEnd = columnStart + 1;
1967
+ if (!roundRelation) {
1968
+ throw new Error('Round relation is missing');
1969
+ }
1970
+ if (roundRelation.type === 'two-to-nothing' || roundRelation.type === 'two-to-one') {
1971
+ throw new Error(`Invalid relation type ${roundRelation.type}`);
1972
+ }
1973
+ const roundItem = {
1974
+ id: round.id,
1975
+ columnStart,
1976
+ columnEnd,
1977
+ roundRelation,
1978
+ items: new Map(),
1979
+ };
1980
+ if (options.includeRoundHeaders) {
1981
+ const roundHeaderItem = {
1982
+ type: 'round',
1983
+ id: round.id,
1984
+ rowStart: currentMatchRow,
1985
+ rowEnd: ++currentMatchRow,
1986
+ component: options.headerComponent,
1987
+ roundRelation,
1988
+ data: {
1989
+ bracketRound: round,
1990
+ },
1991
+ };
1992
+ roundItem.items.set(round.id, roundHeaderItem);
1993
+ }
1994
+ const rootRoundMatchFactor = roundRelation.type !== 'nothing-to-one' ? roundRelation.rootRoundMatchFactor : null;
1995
+ const matchHeight = rootRoundMatchFactor ? rootRoundMatchFactor : 1;
1996
+ for (const match of round.matches.values()) {
1997
+ const matchRelation = matchRelations.get(match.id);
1998
+ if (!matchRelation) {
1999
+ throw new Error('Match relation is missing');
2000
+ }
2001
+ const baseRow = match.indexInRound * matchHeight;
2002
+ const matchItem = {
2003
+ type: 'match',
2004
+ id: match.id,
2005
+ rowStart: baseRow + currentMatchRow,
2006
+ rowEnd: baseRow + currentMatchRow + matchHeight,
2007
+ component: options.matchComponent,
2008
+ matchRelation,
2009
+ roundRelation,
2010
+ data: {
2011
+ bracketRound: round,
2012
+ bracketMatch: match,
2013
+ },
2014
+ };
2015
+ roundItem.items.set(match.id, matchItem);
2016
+ }
2017
+ gridItems.set(round.id, roundItem);
2018
+ }
2019
+ return gridItems;
2020
+ };
2021
+ const generateDoubleEliminationGridPlacements = (bracketData, roundTypeMap, roundRelations, matchRelations, options) => {
2022
+ const gridItems = new Map();
2023
+ return gridItems;
2024
+ };
2025
+ const generateSwissWithEliminationGridPlacements = (bracketData, roundTypeMap, swissGroups, roundRelations, matchRelations, options) => {
2026
+ const gridItems = new Map();
2027
+ return gridItems;
2028
+ };
2029
+
2030
+ class NewBracketComponent {
2031
+ constructor() {
2032
+ this.#domSanitizer = inject(DomSanitizer);
2033
+ this.bracketData = input.required();
2034
+ this.columnWidth = input(250, { transform: numberAttribute });
2035
+ this.matchHeight = input(75, { transform: numberAttribute });
2036
+ this.roundHeaderHeight = input(50, { transform: numberAttribute });
2037
+ this.columnGap = input(60, { transform: numberAttribute });
2038
+ this.rowGap = input(30, { transform: numberAttribute });
2039
+ this.hideRoundHeaders = input(false, { transform: booleanAttribute });
2040
+ this.roundHeaderComponent = input();
2041
+ this.matchComponent = input();
2042
+ this.roundTypeMap = computed(() => generateBracketRoundTypeMap(this.bracketData()));
2043
+ this.matchParticipantMap = computed(() => generateMatchParticipantMap(this.bracketData()));
2044
+ this.matchPositionsMap = computed(() => generateMatchPositionMaps(this.bracketData()));
2045
+ this.roundRelations = computed(() => generateRoundRelations(this.bracketData()));
2046
+ this.matchRelations = computed(() => generateMatchRelations(this.bracketData(), this.roundRelations(), this.matchPositionsMap()));
2047
+ this.swissGroups = computed(() => generateBracketRoundSwissGroupMaps(this.bracketData(), this.matchParticipantMap()));
2048
+ this.items = computed(() => generateBracketGridItems(this.bracketData(), this.roundTypeMap(), this.swissGroups(), this.roundRelations(), this.matchRelations(), {
2049
+ includeRoundHeaders: !this.hideRoundHeaders(),
2050
+ headerComponent: this.roundHeaderComponent(),
2051
+ matchComponent: this.matchComponent(),
2052
+ }));
2053
+ this.definitions = computed(() => generateBracketGridDefinitions(this.bracketData(), this.roundTypeMap(), {
2054
+ includeRoundHeaders: !this.hideRoundHeaders(),
2055
+ }));
2056
+ this.drawManData = computed(() => this.#domSanitizer.bypassSecurityTrustHtml(drawMan(this.items(), this.roundRelations(), {
2057
+ columnGap: this.columnGap(),
2058
+ columnWidth: this.columnWidth(),
2059
+ matchHeight: this.matchHeight(),
2060
+ roundHeaderHeight: this.hideRoundHeaders() ? 0 : this.roundHeaderHeight(),
2061
+ rowGap: this.rowGap(),
2062
+ gridDefinitions: this.definitions(),
2063
+ })));
2064
+ }
2065
+ #domSanitizer;
2066
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: NewBracketComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2067
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.11", type: NewBracketComponent, isStandalone: true, selector: "et-new-bracket", inputs: { bracketData: { classPropertyName: "bracketData", publicName: "bracketData", isSignal: true, isRequired: true, transformFunction: null }, columnWidth: { classPropertyName: "columnWidth", publicName: "columnWidth", isSignal: true, isRequired: false, transformFunction: null }, matchHeight: { classPropertyName: "matchHeight", publicName: "matchHeight", isSignal: true, isRequired: false, transformFunction: null }, roundHeaderHeight: { classPropertyName: "roundHeaderHeight", publicName: "roundHeaderHeight", isSignal: true, isRequired: false, transformFunction: null }, columnGap: { classPropertyName: "columnGap", publicName: "columnGap", isSignal: true, isRequired: false, transformFunction: null }, rowGap: { classPropertyName: "rowGap", publicName: "rowGap", isSignal: true, isRequired: false, transformFunction: null }, hideRoundHeaders: { classPropertyName: "hideRoundHeaders", publicName: "hideRoundHeaders", isSignal: true, isRequired: false, transformFunction: null }, roundHeaderComponent: { classPropertyName: "roundHeaderComponent", publicName: "roundHeaderComponent", isSignal: true, isRequired: false, transformFunction: null }, matchComponent: { classPropertyName: "matchComponent", publicName: "matchComponent", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "et-new-bracket-host" }, ngImport: i0, template: "<section\n [style.--_cw.px]=\"columnWidth()\"\n [style.--_mh.px]=\"matchHeight()\"\n [style.--_rhh.px]=\"roundHeaderHeight()\"\n [style.--_cg.px]=\"columnGap()\"\n [style.--_rg.px]=\"rowGap()\"\n [style.--_bcc]=\"definitions().columnCount\"\n [style.--_brc]=\"definitions().rowCount\"\n class=\"et-bracket-new\"\n>\n <svg [innerHTML]=\"drawManData()\" class=\"et-bracket-new-svg\" xmlns=\"http://www.w3.org/2000/svg\" />\n\n @for (round of items().values(); track round.id) {\n <ul [style.--_c]=\"round.columnStart + ' / ' + round.columnEnd\" class=\"et-bracket-new-round\">\n @for (item of round.items.values(); track item.id) {\n <li [style.--_r]=\"item.rowStart + ' / ' + item.rowEnd\" class=\"et-bracket-new-item\">\n <ng-container *ngComponentOutlet=\"item.component; inputs: item.data\" />\n </li>\n }\n </ul>\n }\n</section>\n", styles: [".et-bracket-new{display:grid;gap:var(--_cg);grid-auto-columns:var(--_cw)}.et-bracket-new-round{display:grid;grid-column:var(--_c);grid-row:1;list-style:none;margin:0;padding:0;gap:var(--_rg);grid-template-rows:var(--_rhh);grid-auto-rows:var(--_mh)}.et-bracket-new-item{grid-row:var(--_r);place-self:center}.et-bracket-new-svg{grid-column:1/calc(var(--_bcc) + 1);grid-row:1/2;inline-size:100%;block-size:100%}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2068
+ }
2069
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: NewBracketComponent, decorators: [{
2070
+ type: Component,
2071
+ args: [{ selector: 'et-new-bracket', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
2072
+ class: 'et-new-bracket-host',
2073
+ }, imports: [NgComponentOutlet], template: "<section\n [style.--_cw.px]=\"columnWidth()\"\n [style.--_mh.px]=\"matchHeight()\"\n [style.--_rhh.px]=\"roundHeaderHeight()\"\n [style.--_cg.px]=\"columnGap()\"\n [style.--_rg.px]=\"rowGap()\"\n [style.--_bcc]=\"definitions().columnCount\"\n [style.--_brc]=\"definitions().rowCount\"\n class=\"et-bracket-new\"\n>\n <svg [innerHTML]=\"drawManData()\" class=\"et-bracket-new-svg\" xmlns=\"http://www.w3.org/2000/svg\" />\n\n @for (round of items().values(); track round.id) {\n <ul [style.--_c]=\"round.columnStart + ' / ' + round.columnEnd\" class=\"et-bracket-new-round\">\n @for (item of round.items.values(); track item.id) {\n <li [style.--_r]=\"item.rowStart + ' / ' + item.rowEnd\" class=\"et-bracket-new-item\">\n <ng-container *ngComponentOutlet=\"item.component; inputs: item.data\" />\n </li>\n }\n </ul>\n }\n</section>\n", styles: [".et-bracket-new{display:grid;gap:var(--_cg);grid-auto-columns:var(--_cw)}.et-bracket-new-round{display:grid;grid-column:var(--_c);grid-row:1;list-style:none;margin:0;padding:0;gap:var(--_rg);grid-template-rows:var(--_rhh);grid-auto-rows:var(--_mh)}.et-bracket-new-item{grid-row:var(--_r);place-self:center}.et-bracket-new-svg{grid-column:1/calc(var(--_bcc) + 1);grid-row:1/2;inline-size:100%;block-size:100%}\n"] }]
2074
+ }] });
2075
+
2076
+ var index = /*#__PURE__*/Object.freeze({
2077
+ __proto__: null,
2078
+ COMMON_BRACKET_ROUND_TYPE: COMMON_BRACKET_ROUND_TYPE,
2079
+ DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE: DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE,
2080
+ FALLBACK_MATCH_POSITION: FALLBACK_MATCH_POSITION,
2081
+ GROUP_BRACKET_ROUND_TYPE: GROUP_BRACKET_ROUND_TYPE,
2082
+ NewBracketComponent: NewBracketComponent,
2083
+ NewBracketDefaultMatchComponent: NewBracketDefaultMatchComponent,
2084
+ NewBracketDefaultRoundHeaderComponent: NewBracketDefaultRoundHeaderComponent,
2085
+ SINGLE_ELIMINATION_BRACKET_ROUND_TYPE: SINGLE_ELIMINATION_BRACKET_ROUND_TYPE,
2086
+ SWISS_BRACKET_ROUND_TYPE: SWISS_BRACKET_ROUND_TYPE,
2087
+ TOURNAMENT_MODE: TOURNAMENT_MODE,
2088
+ drawMan: drawMan,
2089
+ generateBracketDataForEthlete: generateBracketDataForEthlete,
2090
+ generateBracketGridDefinitions: generateBracketGridDefinitions,
2091
+ generateBracketGridItems: generateBracketGridItems,
2092
+ generateBracketRoundSwissGroupMaps: generateBracketRoundSwissGroupMaps,
2093
+ generateBracketRoundTypeMap: generateBracketRoundTypeMap,
2094
+ generateMatchParticipantMap: generateMatchParticipantMap,
2095
+ generateMatchPosition: generateMatchPosition,
2096
+ generateMatchPositionMaps: generateMatchPositionMaps,
2097
+ generateMatchRelationPositions: generateMatchRelationPositions,
2098
+ generateMatchRelations: generateMatchRelations,
2099
+ generateRoundRelations: generateRoundRelations,
2100
+ generateRoundTypeFromEthleteRoundType: generateRoundTypeFromEthleteRoundType,
2101
+ generateTournamentModeFormEthleteRounds: generateTournamentModeFormEthleteRounds,
2102
+ getAvailableSwissGroupsForRound: getAvailableSwissGroupsForRound,
2103
+ logRoundRelations: logRoundRelations
2104
+ });
2105
+
1013
2106
  class ButtonDirective {
1014
2107
  constructor() {
1015
2108
  this.isButton = inject(ElementRef).nativeElement.tagName === 'BUTTON';
@@ -18081,5 +19174,5 @@ const FLOATING_UI_PLACEMENTS = [
18081
19174
  * Generated bundle index. Do not edit.
18082
19175
  */
18083
19176
 
18084
- export { ACCORDION_COMPONENT, ACCORDION_HINT_WRAPPER_DIRECTIVE, ACCORDION_LABEL_WRAPPER_DIRECTIVE, AccordionComponent, AccordionGroupComponent, AccordionHintDirective, AccordionHintWrapperDirective, AccordionImports, AccordionLabelDirective, AccordionLabelWrapperDirective, ActiveTabUnderlineBarManager, ActiveTabUnderlineDirective, AutosizeTextareaDirective, BOTTOM_SHEET_CONFIG, BOTTOM_SHEET_DATA, BOTTOM_SHEET_DEFAULT_CONFIG, BOTTOM_SHEET_DEFAULT_OPTIONS, BOTTOM_SHEET_MIN_SWIPE_TO_CLOSE_LENGTH, BOTTOM_SHEET_MIN_VELOCITY_TO_CLOSE, BOTTOM_SHEET_SCROLL_STRATEGY, BOTTOM_SHEET_SCROLL_STRATEGY_PROVIDER, BOTTOM_SHEET_SCROLL_STRATEGY_PROVIDER_FACTORY, BRACKET_CONFIG_TOKEN, BRACKET_DEFAULT_CONFIG, BRACKET_MATCH_ID_TOKEN, BRACKET_ROUND_ID_TOKEN, BRACKET_TOKEN, BottomSheetContainerBaseComponent, BottomSheetContainerComponent, BottomSheetDragHandleComponent, BottomSheetImports, BottomSheetRef, BottomSheetService, BottomSheetServiceBase, BottomSheetSwipeHandlerService, BottomSheetTitleDirective, Bracket, BracketComponent, BracketImports, BracketMatchComponent, BracketMatchDirective, BracketRoundDirective, BracketRoundHeaderComponent, ButtonComponent, ButtonDirective, ButtonImports, CAROUSEL_ITEM_NAV_TOKEN, CAROUSEL_ITEM_TOKEN, CAROUSEL_NEXT_BUTTON_TOKEN, CAROUSEL_PREVIOUS_BUTTON_TOKEN, CAROUSEL_TOGGLE_AUTO_PLAY_BUTTON_TOKEN, CAROUSEL_TOKEN, CDK_MENU, CHECKBOX_FIELD_TOKEN, CHECKBOX_GROUP_CONTROL_TOKEN, CHECKBOX_GROUP_TOKEN, CHECKBOX_TOKEN, COLOR_INPUT_TOKEN, COMBOBOX_BODY_EMPTY_TEMPLATE_TOKEN, COMBOBOX_BODY_ERROR_TEMPLATE_TOKEN, COMBOBOX_BODY_LOADING_TEMPLATE_TOKEN, COMBOBOX_BODY_MORE_ITEMS_HINT_TEMPLATE_TOKEN, COMBOBOX_BODY_TOKEN, COMBOBOX_CONFIG_TOKEN, COMBOBOX_DEFAULT_CONFIG, COMBOBOX_OPTION_TEMPLATE_TOKEN, COMBOBOX_OPTION_TOKEN, COMBOBOX_SELECTED_OPTION_TEMPLATE_TOKEN, COMBOBOX_TOKEN, CarouselComponent, CarouselDirective, CarouselImports, CarouselItemComponent, CarouselItemDirective, CarouselItemNavComponent, CarouselItemNavDirective, CarouselNextButtonDirective, CarouselPreviousButtonDirective, CarouselToggleAutoPlayButtonDirective, CdkContextMenuTrigger, CdkMenu, CdkMenuBar, CdkMenuBase, CdkMenuGroup, CdkMenuItem, CdkMenuItemCheckbox, CdkMenuItemRadio, CdkMenuItemSelectable, CdkMenuModule, CdkMenuTrigger, CdkMenuTriggerBase, CdkTargetMenuAim, CellDefDirective, CellDirective, CheckboxComponent, CheckboxDirective, CheckboxFieldComponent, CheckboxFieldDirective, CheckboxGroupComponent, CheckboxGroupControlDirective, CheckboxGroupDirective, CheckboxImports, ChevronIconComponent, ColorInputComponent, ColorInputDirective, ColumnDefDirective, ComboboxBodyComponent, ComboboxBodyEmptyTemplateDirective, ComboboxBodyErrorTemplateDirective, ComboboxBodyLoadingTemplateDirective, ComboboxBodyMoreItemsHintTemplateDirective, ComboboxComponent, ComboboxDirective, ComboboxImports, ComboboxOptionComponent, ComboboxOptionTemplateDirective, ComboboxSelectedOptionTemplateDirective, ContextMenuTracker, DATE_INPUT_FORMAT_TOKEN, DATE_INPUT_TOKEN, DATE_TIME_INPUT_FORMAT_TOKEN, DATE_TIME_INPUT_TOKEN, DEFAULT_DATE_INPUT_FORMAT, DEFAULT_DATE_TIME_INPUT_FORMAT, DEFAULT_TIME_INPUT_FORMAT, DIALOG_CONFIG, DIALOG_DATA, DIALOG_DEFAULT_CONFIG, DIALOG_DEFAULT_OPTIONS, DIALOG_SCROLL_STRATEGY, DIALOG_SCROLL_STRATEGY_PROVIDER, DIALOG_SCROLL_STRATEGY_PROVIDER_FACTORY, DYNAMIC_FORM_FIELD_TOKEN, DYNAMIC_FORM_GROUP_TOKEN, DateInputComponent, DateInputDirective, DateTimeInputComponent, DateTimeInputDirective, DecoratedFormFieldBase, DecoratedInputBase, DefaultValidatorErrorsService, DialogCloseDirective, DialogContainerBaseComponent, DialogContainerComponent, DialogImports, DialogRef, DialogService, DialogServiceBase, DialogTitleDirective, DynamicFormFieldDirective, DynamicFormGroupDirective, DynamicOverlayService, DynamicOverlayTitleDirective, EMAIL_INPUT_TOKEN, ET_OVERLAY_BOTTOM_SHEET_CLASS, ET_OVERLAY_CONFIG_CLASS_KEYS, ET_OVERLAY_DIALOG_CLASS, ET_OVERLAY_FULL_SCREEN_DIALOG_CLASS, ET_OVERLAY_LAYOUT_CLASSES, ET_OVERLAY_LEFT_SHEET_CLASS, ET_OVERLAY_RIGHT_SHEET_CLASS, ET_OVERLAY_TOP_SHEET_CLASS, EXPOSE_INPUT_VARS_TOKEN, EmailInputComponent, EmailInputDirective, ErrorComponent, ExposeInputVarsDirective, FILTER_OVERLAY_CONFIG, FLOATING_UI_PLACEMENTS, FilterOverlayService, FooterCellDefDirective, FooterCellDirective, FooterRowComponent, FooterRowDefDirective, FormFieldStateService, FormGroupStateService, HeaderCellDefDirective, HeaderCellDirective, HeaderRowComponent, HeaderRowDefDirective, IMAGE_CONFIG_TOKEN, INPUT_PREFIX_TOKEN, INPUT_SUFFIX_TOKEN, INPUT_TOKEN, IconImports, IfInputEmptyDirective, IfInputFilledDirective, IfSupportsShowPickerDirective, InlineTabBodyComponent, InlineTabBodyHostDirective, InlineTabChangeEvent, InlineTabComponent, InlineTabContentDirective, InlineTabHeaderComponent, InlineTabLabelDirective, InlineTabLabelWrapperDirective, InlineTabsComponent, InputBase, InputDirective, InputFieldComponent, InputImports, InputPrefixDirective, InputStateService, InputSuffixDirective, LABEL_TOKEN, LabelComponent, LabelImports, LabelSuffixDirective, MASONRY_ITEM_TOKEN, MAX_SAFE_INTEGER, MENU, MENU_AIM, MENU_CHECKBOX_GROUP_TOKEN, MENU_CONTAINER, MENU_GROUP_TITLE_TOKEN, MENU_GROUP_TOKEN, MENU_ITEM_TOKEN, MENU_RADIO_GROUP_TOKEN, MENU_SEARCH_TEMPLATE_TOKEN, MENU_STACK, MENU_TEMPLATE, MENU_TRIGGER, MENU_TRIGGER_TOKEN, MasonryComponent, MasonryImports, MasonryItemComponent, MenuCheckboxGroupDirective, MenuCheckboxItemComponent, MenuComponent, MenuContainerComponent, MenuGroupDirective, MenuGroupTitleDirective, MenuImports, MenuItemDirective, MenuRadioGroupDirective, MenuRadioItemComponent, MenuSearchTemplateDirective, MenuStack, MenuTriggerDirective, NATIVE_INPUT_REF_TOKEN, NATIVE_SELECT_INPUT_TOKEN, NATIVE_SELECT_OPTION_TOKEN, NUMBER_INPUT_TOKEN, NativeInputRefDirective, NativeSelectImports, NativeSelectInputComponent, NativeSelectInputDirective, NativeSelectOptionComponent, NativeSelectOptionDirective, NavTabLinkComponent, NavTabsComponent, NavTabsOutletComponent, NoDataRowDirective, NumberInputComponent, NumberInputDirective, OVERLAY_BACK_OR_CLOSE_TOKEN, OVERLAY_BODY_TOKEN, OVERLAY_CLOSE_BLOCKER_TOKEN, OVERLAY_CONFIG, OVERLAY_DATA, OVERLAY_DEFAULT_CONFIG, OVERLAY_DEFAULT_OPTIONS, OVERLAY_FOOTER_TOKEN, OVERLAY_HEADER_TEMPLATE_TOKEN, OVERLAY_HEADER_TOKEN, OVERLAY_MAIN_TOKEN, OVERLAY_QUERY_PARAM_INPUT_NAME, OVERLAY_ROUTER_CONFIG_TOKEN, OVERLAY_ROUTER_LINK_TOKEN, OVERLAY_ROUTER_OUTLET_DISABLED_TEMPLATE_TOKEN, OVERLAY_ROUTER_OUTLET_TOKEN, OVERLAY_SCROLL_STRATEGY, OVERLAY_SHARED_ROUTE_TEMPLATE_TOKEN, OVERLAY_STATE, OverlayBackOrCloseDirective, OverlayBodyComponent, OverlayCloseBlockerDirective, OverlayCloseDirective, OverlayContainerComponent, OverlayFooterDirective, OverlayHandlerLinkDirective, OverlayHeaderDirective, OverlayHeaderTemplateDirective, OverlayImports, OverlayMainDirective, OverlayPositionBuilder, OverlayRef, OverlayRouteHeaderTemplateOutletComponent, OverlayRouterLinkDirective, OverlayRouterOutletComponent, OverlayRouterOutletDisabledTemplateDirective, OverlayRouterService, OverlayService, OverlaySharedRouteTemplateDirective, OverlaySharedRouteTemplateOutletComponent, OverlaySidebarComponent, OverlaySidebarPageComponent, OverlayTitleDirective, OverlayWithRoutingImports, OverlayWithSidebarImports, PARENT_OR_NEW_INLINE_MENU_STACK_PROVIDER, PARENT_OR_NEW_MENU_STACK_PROVIDER, PASSWORD_INPUT_TOKEN, PROGRESS_SPINNER_DEFAULT_OPTIONS, PROGRESS_SPINNER_DEFAULT_OPTIONS_FACTORY, PaginatedTabHeaderDirective, PaginationComponent, PaginationHeadService, PaginationImports, PaginationLinkDirective, PasswordInputComponent, PasswordInputDirective, PasswordInputToggleComponent, PictureComponent, PointerFocusTracker, ProgressSpinnerComponent, QUERY_ERROR_TOKEN, QueryButtonComponent, QueryButtonDirective, QueryErrorComponent, QueryErrorDirective, RADIO_FIELD_TOKEN, RADIO_GROUP_TOKEN, RADIO_TOKEN, RICH_FILTER_BUTTON_SLOT_TOKEN, RICH_FILTER_BUTTON_TOKEN, RICH_FILTER_CONTENT_TOKEN, RICH_FILTER_TOP_TOKEN, RadioComponent, RadioDirective, RadioFieldComponent, RadioFieldDirective, RadioGroupComponent, RadioGroupDirective, RadioImports, RecycleRowsDirective, RichFilterButtonDirective, RichFilterButtonSlotDirective, RichFilterContentDirective, RichFilterHostComponent, RichFilterImports, RichFilterTopDirective, RowComponent, RowDefDirective, SCROLLABLE_IGNORE_CHILD_ATTRIBUTE, SCROLLABLE_IGNORE_CHILD_TOKEN, SCROLLABLE_IS_ACTIVE_CHILD_ATTRIBUTE, SCROLLABLE_IS_ACTIVE_CHILD_TOKEN, SCROLLABLE_LOADING_TEMPLATE_TOKEN, SCROLLABLE_PLACEHOLDER_ITEM_TEMPLATE_TOKEN, SCROLLABLE_PLACEHOLDER_OVERLAY_TEMPLATE_TOKEN, SEARCH_INPUT_TOKEN, SEGMENTED_BUTTON_FIELD_TOKEN, SEGMENTED_BUTTON_GROUP_TOKEN, SEGMENTED_BUTTON_TOKEN, SELECTION_LIST_FIELD, SELECTION_LIST_OPTION, SELECT_BODY_TOKEN, SELECT_FIELD_TOKEN, SELECT_OPTION_TOKEN, SELECT_TOKEN, SHOW_PICKER_TRIGGER_TOKEN, SIDEBAR_OVERLAY_CONFIG, SLIDE_TOGGLE_TOKEN, SORT_DEFAULT_OPTIONS, SORT_HEADER_COLUMN_DEF, SORT_HEADER_INTL_PROVIDER, SORT_HEADER_INTL_PROVIDER_FACTORY, STATIC_FORM_FIELD_TOKEN, STATIC_FORM_GROUP_TOKEN, ScrollableComponent, ScrollableIgnoreChildDirective, ScrollableImports, ScrollableIsActiveChildDirective, ScrollableLoadingTemplateDirective, ScrollablePlaceholderComponent, ScrollablePlaceholderItemTemplateDirective, ScrollablePlaceholderOverlayTemplateDirective, SearchInputClearComponent, SearchInputComponent, SearchInputDirective, SegmentedButtonComponent, SegmentedButtonDirective, SegmentedButtonFieldComponent, SegmentedButtonFieldDirective, SegmentedButtonGroupComponent, SegmentedButtonGroupDirective, SegmentedButtonImports, SelectBodyComponent, SelectBodyDirective, SelectComponent, SelectDirective, SelectFieldComponent, SelectFieldDirective, SelectImports, SelectOptionComponent, SelectOptionDirective, SelectionListFieldComponent, SelectionListFieldDirective, SelectionListImports, SelectionListOptionComponent, SelectionListOptionDirective, ShowPickerTriggerDirective, SidebarOverlayService, SkeletonComponent, SkeletonImports, SkeletonItemComponent, SlideToggleComponent, SlideToggleDirective, SlideToggleFieldComponent, SlideToggleImports, SliderComponent, SliderFieldComponent, SliderImports, SortDirective, SortHeaderComponent, SortHeaderIntl, SortImports, StaticFormFieldDirective, StaticFormGroupDirective, SwipeHandlerService, TAB, TABS_CONFIG, TAB_CONTENT, TAB_GROUP, TAB_LABEL, TEL_INPUT_TOKEN, TEXTAREA_INPUT_TOKEN, TEXT_INPUT_TOKEN, TIME_INPUT_FORMAT_TOKEN, TIME_INPUT_TOKEN, TOGGLETIP, TOGGLETIP_CONFIG, TOGGLETIP_DEFAULT_CONFIG, TOGGLETIP_DIRECTIVE, TOGGLETIP_TEMPLATE, TOGGLETIP_TEXT, TOOLTIP, TOOLTIP_CONFIG, TOOLTIP_DEFAULT_CONFIG, TOOLTIP_DIRECTIVE, TOOLTIP_TEMPLATE, TOOLTIP_TEXT, TabImports, TableBusyDirective, TableBusyOutletDirective, TableComponent, TableDataSource, TableImports, TargetMenuAim, TelInputComponent, TelInputDirective, TextColumnComponent, TextInputComponent, TextInputDirective, TextareaInputComponent, TextareaInputDirective, TimeInputComponent, TimeInputDirective, TimesIconComponent, ToggletipCloseDirective, ToggletipComponent, ToggletipDirective, ToggletipImports, TooltipComponent, TooltipDirective, TooltipImports, VALIDATOR_ERROR_SERVICE_TOKEN, WRITEABLE_INPUT_TOKEN, WRITEABLE_INPUT_VALUE_ACCESSOR, WriteableInputDirective, _MAT_INK_BAR_POSITIONER, _MAT_INK_BAR_POSITIONER_FACTORY, accordionAnimations, convertHttpStatusCodeToMessageDe, convertHttpStatusCodeToMessageEn, convertHttpStatusCodeToTitleDe, convertHttpStatusCodeToTitleEn, createBottomSheetConfig, createBracketConfig, createComboboxConfig, createDialogConfig, createFormChangesTracker, createOverlayConfig, createOverlayDismissChecker, createOverlayHandler, createOverlayHandlerWithQueryParamLifecycle, createToggletipConfig, createTooltipConfig, defaultSubmitButtonConfigFn, getClosestBottomSheet, getClosestDialog, getClosestOverlay, isScrollableChildActive, isScrollableChildIgnored, isUpperBracketMatch, normalizePictureSizes, normalizePictureSource, normalizeRoundType, orderRounds, orderRoundsByRoundNumber, paginate, provideBottomSheet, provideBottomSheetDefaultConfig, provideBracketConfig, provideComboboxConfig, provideDateFormat, provideDateTimeFormat, provideDialog, provideDialogDefaultConfig, provideFilterOverlayConfig, provideImageConfig, provideOverlay, provideOverlayDefaultConfig, provideOverlayRouterConfig, provideSidebarOverlayConfig, provideSort, provideTimeFormat, provideToggletipConfig, provideTooltipConfig, provideValidatorErrorsService, tabAnimations };
19177
+ export { ACCORDION_COMPONENT, ACCORDION_HINT_WRAPPER_DIRECTIVE, ACCORDION_LABEL_WRAPPER_DIRECTIVE, AccordionComponent, AccordionGroupComponent, AccordionHintDirective, AccordionHintWrapperDirective, AccordionImports, AccordionLabelDirective, AccordionLabelWrapperDirective, ActiveTabUnderlineBarManager, ActiveTabUnderlineDirective, AutosizeTextareaDirective, BOTTOM_SHEET_CONFIG, BOTTOM_SHEET_DATA, BOTTOM_SHEET_DEFAULT_CONFIG, BOTTOM_SHEET_DEFAULT_OPTIONS, BOTTOM_SHEET_MIN_SWIPE_TO_CLOSE_LENGTH, BOTTOM_SHEET_MIN_VELOCITY_TO_CLOSE, BOTTOM_SHEET_SCROLL_STRATEGY, BOTTOM_SHEET_SCROLL_STRATEGY_PROVIDER, BOTTOM_SHEET_SCROLL_STRATEGY_PROVIDER_FACTORY, BRACKET_CONFIG_TOKEN, BRACKET_DEFAULT_CONFIG, BRACKET_MATCH_ID_TOKEN, BRACKET_ROUND_ID_TOKEN, BRACKET_TOKEN, BottomSheetContainerBaseComponent, BottomSheetContainerComponent, BottomSheetDragHandleComponent, BottomSheetImports, BottomSheetRef, BottomSheetService, BottomSheetServiceBase, BottomSheetSwipeHandlerService, BottomSheetTitleDirective, Bracket, BracketComponent, BracketImports, BracketMatchComponent, BracketMatchDirective, index as BracketNew, BracketRoundDirective, BracketRoundHeaderComponent, ButtonComponent, ButtonDirective, ButtonImports, CAROUSEL_ITEM_NAV_TOKEN, CAROUSEL_ITEM_TOKEN, CAROUSEL_NEXT_BUTTON_TOKEN, CAROUSEL_PREVIOUS_BUTTON_TOKEN, CAROUSEL_TOGGLE_AUTO_PLAY_BUTTON_TOKEN, CAROUSEL_TOKEN, CDK_MENU, CHECKBOX_FIELD_TOKEN, CHECKBOX_GROUP_CONTROL_TOKEN, CHECKBOX_GROUP_TOKEN, CHECKBOX_TOKEN, COLOR_INPUT_TOKEN, COMBOBOX_BODY_EMPTY_TEMPLATE_TOKEN, COMBOBOX_BODY_ERROR_TEMPLATE_TOKEN, COMBOBOX_BODY_LOADING_TEMPLATE_TOKEN, COMBOBOX_BODY_MORE_ITEMS_HINT_TEMPLATE_TOKEN, COMBOBOX_BODY_TOKEN, COMBOBOX_CONFIG_TOKEN, COMBOBOX_DEFAULT_CONFIG, COMBOBOX_OPTION_TEMPLATE_TOKEN, COMBOBOX_OPTION_TOKEN, COMBOBOX_SELECTED_OPTION_TEMPLATE_TOKEN, COMBOBOX_TOKEN, CarouselComponent, CarouselDirective, CarouselImports, CarouselItemComponent, CarouselItemDirective, CarouselItemNavComponent, CarouselItemNavDirective, CarouselNextButtonDirective, CarouselPreviousButtonDirective, CarouselToggleAutoPlayButtonDirective, CdkContextMenuTrigger, CdkMenu, CdkMenuBar, CdkMenuBase, CdkMenuGroup, CdkMenuItem, CdkMenuItemCheckbox, CdkMenuItemRadio, CdkMenuItemSelectable, CdkMenuModule, CdkMenuTrigger, CdkMenuTriggerBase, CdkTargetMenuAim, CellDefDirective, CellDirective, CheckboxComponent, CheckboxDirective, CheckboxFieldComponent, CheckboxFieldDirective, CheckboxGroupComponent, CheckboxGroupControlDirective, CheckboxGroupDirective, CheckboxImports, ChevronIconComponent, ColorInputComponent, ColorInputDirective, ColumnDefDirective, ComboboxBodyComponent, ComboboxBodyEmptyTemplateDirective, ComboboxBodyErrorTemplateDirective, ComboboxBodyLoadingTemplateDirective, ComboboxBodyMoreItemsHintTemplateDirective, ComboboxComponent, ComboboxDirective, ComboboxImports, ComboboxOptionComponent, ComboboxOptionTemplateDirective, ComboboxSelectedOptionTemplateDirective, ContextMenuTracker, DATE_INPUT_FORMAT_TOKEN, DATE_INPUT_TOKEN, DATE_TIME_INPUT_FORMAT_TOKEN, DATE_TIME_INPUT_TOKEN, DEFAULT_DATE_INPUT_FORMAT, DEFAULT_DATE_TIME_INPUT_FORMAT, DEFAULT_TIME_INPUT_FORMAT, DIALOG_CONFIG, DIALOG_DATA, DIALOG_DEFAULT_CONFIG, DIALOG_DEFAULT_OPTIONS, DIALOG_SCROLL_STRATEGY, DIALOG_SCROLL_STRATEGY_PROVIDER, DIALOG_SCROLL_STRATEGY_PROVIDER_FACTORY, DYNAMIC_FORM_FIELD_TOKEN, DYNAMIC_FORM_GROUP_TOKEN, DateInputComponent, DateInputDirective, DateTimeInputComponent, DateTimeInputDirective, DecoratedFormFieldBase, DecoratedInputBase, DefaultValidatorErrorsService, DialogCloseDirective, DialogContainerBaseComponent, DialogContainerComponent, DialogImports, DialogRef, DialogService, DialogServiceBase, DialogTitleDirective, DynamicFormFieldDirective, DynamicFormGroupDirective, DynamicOverlayService, DynamicOverlayTitleDirective, EMAIL_INPUT_TOKEN, ET_OVERLAY_BOTTOM_SHEET_CLASS, ET_OVERLAY_CONFIG_CLASS_KEYS, ET_OVERLAY_DIALOG_CLASS, ET_OVERLAY_FULL_SCREEN_DIALOG_CLASS, ET_OVERLAY_LAYOUT_CLASSES, ET_OVERLAY_LEFT_SHEET_CLASS, ET_OVERLAY_RIGHT_SHEET_CLASS, ET_OVERLAY_TOP_SHEET_CLASS, EXPOSE_INPUT_VARS_TOKEN, EmailInputComponent, EmailInputDirective, ErrorComponent, ExposeInputVarsDirective, FILTER_OVERLAY_CONFIG, FLOATING_UI_PLACEMENTS, FilterOverlayService, FooterCellDefDirective, FooterCellDirective, FooterRowComponent, FooterRowDefDirective, FormFieldStateService, FormGroupStateService, HeaderCellDefDirective, HeaderCellDirective, HeaderRowComponent, HeaderRowDefDirective, IMAGE_CONFIG_TOKEN, INPUT_PREFIX_TOKEN, INPUT_SUFFIX_TOKEN, INPUT_TOKEN, IconImports, IfInputEmptyDirective, IfInputFilledDirective, IfSupportsShowPickerDirective, InlineTabBodyComponent, InlineTabBodyHostDirective, InlineTabChangeEvent, InlineTabComponent, InlineTabContentDirective, InlineTabHeaderComponent, InlineTabLabelDirective, InlineTabLabelWrapperDirective, InlineTabsComponent, InputBase, InputDirective, InputFieldComponent, InputImports, InputPrefixDirective, InputStateService, InputSuffixDirective, LABEL_TOKEN, LabelComponent, LabelImports, LabelSuffixDirective, MASONRY_ITEM_TOKEN, MAX_SAFE_INTEGER, MENU, MENU_AIM, MENU_CHECKBOX_GROUP_TOKEN, MENU_CONTAINER, MENU_GROUP_TITLE_TOKEN, MENU_GROUP_TOKEN, MENU_ITEM_TOKEN, MENU_RADIO_GROUP_TOKEN, MENU_SEARCH_TEMPLATE_TOKEN, MENU_STACK, MENU_TEMPLATE, MENU_TRIGGER, MENU_TRIGGER_TOKEN, MasonryComponent, MasonryImports, MasonryItemComponent, MenuCheckboxGroupDirective, MenuCheckboxItemComponent, MenuComponent, MenuContainerComponent, MenuGroupDirective, MenuGroupTitleDirective, MenuImports, MenuItemDirective, MenuRadioGroupDirective, MenuRadioItemComponent, MenuSearchTemplateDirective, MenuStack, MenuTriggerDirective, NATIVE_INPUT_REF_TOKEN, NATIVE_SELECT_INPUT_TOKEN, NATIVE_SELECT_OPTION_TOKEN, NUMBER_INPUT_TOKEN, NativeInputRefDirective, NativeSelectImports, NativeSelectInputComponent, NativeSelectInputDirective, NativeSelectOptionComponent, NativeSelectOptionDirective, NavTabLinkComponent, NavTabsComponent, NavTabsOutletComponent, NoDataRowDirective, NumberInputComponent, NumberInputDirective, OVERLAY_BACK_OR_CLOSE_TOKEN, OVERLAY_BODY_TOKEN, OVERLAY_CLOSE_BLOCKER_TOKEN, OVERLAY_CONFIG, OVERLAY_DATA, OVERLAY_DEFAULT_CONFIG, OVERLAY_DEFAULT_OPTIONS, OVERLAY_FOOTER_TOKEN, OVERLAY_HEADER_TEMPLATE_TOKEN, OVERLAY_HEADER_TOKEN, OVERLAY_MAIN_TOKEN, OVERLAY_QUERY_PARAM_INPUT_NAME, OVERLAY_ROUTER_CONFIG_TOKEN, OVERLAY_ROUTER_LINK_TOKEN, OVERLAY_ROUTER_OUTLET_DISABLED_TEMPLATE_TOKEN, OVERLAY_ROUTER_OUTLET_TOKEN, OVERLAY_SCROLL_STRATEGY, OVERLAY_SHARED_ROUTE_TEMPLATE_TOKEN, OVERLAY_STATE, OverlayBackOrCloseDirective, OverlayBodyComponent, OverlayCloseBlockerDirective, OverlayCloseDirective, OverlayContainerComponent, OverlayFooterDirective, OverlayHandlerLinkDirective, OverlayHeaderDirective, OverlayHeaderTemplateDirective, OverlayImports, OverlayMainDirective, OverlayPositionBuilder, OverlayRef, OverlayRouteHeaderTemplateOutletComponent, OverlayRouterLinkDirective, OverlayRouterOutletComponent, OverlayRouterOutletDisabledTemplateDirective, OverlayRouterService, OverlayService, OverlaySharedRouteTemplateDirective, OverlaySharedRouteTemplateOutletComponent, OverlaySidebarComponent, OverlaySidebarPageComponent, OverlayTitleDirective, OverlayWithRoutingImports, OverlayWithSidebarImports, PARENT_OR_NEW_INLINE_MENU_STACK_PROVIDER, PARENT_OR_NEW_MENU_STACK_PROVIDER, PASSWORD_INPUT_TOKEN, PROGRESS_SPINNER_DEFAULT_OPTIONS, PROGRESS_SPINNER_DEFAULT_OPTIONS_FACTORY, PaginatedTabHeaderDirective, PaginationComponent, PaginationHeadService, PaginationImports, PaginationLinkDirective, PasswordInputComponent, PasswordInputDirective, PasswordInputToggleComponent, PictureComponent, PointerFocusTracker, ProgressSpinnerComponent, QUERY_ERROR_TOKEN, QueryButtonComponent, QueryButtonDirective, QueryErrorComponent, QueryErrorDirective, RADIO_FIELD_TOKEN, RADIO_GROUP_TOKEN, RADIO_TOKEN, RICH_FILTER_BUTTON_SLOT_TOKEN, RICH_FILTER_BUTTON_TOKEN, RICH_FILTER_CONTENT_TOKEN, RICH_FILTER_TOP_TOKEN, RadioComponent, RadioDirective, RadioFieldComponent, RadioFieldDirective, RadioGroupComponent, RadioGroupDirective, RadioImports, RecycleRowsDirective, RichFilterButtonDirective, RichFilterButtonSlotDirective, RichFilterContentDirective, RichFilterHostComponent, RichFilterImports, RichFilterTopDirective, RowComponent, RowDefDirective, SCROLLABLE_IGNORE_CHILD_ATTRIBUTE, SCROLLABLE_IGNORE_CHILD_TOKEN, SCROLLABLE_IS_ACTIVE_CHILD_ATTRIBUTE, SCROLLABLE_IS_ACTIVE_CHILD_TOKEN, SCROLLABLE_LOADING_TEMPLATE_TOKEN, SCROLLABLE_PLACEHOLDER_ITEM_TEMPLATE_TOKEN, SCROLLABLE_PLACEHOLDER_OVERLAY_TEMPLATE_TOKEN, SEARCH_INPUT_TOKEN, SEGMENTED_BUTTON_FIELD_TOKEN, SEGMENTED_BUTTON_GROUP_TOKEN, SEGMENTED_BUTTON_TOKEN, SELECTION_LIST_FIELD, SELECTION_LIST_OPTION, SELECT_BODY_TOKEN, SELECT_FIELD_TOKEN, SELECT_OPTION_TOKEN, SELECT_TOKEN, SHOW_PICKER_TRIGGER_TOKEN, SIDEBAR_OVERLAY_CONFIG, SLIDE_TOGGLE_TOKEN, SORT_DEFAULT_OPTIONS, SORT_HEADER_COLUMN_DEF, SORT_HEADER_INTL_PROVIDER, SORT_HEADER_INTL_PROVIDER_FACTORY, STATIC_FORM_FIELD_TOKEN, STATIC_FORM_GROUP_TOKEN, ScrollableComponent, ScrollableIgnoreChildDirective, ScrollableImports, ScrollableIsActiveChildDirective, ScrollableLoadingTemplateDirective, ScrollablePlaceholderComponent, ScrollablePlaceholderItemTemplateDirective, ScrollablePlaceholderOverlayTemplateDirective, SearchInputClearComponent, SearchInputComponent, SearchInputDirective, SegmentedButtonComponent, SegmentedButtonDirective, SegmentedButtonFieldComponent, SegmentedButtonFieldDirective, SegmentedButtonGroupComponent, SegmentedButtonGroupDirective, SegmentedButtonImports, SelectBodyComponent, SelectBodyDirective, SelectComponent, SelectDirective, SelectFieldComponent, SelectFieldDirective, SelectImports, SelectOptionComponent, SelectOptionDirective, SelectionListFieldComponent, SelectionListFieldDirective, SelectionListImports, SelectionListOptionComponent, SelectionListOptionDirective, ShowPickerTriggerDirective, SidebarOverlayService, SkeletonComponent, SkeletonImports, SkeletonItemComponent, SlideToggleComponent, SlideToggleDirective, SlideToggleFieldComponent, SlideToggleImports, SliderComponent, SliderFieldComponent, SliderImports, SortDirective, SortHeaderComponent, SortHeaderIntl, SortImports, StaticFormFieldDirective, StaticFormGroupDirective, SwipeHandlerService, TAB, TABS_CONFIG, TAB_CONTENT, TAB_GROUP, TAB_LABEL, TEL_INPUT_TOKEN, TEXTAREA_INPUT_TOKEN, TEXT_INPUT_TOKEN, TIME_INPUT_FORMAT_TOKEN, TIME_INPUT_TOKEN, TOGGLETIP, TOGGLETIP_CONFIG, TOGGLETIP_DEFAULT_CONFIG, TOGGLETIP_DIRECTIVE, TOGGLETIP_TEMPLATE, TOGGLETIP_TEXT, TOOLTIP, TOOLTIP_CONFIG, TOOLTIP_DEFAULT_CONFIG, TOOLTIP_DIRECTIVE, TOOLTIP_TEMPLATE, TOOLTIP_TEXT, TabImports, TableBusyDirective, TableBusyOutletDirective, TableComponent, TableDataSource, TableImports, TargetMenuAim, TelInputComponent, TelInputDirective, TextColumnComponent, TextInputComponent, TextInputDirective, TextareaInputComponent, TextareaInputDirective, TimeInputComponent, TimeInputDirective, TimesIconComponent, ToggletipCloseDirective, ToggletipComponent, ToggletipDirective, ToggletipImports, TooltipComponent, TooltipDirective, TooltipImports, VALIDATOR_ERROR_SERVICE_TOKEN, WRITEABLE_INPUT_TOKEN, WRITEABLE_INPUT_VALUE_ACCESSOR, WriteableInputDirective, _MAT_INK_BAR_POSITIONER, _MAT_INK_BAR_POSITIONER_FACTORY, accordionAnimations, convertHttpStatusCodeToMessageDe, convertHttpStatusCodeToMessageEn, convertHttpStatusCodeToTitleDe, convertHttpStatusCodeToTitleEn, createBottomSheetConfig, createBracketConfig, createComboboxConfig, createDialogConfig, createFormChangesTracker, createOverlayConfig, createOverlayDismissChecker, createOverlayHandler, createOverlayHandlerWithQueryParamLifecycle, createToggletipConfig, createTooltipConfig, defaultSubmitButtonConfigFn, getClosestBottomSheet, getClosestDialog, getClosestOverlay, isScrollableChildActive, isScrollableChildIgnored, isUpperBracketMatch, normalizePictureSizes, normalizePictureSource, normalizeRoundType, orderRounds, orderRoundsByRoundNumber, paginate, provideBottomSheet, provideBottomSheetDefaultConfig, provideBracketConfig, provideComboboxConfig, provideDateFormat, provideDateTimeFormat, provideDialog, provideDialogDefaultConfig, provideFilterOverlayConfig, provideImageConfig, provideOverlay, provideOverlayDefaultConfig, provideOverlayRouterConfig, provideSidebarOverlayConfig, provideSort, provideTimeFormat, provideToggletipConfig, provideTooltipConfig, provideValidatorErrorsService, tabAnimations };
18085
19178
  //# sourceMappingURL=ethlete-cdk.mjs.map