tods-competition-factory 1.8.10 → 1.8.11

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.
package/dist/index.mjs CHANGED
@@ -2375,7 +2375,7 @@ const matchUpFormatCode = {
2375
2375
  };
2376
2376
 
2377
2377
  function factoryVersion() {
2378
- return "1.8.10";
2378
+ return "1.8.11";
2379
2379
  }
2380
2380
 
2381
2381
  function getObjectTieFormat(obj) {
@@ -15075,7 +15075,7 @@ const POLICY_PRIVACY_DEFAULT = {
15075
15075
  const ADULT = "ADULT";
15076
15076
  const JUNIOR = "JUNIOR";
15077
15077
  const WHEELCHAIR = "WHEELCHAIR";
15078
- const POLICY_SCHEDULING_USTA = {
15078
+ const POLICY_SCHEDULING_DEFAULT = {
15079
15079
  [POLICY_TYPE_SCHEDULING]: {
15080
15080
  defaultTimes: {
15081
15081
  averageTimes: [{ categoryNames: [], minutes: { default: 90 } }],
@@ -15422,7 +15422,7 @@ const policies = {
15422
15422
  POLICY_POSITION_ACTIONS_UNRESTRICTED,
15423
15423
  POLICY_PRIVACY_DEFAULT,
15424
15424
  POLICY_ROUND_NAMING_DEFAULT,
15425
- POLICY_SCHEDULING_USTA,
15425
+ POLICY_SCHEDULING_DEFAULT,
15426
15426
  POLICY_SCORING_DEFAULT,
15427
15427
  POLICY_SCORING_USTA,
15428
15428
  POLICY_SEEDING_ITF,
@@ -26925,7 +26925,7 @@ function addStructureParticipation({
26925
26925
 
26926
26926
  function processSides(params) {
26927
26927
  const {
26928
- withScheduleTimes,
26928
+ withScheduleItems,
26929
26929
  scheduleAnalysis,
26930
26930
  withTeamMatchUps,
26931
26931
  participantMap,
@@ -27035,7 +27035,7 @@ function processSides(params) {
27035
27035
  stage
27036
27036
  });
27037
27037
  }
27038
- if (scheduleAnalysis || withScheduleTimes) {
27038
+ if (scheduleAnalysis || withScheduleItems) {
27039
27039
  addScheduleItem({
27040
27040
  participantMap,
27041
27041
  participantId: participantId2,
@@ -27181,6 +27181,7 @@ function getParticipantEntries(params) {
27181
27181
  participantMap,
27182
27182
  withPotentialMatchUps,
27183
27183
  withRankingProfile,
27184
+ withScheduleItems,
27184
27185
  scheduleAnalysis,
27185
27186
  withTeamMatchUps,
27186
27187
  withStatistics,
@@ -27190,7 +27191,6 @@ function getParticipantEntries(params) {
27190
27191
  withEvents,
27191
27192
  withDraws
27192
27193
  } = params;
27193
- const withScheduleTimes = params.withScheduleTimes ?? params.withScheduleItems;
27194
27194
  const targetParticipantIds = participantFilters?.participantIds;
27195
27195
  const getRelevantParticipantIds = (participantId) => {
27196
27196
  const relevantParticipantIds = [participantId];
@@ -27208,7 +27208,7 @@ function getParticipantEntries(params) {
27208
27208
  withDraws: withDraws || withRankingProfile,
27209
27209
  withPotentialMatchUps,
27210
27210
  withRankingProfile,
27211
- withScheduleTimes,
27211
+ withScheduleItems,
27212
27212
  scheduleAnalysis,
27213
27213
  withTeamMatchUps,
27214
27214
  withStatistics,
@@ -27528,7 +27528,7 @@ function getParticipantEntries(params) {
27528
27528
  matchUpType: matchUpType2
27529
27529
  });
27530
27530
  }
27531
- if (Array.isArray(potentialParticipants) && (nextMatchUps || !!scheduleAnalysis || withScheduleTimes)) {
27531
+ if (Array.isArray(potentialParticipants) && (nextMatchUps || !!scheduleAnalysis || withScheduleItems)) {
27532
27532
  const potentialParticipantIds = potentialParticipants.flat().map(extractAttributes("participantId")).filter(Boolean);
27533
27533
  potentialParticipantIds?.forEach((participantId) => {
27534
27534
  const relevantParticipantIds = getRelevantParticipantIds(participantId);
@@ -27543,7 +27543,7 @@ function getParticipantEntries(params) {
27543
27543
  drawId
27544
27544
  });
27545
27545
  });
27546
- if (!!scheduleAnalysis || withScheduleTimes) {
27546
+ if (!!scheduleAnalysis || withScheduleItems) {
27547
27547
  addScheduleItem({
27548
27548
  potential: true,
27549
27549
  participantMap,
@@ -27652,13 +27652,18 @@ function getParticipantEntries(params) {
27652
27652
  const notBeforeTime = typeChange ? typeChangeTimeAfterRecovery || timeAfterRecovery : timeAfterRecovery;
27653
27653
  const sameDraw = scheduleItem.drawId === consideredItem.drawId;
27654
27654
  const bothPotential = potentialMatchUps[scheduleItem.matchUpId] && potentialMatchUps[consideredItem.matchUpId];
27655
- const nextMinutes = timeStringMinutes(consideredItem.scheduledTime);
27656
- const minutesDifference = Math.abs(nextMinutes - scheduledMinutes);
27657
- const timeOverlap = scheduledMinutesDifference && !isNaN(scheduledMinutesDifference) ? minutesDifference <= scheduledMinutesDifference : timeStringMinutes(notBeforeTime) > timeStringMinutes(consideredItem.scheduledTime);
27658
- if (timeOverlap && !(bothPotential && sameDraw)) {
27655
+ const consideredMinutes = timeStringMinutes(
27656
+ consideredItem.scheduledTime
27657
+ );
27658
+ const minutesDifference = Math.abs(
27659
+ consideredMinutes - scheduledMinutes
27660
+ );
27661
+ const itemIsPrior = consideredMinutes > scheduledMinutes;
27662
+ const timeOverlap = scheduledMinutesDifference && !isNaN(scheduledMinutesDifference) ? minutesDifference <= scheduledMinutesDifference : itemIsPrior && timeStringMinutes(consideredItem.scheduledTime) < timeStringMinutes(notBeforeTime);
27663
+ if (timeOverlap && !(bothPotential && sameDraw) && itemIsPrior) {
27659
27664
  participantAggregator.scheduleConflicts.push({
27660
- priorScheduledMatchUpId: consideredItem.matchUpId,
27661
- matchUpIdWithConflict: scheduleItem.matchUpId
27665
+ priorScheduledMatchUpId: scheduleItem.matchUpId,
27666
+ matchUpIdWithConflict: consideredItem.matchUpId
27662
27667
  });
27663
27668
  }
27664
27669
  }
@@ -27874,6 +27879,7 @@ function getParticipants$1(params) {
27874
27879
  ({
27875
27880
  potentialMatchUps,
27876
27881
  scheduleConflicts,
27882
+ scheduleItems,
27877
27883
  participant,
27878
27884
  statistics,
27879
27885
  opponents,
@@ -27899,7 +27905,8 @@ function getParticipants$1(params) {
27899
27905
  matchUps: withMatchUps || withRankingProfile ? Object.values(matchUps2) : void 0,
27900
27906
  opponents: withOpponents ? participantOpponents : void 0,
27901
27907
  potentialMatchUps: nextMatchUps ? Object.values(potentialMatchUps) : void 0,
27902
- statistics: withStatistics ? Object.values(statistics) : void 0
27908
+ statistics: withStatistics ? Object.values(statistics) : void 0,
27909
+ scheduleItems: withScheduleItems ? scheduleItems : void 0
27903
27910
  },
27904
27911
  false,
27905
27912
  false,
@@ -27930,1465 +27937,372 @@ function getParticipants$1(params) {
27930
27937
  };
27931
27938
  }
27932
27939
 
27933
- function getDerivedPositionAssignments({
27934
- derivedDrawInfo,
27940
+ function deepMerge(existing, incoming, arrayMerge) {
27941
+ if (!existing && incoming)
27942
+ return incoming;
27943
+ if (existing && !incoming)
27944
+ return existing;
27945
+ if (typeof existing !== "object" || typeof incoming !== "object")
27946
+ return existing;
27947
+ const keys = unique(Object.keys(existing).concat(Object.keys(incoming)));
27948
+ return keys.reduce((merged, key) => {
27949
+ if (!incoming[key]) {
27950
+ merged[key] = existing[key];
27951
+ } else if (!existing[key]) {
27952
+ merged[key] = incoming[key];
27953
+ } else if (typeof existing[key] !== typeof incoming[key]) {
27954
+ merged[key] = incoming[key];
27955
+ } else if (Array.isArray(existing[key])) {
27956
+ if (arrayMerge === true || Array.isArray(arrayMerge) && arrayMerge.includes(key)) {
27957
+ const mergedArrays = unique(
27958
+ existing[key].map((e) => JSON.stringify(e)).concat(incoming[key].map((i) => JSON.stringify(i)))
27959
+ ).map((u) => JSON.parse(u));
27960
+ merged[key] = mergedArrays;
27961
+ } else {
27962
+ merged[key] = incoming[key];
27963
+ }
27964
+ } else if (typeof existing[key] === "object") {
27965
+ merged[key] = deepMerge(existing[key], incoming[key], arrayMerge);
27966
+ } else {
27967
+ merged[key] = incoming[key];
27968
+ }
27969
+ return merged;
27970
+ }, {});
27971
+ }
27972
+
27973
+ function getParticipants(params) {
27974
+ const { tournamentRecords } = params || {};
27975
+ if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length) {
27976
+ return { error: MISSING_TOURNAMENT_RECORDS };
27977
+ }
27978
+ const participantMap = {};
27979
+ const participants = [];
27980
+ const derivedEventInfo = {};
27981
+ const derivedDrawInfo = {};
27982
+ const matchUps = [];
27983
+ const mappedMatchUps = {};
27984
+ const participantIdsWithConflicts = [];
27985
+ for (const tournamentRecord of Object.values(tournamentRecords)) {
27986
+ const {
27987
+ participantIdsWithConflicts: idsWithConflicts,
27988
+ mappedMatchUps: tournamentMappedMatchUps,
27989
+ participantMap: tournamentParticipantMap,
27990
+ participants: tournamentParticipants,
27991
+ matchUps: tournamentMatchUps,
27992
+ derivedEventInfo: eventInfo,
27993
+ derivedDrawInfo: drawInfo
27994
+ } = getParticipants$1({ tournamentRecord, ...params });
27995
+ Object.assign(mappedMatchUps, tournamentMappedMatchUps);
27996
+ Object.assign(participantMap, tournamentParticipantMap);
27997
+ Object.assign(derivedEventInfo, eventInfo);
27998
+ Object.assign(derivedDrawInfo, drawInfo);
27999
+ participants.push(...tournamentParticipants ?? []);
28000
+ matchUps.push(...tournamentMatchUps ?? []);
28001
+ idsWithConflicts?.forEach((participantId) => {
28002
+ if (!participantIdsWithConflicts.includes(participantId))
28003
+ participantIdsWithConflicts.push(participantId);
28004
+ });
28005
+ }
28006
+ return {
28007
+ participantIdsWithConflicts,
28008
+ derivedEventInfo,
28009
+ derivedDrawInfo,
28010
+ participantMap,
28011
+ mappedMatchUps,
28012
+ participants,
28013
+ ...SUCCESS,
28014
+ matchUps
28015
+ };
28016
+ }
28017
+ function getCompetitionParticipants(params) {
28018
+ const { tournamentRecords } = params || {};
28019
+ if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length)
28020
+ return { error: MISSING_TOURNAMENT_RECORDS };
28021
+ let competitionParticipants = [];
28022
+ const participantIdsWithConflicts = [];
28023
+ const competitionParticipantIds = [];
28024
+ const mappedMatchUps = {};
28025
+ for (const tournamentRecord of Object.values(tournamentRecords)) {
28026
+ const {
28027
+ participants,
28028
+ participantIdsWithConflicts: idsWithConflicts,
28029
+ mappedMatchUps: matchUpsMap
28030
+ } = getParticipants$1({
28031
+ tournamentRecord,
28032
+ ...params
28033
+ });
28034
+ if (matchUpsMap)
28035
+ Object.assign(mappedMatchUps, matchUpsMap);
28036
+ for (const tournamentParticipant of participants ?? []) {
28037
+ const { participantId } = tournamentParticipant;
28038
+ if (!competitionParticipantIds.includes(participantId)) {
28039
+ competitionParticipantIds.push(participantId);
28040
+ competitionParticipants.push(tournamentParticipant);
28041
+ } else {
28042
+ competitionParticipants = competitionParticipants.map(
28043
+ (participant) => participant.participantId !== participantId ? participant : deepMerge(participant, tournamentParticipant, true)
28044
+ );
28045
+ }
28046
+ }
28047
+ idsWithConflicts?.forEach((participantId) => {
28048
+ if (!participantIdsWithConflicts.includes(participantId))
28049
+ participantIdsWithConflicts.push(participantId);
28050
+ });
28051
+ }
28052
+ return {
28053
+ competitionParticipants,
28054
+ participantIdsWithConflicts,
28055
+ mappedMatchUps,
28056
+ ...SUCCESS
28057
+ };
28058
+ }
28059
+ function publicFindParticipant({
28060
+ tournamentRecords,
28061
+ policyDefinitions,
28062
+ contextProfile,
27935
28063
  participantId,
27936
- drawId
28064
+ personId
27937
28065
  }) {
27938
- const mainPositionAssignment = derivedDrawInfo[drawId]?.mainPositionAssignments?.find(
27939
- (assignment) => assignment.participantId === participantId
27940
- );
27941
- const qualifyingPositionAssignment = derivedDrawInfo[drawId]?.qualifyingPositionAssignments?.find(
27942
- (assignment) => assignment.participantId === participantId
28066
+ if (!tournamentRecords)
28067
+ return { error: MISSING_TOURNAMENT_RECORDS };
28068
+ if (typeof participantId !== "string" && typeof personId !== "string")
28069
+ return { error: MISSING_VALUE, stack: "publicFindParticipant" };
28070
+ let participant, tournamentId;
28071
+ for (const tournamentRecord of Object.values(tournamentRecords)) {
28072
+ tournamentId = tournamentRecord.tournamentId;
28073
+ const participants = getParticipants$1({
28074
+ policyDefinitions,
28075
+ tournamentRecord
28076
+ }).participants ?? [];
28077
+ participant = findParticipant({
28078
+ tournamentParticipants: participants,
28079
+ internalUse: true,
28080
+ policyDefinitions,
28081
+ contextProfile,
28082
+ participantId,
28083
+ personId
28084
+ });
28085
+ if (participant)
28086
+ break;
28087
+ }
28088
+ return { participant, tournamentId, ...SUCCESS };
28089
+ }
28090
+
28091
+ const penaltyTemplate = ({ penaltyId = UUID() } = {}) => ({
28092
+ refereeParticipantId: void 0,
28093
+ penaltyCode: void 0,
28094
+ penaltyType: void 0,
28095
+ extensions: void 0,
28096
+ matchUpId: void 0,
28097
+ createdAt: void 0,
28098
+ issuedAt: void 0,
28099
+ notes: void 0,
28100
+ penaltyId
28101
+ });
28102
+
28103
+ function addPenalty$1({
28104
+ refereeParticipantId,
28105
+ tournamentRecord,
28106
+ participantIds,
28107
+ penaltyCode,
28108
+ penaltyType,
28109
+ extensions,
28110
+ penaltyId,
28111
+ matchUpId,
28112
+ issuedAt,
28113
+ notes
28114
+ }) {
28115
+ if (!tournamentRecord)
28116
+ return { error: MISSING_TOURNAMENT_RECORD };
28117
+ if (!participantIds)
28118
+ return { error: MISSING_PARTICIPANT_ID };
28119
+ if (!penaltyType)
28120
+ return { error: MISSING_PENALTY_TYPE };
28121
+ const participants = tournamentRecord?.participants || [];
28122
+ const relevantParticipants = participants.filter(
28123
+ (participant) => participantIds.includes(participant.participantId)
27943
28124
  );
27944
- const positionAssignments = {};
27945
- if (mainPositionAssignment) {
27946
- const { participantId: participantId2, ...props } = mainPositionAssignment;
27947
- if (participantId2)
27948
- positionAssignments[MAIN] = { ...props };
28125
+ if (!relevantParticipants.length)
28126
+ return { error: PARTICIPANT_NOT_FOUND };
28127
+ const createdAt = (/* @__PURE__ */ new Date()).toISOString();
28128
+ const penaltyItem = Object.assign(penaltyTemplate({ penaltyId }), {
28129
+ refereeParticipantId,
28130
+ penaltyCode,
28131
+ penaltyType,
28132
+ matchUpId,
28133
+ notes,
28134
+ issuedAt,
28135
+ createdAt
28136
+ });
28137
+ if (Array.isArray(extensions)) {
28138
+ extensions.forEach(
28139
+ (extension) => addExtension$1({ element: penaltyItem, extension })
28140
+ );
27949
28141
  }
27950
- if (qualifyingPositionAssignment) {
27951
- const { participantId: participantId2, ...props } = qualifyingPositionAssignment;
27952
- if (participantId2)
27953
- positionAssignments[QUALIFYING] = { ...props };
28142
+ relevantParticipants.forEach((participant) => {
28143
+ if (!participant.penalties)
28144
+ participant.penalties = [];
28145
+ participant.penalties.push(penaltyItem);
28146
+ });
28147
+ addNotice({
28148
+ topic: MODIFY_PARTICIPANTS,
28149
+ payload: {
28150
+ tournamentId: tournamentRecord.tournamentId,
28151
+ participants: relevantParticipants
28152
+ }
28153
+ });
28154
+ return { ...SUCCESS, penaltyId: penaltyItem.penaltyId };
28155
+ }
28156
+ function removePenalty$1({
28157
+ tournamentRecord,
28158
+ penaltyId
28159
+ }) {
28160
+ if (!tournamentRecord)
28161
+ return { error: MISSING_TOURNAMENT_RECORD };
28162
+ if (!penaltyId)
28163
+ return { error: MISSING_PENALTY_ID };
28164
+ const participants = tournamentRecord?.participants || [];
28165
+ const modifiedParticipants = [];
28166
+ let penaltyRemoved = false;
28167
+ let removedPenalty;
28168
+ participants.forEach((participant) => {
28169
+ let participantModified = false;
28170
+ participant.penalties = (participant.penalties || []).filter((penalty) => {
28171
+ if (penalty.penaltyId === penaltyId) {
28172
+ participantModified = true;
28173
+ if (!penaltyRemoved) {
28174
+ removedPenalty = penalty;
28175
+ penaltyRemoved = true;
28176
+ }
28177
+ }
28178
+ if (participantModified)
28179
+ modifiedParticipants.push(participant);
28180
+ return penalty.penaltyId !== penaltyId;
28181
+ });
28182
+ });
28183
+ if (removedPenalty) {
28184
+ addNotice({
28185
+ topic: MODIFY_PARTICIPANTS,
28186
+ payload: {
28187
+ tournamentId: tournamentRecord.tournamentId,
28188
+ participants: modifiedParticipants
28189
+ }
28190
+ });
27954
28191
  }
27955
- return Object.keys(positionAssignments).length ? positionAssignments : void 0;
28192
+ return removedPenalty ? { ...SUCCESS, penalty: removedPenalty } : { error: PENALTY_NOT_FOUND };
27956
28193
  }
27957
-
27958
- function getRelevantParticipantIdsMap({
27959
- processParticipantId,
27960
- // optional method which is passed each participantId
27961
- tournamentRecords,
28194
+ function getTournamentPenalties({
27962
28195
  tournamentRecord
27963
28196
  }) {
27964
- if (typeof tournamentRecord !== "object" && typeof tournamentRecords !== "object")
28197
+ if (!tournamentRecord)
27965
28198
  return { error: MISSING_TOURNAMENT_RECORD };
27966
- const allParticipants = tournamentRecords ? Object.values(tournamentRecords).map((tournamentRecord2) => tournamentRecord2?.participants || []).flat() : tournamentRecord?.participants || [];
27967
- const relevantParticipantIdsMap = Object.assign(
27968
- {},
27969
- ...allParticipants.map(
27970
- ({ participantId, participantType, individualParticipantIds }) => {
27971
- typeof processParticipantId === "function" && processParticipantId(participantId);
27972
- const individualParticipantIdObjects = (individualParticipantIds || []).map((relevantParticipantId) => ({
27973
- participantType: INDIVIDUAL,
27974
- relevantParticipantId
27975
- }));
27976
- return {
27977
- [participantId]: individualParticipantIdObjects.concat({
27978
- relevantParticipantId: participantId,
27979
- participantType
27980
- })
28199
+ const participants = tournamentRecord?.participants || [];
28200
+ const allPenalties = participants.reduce((penalties, participant) => {
28201
+ const { participantId } = participant;
28202
+ (participant.penalties || []).forEach((penalty) => {
28203
+ const { penaltyId } = penalty || {};
28204
+ if (penalties[penaltyId]) {
28205
+ penalties[penaltyId].participants.push(participantId);
28206
+ } else {
28207
+ penalties[penaltyId] = {
28208
+ ...penalty,
28209
+ participantIds: [participantId]
27981
28210
  };
27982
28211
  }
27983
- )
27984
- );
27985
- return { relevantParticipantIdsMap };
28212
+ });
28213
+ return penalties;
28214
+ }, {});
28215
+ return { penalties: Object.values(allPenalties) };
27986
28216
  }
27987
-
27988
- function getDerivedSeedAssignments({
27989
- derivedDrawInfo,
27990
- participantId,
27991
- drawId
28217
+ function modifyPenalty$1({
28218
+ tournamentRecord,
28219
+ modifications,
28220
+ penaltyId
27992
28221
  }) {
27993
- const mainSeedAssignment = derivedDrawInfo[drawId]?.mainSeedAssignments?.find(
27994
- (assignment) => assignment.participantId === participantId
28222
+ if (!tournamentRecord)
28223
+ return { error: MISSING_TOURNAMENT_RECORD };
28224
+ if (!modifications)
28225
+ return { error: INVALID_VALUES, modifications };
28226
+ if (!penaltyId)
28227
+ return { error: MISSING_PENALTY_ID };
28228
+ const participants = tournamentRecord?.participants || [];
28229
+ const validAttributes = Object.keys(penaltyTemplate()).filter(
28230
+ (attribute) => attribute !== "penaltyId"
27995
28231
  );
27996
- const qualifyingSeedAssignment = derivedDrawInfo[drawId]?.qualifyingSeedAssignments?.find(
27997
- (assignment) => assignment.participantId === participantId
28232
+ const validModificationAttributes = Object.keys(modifications).filter(
28233
+ (attribute) => validAttributes.includes(attribute)
27998
28234
  );
27999
- const seedAssignments = {};
28000
- if (mainSeedAssignment) {
28001
- const { participantId: participantId2, ...props } = mainSeedAssignment;
28002
- if (participantId2)
28003
- seedAssignments[MAIN] = { ...props };
28004
- }
28005
- if (qualifyingSeedAssignment) {
28006
- const { participantId: participantId2, ...props } = qualifyingSeedAssignment;
28007
- if (participantId2)
28008
- seedAssignments[QUALIFYING] = { ...props };
28235
+ if (!validModificationAttributes.length)
28236
+ return { error: NO_VALID_ATTRIBUTES };
28237
+ let updatedPenalty;
28238
+ const modifiedParticipants = [];
28239
+ participants.forEach((participant) => {
28240
+ let participantModified = false;
28241
+ participant.penalties = (participant.penalties || []).map((penalty) => {
28242
+ if (penalty.penaltyId === penaltyId) {
28243
+ participantModified = true;
28244
+ validModificationAttributes.forEach(
28245
+ (attribute) => Object.assign(penalty, { [attribute]: modifications[attribute] })
28246
+ );
28247
+ if (!updatedPenalty)
28248
+ updatedPenalty = penalty;
28249
+ }
28250
+ return penalty;
28251
+ });
28252
+ if (participantModified)
28253
+ modifiedParticipants.push(participant);
28254
+ });
28255
+ if (updatedPenalty) {
28256
+ addNotice({
28257
+ topic: MODIFY_PARTICIPANTS,
28258
+ payload: {
28259
+ tournamentId: tournamentRecord.tournamentId,
28260
+ participants: modifiedParticipants
28261
+ }
28262
+ });
28009
28263
  }
28010
- return Object.keys(seedAssignments).length ? seedAssignments : void 0;
28264
+ return updatedPenalty ? { ...SUCCESS, penalty: updatedPenalty } : { error: PENALTY_NOT_FOUND };
28011
28265
  }
28012
28266
 
28013
- const hasSchedule = ({
28014
- scheduleAttributes = ["scheduledDate", "scheduledTime"],
28015
- schedule = {}
28016
- }) => {
28017
- const matchUpScheduleKeys = Object.keys(schedule).filter((key) => scheduleAttributes.includes(key)).filter((key) => schedule[key]);
28018
- return !!matchUpScheduleKeys.length;
28019
- };
28020
-
28021
- function participantScheduledMatchUps({
28022
- scheduleAttributes = ["scheduledDate", "scheduledTime"],
28023
- matchUps = []
28024
- }) {
28025
- if (!validMatchUps(matchUps))
28026
- return { error: MISSING_MATCHUPS };
28027
- if (!Array.isArray(scheduleAttributes))
28028
- return { error: INVALID_VALUES };
28029
- const scheduledMatchUps = matchUps.filter(Boolean).filter(({ schedule }) => hasSchedule({ schedule, scheduleAttributes })).reduce((dateMatchUps, matchUp) => {
28030
- const { schedule } = matchUp;
28031
- const date = extractDate(schedule?.scheduledDate);
28032
- const time = extractTime(schedule?.scheduledTime);
28033
- if (date && time) {
28034
- if (dateMatchUps[date]) {
28035
- dateMatchUps[date].push(matchUp);
28036
- } else {
28037
- dateMatchUps[date] = [matchUp];
28038
- }
28267
+ function addPenalty(params) {
28268
+ const { tournamentRecords, participantIds } = params;
28269
+ let penaltyId;
28270
+ for (const tournamentRecord of Object.values(tournamentRecords)) {
28271
+ const participants = getParticipants$1({
28272
+ tournamentRecord
28273
+ }).participants ?? [];
28274
+ const tournamentParticipantIds = participants?.map(extractAttributes("participantId")).filter((participantId) => participantIds.includes(participantId));
28275
+ if (tournamentParticipantIds.length) {
28276
+ const result = addPenalty$1({
28277
+ ...params,
28278
+ penaltyId: params.penaltyId || penaltyId,
28279
+ tournamentRecord,
28280
+ participantIds: tournamentParticipantIds
28281
+ });
28282
+ penaltyId = result.penaltyId;
28039
28283
  }
28040
- return dateMatchUps;
28041
- }, {});
28042
- const dates = Object.keys(scheduledMatchUps);
28043
- dates.forEach((date) => {
28044
- scheduledMatchUps[date].sort(
28045
- (a, b) => timeSort(
28046
- extractTime(a.schedule?.scheduledTime),
28047
- extractTime(b.schedule?.scheduledTime)
28048
- )
28049
- );
28050
- });
28051
- return { scheduledMatchUps };
28284
+ }
28285
+ return penaltyId ? { ...SUCCESS, penaltyId } : { error: PARTICIPANT_NOT_FOUND };
28052
28286
  }
28053
-
28054
- function annotateParticipant(params) {
28055
- const {
28056
- withScaleValues = true,
28057
- eventsPublishStatuses,
28058
- withEvents = true,
28059
- withDraws = true,
28060
- participantIdMap,
28061
- scheduleAnalysis,
28062
- derivedDrawInfo,
28063
- usePublishState,
28064
- withStatistics,
28065
- withOpponents,
28066
- withMatchUps,
28067
- withSeeding,
28068
- participant,
28069
- withISO2,
28070
- withIOC
28071
- } = params;
28072
- const scheduleConflicts = [];
28073
- const scheduleItems = [];
28074
- if (withIOC || withISO2)
28075
- addNationalityCode({ participant, withIOC, withISO2 });
28076
- if (withScaleValues) {
28077
- const { ratings, rankings } = getScaleValues({ participant });
28078
- participant.rankings = rankings;
28079
- participant.ratings = ratings;
28287
+ function modifyPenalty(params) {
28288
+ const { tournamentRecords } = params;
28289
+ if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length)
28290
+ return { error: MISSING_TOURNAMENT_RECORDS };
28291
+ for (const tournamentRecord of Object.values(tournamentRecords)) {
28292
+ const result = modifyPenalty$1({ tournamentRecord, ...params });
28293
+ if (result.error && result.error !== PENALTY_NOT_FOUND)
28294
+ return result;
28080
28295
  }
28081
- const participantId = participant?.participantId;
28082
- if (!participantId || !participantIdMap[participantId])
28083
- return {};
28084
- const {
28085
- potentialMatchUps,
28086
- opponents,
28087
- matchUps,
28088
- events,
28089
- losses,
28090
- draws,
28091
- wins
28092
- } = participantIdMap[participantId];
28093
- const denominator = wins + losses;
28094
- const numerator = wins;
28095
- const statValue = denominator && numerator / denominator;
28096
- const winRatioStat = {
28097
- statCode: WIN_RATIO$1,
28098
- denominator,
28099
- numerator,
28100
- statValue
28101
- };
28102
- const participantDraws = Object.values(draws);
28103
- const participantEvents = Object.values(events);
28104
- if (withDraws && participantDraws) {
28105
- participant.draws = participantDraws;
28106
- for (const participantDraw of participantDraws) {
28107
- const publishedSeeding = eventsPublishStatuses[participantDraw.eventId]?.publishedSeeding;
28108
- const seedingPublished = !usePublishState || publishedSeeding?.published && (publishedSeeding?.drawIds?.length === 0 || publishedSeeding?.drawIds?.includes(participantDraw.drawId));
28109
- if (seedingPublished) {
28110
- const seedAssignments = getDerivedSeedAssignments({
28111
- drawId: participantDraw.drawId,
28112
- derivedDrawInfo,
28113
- participantId
28114
- });
28115
- if (seedAssignments) {
28116
- participantDraw.seedAssignments = seedAssignments;
28117
- }
28118
- }
28119
- }
28120
- }
28121
- if (withEvents && participantEvents) {
28122
- participant.events = participantEvents;
28123
- if (withSeeding) {
28124
- const seedingScales = Object.assign(
28125
- {},
28126
- ...(participant.timeItems || []).filter(({ itemType }) => itemType.split(".")[1] === SEEDING$1).map(({ itemType: seedingScaleName, itemValue: seedValue }) => ({
28127
- [seedingScaleName]: seedValue
28128
- }))
28129
- );
28130
- for (const participantEvent of participantEvents) {
28131
- const getScaleAccessor = (scaleName) => [SCALE$1, SEEDING$1, participantEvent.eventType, scaleName].join(".");
28132
- const publishedSeeding = eventsPublishStatuses[participantEvent.eventId]?.publishedSeeding;
28133
- const eventSeedingScaleNames = (publishedSeeding?.stageSeedingScaleNames && Object.values(publishedSeeding?.stageSeedingScaleNames) || Array.isArray(publishedSeeding?.seedingScaleNames) && publishedSeeding.seedingScaleNames || []).map(getScaleAccessor);
28134
- const publishedEventSeedingScaleNames = intersection(
28135
- Object.keys(seedingScales),
28136
- eventSeedingScaleNames
28137
- );
28138
- const eventSeedingPublished = !!(!usePublishState || !Object.keys(seedingScales).length && !publishedSeeding?.drawIds?.length || publishedEventSeedingScaleNames.length);
28139
- if (eventSeedingPublished && publishedEventSeedingScaleNames.length) {
28140
- if (publishedSeeding?.stageSeedingScaleNames) {
28141
- const scaleValues = Object.keys(
28142
- publishedSeeding.stageSeedingScaleNames
28143
- ).map((key) => {
28144
- const accessor = getScaleAccessor(
28145
- publishedSeeding.stageSeedingScaleNames[key]
28146
- );
28147
- const scaleValue = seedingScales[accessor];
28148
- return [key, scaleValue];
28149
- }).filter((pair) => pair[1]).map((pair) => ({ [pair[0]]: { seedValue: pair[1] } }));
28150
- const seedAssignments = Object.assign({}, ...scaleValues);
28151
- participantEvent.seedAssignments = seedAssignments;
28152
- } else if (publishedEventSeedingScaleNames) {
28153
- const seedValues = publishedEventSeedingScaleNames.map(
28154
- (scaleName) => seedingScales[scaleName]
28155
- );
28156
- participantEvent.seedValue = seedValues.pop();
28157
- }
28158
- } else if (!usePublishState && typeof withSeeding === "object") {
28159
- const scaleValues = Object.keys(withSeeding).map((key) => {
28160
- const accessor = getScaleAccessor(withSeeding[key]);
28161
- const scaleValue = seedingScales[accessor];
28162
- return [key, scaleValue];
28163
- }).filter((pair) => pair[1]).map((pair) => ({ [pair[0]]: { seedValue: pair[1] } }));
28164
- const seedAssignments = Object.assign({}, ...scaleValues);
28165
- participantEvent.seedAssignments = seedAssignments;
28166
- } else {
28167
- const { categoryName, ageCategoryCode } = participantEvent.category || {};
28168
- let scaleItem;
28169
- for (const scaleName of [
28170
- participantEvent.eventId,
28171
- ageCategoryCode,
28172
- categoryName
28173
- ]) {
28174
- const scaleAttributes = {
28175
- eventType: participantEvent.eventType,
28176
- scaleType: SEEDING$1,
28177
- scaleName
28178
- };
28179
- const result = participantScaleItem({
28180
- scaleAttributes,
28181
- participant
28182
- });
28183
- if (result.scaleItem) {
28184
- scaleItem = result.scaleItem;
28185
- break;
28186
- }
28187
- }
28188
- if (scaleItem) {
28189
- const seedValue = scaleItem.scaleValue;
28190
- const seedingPublished = !usePublishState || publishedSeeding?.published && (publishedSeeding?.drawIds?.length === 0 || publishedSeeding?.drawIds?.includes(
28191
- participantEvent.drawId
28192
- ));
28193
- if (seedingPublished) {
28194
- participantEvent.seedValue = seedValue;
28195
- }
28196
- }
28197
- }
28198
- if (participantEvent.drawIds?.length) {
28199
- for (const flightDrawId of participantEvent.drawIds || []) {
28200
- const drawSeedPublishingDisabled = publishedSeeding?.drawIds?.length && !publishedSeeding?.drawIds?.includes(flightDrawId);
28201
- if (eventSeedingPublished && !drawSeedPublishingDisabled) {
28202
- const seedAssignments = getDerivedSeedAssignments({
28203
- drawId: flightDrawId,
28204
- derivedDrawInfo,
28205
- participantId
28206
- });
28207
- if (seedAssignments && participantEvent.seedAssignments) {
28208
- for (const key of Object.keys(
28209
- participantEvent.seedAssignments
28210
- )) {
28211
- participantEvent.seedAssignments[key] = seedAssignments[key];
28212
- }
28213
- } else {
28214
- participantEvent.seedAssignments = seedAssignments;
28215
- }
28216
- }
28217
- }
28218
- }
28219
- }
28220
- }
28221
- }
28222
- const participantOpponents = Object.values(opponents).flat();
28223
- if (withOpponents && participantOpponents?.length) {
28224
- participant.opponents = participantOpponents;
28225
- participantDraws?.forEach((draw) => {
28226
- draw.opponents = participantOpponents.filter(
28227
- (opponent) => opponent.drawId === draw.drawId
28228
- );
28229
- });
28230
- }
28231
- const participantPotentialMatchUps = Object.values(potentialMatchUps);
28232
- const participantMatchUps = Object.values(matchUps);
28233
- if (withMatchUps) {
28234
- participant.potentialMatchUps = participantPotentialMatchUps;
28235
- participant.matchUps = participantMatchUps;
28236
- }
28237
- const allParticipantMatchUps = participantMatchUps.concat(
28238
- participantPotentialMatchUps
28239
- );
28240
- const scheduledMatchUps = participantScheduledMatchUps({
28241
- matchUps: allParticipantMatchUps
28242
- })?.scheduledMatchUps || [];
28243
- const { scheduledMinutesDifference } = scheduleAnalysis || {};
28244
- const dates = Object.keys(scheduledMatchUps);
28245
- dates.forEach((date) => {
28246
- scheduledMatchUps[date].filter(Boolean).forEach((matchUp, i) => {
28247
- const {
28248
- schedule: {
28249
- scheduledTime,
28250
- timeAfterRecovery,
28251
- typeChangeTimeAfterRecovery
28252
- },
28253
- matchUpStatus,
28254
- roundPosition,
28255
- structureName,
28256
- matchUpType,
28257
- roundNumber,
28258
- matchUpId,
28259
- drawId,
28260
- score
28261
- } = matchUp;
28262
- scheduleItems.push({
28263
- ...matchUp.schedule,
28264
- scheduledTime: extractTime(matchUp.schedule?.scheduledTime),
28265
- roundPosition,
28266
- structureName,
28267
- matchUpType,
28268
- roundNumber,
28269
- matchUpId,
28270
- drawId
28271
- });
28272
- const ignoreMatchUp = matchUpStatus === BYE || [WALKOVER$2, DEFAULTED].includes(matchUpStatus) && !scoreHasValue({ score });
28273
- if (scheduledTime && !ignoreMatchUp) {
28274
- const scheduledMinutes = timeStringMinutes(scheduledTime);
28275
- const matchUpsToConsider = scheduledMatchUps[date].slice(i + 1);
28276
- for (const consideredMatchUp of matchUpsToConsider) {
28277
- const ignoreMatchUp2 = consideredMatchUp.matchUpStatus === BYE || [WALKOVER$2, DEFAULTED].includes(consideredMatchUp.matchUpStatus) && !scoreHasValue(consideredMatchUp);
28278
- if (!ignoreMatchUp2 && consideredMatchUp.schedule?.scheduledTime) {
28279
- const typeChange = matchUp.matchUpType !== consideredMatchUp.matchUpType;
28280
- const notBeforeTime = typeChange ? typeChangeTimeAfterRecovery || timeAfterRecovery : timeAfterRecovery;
28281
- const sameDraw = matchUp.drawId === consideredMatchUp.drawId;
28282
- const bothPotential = matchUp.potential && consideredMatchUp.potential;
28283
- const nextMinutes = timeStringMinutes(
28284
- consideredMatchUp.schedule?.scheduledTime
28285
- );
28286
- const minutesDifference = nextMinutes - scheduledMinutes;
28287
- const timeOverlap = scheduledMinutesDifference && !isNaN(scheduledMinutesDifference) ? minutesDifference <= scheduledMinutesDifference : timeStringMinutes(notBeforeTime) > timeStringMinutes(consideredMatchUp.schedule?.scheduledTime);
28288
- if (timeOverlap && !(bothPotential && sameDraw)) {
28289
- scheduleConflicts.push({
28290
- priorScheduledMatchUpId: consideredMatchUp.matchUpId,
28291
- matchUpIdWithConflict: matchUpId
28292
- });
28293
- }
28294
- }
28295
- }
28296
- }
28297
- });
28298
- });
28299
- if (withStatistics)
28300
- participant.statistics = [winRatioStat];
28301
- return { scheduleConflicts, scheduleItems };
28302
- }
28303
-
28304
- function getDrawDetails({
28305
- eventEntries,
28306
- sortConfig,
28307
- event
28308
- }) {
28309
- const derivedInfo = {};
28310
- const drawDetails = Object.assign(
28311
- {},
28312
- ...(event.drawDefinitions ?? []).map((drawDefinition) => {
28313
- const entriesMap = Object.assign(
28314
- {},
28315
- ...(eventEntries ?? []).filter((entry) => entry.participantId).map((entry) => ({ [entry.participantId]: entry })),
28316
- ...drawDefinition.entries.filter((entry) => entry.participantId).map((entry) => ({ [entry.participantId]: entry }))
28317
- );
28318
- const drawEntries = Object.values(entriesMap);
28319
- const mainStructure = getDrawStructures({
28320
- stageSequence: 1,
28321
- drawDefinition,
28322
- stage: MAIN
28323
- })?.structures?.[0];
28324
- const mainPositionAssignments = mainStructure && getPositionAssignments$1({
28325
- structure: mainStructure
28326
- })?.positionAssignments;
28327
- const drawSize = mainPositionAssignments?.length;
28328
- const qualifyingStructure = getDrawStructures({
28329
- stageSequence: 1,
28330
- stage: QUALIFYING,
28331
- drawDefinition
28332
- })?.structures?.[0];
28333
- const qualifyingPositionAssignments = mainStructure && getPositionAssignments$1({
28334
- structure: qualifyingStructure
28335
- })?.positionAssignments;
28336
- const qualifyingDrawSize = qualifyingPositionAssignments?.length;
28337
- const mainSeedAssignments = mainStructure?.seedAssignments;
28338
- const qualifyingSeedAssignments = qualifyingStructure?.seedAssignments;
28339
- const orderedStructureIds = (drawDefinition.structures || []).sort((a, b) => structureSort(a, b, sortConfig)).map(({ structureId, structures }) => {
28340
- return [
28341
- structureId,
28342
- ...(structures || []).map(({ structureId: structureId2 }) => structureId2)
28343
- ];
28344
- }).flat(Infinity);
28345
- const flightNumber = event?._flightProfile?.flights?.find(
28346
- (flight) => flight.drawId === drawDefinition.drawId
28347
- )?.flightNumber;
28348
- derivedInfo[drawDefinition.drawId] = {
28349
- qualifyingPositionAssignments,
28350
- qualifyingSeedAssignments,
28351
- mainPositionAssignments,
28352
- mainSeedAssignments,
28353
- orderedStructureIds,
28354
- qualifyingDrawSize,
28355
- flightNumber,
28356
- drawSize
28357
- };
28358
- return {
28359
- [drawDefinition.drawId]: {
28360
- drawType: drawDefinition.drawType,
28361
- drawEntries
28362
- }
28363
- };
28364
- })
28365
- );
28366
- return { derivedInfo, drawDetails };
28367
- }
28368
-
28369
- function processMatchUp({
28370
- relevantParticipantIdsMap,
28371
- participantFilters,
28372
- participantIdMap,
28373
- derivedDrawInfo,
28374
- eventDrawsCount,
28375
- drawDetails,
28376
- eventType,
28377
- matchUp
28378
- }) {
28379
- const {
28380
- collectionId,
28381
- collectionPosition,
28382
- drawId,
28383
- drawName,
28384
- eventId,
28385
- eventName,
28386
- finishingRound,
28387
- finishingPositionRange,
28388
- processCodes,
28389
- loserTo,
28390
- matchUpId,
28391
- matchUpType,
28392
- matchUpFormat,
28393
- matchUpStatus,
28394
- matchUpStatusCodes,
28395
- matchUpTieId,
28396
- roundName,
28397
- roundNumber,
28398
- roundPosition,
28399
- score,
28400
- sides,
28401
- stage,
28402
- stageSequence,
28403
- schedule,
28404
- structureName,
28405
- structureId,
28406
- tieFormat,
28407
- tieMatchUps,
28408
- tournamentId,
28409
- winnerTo,
28410
- winningSide
28411
- } = matchUp;
28412
- const targetParticipantIds = participantFilters?.participantIds;
28413
- const getRelevantParticipantIds = (participantId) => {
28414
- const relevantParticipantIds = participantId && relevantParticipantIdsMap[participantId] || [];
28415
- relevantParticipantIds.push(participantId);
28416
- return relevantParticipantIds.some(
28417
- (obj) => !targetParticipantIds || targetParticipantIds.includes(obj.relevantParticipantId)
28418
- ) ? relevantParticipantIds : [];
28419
- };
28420
- const { winner, loser } = finishingPositionRange || {};
28421
- const doublesTieParticipants = tieMatchUps?.length && tieMatchUps.filter(({ matchUpType: matchUpType2 }) => matchUpType2 === DOUBLES_MATCHUP).map(
28422
- ({ sides: sides2 }) => sides2.map(
28423
- ({ sideNumber, participantId, participant }) => sideNumber && participantId && {
28424
- sideNumber,
28425
- participantId,
28426
- participant
28427
- }
28428
- )
28429
- ).flat().filter(Boolean) || [];
28430
- if (eventType === TEAM_EVENT && matchUpType === DOUBLES_MATCHUP) {
28431
- const participants = (matchUp.sides?.filter(Boolean) || []).map(
28432
- ({ sideNumber, participantId, participant }) => sideNumber && participantId && {
28433
- sideNumber,
28434
- participantId,
28435
- participant
28436
- }
28437
- ).filter(Boolean);
28438
- doublesTieParticipants.push(...participants);
28439
- }
28440
- sides?.forEach((params) => {
28441
- const { participantId, sideNumber } = params;
28442
- if (!participantId)
28443
- return;
28444
- const { drawType, drawEntries } = drawDetails[drawId];
28445
- const participantScore = sideNumber === 1 ? score?.scoreStringSide1 : score?.scoreStringSide2;
28446
- const participantWon = winningSide && sideNumber === winningSide;
28447
- const opponent = matchUp.sides.find(
28448
- (side) => side.sideNumber === 3 - sideNumber
28449
- );
28450
- const opponentParticipantId = opponent?.participantId;
28451
- const relevantOpponents = opponentParticipantId && relevantParticipantIdsMap[opponentParticipantId] || [];
28452
- const finishingPositionRange2 = participantWon ? winner : loser;
28453
- const drawEntry = drawEntries.find(
28454
- (entry) => entry.participantId === participantId
28455
- );
28456
- const relevantParticipantIds = getRelevantParticipantIds(participantId);
28457
- const addedPairParticipantIds = [];
28458
- doublesTieParticipants?.filter((participant) => participant.sideNumber === sideNumber).forEach((p) => {
28459
- const participantId2 = p.participantId;
28460
- if (participantId2 && !addedPairParticipantIds.includes(participantId2)) {
28461
- relevantParticipantIds.push({
28462
- relevantParticipantId: participantId2,
28463
- participantType: PAIR
28464
- });
28465
- addedPairParticipantIds.push(participantId2);
28466
- }
28467
- });
28468
- const filteredRelevantParticipantIds = relevantParticipantIds.filter(
28469
- (opponent2) => {
28470
- return eventType !== TEAM_EVENT || eventType === TEAM_EVENT && [DOUBLES_MATCHUP, TEAM_MATCHUP].includes(matchUpType) && [PAIR, TEAM_PARTICIPANT].includes(opponent2.participantType) || eventType === TEAM_EVENT && [SINGLES_MATCHUP, DOUBLES_MATCHUP].includes(matchUpType) && [INDIVIDUAL].includes(opponent2.participantType);
28471
- }
28472
- );
28473
- filteredRelevantParticipantIds?.forEach(
28474
- ({ relevantParticipantId, participantType }) => {
28475
- const { entryStage, entryStatus, entryPosition } = drawEntry || {};
28476
- if (!participantIdMap[relevantParticipantId])
28477
- return;
28478
- if (!participantIdMap[relevantParticipantId].draws[drawId]) {
28479
- const positionAssignments = getDerivedPositionAssignments({
28480
- participantId: relevantParticipantId,
28481
- derivedDrawInfo,
28482
- drawId
28483
- });
28484
- const seedAssignments = getDerivedSeedAssignments({
28485
- participantId: relevantParticipantId,
28486
- derivedDrawInfo,
28487
- drawId
28488
- });
28489
- participantIdMap[relevantParticipantId].draws[drawId] = definedAttributes({
28490
- qualifyingDrawSize: derivedDrawInfo[drawId]?.qualifyingDrawSize,
28491
- drawSize: derivedDrawInfo[drawId]?.drawSize,
28492
- partnerParticipantIds: [],
28493
- positionAssignments,
28494
- seedAssignments,
28495
- entryPosition,
28496
- entryStatus,
28497
- entryStage,
28498
- drawName,
28499
- drawType,
28500
- eventId,
28501
- drawId
28502
- });
28503
- }
28504
- if (!participantIdMap[relevantParticipantId].events[eventId]) {
28505
- participantIdMap[relevantParticipantId].events[eventId] = {
28506
- partnerParticipantIds: [],
28507
- drawIds: [],
28508
- eventName,
28509
- eventId
28510
- };
28511
- }
28512
- const eventDrawIds = participantIdMap[relevantParticipantId].events[eventId].drawIds;
28513
- if (eventDrawIds && !eventDrawIds?.includes(drawId)) {
28514
- participantIdMap[relevantParticipantId].events[eventId].drawIds.push(
28515
- drawId
28516
- );
28517
- }
28518
- let partnerParticipantId;
28519
- if (participantType === INDIVIDUAL && matchUpType === DOUBLES_MATCHUP) {
28520
- const relevantParticipantInfo = filteredRelevantParticipantIds.find(
28521
- (participantInfo) => {
28522
- return participantInfo.relevantParticipantId !== relevantParticipantId && participantInfo.participantType === INDIVIDUAL;
28523
- }
28524
- );
28525
- partnerParticipantId = relevantParticipantInfo?.relevantParticipantId;
28526
- }
28527
- const filteredRelevantOpponents = relevantOpponents?.filter(
28528
- (opponent2) => matchUpType === TEAM_MATCHUP && participantType === TEAM_PARTICIPANT && opponent2.participantType === TEAM_PARTICIPANT || matchUpType === SINGLES_MATCHUP && opponent2.participantType === INDIVIDUAL || matchUpType === DOUBLES_MATCHUP && (participantType === INDIVIDUAL ? [INDIVIDUAL, PAIR].includes(opponent2.participantType) : (
28529
- // for PAIR participants only show PAIR opponenents
28530
- opponent2.participantType === PAIR
28531
- ))
28532
- ) || [];
28533
- filteredRelevantOpponents.forEach(
28534
- ({
28535
- relevantParticipantId: opponentParticipantId2,
28536
- participantType: opponentParticipantType
28537
- }) => {
28538
- if (!participantIdMap[relevantParticipantId].opponents) {
28539
- participantIdMap[relevantParticipantId].opponents = {};
28540
- }
28541
- participantIdMap[relevantParticipantId].opponents[opponentParticipantId2] = {
28542
- eventId,
28543
- drawId,
28544
- matchUpId,
28545
- participantType: opponentParticipantType,
28546
- participantId: opponentParticipantId2
28547
- };
28548
- }
28549
- );
28550
- const opponentParticipantInfo = filteredRelevantOpponents.map(
28551
- ({ relevantParticipantId: relevantParticipantId2, participantType: participantType2 }) => ({
28552
- participantId: relevantParticipantId2,
28553
- participantType: participantType2
28554
- })
28555
- );
28556
- const includeMatchUp = matchUpType !== TEAM_MATCHUP && [INDIVIDUAL, PAIR].includes(participantType) || matchUpType === TEAM_MATCHUP && participantType === TEAM_PARTICIPANT;
28557
- if (includeMatchUp)
28558
- participantIdMap[relevantParticipantId].matchUps[matchUpId] = definedAttributes({
28559
- collectionId,
28560
- collectionPosition,
28561
- drawId,
28562
- eventId,
28563
- eventType,
28564
- eventDrawsCount,
28565
- finishingRound,
28566
- finishingPositionRange: finishingPositionRange2,
28567
- loserTo,
28568
- matchUpId,
28569
- matchUpType,
28570
- matchUpFormat,
28571
- matchUpStatus,
28572
- matchUpStatusCodes,
28573
- matchUpTieId,
28574
- opponentParticipantInfo,
28575
- participantWon,
28576
- partnerParticipantId,
28577
- perspectiveScoreString: participantScore,
28578
- processCodes,
28579
- roundName,
28580
- roundNumber,
28581
- roundPosition,
28582
- schedule,
28583
- score,
28584
- sides,
28585
- stage,
28586
- stageSequence,
28587
- structureName,
28588
- structureId,
28589
- tieFormat,
28590
- tournamentId,
28591
- winnerTo,
28592
- winningSide
28593
- });
28594
- if (partnerParticipantId) {
28595
- participantIdMap[relevantParticipantId].events[eventId].partnerParticipantIds.push(partnerParticipantId);
28596
- participantIdMap[relevantParticipantId].draws[drawId].partnerParticipantIds.push(partnerParticipantId);
28597
- participantIdMap[relevantParticipantId].events[eventId].partnerParticipantId = partnerParticipantId;
28598
- participantIdMap[relevantParticipantId].draws[drawId].partnerParticipantId = partnerParticipantId;
28599
- }
28600
- if (winningSide) {
28601
- if (participantWon) {
28602
- participantIdMap[relevantParticipantId].wins++;
28603
- } else {
28604
- participantIdMap[relevantParticipantId].losses++;
28605
- }
28606
- }
28607
- }
28608
- );
28609
- });
28610
- if (Array.isArray(matchUp.potentialParticipants)) {
28611
- const potentialParticipantIds = getParticipantIds(
28612
- matchUp.potentialParticipants.flat()
28613
- );
28614
- potentialParticipantIds?.forEach((participantId) => {
28615
- const relevantParticipantIds = getRelevantParticipantIds(participantId);
28616
- relevantParticipantIds?.forEach(({ relevantParticipantId }) => {
28617
- participantIdMap[relevantParticipantId].potentialMatchUps[matchUpId] = definedAttributes({
28618
- drawId,
28619
- eventId,
28620
- eventType,
28621
- matchUpId,
28622
- matchUpType,
28623
- matchUpFormat,
28624
- roundName,
28625
- roundNumber,
28626
- roundPosition,
28627
- schedule,
28628
- tieFormat,
28629
- structureName,
28630
- tournamentId,
28631
- potential: true
28632
- });
28633
- });
28634
- });
28635
- }
28636
- }
28637
-
28638
- function addParticipantContext(params) {
28639
- const participantIdsWithConflicts = [];
28640
- const eventsPublishStatuses = {};
28641
- const derivedDrawInfo = {};
28642
- const participantIdMap = {};
28643
- const initializeParticipantId = (participantId) => {
28644
- if (!participantIdMap[participantId])
28645
- participantIdMap[participantId] = {
28646
- groupParticipantIds: [],
28647
- teamParticipantIds: [],
28648
- pairParticipantIds: [],
28649
- potentialMatchUps: {},
28650
- scheduleItems: [],
28651
- opponents: {},
28652
- matchUps: {},
28653
- events: {},
28654
- groups: [],
28655
- teams: [],
28656
- draws: {},
28657
- losses: 0,
28658
- wins: 0
28659
- };
28660
- };
28661
- const { tournamentRecord, participantFilters, allTournamentParticipants } = params;
28662
- const { relevantParticipantIdsMap } = getRelevantParticipantIdsMap({
28663
- processParticipantId: initializeParticipantId,
28664
- tournamentRecord
28665
- });
28666
- const targetParticipantIds = participantFilters?.participantIds;
28667
- const getRelevantParticipantIds = (participantId) => {
28668
- const relevantParticipantIds = participantId && relevantParticipantIdsMap[participantId] || [];
28669
- relevantParticipantIds.push(participantId);
28670
- return relevantParticipantIds.some(
28671
- (obj) => !targetParticipantIds || targetParticipantIds.includes(obj.relevantParticipantId)
28672
- ) ? relevantParticipantIds : [];
28673
- };
28674
- params.withGroupings && allTournamentParticipants.forEach((participant) => {
28675
- if (participant.participantType === GROUP) {
28676
- const groupParticipantId = participant.participantId;
28677
- participant?.individualParticipantIds?.forEach((participantId) => {
28678
- if (!participantIdMap[participantId].groupParticipantIds.includes(
28679
- groupParticipantId
28680
- )) {
28681
- participantIdMap[participantId].groupParticipantIds.push(
28682
- groupParticipantId
28683
- );
28684
- participantIdMap[participantId].groups.push({
28685
- participantRoleResponsibilities: participant.participantRoleResponsibilities,
28686
- participantOtherName: participant.participantOtherName,
28687
- participantName: participant.participantName,
28688
- participantId: participant.participantId
28689
- });
28690
- }
28691
- });
28692
- }
28693
- if (participant.participantType === TEAM$2) {
28694
- const teamParticipantId = participant.participantId;
28695
- participant?.individualParticipantIds?.forEach((participantId) => {
28696
- if (!participantIdMap[participantId]?.teamParticipantIds?.includes(
28697
- teamParticipantId
28698
- )) {
28699
- participantIdMap[participantId]?.teamParticipantIds.push(
28700
- teamParticipantId
28701
- );
28702
- participantIdMap[participantId]?.teams.push({
28703
- participantRoleResponsibilities: participant.participantRoleResponsibilities,
28704
- participantOtherName: participant.participantOtherName,
28705
- participantName: participant.participantName,
28706
- participantId: participant.participantId,
28707
- teamId: participant.teamId
28708
- });
28709
- }
28710
- });
28711
- }
28712
- if (participant.participantType === PAIR) {
28713
- const pairParticipantId = participant.participantId;
28714
- participant?.individualParticipantIds?.forEach((participantId) => {
28715
- if (participantIdMap[participantId] && !participantIdMap[participantId].pairParticipantIds.includes(
28716
- pairParticipantId
28717
- )) {
28718
- participantIdMap[participantId].pairParticipantIds.push(
28719
- pairParticipantId
28720
- );
28721
- }
28722
- });
28723
- }
28724
- });
28725
- if (params.withMatchUps) {
28726
- getMatchUpDependencies({ tournamentRecord });
28727
- }
28728
- if (params.withScheduleItems || params.scheduleAnalysis || params.withStatistics || params.withOpponents || params.withMatchUps || params.withSeeding || params.withEvents || params.withDraws) {
28729
- params.tournamentEvents?.forEach((rawEvent) => {
28730
- const event = makeDeepCopy(rawEvent, true, true);
28731
- const flightProfile = getFlightProfile({ event }).flightProfile;
28732
- const eventDrawsCount = flightProfile?.flights?.length || event.drawDefinitions?.length || 0;
28733
- (event.drawDefinitions || []).forEach((drawDefinition, i) => {
28734
- if (event?.eventType === TEAM$2) {
28735
- const { extension } = findExtension$2({
28736
- element: rawEvent.drawDefinitions[i],
28737
- // rawEvent because deepCopy has converted extensions
28738
- name: LINEUPS
28739
- });
28740
- if (extension)
28741
- drawDefinition.extensions = [extension];
28742
- }
28743
- });
28744
- const { eventId, eventName, eventType, category } = event;
28745
- const eventInfo = { eventId, eventName, eventType, category };
28746
- const extensionKeys = event && Object.keys(event).filter((key) => key.startsWith("_"));
28747
- extensionKeys?.forEach(
28748
- (extensionKey) => eventInfo[extensionKey] = event[extensionKey]
28749
- );
28750
- const eventEntries = event.entries || [];
28751
- const itemType = `${PUBLISH}.${STATUS$1}`;
28752
- const { timeItem } = getEventTimeItem({
28753
- itemType,
28754
- event
28755
- });
28756
- if (timeItem?.itemValue?.PUBLIC) {
28757
- const { drawIds: publishedDrawIds = [], seeding } = timeItem.itemValue.PUBLIC || {};
28758
- const publishedSeeding = {
28759
- published: void 0,
28760
- // seeding can be present for all entries in an event when no flights have been defined
28761
- seedingScaleNames: [],
28762
- drawIds: []
28763
- // seeding can be specific to drawIds
28764
- };
28765
- if (seeding)
28766
- Object.assign(publishedSeeding, timeItem.itemValue.PUBLIC.seeding);
28767
- eventsPublishStatuses[eventId] = {
28768
- publishedDrawIds,
28769
- publishedSeeding
28770
- };
28771
- }
28772
- const disallowedConstants = [
28773
- ...Object.values(extensionConstants)
28774
- ];
28775
- const disallowedKeys = disallowedConstants.map(
28776
- (constant) => `_${constant}`
28777
- );
28778
- const filteredEventInfo = eventInfo && Object.keys(eventInfo).filter((key) => !disallowedKeys.includes(key)).reduce((obj, key) => {
28779
- obj[key] = eventInfo[key];
28780
- return obj;
28781
- }, {});
28782
- eventEntries?.filter((entry) => entry?.participantId).forEach((entry) => {
28783
- const { participantId, entryStage, entryStatus, entryPosition } = entry;
28784
- const relevantParticipantIds = getRelevantParticipantIds(participantId);
28785
- relevantParticipantIds?.forEach(({ relevantParticipantId }) => {
28786
- if (!participantIdMap[relevantParticipantId])
28787
- initializeParticipantId(relevantParticipantId);
28788
- participantIdMap[relevantParticipantId].events[eventId] = {
28789
- ...filteredEventInfo,
28790
- partnerParticipantIds: [],
28791
- entryPosition,
28792
- entryStatus,
28793
- entryStage,
28794
- drawIds: [],
28795
- eventId
28796
- };
28797
- });
28798
- });
28799
- const addDrawData = ({ drawEntry, drawId }) => {
28800
- const { participantId, entryStage, entryStatus, entryPosition } = drawEntry;
28801
- const relevantParticipantIds = getRelevantParticipantIds(participantId);
28802
- relevantParticipantIds?.forEach(({ relevantParticipantId }) => {
28803
- if (!participantIdMap[relevantParticipantId].events[eventId]) {
28804
- participantIdMap[relevantParticipantId].events[eventId] = {
28805
- ...filteredEventInfo,
28806
- partnerParticipantIds: [],
28807
- entryPosition,
28808
- entryStatus,
28809
- entryStage,
28810
- drawIds: [],
28811
- eventId
28812
- };
28813
- }
28814
- if (!participantIdMap[relevantParticipantId].draws[drawId]) {
28815
- const positionAssignments = getDerivedPositionAssignments({
28816
- participantId: relevantParticipantId,
28817
- derivedDrawInfo,
28818
- drawId
28819
- });
28820
- const seedAssignments = getDerivedSeedAssignments({
28821
- participantId: relevantParticipantId,
28822
- derivedDrawInfo,
28823
- drawId
28824
- });
28825
- participantIdMap[relevantParticipantId].draws[drawId] = definedAttributes({
28826
- qualifyingDrawSize: derivedDrawInfo[drawId]?.qualifyingDrawSize,
28827
- drawSize: derivedDrawInfo[drawId]?.drawSize,
28828
- partnerParticipantIds: [],
28829
- positionAssignments,
28830
- eventDrawsCount,
28831
- seedAssignments,
28832
- entryPosition,
28833
- entryStatus,
28834
- entryStage,
28835
- eventId,
28836
- drawId
28837
- });
28838
- }
28839
- const eventDrawIds = participantIdMap[relevantParticipantId].events[eventId].drawIds;
28840
- if (eventDrawIds && !eventDrawIds?.includes(drawId)) {
28841
- participantIdMap[relevantParticipantId].events[eventId].drawIds.push(drawId);
28842
- }
28843
- });
28844
- };
28845
- const drawIdsWithDefinitions = event.drawDefinitions?.map(({ drawId }) => drawId) || [];
28846
- eventInfo._flightProfile?.flights?.forEach((flight) => {
28847
- const { drawId, drawEntries } = flight;
28848
- if (!drawIdsWithDefinitions.includes(drawId)) {
28849
- drawEntries?.forEach(
28850
- (drawEntry) => addDrawData({ drawEntry, drawId })
28851
- );
28852
- }
28853
- });
28854
- const { drawDetails, derivedInfo } = getDrawDetails({
28855
- eventEntries,
28856
- event
28857
- });
28858
- Object.assign(derivedDrawInfo, derivedInfo);
28859
- if (event.eventType === TEAM$2 || // for TEAM events some individual attributes can only be derived by processing
28860
- params.withScheduleItems || params.scheduleAnalysis || params.withStatistics || params.withOpponents || params.withMatchUps || params.withDraws) {
28861
- const matchUps = allEventMatchUps({
28862
- afterRecoveryTimes: params.scheduleAnalysis,
28863
- participants: allTournamentParticipants,
28864
- nextMatchUps: true,
28865
- tournamentRecord,
28866
- inContext: true,
28867
- event
28868
- })?.matchUps;
28869
- matchUps?.forEach(
28870
- (matchUp) => processMatchUp({
28871
- relevantParticipantIdsMap,
28872
- participantFilters,
28873
- participantIdMap,
28874
- derivedDrawInfo,
28875
- eventDrawsCount,
28876
- drawDetails,
28877
- eventType,
28878
- matchUp
28879
- })
28880
- );
28881
- }
28882
- });
28883
- }
28884
- params.tournamentParticipants?.forEach((participant) => {
28885
- const { scheduleConflicts, scheduleItems } = annotateParticipant({
28886
- ...params,
28887
- eventsPublishStatuses,
28888
- participantIdMap,
28889
- derivedDrawInfo,
28890
- participant
28891
- });
28892
- if (params.withSignInStatus) {
28893
- const { timeItem } = getTimeItem({
28894
- itemType: SIGN_IN_STATUS,
28895
- element: participant
28896
- });
28897
- participant.signedIn = timeItem?.itemValue === SIGNED_IN;
28898
- }
28899
- if (params.withScheduleItems) {
28900
- participant.scheduleItems = scheduleItems;
28901
- }
28902
- if (params.scheduleAnalysis) {
28903
- participant.scheduleConflicts = scheduleConflicts;
28904
- if (scheduleConflicts?.length && !participantIdsWithConflicts.includes(participant.participantId)) {
28905
- participantIdsWithConflicts.push(participant.participantId);
28906
- }
28907
- }
28908
- if (params.withGroupings !== false) {
28909
- const participantAttributes = participantIdMap[participant.participantId];
28910
- participant.groupParticipantIds = participantAttributes?.groupParticipantIds;
28911
- participant.pairParticipantIds = participantAttributes?.pairParticipantIds;
28912
- participant.teamParticipantIds = participantAttributes?.teamParticipantIds;
28913
- participant.groups = participantAttributes?.groups;
28914
- participant.teams = participantAttributes?.teams;
28915
- }
28916
- if (params.withTeamMatchUps) ;
28917
- });
28918
- return { participantIdsWithConflicts, eventsPublishStatuses };
28919
- }
28920
-
28921
- function getTournamentParticipants(params) {
28922
- const {
28923
- participantFilters = {},
28924
- convertExtensions,
28925
- policyDefinitions,
28926
- withScheduleItems,
28927
- scheduleAnalysis,
28928
- withSignInStatus,
28929
- withTeamMatchUps,
28930
- // not implemented
28931
- tournamentRecord,
28932
- usePublishState,
28933
- withScaleValues,
28934
- withStatistics,
28935
- withGroupings,
28936
- withOpponents,
28937
- withMatchUps,
28938
- withSeeding,
28939
- withEvents,
28940
- withDraws,
28941
- inContext,
28942
- withISO2,
28943
- withIOC
28944
- } = params;
28945
- if (!tournamentRecord)
28946
- return { error: MISSING_TOURNAMENT_RECORD };
28947
- if (!tournamentRecord.participants)
28948
- return { error: MISSING_PARTICIPANTS };
28949
- const allTournamentParticipants = tournamentRecord.participants.map(
28950
- // (participant) => makeDeepCopy(participant, convertExtensions, true)
28951
- (participant) => makeDeepCopy(participant, convertExtensions)
28952
- // removed until Mongo/Mongoose issues resolved
28953
- );
28954
- if (typeof participantFilters !== "object")
28955
- return { error: INVALID_OBJECT, participantFilters };
28956
- if (inContext) {
28957
- allTournamentParticipants?.forEach((participant) => {
28958
- if ([PAIR, TEAM, GROUP].includes(participant.participantType)) {
28959
- participant.individualParticipants = participant.individualParticipantIds?.map((participantId) => {
28960
- const targetParticipant = tournamentRecord.participants.find(
28961
- (p) => p.participantId === participantId
28962
- );
28963
- const individualParticipant = makeDeepCopy(
28964
- targetParticipant,
28965
- convertExtensions,
28966
- true
28967
- );
28968
- if (withScaleValues) {
28969
- const { ratings, rankings } = getScaleValues({
28970
- participant: individualParticipant
28971
- });
28972
- individualParticipant.ratings = ratings;
28973
- individualParticipant.rankings = rankings;
28974
- }
28975
- if (withIOC || withISO2)
28976
- addNationalityCode({
28977
- participant: individualParticipant,
28978
- withISO2,
28979
- withIOC
28980
- });
28981
- return individualParticipant;
28982
- });
28983
- }
28984
- });
28985
- }
28986
- let tournamentParticipants = participantFilters ? filterParticipants({
28987
- participants: allTournamentParticipants,
28988
- participantFilters,
28989
- tournamentRecord
28990
- }) : allTournamentParticipants;
28991
- let participantIdsWithConflicts, eventsPublishStatuses;
28992
- const addContext = withScheduleItems || withSignInStatus || scheduleAnalysis || withScaleValues || withStatistics || withGroupings || withOpponents || withMatchUps || withSeeding || withEvents || withDraws || withISO2 || withIOC;
28993
- if (addContext) {
28994
- const result = addParticipantContext({
28995
- tournamentEvents: tournamentRecord.events,
28996
- allTournamentParticipants,
28997
- tournamentParticipants,
28998
- participantFilters,
28999
- withScheduleItems,
29000
- withSignInStatus,
29001
- tournamentRecord,
29002
- scheduleAnalysis,
29003
- withTeamMatchUps,
29004
- usePublishState,
29005
- withScaleValues,
29006
- withStatistics,
29007
- withGroupings,
29008
- withOpponents,
29009
- withMatchUps,
29010
- withSeeding,
29011
- withEvents,
29012
- withDraws,
29013
- withISO2,
29014
- withIOC
29015
- });
29016
- participantIdsWithConflicts = result?.participantIdsWithConflicts;
29017
- eventsPublishStatuses = result?.eventsPublishStatuses;
29018
- }
29019
- const participantAttributes = policyDefinitions?.[POLICY_TYPE_PARTICIPANT];
29020
- if (participantAttributes?.participant) {
29021
- tournamentParticipants = tournamentParticipants.map(
29022
- (participant) => attributeFilter({
29023
- template: participantAttributes.participant,
29024
- source: participant
29025
- })
29026
- );
29027
- }
29028
- return {
29029
- participantIdsWithConflicts,
29030
- tournamentParticipants,
29031
- eventsPublishStatuses
29032
- };
29033
- }
29034
-
29035
- function deepMerge(existing, incoming, arrayMerge) {
29036
- if (!existing && incoming)
29037
- return incoming;
29038
- if (existing && !incoming)
29039
- return existing;
29040
- if (typeof existing !== "object" || typeof incoming !== "object")
29041
- return existing;
29042
- const keys = unique(Object.keys(existing).concat(Object.keys(incoming)));
29043
- return keys.reduce((merged, key) => {
29044
- if (!incoming[key]) {
29045
- merged[key] = existing[key];
29046
- } else if (!existing[key]) {
29047
- merged[key] = incoming[key];
29048
- } else if (typeof existing[key] !== typeof incoming[key]) {
29049
- merged[key] = incoming[key];
29050
- } else if (Array.isArray(existing[key])) {
29051
- if (arrayMerge === true || Array.isArray(arrayMerge) && arrayMerge.includes(key)) {
29052
- const mergedArrays = unique(
29053
- existing[key].map((e) => JSON.stringify(e)).concat(incoming[key].map((i) => JSON.stringify(i)))
29054
- ).map((u) => JSON.parse(u));
29055
- merged[key] = mergedArrays;
29056
- } else {
29057
- merged[key] = incoming[key];
29058
- }
29059
- } else if (typeof existing[key] === "object") {
29060
- merged[key] = deepMerge(existing[key], incoming[key], arrayMerge);
29061
- } else {
29062
- merged[key] = incoming[key];
29063
- }
29064
- return merged;
29065
- }, {});
29066
- }
29067
-
29068
- function getParticipants(params) {
29069
- const { tournamentRecords } = params || {};
29070
- if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length) {
29071
- return { error: MISSING_TOURNAMENT_RECORDS };
29072
- }
29073
- const participantMap = {};
29074
- const participants = [];
29075
- const derivedEventInfo = {};
29076
- const derivedDrawInfo = {};
29077
- const matchUps = [];
29078
- const mappedMatchUps = {};
29079
- const participantIdsWithConflicts = [];
29080
- for (const tournamentRecord of Object.values(tournamentRecords)) {
29081
- const {
29082
- participantIdsWithConflicts: idsWithConflicts,
29083
- mappedMatchUps: tournamentMappedMatchUps,
29084
- participantMap: tournamentParticipantMap,
29085
- participants: tournamentParticipants,
29086
- matchUps: tournamentMatchUps,
29087
- derivedEventInfo: eventInfo,
29088
- derivedDrawInfo: drawInfo
29089
- } = getParticipants$1({ tournamentRecord, ...params });
29090
- Object.assign(mappedMatchUps, tournamentMappedMatchUps);
29091
- Object.assign(participantMap, tournamentParticipantMap);
29092
- Object.assign(derivedEventInfo, eventInfo);
29093
- Object.assign(derivedDrawInfo, drawInfo);
29094
- participants.push(...tournamentParticipants ?? []);
29095
- matchUps.push(...tournamentMatchUps ?? []);
29096
- idsWithConflicts?.forEach((participantId) => {
29097
- if (!participantIdsWithConflicts.includes(participantId))
29098
- participantIdsWithConflicts.push(participantId);
29099
- });
29100
- }
29101
- return {
29102
- participantIdsWithConflicts,
29103
- derivedEventInfo,
29104
- derivedDrawInfo,
29105
- participantMap,
29106
- mappedMatchUps,
29107
- participants,
29108
- ...SUCCESS,
29109
- matchUps
29110
- };
29111
- }
29112
- function getCompetitionParticipants(params) {
29113
- const { tournamentRecords } = params || {};
29114
- if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length)
29115
- return { error: MISSING_TOURNAMENT_RECORDS };
29116
- let competitionParticipants = [];
29117
- const participantIdsWithConflicts = [];
29118
- const competitionParticipantIds = [];
29119
- for (const tournamentRecord of Object.values(tournamentRecords)) {
29120
- const {
29121
- tournamentParticipants,
29122
- participantIdsWithConflicts: idsWithConflicts
29123
- } = getTournamentParticipants({
29124
- tournamentRecord,
29125
- ...params
29126
- });
29127
- for (const tournamentParticipant of tournamentParticipants) {
29128
- const { participantId } = tournamentParticipant;
29129
- if (!competitionParticipantIds.includes(participantId)) {
29130
- competitionParticipantIds.push(participantId);
29131
- competitionParticipants.push(tournamentParticipant);
29132
- } else {
29133
- competitionParticipants = competitionParticipants.map(
29134
- (participant) => participant.participantId !== participantId ? participant : deepMerge(participant, tournamentParticipant, true)
29135
- );
29136
- }
29137
- }
29138
- idsWithConflicts?.forEach((participantId) => {
29139
- if (!participantIdsWithConflicts.includes(participantId))
29140
- participantIdsWithConflicts.push(participantId);
29141
- });
29142
- }
29143
- return { competitionParticipants, participantIdsWithConflicts, ...SUCCESS };
29144
- }
29145
- function publicFindParticipant({
29146
- policyDefinitions,
29147
- tournamentRecords,
29148
- participantId,
29149
- inContext,
29150
- personId
29151
- }) {
29152
- if (!tournamentRecords)
29153
- return { error: MISSING_TOURNAMENT_RECORDS };
29154
- if (typeof participantId !== "string" && typeof personId !== "string")
29155
- return { error: MISSING_VALUE, stack: "publicFindParticipant" };
29156
- let participant, tournamentId;
29157
- for (const tournamentRecord of Object.values(tournamentRecords)) {
29158
- tournamentId = tournamentRecord.tournamentId;
29159
- const { tournamentParticipants } = getTournamentParticipants({
29160
- policyDefinitions,
29161
- tournamentRecord,
29162
- inContext
29163
- });
29164
- participant = findParticipant({
29165
- tournamentParticipants,
29166
- internalUse: true,
29167
- policyDefinitions,
29168
- participantId,
29169
- personId
29170
- });
29171
- if (participant)
29172
- break;
29173
- }
29174
- return { participant, tournamentId, ...SUCCESS };
29175
- }
29176
-
29177
- const penaltyTemplate = ({ penaltyId = UUID() } = {}) => ({
29178
- refereeParticipantId: void 0,
29179
- penaltyCode: void 0,
29180
- penaltyType: void 0,
29181
- extensions: void 0,
29182
- matchUpId: void 0,
29183
- createdAt: void 0,
29184
- issuedAt: void 0,
29185
- notes: void 0,
29186
- penaltyId
29187
- });
29188
-
29189
- function addPenalty$1({
29190
- refereeParticipantId,
29191
- tournamentRecord,
29192
- participantIds,
29193
- penaltyCode,
29194
- penaltyType,
29195
- extensions,
29196
- penaltyId,
29197
- matchUpId,
29198
- issuedAt,
29199
- notes
29200
- }) {
29201
- if (!tournamentRecord)
29202
- return { error: MISSING_TOURNAMENT_RECORD };
29203
- if (!participantIds)
29204
- return { error: MISSING_PARTICIPANT_ID };
29205
- if (!penaltyType)
29206
- return { error: MISSING_PENALTY_TYPE };
29207
- const participants = tournamentRecord?.participants || [];
29208
- const relevantParticipants = participants.filter(
29209
- (participant) => participantIds.includes(participant.participantId)
29210
- );
29211
- if (!relevantParticipants.length)
29212
- return { error: PARTICIPANT_NOT_FOUND };
29213
- const createdAt = (/* @__PURE__ */ new Date()).toISOString();
29214
- const penaltyItem = Object.assign(penaltyTemplate({ penaltyId }), {
29215
- refereeParticipantId,
29216
- penaltyCode,
29217
- penaltyType,
29218
- matchUpId,
29219
- notes,
29220
- issuedAt,
29221
- createdAt
29222
- });
29223
- if (Array.isArray(extensions)) {
29224
- extensions.forEach(
29225
- (extension) => addExtension$1({ element: penaltyItem, extension })
29226
- );
29227
- }
29228
- relevantParticipants.forEach((participant) => {
29229
- if (!participant.penalties)
29230
- participant.penalties = [];
29231
- participant.penalties.push(penaltyItem);
29232
- });
29233
- addNotice({
29234
- topic: MODIFY_PARTICIPANTS,
29235
- payload: {
29236
- tournamentId: tournamentRecord.tournamentId,
29237
- participants: relevantParticipants
29238
- }
29239
- });
29240
- return { ...SUCCESS, penaltyId: penaltyItem.penaltyId };
29241
- }
29242
- function removePenalty$1({
29243
- tournamentRecord,
29244
- penaltyId
29245
- }) {
29246
- if (!tournamentRecord)
29247
- return { error: MISSING_TOURNAMENT_RECORD };
29248
- if (!penaltyId)
29249
- return { error: MISSING_PENALTY_ID };
29250
- const participants = tournamentRecord?.participants || [];
29251
- const modifiedParticipants = [];
29252
- let penaltyRemoved = false;
29253
- let removedPenalty;
29254
- participants.forEach((participant) => {
29255
- let participantModified = false;
29256
- participant.penalties = (participant.penalties || []).filter((penalty) => {
29257
- if (penalty.penaltyId === penaltyId) {
29258
- participantModified = true;
29259
- if (!penaltyRemoved) {
29260
- removedPenalty = penalty;
29261
- penaltyRemoved = true;
29262
- }
29263
- }
29264
- if (participantModified)
29265
- modifiedParticipants.push(participant);
29266
- return penalty.penaltyId !== penaltyId;
29267
- });
29268
- });
29269
- if (removedPenalty) {
29270
- addNotice({
29271
- topic: MODIFY_PARTICIPANTS,
29272
- payload: {
29273
- tournamentId: tournamentRecord.tournamentId,
29274
- participants: modifiedParticipants
29275
- }
29276
- });
29277
- }
29278
- return removedPenalty ? { ...SUCCESS, penalty: removedPenalty } : { error: PENALTY_NOT_FOUND };
29279
- }
29280
- function getTournamentPenalties({
29281
- tournamentRecord
29282
- }) {
29283
- if (!tournamentRecord)
29284
- return { error: MISSING_TOURNAMENT_RECORD };
29285
- const participants = tournamentRecord?.participants || [];
29286
- const allPenalties = participants.reduce((penalties, participant) => {
29287
- const { participantId } = participant;
29288
- (participant.penalties || []).forEach((penalty) => {
29289
- const { penaltyId } = penalty || {};
29290
- if (penalties[penaltyId]) {
29291
- penalties[penaltyId].participants.push(participantId);
29292
- } else {
29293
- penalties[penaltyId] = {
29294
- ...penalty,
29295
- participantIds: [participantId]
29296
- };
29297
- }
29298
- });
29299
- return penalties;
29300
- }, {});
29301
- return { penalties: Object.values(allPenalties) };
29302
- }
29303
- function modifyPenalty$1({
29304
- tournamentRecord,
29305
- modifications,
29306
- penaltyId
29307
- }) {
29308
- if (!tournamentRecord)
29309
- return { error: MISSING_TOURNAMENT_RECORD };
29310
- if (!modifications)
29311
- return { error: INVALID_VALUES, modifications };
29312
- if (!penaltyId)
29313
- return { error: MISSING_PENALTY_ID };
29314
- const participants = tournamentRecord?.participants || [];
29315
- const validAttributes = Object.keys(penaltyTemplate()).filter(
29316
- (attribute) => attribute !== "penaltyId"
29317
- );
29318
- const validModificationAttributes = Object.keys(modifications).filter(
29319
- (attribute) => validAttributes.includes(attribute)
29320
- );
29321
- if (!validModificationAttributes.length)
29322
- return { error: NO_VALID_ATTRIBUTES };
29323
- let updatedPenalty;
29324
- const modifiedParticipants = [];
29325
- participants.forEach((participant) => {
29326
- let participantModified = false;
29327
- participant.penalties = (participant.penalties || []).map((penalty) => {
29328
- if (penalty.penaltyId === penaltyId) {
29329
- participantModified = true;
29330
- validModificationAttributes.forEach(
29331
- (attribute) => Object.assign(penalty, { [attribute]: modifications[attribute] })
29332
- );
29333
- if (!updatedPenalty)
29334
- updatedPenalty = penalty;
29335
- }
29336
- return penalty;
29337
- });
29338
- if (participantModified)
29339
- modifiedParticipants.push(participant);
29340
- });
29341
- if (updatedPenalty) {
29342
- addNotice({
29343
- topic: MODIFY_PARTICIPANTS,
29344
- payload: {
29345
- tournamentId: tournamentRecord.tournamentId,
29346
- participants: modifiedParticipants
29347
- }
29348
- });
29349
- }
29350
- return updatedPenalty ? { ...SUCCESS, penalty: updatedPenalty } : { error: PENALTY_NOT_FOUND };
29351
- }
29352
-
29353
- function addPenalty(params) {
29354
- const { tournamentRecords, participantIds } = params;
29355
- let penaltyId;
29356
- for (const tournamentRecord of Object.values(tournamentRecords)) {
29357
- const participants = getParticipants$1({
29358
- tournamentRecord
29359
- }).participants ?? [];
29360
- const tournamentParticipantIds = participants?.map(extractAttributes("participantId")).filter((participantId) => participantIds.includes(participantId));
29361
- if (tournamentParticipantIds.length) {
29362
- const result = addPenalty$1({
29363
- ...params,
29364
- penaltyId: params.penaltyId || penaltyId,
29365
- tournamentRecord,
29366
- participantIds: tournamentParticipantIds
29367
- });
29368
- penaltyId = result.penaltyId;
29369
- }
29370
- }
29371
- return penaltyId ? { ...SUCCESS, penaltyId } : { error: PARTICIPANT_NOT_FOUND };
29372
- }
29373
- function modifyPenalty(params) {
29374
- const { tournamentRecords } = params;
29375
- if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length)
29376
- return { error: MISSING_TOURNAMENT_RECORDS };
29377
- for (const tournamentRecord of Object.values(tournamentRecords)) {
29378
- const result = modifyPenalty$1({ tournamentRecord, ...params });
29379
- if (result.error && result.error !== PENALTY_NOT_FOUND)
29380
- return result;
29381
- }
29382
- return { ...SUCCESS };
29383
- }
29384
- function removePenalty(params) {
29385
- const { tournamentRecords } = params;
29386
- if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length)
29387
- return { error: MISSING_TOURNAMENT_RECORDS };
29388
- for (const tournamentRecord of Object.values(tournamentRecords)) {
29389
- const result = removePenalty$1({ tournamentRecord, ...params });
29390
- if (result.error && result.error !== PENALTY_NOT_FOUND)
29391
- return result;
28296
+ return { ...SUCCESS };
28297
+ }
28298
+ function removePenalty(params) {
28299
+ const { tournamentRecords } = params;
28300
+ if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length)
28301
+ return { error: MISSING_TOURNAMENT_RECORDS };
28302
+ for (const tournamentRecord of Object.values(tournamentRecords)) {
28303
+ const result = removePenalty$1({ tournamentRecord, ...params });
28304
+ if (result.error && result.error !== PENALTY_NOT_FOUND)
28305
+ return result;
29392
28306
  }
29393
28307
  return { ...SUCCESS };
29394
28308
  }
@@ -31895,6 +30809,7 @@ function getEventMatchUpFormatTiming$1({
31895
30809
  if (!event)
31896
30810
  return { error: MISSING_EVENT };
31897
30811
  let matchUpFormatDefinitions = [];
30812
+ let info;
31898
30813
  if (!matchUpFormats?.length) {
31899
30814
  const { policy } = findPolicy({
31900
30815
  policyType: POLICY_TYPE_SCORING,
@@ -31908,20 +30823,19 @@ function getEventMatchUpFormatTiming$1({
31908
30823
  name: SCHEDULE_TIMING,
31909
30824
  event
31910
30825
  });
30826
+ let matchUpAverageTimes, matchUpRecoveryTimes;
31911
30827
  if (extension?.value) {
31912
- matchUpFormatDefinitions = unique(
31913
- [
31914
- ...(extension.value.matchUpAverageTimes || []).map(
31915
- (at) => at.matchUpFormatCodes
31916
- ),
31917
- ...(extension.value.matchUpRecoveryTimes || []).map(
31918
- (at) => at.matchUpFormatCodes
31919
- )
31920
- ].flat()
31921
- ).map((matchUpFormat) => ({ matchUpFormat }));
30828
+ ({ matchUpAverageTimes, matchUpRecoveryTimes } = extension.value);
31922
30829
  } else {
31923
- return { error: MISSING_SCORING_POLICY };
30830
+ ({ matchUpAverageTimes, matchUpRecoveryTimes } = POLICY_SCHEDULING_DEFAULT[POLICY_TYPE_SCHEDULING]);
31924
30831
  }
30832
+ matchUpFormatDefinitions = unique(
30833
+ [
30834
+ ...(matchUpAverageTimes || []).map((at) => at.matchUpFormatCodes),
30835
+ ...(matchUpRecoveryTimes || []).map((at) => at.matchUpFormatCodes)
30836
+ ].flat()
30837
+ ).map((matchUpFormat) => ({ matchUpFormat }));
30838
+ info = "default scheduling policy in use";
31925
30839
  }
31926
30840
  } else {
31927
30841
  const uniqueMatchUpFormats = [];
@@ -31936,7 +30850,7 @@ function getEventMatchUpFormatTiming$1({
31936
30850
  }).filter(Boolean);
31937
30851
  }
31938
30852
  const { eventType, eventId, category } = event;
31939
- const categoryName = category?.categoryName || category?.ageCategoryCode || eventId;
30853
+ const categoryName = category?.categoryName ?? category?.ageCategoryCode ?? eventId;
31940
30854
  if (!eventId)
31941
30855
  return { error: MISSING_EVENT };
31942
30856
  const eventMatchUpFormatTiming = matchUpFormatDefinitions.map(
@@ -31949,17 +30863,14 @@ function getEventMatchUpFormatTiming$1({
31949
30863
  eventType,
31950
30864
  event
31951
30865
  });
31952
- return Object.assign(
31953
- {},
31954
- {
31955
- ...timing,
31956
- description,
31957
- matchUpFormat
31958
- }
31959
- );
30866
+ return {
30867
+ matchUpFormat,
30868
+ description,
30869
+ ...timing
30870
+ };
31960
30871
  }
31961
30872
  );
31962
- return { eventMatchUpFormatTiming };
30873
+ return definedAttributes({ eventMatchUpFormatTiming, info });
31963
30874
  }
31964
30875
 
31965
30876
  function getEventMatchUpFormatTiming({
@@ -33223,6 +32134,14 @@ function modifyParticipantMatchUpsCount({
33223
32134
  });
33224
32135
  }
33225
32136
 
32137
+ const hasSchedule = ({
32138
+ scheduleAttributes = ["scheduledDate", "scheduledTime"],
32139
+ schedule = {}
32140
+ }) => {
32141
+ const matchUpScheduleKeys = Object.keys(schedule).filter((key) => scheduleAttributes.includes(key)).filter((key) => schedule[key]);
32142
+ return !!matchUpScheduleKeys.length;
32143
+ };
32144
+
33226
32145
  function processAlreadyScheduledMatchUps({
33227
32146
  matchUpPotentialParticipantIds,
33228
32147
  individualParticipantProfiles,
@@ -36914,14 +35833,12 @@ function getParticipantScaleItem$1({
36914
35833
  policyDefinitions,
36915
35834
  scaleAttributes,
36916
35835
  participantId,
36917
- inContext,
36918
35836
  personId
36919
35837
  }) {
36920
35838
  let result = publicFindParticipant({
36921
35839
  tournamentRecords,
36922
35840
  policyDefinitions,
36923
35841
  participantId,
36924
- inContext,
36925
35842
  personId
36926
35843
  });
36927
35844
  if (result.error)
@@ -50086,496 +49003,1590 @@ function clearHistory({ matchUp }) {
50086
49003
  return saveHistory({ matchUp });
50087
49004
  }
50088
49005
 
50089
- function addPoint({ matchUp, point }) {
50090
- if (!point)
50091
- return { error: MISSING_VALUE };
50092
- if (typeof point !== "object")
50093
- return { error: INVALID_VALUES, context: { point } };
50094
- const { history = [] } = getHistory({ matchUp });
50095
- history.push(point);
50096
- return saveHistory({ matchUp, history });
49006
+ function addPoint({ matchUp, point }) {
49007
+ if (!point)
49008
+ return { error: MISSING_VALUE };
49009
+ if (typeof point !== "object")
49010
+ return { error: INVALID_VALUES, context: { point } };
49011
+ const { history = [] } = getHistory({ matchUp });
49012
+ history.push(point);
49013
+ return saveHistory({ matchUp, history });
49014
+ }
49015
+
49016
+ function addGame({ matchUp, game }) {
49017
+ if (typeof game !== "object")
49018
+ return { error: INVALID_VALUES, context: { game } };
49019
+ const { history = [] } = getHistory({ matchUp });
49020
+ history.push(game);
49021
+ return saveHistory({ matchUp, history });
49022
+ }
49023
+
49024
+ function addShot({ matchUp, shot }) {
49025
+ if (typeof shot !== "object")
49026
+ return { error: MISSING_VALUE };
49027
+ const { history = [] } = getHistory({ matchUp });
49028
+ history.push(shot);
49029
+ return saveHistory({ matchUp, history });
49030
+ }
49031
+
49032
+ function addSet({ matchUp, set }) {
49033
+ if (typeof set !== "object")
49034
+ return { error: MISSING_VALUE };
49035
+ const { history = [] } = getHistory({ matchUp });
49036
+ history.push(set);
49037
+ return saveHistory({ matchUp, history });
49038
+ }
49039
+
49040
+ function redo({ matchUp }) {
49041
+ const { history = [], undoHistory = [] } = getHistory({ matchUp });
49042
+ if (undoHistory.length)
49043
+ history.push(undoHistory.pop());
49044
+ return saveHistory({ matchUp, history, undoHistory });
49045
+ }
49046
+
49047
+ function undo({ matchUp }) {
49048
+ const { history = [], undoHistory = [] } = getHistory({ matchUp });
49049
+ undoHistory.push(history.pop());
49050
+ return saveHistory({ matchUp, history, undoHistory });
49051
+ }
49052
+
49053
+ const umo = {
49054
+ scoreboard: () => {
49055
+ },
49056
+ addPoints: () => {
49057
+ },
49058
+ addPoint: () => {
49059
+ }
49060
+ };
49061
+
49062
+ const historyGovernor = {
49063
+ calculateHistoryScore,
49064
+ setServingSide,
49065
+ clearHistory,
49066
+ addPoint,
49067
+ addGame,
49068
+ addShot,
49069
+ addSet,
49070
+ redo,
49071
+ undo,
49072
+ umo
49073
+ };
49074
+
49075
+ function analyzeMatchUp(params) {
49076
+ const { matchUp, sideNumber, setNumber, isTiebreakValue, isPointValue } = params || {};
49077
+ let { matchUpFormat } = params || {};
49078
+ if (!matchUp)
49079
+ return { error: MISSING_MATCHUP };
49080
+ matchUpFormat = matchUpFormat || matchUp?.matchUpFormat;
49081
+ const matchUpScoringFormat = parse(matchUpFormat);
49082
+ const isCompletedMatchUp = !!matchUp?.winningSide;
49083
+ const sets = matchUp.score?.sets;
49084
+ const setsCount = sets?.length;
49085
+ const setIndex = setNumber && setNumber - 1;
49086
+ const isExistingSet = !!sets?.find(
49087
+ (set, index) => set.setNumber === setNumber && index === setIndex
49088
+ );
49089
+ const completedSets = sets?.filter((set) => set?.winningSide) || [];
49090
+ const completedSetsCount = completedSets?.length || 0;
49091
+ const setsFollowingCurrent = setNumber && sets?.slice(setNumber) || [];
49092
+ const isLastSetWithValues = !!(setsCount && setNumber && // EVERY: is this a candidate for .every?
49093
+ setsFollowingCurrent?.reduce((noValues, set) => {
49094
+ return (!set || !set.side1Score && !set.side2Score && !set.side1TiebreakScore && !set.side2TiebreakScore && !set.side1PointScore && !set.side2PointScore) && noValues;
49095
+ }, true));
49096
+ const setObject = setNumber <= setsCount && sets.find((set) => set.setNumber === setNumber);
49097
+ const specifiedSetAnalysis = setObject && analyzeSet({ setObject, matchUpScoringFormat });
49098
+ const {
49099
+ isCompletedSet,
49100
+ sideGameScores,
49101
+ // sidePointScores,
49102
+ sideTiebreakScores
49103
+ } = specifiedSetAnalysis || {};
49104
+ const isActiveSet = !!(setObject && !isCompletedSet && isLastSetWithValues || setNumber && setNumber === setsCount + 1 && !isCompletedMatchUp);
49105
+ const isValidSideNumber = [1, 2].includes(sideNumber);
49106
+ const sideIndex = isValidSideNumber ? sideNumber - 1 : 0;
49107
+ const existingValue = setObject && isValidSideNumber && (!isTiebreakValue && !isPointValue && sideGameScores[sideIndex] !== void 0 && sideGameScores[sideIndex] || isTiebreakValue && sideTiebreakScores[sideIndex] !== void 0 && sideTiebreakScores[sideIndex]);
49108
+ const hasExistingValue = !!existingValue;
49109
+ const completedSetsHaveValidOutcomes = completedSets?.map(
49110
+ (setObject2) => analyzeSet({ setObject: setObject2, matchUpScoringFormat }).isValidSetOutcome
49111
+ ).reduce((valid, validOutcome) => valid && validOutcome, true);
49112
+ const setsWinCounts = completedSets.reduce(
49113
+ (counts, set) => {
49114
+ const { winningSide } = set;
49115
+ const winningSideIndex = winningSide - 1;
49116
+ counts[winningSideIndex]++;
49117
+ return counts;
49118
+ },
49119
+ [0, 0]
49120
+ );
49121
+ const matchUpWinningSide = matchUp?.winningSide;
49122
+ const matchUpWinningSideIndex = matchUpWinningSide && matchUpWinningSide - 1;
49123
+ const matchUpLosingSideIndex = 1 - matchUpWinningSideIndex;
49124
+ const winningSideSetsCount = setsWinCounts[matchUpWinningSideIndex];
49125
+ const losingSideSetsCount = setsWinCounts[matchUpLosingSideIndex];
49126
+ const maxSetsCount = Math.max(...setsWinCounts);
49127
+ const maxSetsInstances = instanceCount(setsWinCounts)[maxSetsCount];
49128
+ const { bestOf } = matchUpScoringFormat || {};
49129
+ const setsToWin = bestOf && Math.ceil(bestOf / 2) || 1;
49130
+ const calculatedWinningSide = maxSetsCount === setsToWin && maxSetsInstances === 1 && setsWinCounts.indexOf(maxSetsCount) + 1 || void 0;
49131
+ const validMatchUpWinningSide = winningSideSetsCount > losingSideSetsCount && matchUpWinningSide === calculatedWinningSide;
49132
+ const validMatchUpOutcome = calculatedWinningSide && completedSetsHaveValidOutcomes && validMatchUpWinningSide;
49133
+ return {
49134
+ completedSetsHaveValidOutcomes,
49135
+ validMatchUpWinningSide,
49136
+ calculatedWinningSide,
49137
+ matchUpScoringFormat,
49138
+ validMatchUpOutcome,
49139
+ isLastSetWithValues,
49140
+ completedSetsCount,
49141
+ isCompletedMatchUp,
49142
+ isValidSideNumber,
49143
+ hasExistingValue,
49144
+ existingValue,
49145
+ isExistingSet,
49146
+ isActiveSet,
49147
+ ...specifiedSetAnalysis
49148
+ };
49149
+ }
49150
+
49151
+ const queryGovernor$1 = {
49152
+ tallyParticipantResults,
49153
+ matchUpIsComplete,
49154
+ analyzeMatchUp,
49155
+ getMatchUpType,
49156
+ scoreHasValue,
49157
+ validMatchUps,
49158
+ validMatchUp
49159
+ };
49160
+
49161
+ let keyedMatchUps = {};
49162
+ let matchUpId;
49163
+ function setState$2(value, deepCopyOption = true) {
49164
+ if (!value)
49165
+ return { error: MISSING_VALUE };
49166
+ if (typeof value !== "object")
49167
+ return { error: INVALID_OBJECT };
49168
+ if (value.matchUpId) {
49169
+ matchUpId = value.matchUpId;
49170
+ keyedMatchUps[matchUpId] = deepCopyOption ? makeDeepCopy(value) : value;
49171
+ } else if (Array.isArray(value)) {
49172
+ for (const m of value.reverse()) {
49173
+ if (m.matchUpId) {
49174
+ keyedMatchUps[m.matchUpId] = deepCopyOption ? makeDeepCopy(m) : m;
49175
+ if (!matchUpId)
49176
+ matchUpId = m.matchUpId;
49177
+ }
49178
+ }
49179
+ } else {
49180
+ for (const m of Object.values(value)) {
49181
+ if (m.matchUpId) {
49182
+ keyedMatchUps[m.matchUpId] = deepCopyOption ? makeDeepCopy(m) : m;
49183
+ if (!matchUpId)
49184
+ matchUpId = m.matchUpId;
49185
+ }
49186
+ }
49187
+ }
49188
+ return deepCopyOption ? makeDeepCopy(value) : value;
49189
+ }
49190
+ function getMatchUp() {
49191
+ return keyedMatchUps[matchUpId];
49192
+ }
49193
+ function getMatchUps() {
49194
+ return Object.values(keyedMatchUps);
49195
+ }
49196
+ function reset() {
49197
+ matchUpId = void 0;
49198
+ keyedMatchUps = {};
49199
+ }
49200
+ function getState$2(params) {
49201
+ return makeDeepCopy(
49202
+ keyedMatchUps[matchUpId],
49203
+ params?.convertExtensions,
49204
+ false,
49205
+ params?.removeExtensions
49206
+ );
49207
+ }
49208
+
49209
+ const matchUpEngine = (() => {
49210
+ const engine = {
49211
+ getState: (params) => getState$2(params),
49212
+ version: () => factoryVersion(),
49213
+ reset: () => {
49214
+ reset();
49215
+ return { ...SUCCESS };
49216
+ },
49217
+ drawId: void 0,
49218
+ error: void 0,
49219
+ success: false,
49220
+ devContext: (contextCriteria) => {
49221
+ setDevContext(contextCriteria);
49222
+ return engine;
49223
+ },
49224
+ setState: (definition, deepCopyOption, deepCopyAttributes) => {
49225
+ setDeepCopy(deepCopyOption, deepCopyAttributes);
49226
+ const result = setState$2(definition);
49227
+ return processResult(result);
49228
+ }
49229
+ };
49230
+ function processResult(result) {
49231
+ if (result?.error) {
49232
+ engine.error = result.error;
49233
+ engine.success = false;
49234
+ } else {
49235
+ engine.error = void 0;
49236
+ engine.success = true;
49237
+ engine.drawId = result.drawId;
49238
+ }
49239
+ return engine;
49240
+ }
49241
+ importGovernors([
49242
+ tieFormatGovernor,
49243
+ historyGovernor,
49244
+ queryGovernor$1,
49245
+ scoreGovernor
49246
+ ]);
49247
+ return engine;
49248
+ function importGovernors(governors) {
49249
+ governors.forEach((governor) => {
49250
+ Object.keys(governor).forEach((methodName) => {
49251
+ engine[methodName] = (params) => {
49252
+ if (getDevContext()) {
49253
+ return invoke({ params, governor, methodName });
49254
+ } else {
49255
+ try {
49256
+ return invoke({ params, governor, methodName });
49257
+ } catch (err) {
49258
+ handleCaughtError({
49259
+ engineName: "matchUpEngine",
49260
+ methodName,
49261
+ params,
49262
+ err
49263
+ });
49264
+ }
49265
+ }
49266
+ };
49267
+ });
49268
+ });
49269
+ }
49270
+ function invoke({ params, governor, methodName }) {
49271
+ engine.error = void 0;
49272
+ engine.success = false;
49273
+ const matchUp = params?.matchUp || getMatchUp();
49274
+ const matchUps = params?.matchUps || getMatchUps();
49275
+ const snapshot = params?.rollbackOnError && makeDeepCopy(matchUp, false, true);
49276
+ params = {
49277
+ ...params,
49278
+ matchUpId: matchUp?.matchUpId,
49279
+ matchUps,
49280
+ matchUp
49281
+ };
49282
+ const result = governor[methodName](params);
49283
+ if (result?.error) {
49284
+ if (snapshot)
49285
+ setState$2(snapshot);
49286
+ return { ...result, rolledBack: !!snapshot };
49287
+ }
49288
+ const notify = result?.success && params?.delayNotify !== true && params?.doNotNotify !== true;
49289
+ if (notify)
49290
+ notifySubscribers();
49291
+ if (notify || !result?.success || params?.doNotNotify)
49292
+ deleteNotices();
49293
+ return result;
49294
+ }
49295
+ })();
49296
+
49297
+ function matchUpEngineAsync(test) {
49298
+ const result = createInstanceState();
49299
+ if (result.error && !test)
49300
+ return result;
49301
+ const engine = {
49302
+ getState: (params) => getState$2(params),
49303
+ version: () => factoryVersion(),
49304
+ reset: () => {
49305
+ reset();
49306
+ return { ...SUCCESS };
49307
+ },
49308
+ drawId: void 0,
49309
+ error: void 0,
49310
+ success: false,
49311
+ devContext: (contextCriteria) => {
49312
+ setDevContext(contextCriteria);
49313
+ return engine;
49314
+ },
49315
+ setState: (definition, deepCopyOption, deepCopyAttributes) => {
49316
+ setDeepCopy(deepCopyOption, deepCopyAttributes);
49317
+ const result2 = setState$2(definition);
49318
+ return processResult(result2);
49319
+ }
49320
+ };
49321
+ function processResult(result2) {
49322
+ if (result2?.error) {
49323
+ engine.error = result2.error;
49324
+ engine.success = false;
49325
+ } else {
49326
+ engine.error = void 0;
49327
+ engine.success = true;
49328
+ engine.drawId = result2.drawId;
49329
+ }
49330
+ return engine;
49331
+ }
49332
+ importGovernors([
49333
+ tieFormatGovernor,
49334
+ historyGovernor,
49335
+ queryGovernor$1,
49336
+ scoreGovernor
49337
+ ]);
49338
+ return engine;
49339
+ async function importGovernors(governors) {
49340
+ for (const governor of governors) {
49341
+ const governorMethods = Object.keys(governor);
49342
+ for (const methodName of governorMethods) {
49343
+ engine[methodName] = async (params) => {
49344
+ if (getDevContext()) {
49345
+ return await invoke({ params, governor, methodName });
49346
+ } else {
49347
+ try {
49348
+ return await invoke({ params, governor, methodName });
49349
+ } catch (err) {
49350
+ handleCaughtError({
49351
+ engineName: "matchUpEngine",
49352
+ methodName,
49353
+ params,
49354
+ err
49355
+ });
49356
+ }
49357
+ }
49358
+ };
49359
+ }
49360
+ }
49361
+ }
49362
+ async function invoke({ params, governor, methodName }) {
49363
+ engine.success = false;
49364
+ engine.error = void 0;
49365
+ const matchUp = params?.matchUp || getMatchUp();
49366
+ const matchUps = params?.matchUps || getMatchUps();
49367
+ const snapshot = params?.rollbackOnError && makeDeepCopy(matchUp, false, true);
49368
+ params = {
49369
+ ...params,
49370
+ matchUpId: matchUp?.matchUpId,
49371
+ matchUps,
49372
+ matchUp
49373
+ };
49374
+ const result2 = governor[methodName](params);
49375
+ if (result2?.error) {
49376
+ if (snapshot)
49377
+ setState$2(snapshot);
49378
+ return { ...result2, rolledBack: !!snapshot };
49379
+ }
49380
+ const notify = result2?.success && params?.delayNotify !== true && params?.doNotNotify !== true;
49381
+ if (notify)
49382
+ await notifySubscribersAsync();
49383
+ if (notify || !result2?.success || params?.doNotNotify)
49384
+ deleteNotices();
49385
+ return result2;
49386
+ }
49387
+ }
49388
+
49389
+ function newTournamentRecord(params) {
49390
+ const attributes = params || {};
49391
+ if (!attributes.tournamentId)
49392
+ attributes.tournamentId = UUID();
49393
+ if (attributes.startDate && !isISODateString(attributes.startDate) && !validDateString.test(attributes.startDate)) {
49394
+ return { error: INVALID_DATE };
49395
+ }
49396
+ if (attributes.endDate && !isISODateString(attributes.endDate) && !validDateString.test(attributes.endDate)) {
49397
+ return { error: INVALID_DATE };
49398
+ }
49399
+ if (attributes.extensions) {
49400
+ attributes.extensions = attributes.extensions.filter(isValidExtension);
49401
+ }
49402
+ return { ...attributes };
49403
+ }
49404
+
49405
+ function setState$1(tournament, deepCopyOption) {
49406
+ if (typeof tournament !== "object")
49407
+ return { error: INVALID_OBJECT };
49408
+ const tournamentId = tournament.unifiedTournamentId?.tournamentId || tournament.tournamentId;
49409
+ if (!tournamentId)
49410
+ return { error: MISSING_TOURNAMENT_ID };
49411
+ const tournamentRecord = deepCopyOption !== false ? makeDeepCopy(tournament) : tournament;
49412
+ setTournamentRecords({ [tournamentId]: tournamentRecord });
49413
+ setTournamentId(tournamentId);
49414
+ return tournamentRecord;
49415
+ }
49416
+ function getState$1({
49417
+ convertExtensions = false,
49418
+ removeExtensions = false,
49419
+ tournamentId
49420
+ }) {
49421
+ if (typeof tournamentId !== "string")
49422
+ return {};
49423
+ const tournamentRecord = getTournamentRecord(tournamentId);
49424
+ return {
49425
+ tournamentRecord: makeDeepCopy(
49426
+ tournamentRecord,
49427
+ convertExtensions,
49428
+ false,
49429
+ removeExtensions
49430
+ )
49431
+ };
49432
+ }
49433
+ function paramsMiddleware$1(tournamentRecord, params, prefetch) {
49434
+ if (params) {
49435
+ const drawId = params.drawId || params.matchUp?.drawId;
49436
+ if (drawId) {
49437
+ const { event, drawDefinition } = findEvent({
49438
+ tournamentRecord,
49439
+ drawId
49440
+ });
49441
+ params = {
49442
+ ...params,
49443
+ event,
49444
+ drawDefinition
49445
+ };
49446
+ if (prefetch) {
49447
+ const matchUpsMap = getMatchUpsMap({ drawDefinition });
49448
+ const { matchUps: inContextDrawMatchUps } = getAllDrawMatchUps({
49449
+ inContext: true,
49450
+ drawDefinition,
49451
+ matchUpsMap
49452
+ });
49453
+ params.matchUpsMap = matchUpsMap;
49454
+ params.inContextDrawMatchUps = inContextDrawMatchUps;
49455
+ }
49456
+ }
49457
+ if (params.eventId && !params.event) {
49458
+ const { event } = findEvent({
49459
+ eventId: params.eventId,
49460
+ tournamentRecord
49461
+ });
49462
+ if (event) {
49463
+ params = { ...params, event };
49464
+ }
49465
+ }
49466
+ }
49467
+ return params;
49468
+ }
49469
+
49470
+ function getEligibleVoluntaryConsolationParticipants(params) {
49471
+ if (!params.tournamentRecord)
49472
+ return { error: MISSING_TOURNAMENT_RECORD };
49473
+ return getEligibleVoluntaryConsolationParticipants$1(params);
50097
49474
  }
50098
49475
 
50099
- function addGame({ matchUp, game }) {
50100
- if (typeof game !== "object")
50101
- return { error: INVALID_VALUES, context: { game } };
50102
- const { history = [] } = getHistory({ matchUp });
50103
- history.push(game);
50104
- return saveHistory({ matchUp, history });
49476
+ function getParticipantEventDetails({
49477
+ tournamentRecord,
49478
+ participantId
49479
+ }) {
49480
+ if (!tournamentRecord)
49481
+ return { error: MISSING_TOURNAMENT_RECORD };
49482
+ if (!participantId)
49483
+ return { error: MISSING_PARTICIPANT_ID };
49484
+ const relevantParticipantIds = [participantId].concat(
49485
+ (tournamentRecord.participants || []).filter(
49486
+ (participant) => participant?.participantType && [TEAM, PAIR].includes(participant.participantType) && participant.individualParticipantIds?.includes(participantId)
49487
+ ).map((participant) => participant.participantId)
49488
+ );
49489
+ const relevantEvents = (tournamentRecord.events || []).filter((event) => {
49490
+ const enteredParticipantIds = (event?.entries || []).map(
49491
+ (entry) => entry.participantId
49492
+ );
49493
+ return overlap(enteredParticipantIds, relevantParticipantIds);
49494
+ }).map((event) => ({ eventName: event.eventName, eventId: event.eventId }));
49495
+ return { eventDetails: relevantEvents };
50105
49496
  }
50106
49497
 
50107
- function addShot({ matchUp, shot }) {
50108
- if (typeof shot !== "object")
50109
- return { error: MISSING_VALUE };
50110
- const { history = [] } = getHistory({ matchUp });
50111
- history.push(shot);
50112
- return saveHistory({ matchUp, history });
49498
+ function getDerivedPositionAssignments({
49499
+ derivedDrawInfo,
49500
+ participantId,
49501
+ drawId
49502
+ }) {
49503
+ const mainPositionAssignment = derivedDrawInfo[drawId]?.mainPositionAssignments?.find(
49504
+ (assignment) => assignment.participantId === participantId
49505
+ );
49506
+ const qualifyingPositionAssignment = derivedDrawInfo[drawId]?.qualifyingPositionAssignments?.find(
49507
+ (assignment) => assignment.participantId === participantId
49508
+ );
49509
+ const positionAssignments = {};
49510
+ if (mainPositionAssignment) {
49511
+ const { participantId: participantId2, ...props } = mainPositionAssignment;
49512
+ if (participantId2)
49513
+ positionAssignments[MAIN] = { ...props };
49514
+ }
49515
+ if (qualifyingPositionAssignment) {
49516
+ const { participantId: participantId2, ...props } = qualifyingPositionAssignment;
49517
+ if (participantId2)
49518
+ positionAssignments[QUALIFYING] = { ...props };
49519
+ }
49520
+ return Object.keys(positionAssignments).length ? positionAssignments : void 0;
50113
49521
  }
50114
49522
 
50115
- function addSet({ matchUp, set }) {
50116
- if (typeof set !== "object")
50117
- return { error: MISSING_VALUE };
50118
- const { history = [] } = getHistory({ matchUp });
50119
- history.push(set);
50120
- return saveHistory({ matchUp, history });
49523
+ function getRelevantParticipantIdsMap({
49524
+ processParticipantId,
49525
+ // optional method which is passed each participantId
49526
+ tournamentRecords,
49527
+ tournamentRecord
49528
+ }) {
49529
+ if (typeof tournamentRecord !== "object" && typeof tournamentRecords !== "object")
49530
+ return { error: MISSING_TOURNAMENT_RECORD };
49531
+ const allParticipants = tournamentRecords ? Object.values(tournamentRecords).map((tournamentRecord2) => tournamentRecord2?.participants || []).flat() : tournamentRecord?.participants || [];
49532
+ const relevantParticipantIdsMap = Object.assign(
49533
+ {},
49534
+ ...allParticipants.map(
49535
+ ({ participantId, participantType, individualParticipantIds }) => {
49536
+ typeof processParticipantId === "function" && processParticipantId(participantId);
49537
+ const individualParticipantIdObjects = (individualParticipantIds || []).map((relevantParticipantId) => ({
49538
+ participantType: INDIVIDUAL,
49539
+ relevantParticipantId
49540
+ }));
49541
+ return {
49542
+ [participantId]: individualParticipantIdObjects.concat({
49543
+ relevantParticipantId: participantId,
49544
+ participantType
49545
+ })
49546
+ };
49547
+ }
49548
+ )
49549
+ );
49550
+ return { relevantParticipantIdsMap };
50121
49551
  }
50122
49552
 
50123
- function redo({ matchUp }) {
50124
- const { history = [], undoHistory = [] } = getHistory({ matchUp });
50125
- if (undoHistory.length)
50126
- history.push(undoHistory.pop());
50127
- return saveHistory({ matchUp, history, undoHistory });
49553
+ function getDerivedSeedAssignments({
49554
+ derivedDrawInfo,
49555
+ participantId,
49556
+ drawId
49557
+ }) {
49558
+ const mainSeedAssignment = derivedDrawInfo[drawId]?.mainSeedAssignments?.find(
49559
+ (assignment) => assignment.participantId === participantId
49560
+ );
49561
+ const qualifyingSeedAssignment = derivedDrawInfo[drawId]?.qualifyingSeedAssignments?.find(
49562
+ (assignment) => assignment.participantId === participantId
49563
+ );
49564
+ const seedAssignments = {};
49565
+ if (mainSeedAssignment) {
49566
+ const { participantId: participantId2, ...props } = mainSeedAssignment;
49567
+ if (participantId2)
49568
+ seedAssignments[MAIN] = { ...props };
49569
+ }
49570
+ if (qualifyingSeedAssignment) {
49571
+ const { participantId: participantId2, ...props } = qualifyingSeedAssignment;
49572
+ if (participantId2)
49573
+ seedAssignments[QUALIFYING] = { ...props };
49574
+ }
49575
+ return Object.keys(seedAssignments).length ? seedAssignments : void 0;
50128
49576
  }
50129
49577
 
50130
- function undo({ matchUp }) {
50131
- const { history = [], undoHistory = [] } = getHistory({ matchUp });
50132
- undoHistory.push(history.pop());
50133
- return saveHistory({ matchUp, history, undoHistory });
49578
+ function participantScheduledMatchUps({
49579
+ scheduleAttributes = ["scheduledDate", "scheduledTime"],
49580
+ matchUps = []
49581
+ }) {
49582
+ if (!validMatchUps(matchUps))
49583
+ return { error: MISSING_MATCHUPS };
49584
+ if (!Array.isArray(scheduleAttributes))
49585
+ return { error: INVALID_VALUES };
49586
+ const scheduledMatchUps = matchUps.filter(Boolean).filter(({ schedule }) => hasSchedule({ schedule, scheduleAttributes })).reduce((dateMatchUps, matchUp) => {
49587
+ const { schedule } = matchUp;
49588
+ const date = extractDate(schedule?.scheduledDate);
49589
+ const time = extractTime(schedule?.scheduledTime);
49590
+ if (date && time) {
49591
+ if (dateMatchUps[date]) {
49592
+ dateMatchUps[date].push(matchUp);
49593
+ } else {
49594
+ dateMatchUps[date] = [matchUp];
49595
+ }
49596
+ }
49597
+ return dateMatchUps;
49598
+ }, {});
49599
+ const dates = Object.keys(scheduledMatchUps);
49600
+ dates.forEach((date) => {
49601
+ scheduledMatchUps[date].sort(
49602
+ (a, b) => timeSort(
49603
+ extractTime(a.schedule?.scheduledTime),
49604
+ extractTime(b.schedule?.scheduledTime)
49605
+ )
49606
+ );
49607
+ });
49608
+ return { scheduledMatchUps };
50134
49609
  }
50135
49610
 
50136
- const umo = {
50137
- scoreboard: () => {
50138
- },
50139
- addPoints: () => {
50140
- },
50141
- addPoint: () => {
49611
+ function annotateParticipant(params) {
49612
+ const {
49613
+ withScaleValues = true,
49614
+ eventsPublishStatuses,
49615
+ withEvents = true,
49616
+ withDraws = true,
49617
+ participantIdMap,
49618
+ scheduleAnalysis,
49619
+ derivedDrawInfo,
49620
+ usePublishState,
49621
+ withStatistics,
49622
+ withOpponents,
49623
+ withMatchUps,
49624
+ withSeeding,
49625
+ participant,
49626
+ withISO2,
49627
+ withIOC
49628
+ } = params;
49629
+ const scheduleConflicts = [];
49630
+ const scheduleItems = [];
49631
+ if (withIOC || withISO2)
49632
+ addNationalityCode({ participant, withIOC, withISO2 });
49633
+ if (withScaleValues) {
49634
+ const { ratings, rankings } = getScaleValues({ participant });
49635
+ participant.rankings = rankings;
49636
+ participant.ratings = ratings;
50142
49637
  }
50143
- };
50144
-
50145
- const historyGovernor = {
50146
- calculateHistoryScore,
50147
- setServingSide,
50148
- clearHistory,
50149
- addPoint,
50150
- addGame,
50151
- addShot,
50152
- addSet,
50153
- redo,
50154
- undo,
50155
- umo
50156
- };
50157
-
50158
- function analyzeMatchUp(params) {
50159
- const { matchUp, sideNumber, setNumber, isTiebreakValue, isPointValue } = params || {};
50160
- let { matchUpFormat } = params || {};
50161
- if (!matchUp)
50162
- return { error: MISSING_MATCHUP };
50163
- matchUpFormat = matchUpFormat || matchUp?.matchUpFormat;
50164
- const matchUpScoringFormat = parse(matchUpFormat);
50165
- const isCompletedMatchUp = !!matchUp?.winningSide;
50166
- const sets = matchUp.score?.sets;
50167
- const setsCount = sets?.length;
50168
- const setIndex = setNumber && setNumber - 1;
50169
- const isExistingSet = !!sets?.find(
50170
- (set, index) => set.setNumber === setNumber && index === setIndex
50171
- );
50172
- const completedSets = sets?.filter((set) => set?.winningSide) || [];
50173
- const completedSetsCount = completedSets?.length || 0;
50174
- const setsFollowingCurrent = setNumber && sets?.slice(setNumber) || [];
50175
- const isLastSetWithValues = !!(setsCount && setNumber && // EVERY: is this a candidate for .every?
50176
- setsFollowingCurrent?.reduce((noValues, set) => {
50177
- return (!set || !set.side1Score && !set.side2Score && !set.side1TiebreakScore && !set.side2TiebreakScore && !set.side1PointScore && !set.side2PointScore) && noValues;
50178
- }, true));
50179
- const setObject = setNumber <= setsCount && sets.find((set) => set.setNumber === setNumber);
50180
- const specifiedSetAnalysis = setObject && analyzeSet({ setObject, matchUpScoringFormat });
49638
+ const participantId = participant?.participantId;
49639
+ if (!participantId || !participantIdMap[participantId])
49640
+ return {};
50181
49641
  const {
50182
- isCompletedSet,
50183
- sideGameScores,
50184
- // sidePointScores,
50185
- sideTiebreakScores
50186
- } = specifiedSetAnalysis || {};
50187
- const isActiveSet = !!(setObject && !isCompletedSet && isLastSetWithValues || setNumber && setNumber === setsCount + 1 && !isCompletedMatchUp);
50188
- const isValidSideNumber = [1, 2].includes(sideNumber);
50189
- const sideIndex = isValidSideNumber ? sideNumber - 1 : 0;
50190
- const existingValue = setObject && isValidSideNumber && (!isTiebreakValue && !isPointValue && sideGameScores[sideIndex] !== void 0 && sideGameScores[sideIndex] || isTiebreakValue && sideTiebreakScores[sideIndex] !== void 0 && sideTiebreakScores[sideIndex]);
50191
- const hasExistingValue = !!existingValue;
50192
- const completedSetsHaveValidOutcomes = completedSets?.map(
50193
- (setObject2) => analyzeSet({ setObject: setObject2, matchUpScoringFormat }).isValidSetOutcome
50194
- ).reduce((valid, validOutcome) => valid && validOutcome, true);
50195
- const setsWinCounts = completedSets.reduce(
50196
- (counts, set) => {
50197
- const { winningSide } = set;
50198
- const winningSideIndex = winningSide - 1;
50199
- counts[winningSideIndex]++;
50200
- return counts;
50201
- },
50202
- [0, 0]
50203
- );
50204
- const matchUpWinningSide = matchUp?.winningSide;
50205
- const matchUpWinningSideIndex = matchUpWinningSide && matchUpWinningSide - 1;
50206
- const matchUpLosingSideIndex = 1 - matchUpWinningSideIndex;
50207
- const winningSideSetsCount = setsWinCounts[matchUpWinningSideIndex];
50208
- const losingSideSetsCount = setsWinCounts[matchUpLosingSideIndex];
50209
- const maxSetsCount = Math.max(...setsWinCounts);
50210
- const maxSetsInstances = instanceCount(setsWinCounts)[maxSetsCount];
50211
- const { bestOf } = matchUpScoringFormat || {};
50212
- const setsToWin = bestOf && Math.ceil(bestOf / 2) || 1;
50213
- const calculatedWinningSide = maxSetsCount === setsToWin && maxSetsInstances === 1 && setsWinCounts.indexOf(maxSetsCount) + 1 || void 0;
50214
- const validMatchUpWinningSide = winningSideSetsCount > losingSideSetsCount && matchUpWinningSide === calculatedWinningSide;
50215
- const validMatchUpOutcome = calculatedWinningSide && completedSetsHaveValidOutcomes && validMatchUpWinningSide;
50216
- return {
50217
- completedSetsHaveValidOutcomes,
50218
- validMatchUpWinningSide,
50219
- calculatedWinningSide,
50220
- matchUpScoringFormat,
50221
- validMatchUpOutcome,
50222
- isLastSetWithValues,
50223
- completedSetsCount,
50224
- isCompletedMatchUp,
50225
- isValidSideNumber,
50226
- hasExistingValue,
50227
- existingValue,
50228
- isExistingSet,
50229
- isActiveSet,
50230
- ...specifiedSetAnalysis
49642
+ potentialMatchUps,
49643
+ opponents,
49644
+ matchUps,
49645
+ events,
49646
+ losses,
49647
+ draws,
49648
+ wins
49649
+ } = participantIdMap[participantId];
49650
+ const denominator = wins + losses;
49651
+ const numerator = wins;
49652
+ const statValue = denominator && numerator / denominator;
49653
+ const winRatioStat = {
49654
+ statCode: WIN_RATIO$1,
49655
+ denominator,
49656
+ numerator,
49657
+ statValue
50231
49658
  };
50232
- }
50233
-
50234
- const queryGovernor$1 = {
50235
- tallyParticipantResults,
50236
- matchUpIsComplete,
50237
- analyzeMatchUp,
50238
- getMatchUpType,
50239
- scoreHasValue,
50240
- validMatchUps,
50241
- validMatchUp
50242
- };
50243
-
50244
- let keyedMatchUps = {};
50245
- let matchUpId;
50246
- function setState$2(value, deepCopyOption = true) {
50247
- if (!value)
50248
- return { error: MISSING_VALUE };
50249
- if (typeof value !== "object")
50250
- return { error: INVALID_OBJECT };
50251
- if (value.matchUpId) {
50252
- matchUpId = value.matchUpId;
50253
- keyedMatchUps[matchUpId] = deepCopyOption ? makeDeepCopy(value) : value;
50254
- } else if (Array.isArray(value)) {
50255
- for (const m of value.reverse()) {
50256
- if (m.matchUpId) {
50257
- keyedMatchUps[m.matchUpId] = deepCopyOption ? makeDeepCopy(m) : m;
50258
- if (!matchUpId)
50259
- matchUpId = m.matchUpId;
49659
+ const participantDraws = Object.values(draws);
49660
+ const participantEvents = Object.values(events);
49661
+ if (withDraws && participantDraws) {
49662
+ participant.draws = participantDraws;
49663
+ for (const participantDraw of participantDraws) {
49664
+ const publishedSeeding = eventsPublishStatuses[participantDraw.eventId]?.publishedSeeding;
49665
+ const seedingPublished = !usePublishState || publishedSeeding?.published && (publishedSeeding?.drawIds?.length === 0 || publishedSeeding?.drawIds?.includes(participantDraw.drawId));
49666
+ if (seedingPublished) {
49667
+ const seedAssignments = getDerivedSeedAssignments({
49668
+ drawId: participantDraw.drawId,
49669
+ derivedDrawInfo,
49670
+ participantId
49671
+ });
49672
+ if (seedAssignments) {
49673
+ participantDraw.seedAssignments = seedAssignments;
49674
+ }
50260
49675
  }
50261
49676
  }
50262
- } else {
50263
- for (const m of Object.values(value)) {
50264
- if (m.matchUpId) {
50265
- keyedMatchUps[m.matchUpId] = deepCopyOption ? makeDeepCopy(m) : m;
50266
- if (!matchUpId)
50267
- matchUpId = m.matchUpId;
49677
+ }
49678
+ if (withEvents && participantEvents) {
49679
+ participant.events = participantEvents;
49680
+ if (withSeeding) {
49681
+ const seedingScales = Object.assign(
49682
+ {},
49683
+ ...(participant.timeItems || []).filter(({ itemType }) => itemType.split(".")[1] === SEEDING$1).map(({ itemType: seedingScaleName, itemValue: seedValue }) => ({
49684
+ [seedingScaleName]: seedValue
49685
+ }))
49686
+ );
49687
+ for (const participantEvent of participantEvents) {
49688
+ const getScaleAccessor = (scaleName) => [SCALE$1, SEEDING$1, participantEvent.eventType, scaleName].join(".");
49689
+ const publishedSeeding = eventsPublishStatuses[participantEvent.eventId]?.publishedSeeding;
49690
+ const eventSeedingScaleNames = (publishedSeeding?.stageSeedingScaleNames && Object.values(publishedSeeding?.stageSeedingScaleNames) || Array.isArray(publishedSeeding?.seedingScaleNames) && publishedSeeding.seedingScaleNames || []).map(getScaleAccessor);
49691
+ const publishedEventSeedingScaleNames = intersection(
49692
+ Object.keys(seedingScales),
49693
+ eventSeedingScaleNames
49694
+ );
49695
+ const eventSeedingPublished = !!(!usePublishState || !Object.keys(seedingScales).length && !publishedSeeding?.drawIds?.length || publishedEventSeedingScaleNames.length);
49696
+ if (eventSeedingPublished && publishedEventSeedingScaleNames.length) {
49697
+ if (publishedSeeding?.stageSeedingScaleNames) {
49698
+ const scaleValues = Object.keys(
49699
+ publishedSeeding.stageSeedingScaleNames
49700
+ ).map((key) => {
49701
+ const accessor = getScaleAccessor(
49702
+ publishedSeeding.stageSeedingScaleNames[key]
49703
+ );
49704
+ const scaleValue = seedingScales[accessor];
49705
+ return [key, scaleValue];
49706
+ }).filter((pair) => pair[1]).map((pair) => ({ [pair[0]]: { seedValue: pair[1] } }));
49707
+ const seedAssignments = Object.assign({}, ...scaleValues);
49708
+ participantEvent.seedAssignments = seedAssignments;
49709
+ } else if (publishedEventSeedingScaleNames) {
49710
+ const seedValues = publishedEventSeedingScaleNames.map(
49711
+ (scaleName) => seedingScales[scaleName]
49712
+ );
49713
+ participantEvent.seedValue = seedValues.pop();
49714
+ }
49715
+ } else if (!usePublishState && typeof withSeeding === "object") {
49716
+ const scaleValues = Object.keys(withSeeding).map((key) => {
49717
+ const accessor = getScaleAccessor(withSeeding[key]);
49718
+ const scaleValue = seedingScales[accessor];
49719
+ return [key, scaleValue];
49720
+ }).filter((pair) => pair[1]).map((pair) => ({ [pair[0]]: { seedValue: pair[1] } }));
49721
+ const seedAssignments = Object.assign({}, ...scaleValues);
49722
+ participantEvent.seedAssignments = seedAssignments;
49723
+ } else {
49724
+ const { categoryName, ageCategoryCode } = participantEvent.category || {};
49725
+ let scaleItem;
49726
+ for (const scaleName of [
49727
+ participantEvent.eventId,
49728
+ ageCategoryCode,
49729
+ categoryName
49730
+ ]) {
49731
+ const scaleAttributes = {
49732
+ eventType: participantEvent.eventType,
49733
+ scaleType: SEEDING$1,
49734
+ scaleName
49735
+ };
49736
+ const result = participantScaleItem({
49737
+ scaleAttributes,
49738
+ participant
49739
+ });
49740
+ if (result.scaleItem) {
49741
+ scaleItem = result.scaleItem;
49742
+ break;
49743
+ }
49744
+ }
49745
+ if (scaleItem) {
49746
+ const seedValue = scaleItem.scaleValue;
49747
+ const seedingPublished = !usePublishState || publishedSeeding?.published && (publishedSeeding?.drawIds?.length === 0 || publishedSeeding?.drawIds?.includes(
49748
+ participantEvent.drawId
49749
+ ));
49750
+ if (seedingPublished) {
49751
+ participantEvent.seedValue = seedValue;
49752
+ }
49753
+ }
49754
+ }
49755
+ if (participantEvent.drawIds?.length) {
49756
+ for (const flightDrawId of participantEvent.drawIds || []) {
49757
+ const drawSeedPublishingDisabled = publishedSeeding?.drawIds?.length && !publishedSeeding?.drawIds?.includes(flightDrawId);
49758
+ if (eventSeedingPublished && !drawSeedPublishingDisabled) {
49759
+ const seedAssignments = getDerivedSeedAssignments({
49760
+ drawId: flightDrawId,
49761
+ derivedDrawInfo,
49762
+ participantId
49763
+ });
49764
+ if (seedAssignments && participantEvent.seedAssignments) {
49765
+ for (const key of Object.keys(
49766
+ participantEvent.seedAssignments
49767
+ )) {
49768
+ participantEvent.seedAssignments[key] = seedAssignments[key];
49769
+ }
49770
+ } else {
49771
+ participantEvent.seedAssignments = seedAssignments;
49772
+ }
49773
+ }
49774
+ }
49775
+ }
49776
+ }
49777
+ }
49778
+ }
49779
+ const participantOpponents = Object.values(opponents).flat();
49780
+ if (withOpponents && participantOpponents?.length) {
49781
+ participant.opponents = participantOpponents;
49782
+ participantDraws?.forEach((draw) => {
49783
+ draw.opponents = participantOpponents.filter(
49784
+ (opponent) => opponent.drawId === draw.drawId
49785
+ );
49786
+ });
49787
+ }
49788
+ const participantPotentialMatchUps = Object.values(potentialMatchUps);
49789
+ const participantMatchUps = Object.values(matchUps);
49790
+ if (withMatchUps) {
49791
+ participant.potentialMatchUps = participantPotentialMatchUps;
49792
+ participant.matchUps = participantMatchUps;
49793
+ }
49794
+ const allParticipantMatchUps = participantMatchUps.concat(
49795
+ participantPotentialMatchUps
49796
+ );
49797
+ const scheduledMatchUps = participantScheduledMatchUps({
49798
+ matchUps: allParticipantMatchUps
49799
+ })?.scheduledMatchUps || [];
49800
+ const { scheduledMinutesDifference } = scheduleAnalysis || {};
49801
+ const dates = Object.keys(scheduledMatchUps);
49802
+ dates.forEach((date) => {
49803
+ scheduledMatchUps[date].filter(Boolean).forEach((matchUp, i) => {
49804
+ const {
49805
+ schedule: {
49806
+ scheduledTime,
49807
+ timeAfterRecovery,
49808
+ typeChangeTimeAfterRecovery
49809
+ },
49810
+ matchUpStatus,
49811
+ roundPosition,
49812
+ structureName,
49813
+ matchUpType,
49814
+ roundNumber,
49815
+ matchUpId,
49816
+ drawId,
49817
+ score
49818
+ } = matchUp;
49819
+ scheduleItems.push({
49820
+ ...matchUp.schedule,
49821
+ scheduledTime: extractTime(matchUp.schedule?.scheduledTime),
49822
+ roundPosition,
49823
+ structureName,
49824
+ matchUpType,
49825
+ roundNumber,
49826
+ matchUpId,
49827
+ drawId
49828
+ });
49829
+ const ignoreMatchUp = matchUpStatus === BYE || [WALKOVER$2, DEFAULTED].includes(matchUpStatus) && !scoreHasValue({ score });
49830
+ if (scheduledTime && !ignoreMatchUp) {
49831
+ const scheduledMinutes = timeStringMinutes(scheduledTime);
49832
+ const matchUpsToConsider = scheduledMatchUps[date].slice(i + 1);
49833
+ for (const consideredMatchUp of matchUpsToConsider) {
49834
+ const ignoreMatchUp2 = consideredMatchUp.matchUpStatus === BYE || [WALKOVER$2, DEFAULTED].includes(consideredMatchUp.matchUpStatus) && !scoreHasValue(consideredMatchUp);
49835
+ if (!ignoreMatchUp2 && consideredMatchUp.schedule?.scheduledTime) {
49836
+ const typeChange = matchUp.matchUpType !== consideredMatchUp.matchUpType;
49837
+ const notBeforeTime = typeChange ? typeChangeTimeAfterRecovery || timeAfterRecovery : timeAfterRecovery;
49838
+ const sameDraw = matchUp.drawId === consideredMatchUp.drawId;
49839
+ const bothPotential = matchUp.potential && consideredMatchUp.potential;
49840
+ const nextMinutes = timeStringMinutes(
49841
+ consideredMatchUp.schedule?.scheduledTime
49842
+ );
49843
+ const minutesDifference = nextMinutes - scheduledMinutes;
49844
+ const timeOverlap = scheduledMinutesDifference && !isNaN(scheduledMinutesDifference) ? minutesDifference <= scheduledMinutesDifference : timeStringMinutes(notBeforeTime) > timeStringMinutes(consideredMatchUp.schedule?.scheduledTime);
49845
+ if (timeOverlap && !(bothPotential && sameDraw)) {
49846
+ scheduleConflicts.push({
49847
+ priorScheduledMatchUpId: consideredMatchUp.matchUpId,
49848
+ matchUpIdWithConflict: matchUpId
49849
+ });
49850
+ }
49851
+ }
49852
+ }
50268
49853
  }
50269
- }
50270
- }
50271
- return deepCopyOption ? makeDeepCopy(value) : value;
50272
- }
50273
- function getMatchUp() {
50274
- return keyedMatchUps[matchUpId];
50275
- }
50276
- function getMatchUps() {
50277
- return Object.values(keyedMatchUps);
50278
- }
50279
- function reset() {
50280
- matchUpId = void 0;
50281
- keyedMatchUps = {};
49854
+ });
49855
+ });
49856
+ if (withStatistics)
49857
+ participant.statistics = [winRatioStat];
49858
+ return { scheduleConflicts, scheduleItems };
50282
49859
  }
50283
- function getState$2(params) {
50284
- return makeDeepCopy(
50285
- keyedMatchUps[matchUpId],
50286
- params?.convertExtensions,
50287
- false,
50288
- params?.removeExtensions
49860
+
49861
+ function getDrawDetails({
49862
+ eventEntries,
49863
+ sortConfig,
49864
+ event
49865
+ }) {
49866
+ const derivedInfo = {};
49867
+ const drawDetails = Object.assign(
49868
+ {},
49869
+ ...(event.drawDefinitions ?? []).map((drawDefinition) => {
49870
+ const entriesMap = Object.assign(
49871
+ {},
49872
+ ...(eventEntries ?? []).filter((entry) => entry.participantId).map((entry) => ({ [entry.participantId]: entry })),
49873
+ ...drawDefinition.entries.filter((entry) => entry.participantId).map((entry) => ({ [entry.participantId]: entry }))
49874
+ );
49875
+ const drawEntries = Object.values(entriesMap);
49876
+ const mainStructure = getDrawStructures({
49877
+ stageSequence: 1,
49878
+ drawDefinition,
49879
+ stage: MAIN
49880
+ })?.structures?.[0];
49881
+ const mainPositionAssignments = mainStructure && getPositionAssignments$1({
49882
+ structure: mainStructure
49883
+ })?.positionAssignments;
49884
+ const drawSize = mainPositionAssignments?.length;
49885
+ const qualifyingStructure = getDrawStructures({
49886
+ stageSequence: 1,
49887
+ stage: QUALIFYING,
49888
+ drawDefinition
49889
+ })?.structures?.[0];
49890
+ const qualifyingPositionAssignments = mainStructure && getPositionAssignments$1({
49891
+ structure: qualifyingStructure
49892
+ })?.positionAssignments;
49893
+ const qualifyingDrawSize = qualifyingPositionAssignments?.length;
49894
+ const mainSeedAssignments = mainStructure?.seedAssignments;
49895
+ const qualifyingSeedAssignments = qualifyingStructure?.seedAssignments;
49896
+ const orderedStructureIds = (drawDefinition.structures || []).sort((a, b) => structureSort(a, b, sortConfig)).map(({ structureId, structures }) => {
49897
+ return [
49898
+ structureId,
49899
+ ...(structures || []).map(({ structureId: structureId2 }) => structureId2)
49900
+ ];
49901
+ }).flat(Infinity);
49902
+ const flightNumber = event?._flightProfile?.flights?.find(
49903
+ (flight) => flight.drawId === drawDefinition.drawId
49904
+ )?.flightNumber;
49905
+ derivedInfo[drawDefinition.drawId] = {
49906
+ qualifyingPositionAssignments,
49907
+ qualifyingSeedAssignments,
49908
+ mainPositionAssignments,
49909
+ mainSeedAssignments,
49910
+ orderedStructureIds,
49911
+ qualifyingDrawSize,
49912
+ flightNumber,
49913
+ drawSize
49914
+ };
49915
+ return {
49916
+ [drawDefinition.drawId]: {
49917
+ drawType: drawDefinition.drawType,
49918
+ drawEntries
49919
+ }
49920
+ };
49921
+ })
50289
49922
  );
49923
+ return { derivedInfo, drawDetails };
50290
49924
  }
50291
49925
 
50292
- const matchUpEngine = (() => {
50293
- const engine = {
50294
- getState: (params) => getState$2(params),
50295
- version: () => factoryVersion(),
50296
- reset: () => {
50297
- reset();
50298
- return { ...SUCCESS };
50299
- },
50300
- drawId: void 0,
50301
- error: void 0,
50302
- success: false,
50303
- devContext: (contextCriteria) => {
50304
- setDevContext(contextCriteria);
50305
- return engine;
50306
- },
50307
- setState: (definition, deepCopyOption, deepCopyAttributes) => {
50308
- setDeepCopy(deepCopyOption, deepCopyAttributes);
50309
- const result = setState$2(definition);
50310
- return processResult(result);
50311
- }
49926
+ function processMatchUp({
49927
+ relevantParticipantIdsMap,
49928
+ participantFilters,
49929
+ participantIdMap,
49930
+ derivedDrawInfo,
49931
+ eventDrawsCount,
49932
+ drawDetails,
49933
+ eventType,
49934
+ matchUp
49935
+ }) {
49936
+ const {
49937
+ collectionId,
49938
+ collectionPosition,
49939
+ drawId,
49940
+ drawName,
49941
+ eventId,
49942
+ eventName,
49943
+ finishingRound,
49944
+ finishingPositionRange,
49945
+ processCodes,
49946
+ loserTo,
49947
+ matchUpId,
49948
+ matchUpType,
49949
+ matchUpFormat,
49950
+ matchUpStatus,
49951
+ matchUpStatusCodes,
49952
+ matchUpTieId,
49953
+ roundName,
49954
+ roundNumber,
49955
+ roundPosition,
49956
+ score,
49957
+ sides,
49958
+ stage,
49959
+ stageSequence,
49960
+ schedule,
49961
+ structureName,
49962
+ structureId,
49963
+ tieFormat,
49964
+ tieMatchUps,
49965
+ tournamentId,
49966
+ winnerTo,
49967
+ winningSide
49968
+ } = matchUp;
49969
+ const targetParticipantIds = participantFilters?.participantIds;
49970
+ const getRelevantParticipantIds = (participantId) => {
49971
+ const relevantParticipantIds = participantId && relevantParticipantIdsMap[participantId] || [];
49972
+ relevantParticipantIds.push(participantId);
49973
+ return relevantParticipantIds.some(
49974
+ (obj) => !targetParticipantIds || targetParticipantIds.includes(obj.relevantParticipantId)
49975
+ ) ? relevantParticipantIds : [];
50312
49976
  };
50313
- function processResult(result) {
50314
- if (result?.error) {
50315
- engine.error = result.error;
50316
- engine.success = false;
50317
- } else {
50318
- engine.error = void 0;
50319
- engine.success = true;
50320
- engine.drawId = result.drawId;
50321
- }
50322
- return engine;
49977
+ const { winner, loser } = finishingPositionRange || {};
49978
+ const doublesTieParticipants = tieMatchUps?.length && tieMatchUps.filter(({ matchUpType: matchUpType2 }) => matchUpType2 === DOUBLES_MATCHUP).map(
49979
+ ({ sides: sides2 }) => sides2.map(
49980
+ ({ sideNumber, participantId, participant }) => sideNumber && participantId && {
49981
+ sideNumber,
49982
+ participantId,
49983
+ participant
49984
+ }
49985
+ )
49986
+ ).flat().filter(Boolean) || [];
49987
+ if (eventType === TEAM_EVENT && matchUpType === DOUBLES_MATCHUP) {
49988
+ const participants = (matchUp.sides?.filter(Boolean) || []).map(
49989
+ ({ sideNumber, participantId, participant }) => sideNumber && participantId && {
49990
+ sideNumber,
49991
+ participantId,
49992
+ participant
49993
+ }
49994
+ ).filter(Boolean);
49995
+ doublesTieParticipants.push(...participants);
50323
49996
  }
50324
- importGovernors([
50325
- tieFormatGovernor,
50326
- historyGovernor,
50327
- queryGovernor$1,
50328
- scoreGovernor
50329
- ]);
50330
- return engine;
50331
- function importGovernors(governors) {
50332
- governors.forEach((governor) => {
50333
- Object.keys(governor).forEach((methodName) => {
50334
- engine[methodName] = (params) => {
50335
- if (getDevContext()) {
50336
- return invoke({ params, governor, methodName });
50337
- } else {
50338
- try {
50339
- return invoke({ params, governor, methodName });
50340
- } catch (err) {
50341
- handleCaughtError({
50342
- engineName: "matchUpEngine",
50343
- methodName,
50344
- params,
50345
- err
50346
- });
49997
+ sides?.forEach((params) => {
49998
+ const { participantId, sideNumber } = params;
49999
+ if (!participantId)
50000
+ return;
50001
+ const { drawType, drawEntries } = drawDetails[drawId];
50002
+ const participantScore = sideNumber === 1 ? score?.scoreStringSide1 : score?.scoreStringSide2;
50003
+ const participantWon = winningSide && sideNumber === winningSide;
50004
+ const opponent = matchUp.sides.find(
50005
+ (side) => side.sideNumber === 3 - sideNumber
50006
+ );
50007
+ const opponentParticipantId = opponent?.participantId;
50008
+ const relevantOpponents = opponentParticipantId && relevantParticipantIdsMap[opponentParticipantId] || [];
50009
+ const finishingPositionRange2 = participantWon ? winner : loser;
50010
+ const drawEntry = drawEntries.find(
50011
+ (entry) => entry.participantId === participantId
50012
+ );
50013
+ const relevantParticipantIds = getRelevantParticipantIds(participantId);
50014
+ const addedPairParticipantIds = [];
50015
+ doublesTieParticipants?.filter((participant) => participant.sideNumber === sideNumber).forEach((p) => {
50016
+ const participantId2 = p.participantId;
50017
+ if (participantId2 && !addedPairParticipantIds.includes(participantId2)) {
50018
+ relevantParticipantIds.push({
50019
+ relevantParticipantId: participantId2,
50020
+ participantType: PAIR
50021
+ });
50022
+ addedPairParticipantIds.push(participantId2);
50023
+ }
50024
+ });
50025
+ const filteredRelevantParticipantIds = relevantParticipantIds.filter(
50026
+ (opponent2) => {
50027
+ return eventType !== TEAM_EVENT || eventType === TEAM_EVENT && [DOUBLES_MATCHUP, TEAM_MATCHUP].includes(matchUpType) && [PAIR, TEAM_PARTICIPANT].includes(opponent2.participantType) || eventType === TEAM_EVENT && [SINGLES_MATCHUP, DOUBLES_MATCHUP].includes(matchUpType) && [INDIVIDUAL].includes(opponent2.participantType);
50028
+ }
50029
+ );
50030
+ filteredRelevantParticipantIds?.forEach(
50031
+ ({ relevantParticipantId, participantType }) => {
50032
+ const { entryStage, entryStatus, entryPosition } = drawEntry || {};
50033
+ if (!participantIdMap[relevantParticipantId])
50034
+ return;
50035
+ if (!participantIdMap[relevantParticipantId].draws[drawId]) {
50036
+ const positionAssignments = getDerivedPositionAssignments({
50037
+ participantId: relevantParticipantId,
50038
+ derivedDrawInfo,
50039
+ drawId
50040
+ });
50041
+ const seedAssignments = getDerivedSeedAssignments({
50042
+ participantId: relevantParticipantId,
50043
+ derivedDrawInfo,
50044
+ drawId
50045
+ });
50046
+ participantIdMap[relevantParticipantId].draws[drawId] = definedAttributes({
50047
+ qualifyingDrawSize: derivedDrawInfo[drawId]?.qualifyingDrawSize,
50048
+ drawSize: derivedDrawInfo[drawId]?.drawSize,
50049
+ partnerParticipantIds: [],
50050
+ positionAssignments,
50051
+ seedAssignments,
50052
+ entryPosition,
50053
+ entryStatus,
50054
+ entryStage,
50055
+ drawName,
50056
+ drawType,
50057
+ eventId,
50058
+ drawId
50059
+ });
50060
+ }
50061
+ if (!participantIdMap[relevantParticipantId].events[eventId]) {
50062
+ participantIdMap[relevantParticipantId].events[eventId] = {
50063
+ partnerParticipantIds: [],
50064
+ drawIds: [],
50065
+ eventName,
50066
+ eventId
50067
+ };
50068
+ }
50069
+ const eventDrawIds = participantIdMap[relevantParticipantId].events[eventId].drawIds;
50070
+ if (eventDrawIds && !eventDrawIds?.includes(drawId)) {
50071
+ participantIdMap[relevantParticipantId].events[eventId].drawIds.push(
50072
+ drawId
50073
+ );
50074
+ }
50075
+ let partnerParticipantId;
50076
+ if (participantType === INDIVIDUAL && matchUpType === DOUBLES_MATCHUP) {
50077
+ const relevantParticipantInfo = filteredRelevantParticipantIds.find(
50078
+ (participantInfo) => {
50079
+ return participantInfo.relevantParticipantId !== relevantParticipantId && participantInfo.participantType === INDIVIDUAL;
50080
+ }
50081
+ );
50082
+ partnerParticipantId = relevantParticipantInfo?.relevantParticipantId;
50083
+ }
50084
+ const filteredRelevantOpponents = relevantOpponents?.filter(
50085
+ (opponent2) => matchUpType === TEAM_MATCHUP && participantType === TEAM_PARTICIPANT && opponent2.participantType === TEAM_PARTICIPANT || matchUpType === SINGLES_MATCHUP && opponent2.participantType === INDIVIDUAL || matchUpType === DOUBLES_MATCHUP && (participantType === INDIVIDUAL ? [INDIVIDUAL, PAIR].includes(opponent2.participantType) : (
50086
+ // for PAIR participants only show PAIR opponenents
50087
+ opponent2.participantType === PAIR
50088
+ ))
50089
+ ) || [];
50090
+ filteredRelevantOpponents.forEach(
50091
+ ({
50092
+ relevantParticipantId: opponentParticipantId2,
50093
+ participantType: opponentParticipantType
50094
+ }) => {
50095
+ if (!participantIdMap[relevantParticipantId].opponents) {
50096
+ participantIdMap[relevantParticipantId].opponents = {};
50347
50097
  }
50098
+ participantIdMap[relevantParticipantId].opponents[opponentParticipantId2] = {
50099
+ eventId,
50100
+ drawId,
50101
+ matchUpId,
50102
+ participantType: opponentParticipantType,
50103
+ participantId: opponentParticipantId2
50104
+ };
50348
50105
  }
50349
- };
50106
+ );
50107
+ const opponentParticipantInfo = filteredRelevantOpponents.map(
50108
+ ({ relevantParticipantId: relevantParticipantId2, participantType: participantType2 }) => ({
50109
+ participantId: relevantParticipantId2,
50110
+ participantType: participantType2
50111
+ })
50112
+ );
50113
+ const includeMatchUp = matchUpType !== TEAM_MATCHUP && [INDIVIDUAL, PAIR].includes(participantType) || matchUpType === TEAM_MATCHUP && participantType === TEAM_PARTICIPANT;
50114
+ if (includeMatchUp)
50115
+ participantIdMap[relevantParticipantId].matchUps[matchUpId] = definedAttributes({
50116
+ collectionId,
50117
+ collectionPosition,
50118
+ drawId,
50119
+ eventId,
50120
+ eventType,
50121
+ eventDrawsCount,
50122
+ finishingRound,
50123
+ finishingPositionRange: finishingPositionRange2,
50124
+ loserTo,
50125
+ matchUpId,
50126
+ matchUpType,
50127
+ matchUpFormat,
50128
+ matchUpStatus,
50129
+ matchUpStatusCodes,
50130
+ matchUpTieId,
50131
+ opponentParticipantInfo,
50132
+ participantWon,
50133
+ partnerParticipantId,
50134
+ perspectiveScoreString: participantScore,
50135
+ processCodes,
50136
+ roundName,
50137
+ roundNumber,
50138
+ roundPosition,
50139
+ schedule,
50140
+ score,
50141
+ sides,
50142
+ stage,
50143
+ stageSequence,
50144
+ structureName,
50145
+ structureId,
50146
+ tieFormat,
50147
+ tournamentId,
50148
+ winnerTo,
50149
+ winningSide
50150
+ });
50151
+ if (partnerParticipantId) {
50152
+ participantIdMap[relevantParticipantId].events[eventId].partnerParticipantIds.push(partnerParticipantId);
50153
+ participantIdMap[relevantParticipantId].draws[drawId].partnerParticipantIds.push(partnerParticipantId);
50154
+ participantIdMap[relevantParticipantId].events[eventId].partnerParticipantId = partnerParticipantId;
50155
+ participantIdMap[relevantParticipantId].draws[drawId].partnerParticipantId = partnerParticipantId;
50156
+ }
50157
+ if (winningSide) {
50158
+ if (participantWon) {
50159
+ participantIdMap[relevantParticipantId].wins++;
50160
+ } else {
50161
+ participantIdMap[relevantParticipantId].losses++;
50162
+ }
50163
+ }
50164
+ }
50165
+ );
50166
+ });
50167
+ if (Array.isArray(matchUp.potentialParticipants)) {
50168
+ const potentialParticipantIds = getParticipantIds(
50169
+ matchUp.potentialParticipants.flat()
50170
+ );
50171
+ potentialParticipantIds?.forEach((participantId) => {
50172
+ const relevantParticipantIds = getRelevantParticipantIds(participantId);
50173
+ relevantParticipantIds?.forEach(({ relevantParticipantId }) => {
50174
+ participantIdMap[relevantParticipantId].potentialMatchUps[matchUpId] = definedAttributes({
50175
+ drawId,
50176
+ eventId,
50177
+ eventType,
50178
+ matchUpId,
50179
+ matchUpType,
50180
+ matchUpFormat,
50181
+ roundName,
50182
+ roundNumber,
50183
+ roundPosition,
50184
+ schedule,
50185
+ tieFormat,
50186
+ structureName,
50187
+ tournamentId,
50188
+ potential: true
50189
+ });
50350
50190
  });
50351
50191
  });
50352
50192
  }
50353
- function invoke({ params, governor, methodName }) {
50354
- engine.error = void 0;
50355
- engine.success = false;
50356
- const matchUp = params?.matchUp || getMatchUp();
50357
- const matchUps = params?.matchUps || getMatchUps();
50358
- const snapshot = params?.rollbackOnError && makeDeepCopy(matchUp, false, true);
50359
- params = {
50360
- ...params,
50361
- matchUpId: matchUp?.matchUpId,
50362
- matchUps,
50363
- matchUp
50364
- };
50365
- const result = governor[methodName](params);
50366
- if (result?.error) {
50367
- if (snapshot)
50368
- setState$2(snapshot);
50369
- return { ...result, rolledBack: !!snapshot };
50370
- }
50371
- const notify = result?.success && params?.delayNotify !== true && params?.doNotNotify !== true;
50372
- if (notify)
50373
- notifySubscribers();
50374
- if (notify || !result?.success || params?.doNotNotify)
50375
- deleteNotices();
50376
- return result;
50377
- }
50378
- })();
50193
+ }
50379
50194
 
50380
- function matchUpEngineAsync(test) {
50381
- const result = createInstanceState();
50382
- if (result.error && !test)
50383
- return result;
50384
- const engine = {
50385
- getState: (params) => getState$2(params),
50386
- version: () => factoryVersion(),
50387
- reset: () => {
50388
- reset();
50389
- return { ...SUCCESS };
50390
- },
50391
- drawId: void 0,
50392
- error: void 0,
50393
- success: false,
50394
- devContext: (contextCriteria) => {
50395
- setDevContext(contextCriteria);
50396
- return engine;
50397
- },
50398
- setState: (definition, deepCopyOption, deepCopyAttributes) => {
50399
- setDeepCopy(deepCopyOption, deepCopyAttributes);
50400
- const result2 = setState$2(definition);
50401
- return processResult(result2);
50402
- }
50195
+ function addParticipantContext(params) {
50196
+ const participantIdsWithConflicts = [];
50197
+ const eventsPublishStatuses = {};
50198
+ const derivedDrawInfo = {};
50199
+ const participantIdMap = {};
50200
+ const initializeParticipantId = (participantId) => {
50201
+ if (!participantIdMap[participantId])
50202
+ participantIdMap[participantId] = {
50203
+ groupParticipantIds: [],
50204
+ teamParticipantIds: [],
50205
+ pairParticipantIds: [],
50206
+ potentialMatchUps: {},
50207
+ scheduleItems: [],
50208
+ opponents: {},
50209
+ matchUps: {},
50210
+ events: {},
50211
+ groups: [],
50212
+ teams: [],
50213
+ draws: {},
50214
+ losses: 0,
50215
+ wins: 0
50216
+ };
50217
+ };
50218
+ const { tournamentRecord, participantFilters, allTournamentParticipants } = params;
50219
+ const { relevantParticipantIdsMap } = getRelevantParticipantIdsMap({
50220
+ processParticipantId: initializeParticipantId,
50221
+ tournamentRecord
50222
+ });
50223
+ const targetParticipantIds = participantFilters?.participantIds;
50224
+ const getRelevantParticipantIds = (participantId) => {
50225
+ const relevantParticipantIds = participantId && relevantParticipantIdsMap[participantId] || [];
50226
+ relevantParticipantIds.push(participantId);
50227
+ return relevantParticipantIds.some(
50228
+ (obj) => !targetParticipantIds || targetParticipantIds.includes(obj.relevantParticipantId)
50229
+ ) ? relevantParticipantIds : [];
50403
50230
  };
50404
- function processResult(result2) {
50405
- if (result2?.error) {
50406
- engine.error = result2.error;
50407
- engine.success = false;
50408
- } else {
50409
- engine.error = void 0;
50410
- engine.success = true;
50411
- engine.drawId = result2.drawId;
50231
+ params.withGroupings && allTournamentParticipants.forEach((participant) => {
50232
+ if (participant.participantType === GROUP) {
50233
+ const groupParticipantId = participant.participantId;
50234
+ participant?.individualParticipantIds?.forEach((participantId) => {
50235
+ if (!participantIdMap[participantId].groupParticipantIds.includes(
50236
+ groupParticipantId
50237
+ )) {
50238
+ participantIdMap[participantId].groupParticipantIds.push(
50239
+ groupParticipantId
50240
+ );
50241
+ participantIdMap[participantId].groups.push({
50242
+ participantRoleResponsibilities: participant.participantRoleResponsibilities,
50243
+ participantOtherName: participant.participantOtherName,
50244
+ participantName: participant.participantName,
50245
+ participantId: participant.participantId
50246
+ });
50247
+ }
50248
+ });
50412
50249
  }
50413
- return engine;
50414
- }
50415
- importGovernors([
50416
- tieFormatGovernor,
50417
- historyGovernor,
50418
- queryGovernor$1,
50419
- scoreGovernor
50420
- ]);
50421
- return engine;
50422
- async function importGovernors(governors) {
50423
- for (const governor of governors) {
50424
- const governorMethods = Object.keys(governor);
50425
- for (const methodName of governorMethods) {
50426
- engine[methodName] = async (params) => {
50427
- if (getDevContext()) {
50428
- return await invoke({ params, governor, methodName });
50429
- } else {
50430
- try {
50431
- return await invoke({ params, governor, methodName });
50432
- } catch (err) {
50433
- handleCaughtError({
50434
- engineName: "matchUpEngine",
50435
- methodName,
50436
- params,
50437
- err
50438
- });
50439
- }
50440
- }
50441
- };
50442
- }
50250
+ if (participant.participantType === TEAM$2) {
50251
+ const teamParticipantId = participant.participantId;
50252
+ participant?.individualParticipantIds?.forEach((participantId) => {
50253
+ if (!participantIdMap[participantId]?.teamParticipantIds?.includes(
50254
+ teamParticipantId
50255
+ )) {
50256
+ participantIdMap[participantId]?.teamParticipantIds.push(
50257
+ teamParticipantId
50258
+ );
50259
+ participantIdMap[participantId]?.teams.push({
50260
+ participantRoleResponsibilities: participant.participantRoleResponsibilities,
50261
+ participantOtherName: participant.participantOtherName,
50262
+ participantName: participant.participantName,
50263
+ participantId: participant.participantId,
50264
+ teamId: participant.teamId
50265
+ });
50266
+ }
50267
+ });
50443
50268
  }
50444
- }
50445
- async function invoke({ params, governor, methodName }) {
50446
- engine.success = false;
50447
- engine.error = void 0;
50448
- const matchUp = params?.matchUp || getMatchUp();
50449
- const matchUps = params?.matchUps || getMatchUps();
50450
- const snapshot = params?.rollbackOnError && makeDeepCopy(matchUp, false, true);
50451
- params = {
50452
- ...params,
50453
- matchUpId: matchUp?.matchUpId,
50454
- matchUps,
50455
- matchUp
50456
- };
50457
- const result2 = governor[methodName](params);
50458
- if (result2?.error) {
50459
- if (snapshot)
50460
- setState$2(snapshot);
50461
- return { ...result2, rolledBack: !!snapshot };
50269
+ if (participant.participantType === PAIR) {
50270
+ const pairParticipantId = participant.participantId;
50271
+ participant?.individualParticipantIds?.forEach((participantId) => {
50272
+ if (participantIdMap[participantId] && !participantIdMap[participantId].pairParticipantIds.includes(
50273
+ pairParticipantId
50274
+ )) {
50275
+ participantIdMap[participantId].pairParticipantIds.push(
50276
+ pairParticipantId
50277
+ );
50278
+ }
50279
+ });
50462
50280
  }
50463
- const notify = result2?.success && params?.delayNotify !== true && params?.doNotNotify !== true;
50464
- if (notify)
50465
- await notifySubscribersAsync();
50466
- if (notify || !result2?.success || params?.doNotNotify)
50467
- deleteNotices();
50468
- return result2;
50469
- }
50470
- }
50471
-
50472
- function newTournamentRecord(params) {
50473
- const attributes = params || {};
50474
- if (!attributes.tournamentId)
50475
- attributes.tournamentId = UUID();
50476
- if (attributes.startDate && !isISODateString(attributes.startDate) && !validDateString.test(attributes.startDate)) {
50477
- return { error: INVALID_DATE };
50478
- }
50479
- if (attributes.endDate && !isISODateString(attributes.endDate) && !validDateString.test(attributes.endDate)) {
50480
- return { error: INVALID_DATE };
50481
- }
50482
- if (attributes.extensions) {
50483
- attributes.extensions = attributes.extensions.filter(isValidExtension);
50281
+ });
50282
+ if (params.withMatchUps) {
50283
+ getMatchUpDependencies({ tournamentRecord });
50484
50284
  }
50485
- return { ...attributes };
50486
- }
50487
-
50488
- function setState$1(tournament, deepCopyOption) {
50489
- if (typeof tournament !== "object")
50490
- return { error: INVALID_OBJECT };
50491
- const tournamentId = tournament.unifiedTournamentId?.tournamentId || tournament.tournamentId;
50492
- if (!tournamentId)
50493
- return { error: MISSING_TOURNAMENT_ID };
50494
- const tournamentRecord = deepCopyOption !== false ? makeDeepCopy(tournament) : tournament;
50495
- setTournamentRecords({ [tournamentId]: tournamentRecord });
50496
- setTournamentId(tournamentId);
50497
- return tournamentRecord;
50498
- }
50499
- function getState$1({
50500
- convertExtensions = false,
50501
- removeExtensions = false,
50502
- tournamentId
50503
- }) {
50504
- if (typeof tournamentId !== "string")
50505
- return {};
50506
- const tournamentRecord = getTournamentRecord(tournamentId);
50507
- return {
50508
- tournamentRecord: makeDeepCopy(
50509
- tournamentRecord,
50510
- convertExtensions,
50511
- false,
50512
- removeExtensions
50513
- )
50514
- };
50515
- }
50516
- function paramsMiddleware$1(tournamentRecord, params, prefetch) {
50517
- if (params) {
50518
- const drawId = params.drawId || params.matchUp?.drawId;
50519
- if (drawId) {
50520
- const { event, drawDefinition } = findEvent({
50521
- tournamentRecord,
50522
- drawId
50285
+ if (params.withScheduleItems || params.scheduleAnalysis || params.withStatistics || params.withOpponents || params.withMatchUps || params.withSeeding || params.withEvents || params.withDraws) {
50286
+ params.tournamentEvents?.forEach((rawEvent) => {
50287
+ const event = makeDeepCopy(rawEvent, true, true);
50288
+ const flightProfile = getFlightProfile({ event }).flightProfile;
50289
+ const eventDrawsCount = flightProfile?.flights?.length || event.drawDefinitions?.length || 0;
50290
+ (event.drawDefinitions || []).forEach((drawDefinition, i) => {
50291
+ if (event?.eventType === TEAM$2) {
50292
+ const { extension } = findExtension$2({
50293
+ element: rawEvent.drawDefinitions[i],
50294
+ // rawEvent because deepCopy has converted extensions
50295
+ name: LINEUPS
50296
+ });
50297
+ if (extension)
50298
+ drawDefinition.extensions = [extension];
50299
+ }
50523
50300
  });
50524
- params = {
50525
- ...params,
50526
- event,
50527
- drawDefinition
50301
+ const { eventId, eventName, eventType, category } = event;
50302
+ const eventInfo = { eventId, eventName, eventType, category };
50303
+ const extensionKeys = event && Object.keys(event).filter((key) => key.startsWith("_"));
50304
+ extensionKeys?.forEach(
50305
+ (extensionKey) => eventInfo[extensionKey] = event[extensionKey]
50306
+ );
50307
+ const eventEntries = event.entries || [];
50308
+ const itemType = `${PUBLISH}.${STATUS$1}`;
50309
+ const { timeItem } = getEventTimeItem({
50310
+ itemType,
50311
+ event
50312
+ });
50313
+ if (timeItem?.itemValue?.PUBLIC) {
50314
+ const { drawIds: publishedDrawIds = [], seeding } = timeItem.itemValue.PUBLIC || {};
50315
+ const publishedSeeding = {
50316
+ published: void 0,
50317
+ // seeding can be present for all entries in an event when no flights have been defined
50318
+ seedingScaleNames: [],
50319
+ drawIds: []
50320
+ // seeding can be specific to drawIds
50321
+ };
50322
+ if (seeding)
50323
+ Object.assign(publishedSeeding, timeItem.itemValue.PUBLIC.seeding);
50324
+ eventsPublishStatuses[eventId] = {
50325
+ publishedDrawIds,
50326
+ publishedSeeding
50327
+ };
50328
+ }
50329
+ const disallowedConstants = [
50330
+ ...Object.values(extensionConstants)
50331
+ ];
50332
+ const disallowedKeys = disallowedConstants.map(
50333
+ (constant) => `_${constant}`
50334
+ );
50335
+ const filteredEventInfo = eventInfo && Object.keys(eventInfo).filter((key) => !disallowedKeys.includes(key)).reduce((obj, key) => {
50336
+ obj[key] = eventInfo[key];
50337
+ return obj;
50338
+ }, {});
50339
+ eventEntries?.filter((entry) => entry?.participantId).forEach((entry) => {
50340
+ const { participantId, entryStage, entryStatus, entryPosition } = entry;
50341
+ const relevantParticipantIds = getRelevantParticipantIds(participantId);
50342
+ relevantParticipantIds?.forEach(({ relevantParticipantId }) => {
50343
+ if (!participantIdMap[relevantParticipantId])
50344
+ initializeParticipantId(relevantParticipantId);
50345
+ participantIdMap[relevantParticipantId].events[eventId] = {
50346
+ ...filteredEventInfo,
50347
+ partnerParticipantIds: [],
50348
+ entryPosition,
50349
+ entryStatus,
50350
+ entryStage,
50351
+ drawIds: [],
50352
+ eventId
50353
+ };
50354
+ });
50355
+ });
50356
+ const addDrawData = ({ drawEntry, drawId }) => {
50357
+ const { participantId, entryStage, entryStatus, entryPosition } = drawEntry;
50358
+ const relevantParticipantIds = getRelevantParticipantIds(participantId);
50359
+ relevantParticipantIds?.forEach(({ relevantParticipantId }) => {
50360
+ if (!participantIdMap[relevantParticipantId].events[eventId]) {
50361
+ participantIdMap[relevantParticipantId].events[eventId] = {
50362
+ ...filteredEventInfo,
50363
+ partnerParticipantIds: [],
50364
+ entryPosition,
50365
+ entryStatus,
50366
+ entryStage,
50367
+ drawIds: [],
50368
+ eventId
50369
+ };
50370
+ }
50371
+ if (!participantIdMap[relevantParticipantId].draws[drawId]) {
50372
+ const positionAssignments = getDerivedPositionAssignments({
50373
+ participantId: relevantParticipantId,
50374
+ derivedDrawInfo,
50375
+ drawId
50376
+ });
50377
+ const seedAssignments = getDerivedSeedAssignments({
50378
+ participantId: relevantParticipantId,
50379
+ derivedDrawInfo,
50380
+ drawId
50381
+ });
50382
+ participantIdMap[relevantParticipantId].draws[drawId] = definedAttributes({
50383
+ qualifyingDrawSize: derivedDrawInfo[drawId]?.qualifyingDrawSize,
50384
+ drawSize: derivedDrawInfo[drawId]?.drawSize,
50385
+ partnerParticipantIds: [],
50386
+ positionAssignments,
50387
+ eventDrawsCount,
50388
+ seedAssignments,
50389
+ entryPosition,
50390
+ entryStatus,
50391
+ entryStage,
50392
+ eventId,
50393
+ drawId
50394
+ });
50395
+ }
50396
+ const eventDrawIds = participantIdMap[relevantParticipantId].events[eventId].drawIds;
50397
+ if (eventDrawIds && !eventDrawIds?.includes(drawId)) {
50398
+ participantIdMap[relevantParticipantId].events[eventId].drawIds.push(drawId);
50399
+ }
50400
+ });
50528
50401
  };
50529
- if (prefetch) {
50530
- const matchUpsMap = getMatchUpsMap({ drawDefinition });
50531
- const { matchUps: inContextDrawMatchUps } = getAllDrawMatchUps({
50402
+ const drawIdsWithDefinitions = event.drawDefinitions?.map(({ drawId }) => drawId) || [];
50403
+ eventInfo._flightProfile?.flights?.forEach((flight) => {
50404
+ const { drawId, drawEntries } = flight;
50405
+ if (!drawIdsWithDefinitions.includes(drawId)) {
50406
+ drawEntries?.forEach(
50407
+ (drawEntry) => addDrawData({ drawEntry, drawId })
50408
+ );
50409
+ }
50410
+ });
50411
+ const { drawDetails, derivedInfo } = getDrawDetails({
50412
+ eventEntries,
50413
+ event
50414
+ });
50415
+ Object.assign(derivedDrawInfo, derivedInfo);
50416
+ if (event.eventType === TEAM$2 || // for TEAM events some individual attributes can only be derived by processing
50417
+ params.withScheduleItems || params.scheduleAnalysis || params.withStatistics || params.withOpponents || params.withMatchUps || params.withDraws) {
50418
+ const matchUps = allEventMatchUps({
50419
+ afterRecoveryTimes: params.scheduleAnalysis,
50420
+ participants: allTournamentParticipants,
50421
+ nextMatchUps: true,
50422
+ tournamentRecord,
50532
50423
  inContext: true,
50533
- drawDefinition,
50534
- matchUpsMap
50535
- });
50536
- params.matchUpsMap = matchUpsMap;
50537
- params.inContextDrawMatchUps = inContextDrawMatchUps;
50424
+ event
50425
+ })?.matchUps;
50426
+ matchUps?.forEach(
50427
+ (matchUp) => processMatchUp({
50428
+ relevantParticipantIdsMap,
50429
+ participantFilters,
50430
+ participantIdMap,
50431
+ derivedDrawInfo,
50432
+ eventDrawsCount,
50433
+ drawDetails,
50434
+ eventType,
50435
+ matchUp
50436
+ })
50437
+ );
50538
50438
  }
50539
- }
50540
- if (params.eventId && !params.event) {
50541
- const { event } = findEvent({
50542
- eventId: params.eventId,
50543
- tournamentRecord
50439
+ });
50440
+ }
50441
+ params.tournamentParticipants?.forEach((participant) => {
50442
+ const { scheduleConflicts, scheduleItems } = annotateParticipant({
50443
+ ...params,
50444
+ eventsPublishStatuses,
50445
+ participantIdMap,
50446
+ derivedDrawInfo,
50447
+ participant
50448
+ });
50449
+ if (params.withSignInStatus) {
50450
+ const { timeItem } = getTimeItem({
50451
+ itemType: SIGN_IN_STATUS,
50452
+ element: participant
50544
50453
  });
50545
- if (event) {
50546
- params = { ...params, event };
50454
+ participant.signedIn = timeItem?.itemValue === SIGNED_IN;
50455
+ }
50456
+ if (params.withScheduleItems) {
50457
+ participant.scheduleItems = scheduleItems;
50458
+ }
50459
+ if (params.scheduleAnalysis) {
50460
+ participant.scheduleConflicts = scheduleConflicts;
50461
+ if (scheduleConflicts?.length && !participantIdsWithConflicts.includes(participant.participantId)) {
50462
+ participantIdsWithConflicts.push(participant.participantId);
50547
50463
  }
50548
50464
  }
50549
- }
50550
- return params;
50551
- }
50552
-
50553
- function getEligibleVoluntaryConsolationParticipants(params) {
50554
- if (!params.tournamentRecord)
50555
- return { error: MISSING_TOURNAMENT_RECORD };
50556
- return getEligibleVoluntaryConsolationParticipants$1(params);
50465
+ if (params.withGroupings !== false) {
50466
+ const participantAttributes = participantIdMap[participant.participantId];
50467
+ participant.groupParticipantIds = participantAttributes?.groupParticipantIds;
50468
+ participant.pairParticipantIds = participantAttributes?.pairParticipantIds;
50469
+ participant.teamParticipantIds = participantAttributes?.teamParticipantIds;
50470
+ participant.groups = participantAttributes?.groups;
50471
+ participant.teams = participantAttributes?.teams;
50472
+ }
50473
+ if (params.withTeamMatchUps) ;
50474
+ });
50475
+ return { participantIdsWithConflicts, eventsPublishStatuses };
50557
50476
  }
50558
50477
 
50559
- function getParticipantEventDetails({
50560
- tournamentRecord,
50561
- participantId
50562
- }) {
50478
+ function getTournamentParticipants(params) {
50479
+ const {
50480
+ participantFilters = {},
50481
+ convertExtensions,
50482
+ policyDefinitions,
50483
+ withScheduleItems,
50484
+ scheduleAnalysis,
50485
+ withSignInStatus,
50486
+ withTeamMatchUps,
50487
+ // not implemented
50488
+ tournamentRecord,
50489
+ usePublishState,
50490
+ withScaleValues,
50491
+ withStatistics,
50492
+ withGroupings,
50493
+ withOpponents,
50494
+ withMatchUps,
50495
+ withSeeding,
50496
+ withEvents,
50497
+ withDraws,
50498
+ inContext,
50499
+ withISO2,
50500
+ withIOC
50501
+ } = params;
50563
50502
  if (!tournamentRecord)
50564
50503
  return { error: MISSING_TOURNAMENT_RECORD };
50565
- if (!participantId)
50566
- return { error: MISSING_PARTICIPANT_ID };
50567
- const relevantParticipantIds = [participantId].concat(
50568
- (tournamentRecord.participants || []).filter(
50569
- (participant) => participant?.participantType && [TEAM, PAIR].includes(participant.participantType) && participant.individualParticipantIds?.includes(participantId)
50570
- ).map((participant) => participant.participantId)
50504
+ if (!tournamentRecord.participants)
50505
+ return { error: MISSING_PARTICIPANTS };
50506
+ const allTournamentParticipants = tournamentRecord.participants.map(
50507
+ // (participant) => makeDeepCopy(participant, convertExtensions, true)
50508
+ (participant) => makeDeepCopy(participant, convertExtensions)
50509
+ // removed until Mongo/Mongoose issues resolved
50571
50510
  );
50572
- const relevantEvents = (tournamentRecord.events || []).filter((event) => {
50573
- const enteredParticipantIds = (event?.entries || []).map(
50574
- (entry) => entry.participantId
50511
+ if (typeof participantFilters !== "object")
50512
+ return { error: INVALID_OBJECT, participantFilters };
50513
+ if (inContext) {
50514
+ allTournamentParticipants?.forEach((participant) => {
50515
+ if ([PAIR, TEAM, GROUP].includes(participant.participantType)) {
50516
+ participant.individualParticipants = participant.individualParticipantIds?.map((participantId) => {
50517
+ const targetParticipant = tournamentRecord.participants.find(
50518
+ (p) => p.participantId === participantId
50519
+ );
50520
+ const individualParticipant = makeDeepCopy(
50521
+ targetParticipant,
50522
+ convertExtensions,
50523
+ true
50524
+ );
50525
+ if (withScaleValues) {
50526
+ const { ratings, rankings } = getScaleValues({
50527
+ participant: individualParticipant
50528
+ });
50529
+ individualParticipant.ratings = ratings;
50530
+ individualParticipant.rankings = rankings;
50531
+ }
50532
+ if (withIOC || withISO2)
50533
+ addNationalityCode({
50534
+ participant: individualParticipant,
50535
+ withISO2,
50536
+ withIOC
50537
+ });
50538
+ return individualParticipant;
50539
+ });
50540
+ }
50541
+ });
50542
+ }
50543
+ let tournamentParticipants = participantFilters ? filterParticipants({
50544
+ participants: allTournamentParticipants,
50545
+ participantFilters,
50546
+ tournamentRecord
50547
+ }) : allTournamentParticipants;
50548
+ let participantIdsWithConflicts, eventsPublishStatuses;
50549
+ const addContext = withScheduleItems || withSignInStatus || scheduleAnalysis || withScaleValues || withStatistics || withGroupings || withOpponents || withMatchUps || withSeeding || withEvents || withDraws || withISO2 || withIOC;
50550
+ if (addContext) {
50551
+ const result = addParticipantContext({
50552
+ tournamentEvents: tournamentRecord.events,
50553
+ allTournamentParticipants,
50554
+ tournamentParticipants,
50555
+ participantFilters,
50556
+ withScheduleItems,
50557
+ withSignInStatus,
50558
+ tournamentRecord,
50559
+ scheduleAnalysis,
50560
+ withTeamMatchUps,
50561
+ usePublishState,
50562
+ withScaleValues,
50563
+ withStatistics,
50564
+ withGroupings,
50565
+ withOpponents,
50566
+ withMatchUps,
50567
+ withSeeding,
50568
+ withEvents,
50569
+ withDraws,
50570
+ withISO2,
50571
+ withIOC
50572
+ });
50573
+ participantIdsWithConflicts = result?.participantIdsWithConflicts;
50574
+ eventsPublishStatuses = result?.eventsPublishStatuses;
50575
+ }
50576
+ const participantAttributes = policyDefinitions?.[POLICY_TYPE_PARTICIPANT];
50577
+ if (participantAttributes?.participant) {
50578
+ tournamentParticipants = tournamentParticipants.map(
50579
+ (participant) => attributeFilter({
50580
+ template: participantAttributes.participant,
50581
+ source: participant
50582
+ })
50575
50583
  );
50576
- return overlap(enteredParticipantIds, relevantParticipantIds);
50577
- }).map((event) => ({ eventName: event.eventName, eventId: event.eventId }));
50578
- return { eventDetails: relevantEvents };
50584
+ }
50585
+ return {
50586
+ participantIdsWithConflicts,
50587
+ tournamentParticipants,
50588
+ eventsPublishStatuses
50589
+ };
50579
50590
  }
50580
50591
 
50581
50592
  function getParticipantMembership({
@@ -54079,6 +54090,11 @@ function updateCourtAvailability({ tournamentRecord }) {
54079
54090
  );
54080
54091
  return existing || { date, startTime, endTime };
54081
54092
  });
54093
+ const defaultAvailability = court.dateAvailability?.find(
54094
+ (availability) => !availability.date
54095
+ );
54096
+ if (defaultAvailability)
54097
+ updatedDateAvailability.unshift(defaultAvailability);
54082
54098
  court.dateAvailability = updatedDateAvailability;
54083
54099
  }
54084
54100
  return { ...SUCCESS };
@@ -59018,7 +59034,7 @@ function generateDrawDefinition(params) {
59018
59034
  drawDefinition.links = [];
59019
59035
  drawDefinition.links.push(link);
59020
59036
  }
59021
- drawDefinition.drawName = params.drawName ?? drawType;
59037
+ drawDefinition.drawName = params.drawName ?? (drawType && constantToString(drawType));
59022
59038
  if (typeof voluntaryConsolation === "object") {
59023
59039
  addVoluntaryConsolationStructure({
59024
59040
  ...voluntaryConsolation,