tods-competition-factory 2.0.23 → 2.0.24
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 +5 -5
- package/dist/tods-competition-factory.d.ts +54 -29
- package/dist/tods-competition-factory.development.cjs.js +1446 -1272
- package/dist/tods-competition-factory.development.cjs.js.map +1 -1
- package/dist/tods-competition-factory.production.cjs.min.js +1 -1
- package/dist/tods-competition-factory.production.cjs.min.js.map +1 -1
- package/package.json +18 -18
|
@@ -3,432 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
function factoryVersion() {
|
|
6
|
-
return '2.0.
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const validDateString = /^[\d]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][\d]|3[0-1])$/;
|
|
10
|
-
const validTimeString = /^((0[\d]|1[\d]|2[0-3]):[0-5][\d](:[0-5][\d])?)([.,][0-9]{3})?$/;
|
|
11
|
-
const dateValidation = /^([\d]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][\d]|3[0-1]))([ T](0[\d]|1[\d]|2[0-3]):[0-5][\d](:[0-5][\d])?)?([.,][\d]{3})?Z?$/;
|
|
12
|
-
const timeValidation = /^([\d]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][\d]|3[0-1]))?([ T]?(0[\d]|1[\d]|2[0-3]):[0-5][\d](:[0-5][\d])?)?([.,][\d]{3})?Z?$/;
|
|
13
|
-
|
|
14
|
-
function getIsoDateString(schedule) {
|
|
15
|
-
let { scheduledDate } = schedule;
|
|
16
|
-
if (!scheduledDate && schedule.scheduledTime)
|
|
17
|
-
scheduledDate = extractDate(schedule.scheduledTime);
|
|
18
|
-
if (!scheduledDate)
|
|
19
|
-
return;
|
|
20
|
-
const extractedTime = extractTime(schedule.scheduledTime);
|
|
21
|
-
let isoDateString = extractDate(scheduledDate);
|
|
22
|
-
if (isoDateString && extractedTime)
|
|
23
|
-
isoDateString += `T${extractedTime}`;
|
|
24
|
-
return isoDateString;
|
|
25
|
-
}
|
|
26
|
-
function isDateObject(value) {
|
|
27
|
-
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
const datePrototype = Object.prototype.toString.call(value);
|
|
32
|
-
return datePrototype === '[object Date]';
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
function validTimeValue(value) {
|
|
36
|
-
const spaceSplit = typeof value === 'string' ? value?.split(' ') : [];
|
|
37
|
-
if (value && spaceSplit?.length > 1 && !['AM', 'PM'].includes(spaceSplit[1].toUpperCase()))
|
|
38
|
-
return false;
|
|
39
|
-
return !!(!value || timeValidation.test(convertTime(value, true, true)));
|
|
40
|
-
}
|
|
41
|
-
function isValidDateString(scheduleDate) {
|
|
42
|
-
return isISODateString(scheduleDate) || validDateString.test(scheduleDate);
|
|
43
|
-
}
|
|
44
|
-
function DateHHMM(date) {
|
|
45
|
-
const dt = new Date(date);
|
|
46
|
-
const secs = dt.getSeconds() + 60 * dt.getMinutes() + 60 * 60 * dt.getHours();
|
|
47
|
-
return HHMMSS(secs, { displaySeconds: false });
|
|
48
|
-
}
|
|
49
|
-
function HHMMSS(s, format) {
|
|
50
|
-
const secondNumber = parseInt(s, 10);
|
|
51
|
-
const hours = Math.floor(secondNumber / 3600);
|
|
52
|
-
const minutes = Math.floor((secondNumber - hours * 3600) / 60);
|
|
53
|
-
const seconds = secondNumber - hours * 3600 - minutes * 60;
|
|
54
|
-
const displaySeconds = !format || format?.displaySeconds;
|
|
55
|
-
const timeString = displaySeconds ? hours + ':' + minutes + ':' + seconds : hours + ':' + minutes;
|
|
56
|
-
return timeString.split(':').map(zeroPad).join(':');
|
|
57
|
-
}
|
|
58
|
-
const getUTCdateString = (date) => {
|
|
59
|
-
const dateDate = isDate(date) || isISODateString(date) ? new Date(date) : new Date();
|
|
60
|
-
const monthNumber = dateDate.getUTCMonth() + 1;
|
|
61
|
-
const utcMonth = monthNumber < 10 ? `0${monthNumber}` : `${monthNumber}`;
|
|
62
|
-
return `${dateDate.getUTCFullYear()}-${zeroPad(utcMonth)}-${zeroPad(dateDate.getUTCDate())}`;
|
|
63
|
-
};
|
|
64
|
-
function timeUTC(date) {
|
|
65
|
-
const dateDate = isDate(date) || isISODateString(date) ? new Date(date) : new Date();
|
|
66
|
-
return Date.UTC(dateDate.getFullYear(), dateDate.getMonth(), dateDate.getDate());
|
|
67
|
-
}
|
|
68
|
-
function formatDate(date, separator = '-', format = 'YMD') {
|
|
69
|
-
if (!date)
|
|
70
|
-
return '';
|
|
71
|
-
if (typeof date === 'string' && date.indexOf('T') < 0)
|
|
72
|
-
date = date + 'T00:00';
|
|
73
|
-
const d = new Date(date);
|
|
74
|
-
let month = '' + (d.getMonth() + 1);
|
|
75
|
-
let day = '' + d.getDate();
|
|
76
|
-
const year = d.getFullYear();
|
|
77
|
-
if (month.length < 2)
|
|
78
|
-
month = '0' + month;
|
|
79
|
-
if (day.length < 2)
|
|
80
|
-
day = '0' + day;
|
|
81
|
-
if (format === 'DMY')
|
|
82
|
-
return [day, month, year].join(separator);
|
|
83
|
-
if (format === 'MDY')
|
|
84
|
-
return [month, day, year].join(separator);
|
|
85
|
-
if (format === 'YDM')
|
|
86
|
-
return [year, day, month].join(separator);
|
|
87
|
-
if (format === 'DYM')
|
|
88
|
-
return [day, year, month].join(separator);
|
|
89
|
-
if (format === 'MYD')
|
|
90
|
-
return [month, year, day].join(separator);
|
|
91
|
-
return [year, month, day].join(separator);
|
|
92
|
-
}
|
|
93
|
-
function offsetDate(date) {
|
|
94
|
-
const targetTime = date ? new Date(date) : new Date();
|
|
95
|
-
const tzDifference = targetTime.getTimezoneOffset();
|
|
96
|
-
return new Date(targetTime.getTime() - tzDifference * 60 * 1000);
|
|
97
|
-
}
|
|
98
|
-
function offsetTime(date) {
|
|
99
|
-
return offsetDate(date).getTime();
|
|
100
|
-
}
|
|
101
|
-
function isDate(dateArg) {
|
|
102
|
-
if (typeof dateArg == 'boolean')
|
|
103
|
-
return false;
|
|
104
|
-
const t = (dateArg instanceof Date && dateArg) || (!isNaN(dateArg) && new Date(dateArg)) || false;
|
|
105
|
-
return t && !isNaN(t.valueOf());
|
|
106
|
-
}
|
|
107
|
-
function generateDateRange(startDt, endDt) {
|
|
108
|
-
if (!isValidDateString(startDt) || !isValidDateString(endDt))
|
|
109
|
-
return [];
|
|
110
|
-
const startDateString = extractDate(startDt) + 'T00:00';
|
|
111
|
-
const endDateString = extractDate(endDt) + 'T00:00';
|
|
112
|
-
const startDate = new Date(startDateString);
|
|
113
|
-
const endDate = new Date(endDateString);
|
|
114
|
-
const process = isDate(endDate) && isDate(startDate) && isValidDateRange(startDate, endDate);
|
|
115
|
-
const between = [];
|
|
116
|
-
let iterations = 0;
|
|
117
|
-
if (process) {
|
|
118
|
-
const currentDate = startDate;
|
|
119
|
-
let dateSecs = currentDate.getTime();
|
|
120
|
-
while (dateSecs <= endDate.getTime() && iterations < 300) {
|
|
121
|
-
iterations += 1;
|
|
122
|
-
between.push(new Date(currentDate));
|
|
123
|
-
dateSecs = currentDate.setDate(currentDate.getDate() + 1);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return between.map((date) => formatDate(date));
|
|
127
|
-
function isValidDateRange(minDate, maxDate) {
|
|
128
|
-
return minDate <= maxDate;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
const re = /^([+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([.,]\d+(?!:))?)?(\17[0-5]\d([.,]\d+)?)?([zZ]|([+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;
|
|
132
|
-
function isISODateString(dateString) {
|
|
133
|
-
if (typeof dateString !== 'string')
|
|
134
|
-
return false;
|
|
135
|
-
return re.test(dateString);
|
|
136
|
-
}
|
|
137
|
-
function isTimeString(timeString) {
|
|
138
|
-
if (typeof timeString !== 'string')
|
|
139
|
-
return false;
|
|
140
|
-
const noZ = timeString.split('Z')[0];
|
|
141
|
-
const parts = noZ.split(':');
|
|
142
|
-
const isNumeric = parts.every((part) => !isNaN(parseInt(part)));
|
|
143
|
-
const invalid = parts.length < 2 || !isNumeric || parseInt(parts[0]) > 23 || parseInt(parts[1]) > 60;
|
|
144
|
-
return !invalid;
|
|
145
|
-
}
|
|
146
|
-
function timeStringMinutes(timeString) {
|
|
147
|
-
const validTimeString = extractTime(timeString);
|
|
148
|
-
if (!validTimeString)
|
|
149
|
-
return 0;
|
|
150
|
-
const [hours, minutes] = validTimeString.split(':').map((value) => parseInt(value));
|
|
151
|
-
return hours * 60 + minutes;
|
|
152
|
-
}
|
|
153
|
-
function dayMinutesToTimeString(totalMinutes) {
|
|
154
|
-
let hours = Math.floor(totalMinutes / 60);
|
|
155
|
-
const minutes = totalMinutes - hours * 60;
|
|
156
|
-
if (hours > 23)
|
|
157
|
-
hours = hours % 24;
|
|
158
|
-
return [zeroPad(hours), zeroPad(minutes)].join(':');
|
|
159
|
-
}
|
|
160
|
-
function tidyTime(timeString) {
|
|
161
|
-
return isTimeString(timeString) ? timeString.split(':').slice(0, 2).map(zeroPad).join(':') : undefined;
|
|
162
|
-
}
|
|
163
|
-
function extractTime(dateString) {
|
|
164
|
-
return isISODateString(dateString) && dateString.indexOf('T') > 0
|
|
165
|
-
? tidyTime(dateString.split('T').reverse()[0])
|
|
166
|
-
: tidyTime(dateString);
|
|
167
|
-
}
|
|
168
|
-
function extractDate(dateString) {
|
|
169
|
-
return isISODateString(dateString) || dateValidation.test(dateString) ? dateString.split('T')[0] : undefined;
|
|
170
|
-
}
|
|
171
|
-
function dateStringDaysChange(dateString, daysChange) {
|
|
172
|
-
const date = new Date(dateString);
|
|
173
|
-
date.setDate(date.getDate() + daysChange);
|
|
174
|
-
return extractDate(date.toISOString());
|
|
175
|
-
}
|
|
176
|
-
function splitTime(value) {
|
|
177
|
-
value = typeof value !== 'string' ? '00:00' : value;
|
|
178
|
-
const o = {}, time = {};
|
|
179
|
-
({ 0: o.time, 1: o.ampm } = value.split(' ') || []);
|
|
180
|
-
({ 0: time.hours, 1: time.minutes } = o.time.split(':') || []);
|
|
181
|
-
time.ampm = o.ampm;
|
|
182
|
-
if (isNaN(time.hours) || isNaN(time.minutes) || (time.ampm && !['AM', 'PM'].includes(time.ampm.toUpperCase())))
|
|
183
|
-
return {};
|
|
184
|
-
return time;
|
|
185
|
-
}
|
|
186
|
-
function militaryTime(value) {
|
|
187
|
-
const time = splitTime(value);
|
|
188
|
-
if (time.ampm && time.hours) {
|
|
189
|
-
if (time.ampm.toLowerCase() === 'pm' && parseInt(time.hours) < 12)
|
|
190
|
-
time.hours = ((time.hours && parseInt(time.hours)) || 0) + 12;
|
|
191
|
-
if (time.ampm.toLowerCase() === 'am' && time.hours === '12')
|
|
192
|
-
time.hours = '00';
|
|
193
|
-
}
|
|
194
|
-
const timeString = `${time.hours || '12'}:${time.minutes || '00'}`;
|
|
195
|
-
return timeString.split(':').map(zeroPad).join(':');
|
|
196
|
-
}
|
|
197
|
-
function regularTime(value) {
|
|
198
|
-
const time = splitTime(value);
|
|
199
|
-
if (typeof time === 'object' && !Object.keys(time).length)
|
|
200
|
-
return undefined;
|
|
201
|
-
if (time.ampm)
|
|
202
|
-
return value;
|
|
203
|
-
if (time.hours > 12) {
|
|
204
|
-
time.hours -= 12;
|
|
205
|
-
time.ampm = 'PM';
|
|
206
|
-
}
|
|
207
|
-
else if (time.hours === '12') {
|
|
208
|
-
time.ampm = 'PM';
|
|
209
|
-
}
|
|
210
|
-
else if (time.hours === '00') {
|
|
211
|
-
time.hours = '12';
|
|
212
|
-
time.ampm = 'AM';
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
time.ampm = 'AM';
|
|
216
|
-
}
|
|
217
|
-
if (time.hours?.[0] === '0') {
|
|
218
|
-
time.hours = time.hours.slice(1);
|
|
219
|
-
}
|
|
220
|
-
return `${time.hours || '12'}:${time.minutes || '00'} ${time.ampm}`;
|
|
221
|
-
}
|
|
222
|
-
function convertTime(value, time24, keepDate) {
|
|
223
|
-
const hasDate = extractDate(value);
|
|
224
|
-
const timeString = extractTime(value);
|
|
225
|
-
const timeValue = hasDate ? timeString : value;
|
|
226
|
-
return !value
|
|
227
|
-
? undefined
|
|
228
|
-
: (time24 && ((hasDate && keepDate && value) || militaryTime(timeValue))) || regularTime(timeValue);
|
|
229
|
-
}
|
|
230
|
-
function timeSort(a, b) {
|
|
231
|
-
const as = splitTime(a);
|
|
232
|
-
const bs = splitTime(b);
|
|
233
|
-
if (parseInt(as.hours) < parseInt(bs.hours))
|
|
234
|
-
return -1;
|
|
235
|
-
if (parseInt(as.hours) > parseInt(bs.hours))
|
|
236
|
-
return 1;
|
|
237
|
-
if (as.hours === bs.hours) {
|
|
238
|
-
if (parseInt(as.minutes) < parseInt(bs.minutes))
|
|
239
|
-
return -1;
|
|
240
|
-
if (parseInt(as.minutes) > parseInt(bs.minutes))
|
|
241
|
-
return 1;
|
|
242
|
-
}
|
|
243
|
-
return 0;
|
|
244
|
-
}
|
|
245
|
-
function addDays(date, days = 7) {
|
|
246
|
-
const universalDate = extractDate(date) + 'T00:00';
|
|
247
|
-
const now = new Date(universalDate);
|
|
248
|
-
const adjustedDate = new Date(now.setDate(now.getDate() + days));
|
|
249
|
-
return formatDate(adjustedDate);
|
|
250
|
-
}
|
|
251
|
-
function addWeek(date) {
|
|
252
|
-
return addDays(date);
|
|
253
|
-
}
|
|
254
|
-
function getDateByWeek(week, year, dateFormat, sunday = false) {
|
|
255
|
-
const date = new Date(year, 0, 1 + (week - 1) * 7);
|
|
256
|
-
const startValue = sunday ? 0 : 1;
|
|
257
|
-
date.setDate(date.getDate() + (startValue - date.getDay()));
|
|
258
|
-
return formatDate(date, dateFormat);
|
|
259
|
-
}
|
|
260
|
-
function dateFromDay(year, day, dateFormat) {
|
|
261
|
-
const date = new Date(year, 0);
|
|
262
|
-
return formatDate(new Date(date.setDate(day)), dateFormat);
|
|
263
|
-
}
|
|
264
|
-
function timeToDate(timeString, date = undefined) {
|
|
265
|
-
const [hours, minutes] = (timeString || '00:00').split(':').map(zeroPad);
|
|
266
|
-
const milliseconds = offsetDate(date).setHours(hours, minutes, 0, 0);
|
|
267
|
-
return offsetDate(milliseconds);
|
|
268
|
-
}
|
|
269
|
-
function minutesDifference(date1, date2, absolute = true) {
|
|
270
|
-
const dt1 = new Date(date1);
|
|
271
|
-
const dt2 = new Date(date2);
|
|
272
|
-
const diff = (dt2.getTime() - dt1.getTime()) / 1000 / 60;
|
|
273
|
-
return absolute ? Math.abs(Math.round(diff)) : Math.round(diff);
|
|
274
|
-
}
|
|
275
|
-
function addMinutesToTimeString(timeString, minutes) {
|
|
276
|
-
const validTimeString = extractTime(timeString);
|
|
277
|
-
if (!validTimeString)
|
|
278
|
-
return '00:00';
|
|
279
|
-
const minutesToAdd = isNaN(minutes) ? 0 : minutes;
|
|
280
|
-
return extractTime(addMinutes(timeToDate(validTimeString), minutesToAdd).toISOString());
|
|
281
|
-
}
|
|
282
|
-
function addMinutes(startDate, minutes) {
|
|
283
|
-
const date = new Date(startDate);
|
|
284
|
-
return new Date(date.getTime() + minutes * 60000);
|
|
285
|
-
}
|
|
286
|
-
function zeroPad(number) {
|
|
287
|
-
return number.toString()[1] ? number : '0' + number;
|
|
288
|
-
}
|
|
289
|
-
function sameDay(date1, date2) {
|
|
290
|
-
const d1 = new Date(date1);
|
|
291
|
-
const d2 = new Date(date2);
|
|
292
|
-
return d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() === d2.getDate();
|
|
293
|
-
}
|
|
294
|
-
const dateTime = {
|
|
295
|
-
addDays,
|
|
296
|
-
addWeek,
|
|
297
|
-
addMinutesToTimeString,
|
|
298
|
-
convertTime,
|
|
299
|
-
getIsoDateString,
|
|
300
|
-
getUTCdateString,
|
|
301
|
-
DateHHMM,
|
|
302
|
-
extractDate,
|
|
303
|
-
extractTime,
|
|
304
|
-
formatDate,
|
|
305
|
-
getDateByWeek,
|
|
306
|
-
isISODateString,
|
|
307
|
-
isDate,
|
|
308
|
-
isTimeString,
|
|
309
|
-
offsetDate,
|
|
310
|
-
offsetTime,
|
|
311
|
-
sameDay,
|
|
312
|
-
timeStringMinutes,
|
|
313
|
-
timeToDate,
|
|
314
|
-
timeUTC,
|
|
315
|
-
validTimeValue,
|
|
316
|
-
validDateString,
|
|
317
|
-
timeValidation,
|
|
318
|
-
dateValidation,
|
|
319
|
-
};
|
|
320
|
-
|
|
321
|
-
function makeDeepCopy(sourceObject, convertExtensions, internalUse, removeExtensions, iteration = 0) {
|
|
322
|
-
if (getProvider().makeDeepCopy)
|
|
323
|
-
return getProvider().makeDeepCopy(sourceObject, convertExtensions, internalUse, removeExtensions);
|
|
324
|
-
const deepCopy = deepCopyEnabled();
|
|
325
|
-
const { stringify, toJSON, ignore, modulate } = deepCopy || {};
|
|
326
|
-
if ((!deepCopy?.enabled && !internalUse) ||
|
|
327
|
-
typeof sourceObject !== 'object' ||
|
|
328
|
-
typeof sourceObject === 'function' ||
|
|
329
|
-
sourceObject === null ||
|
|
330
|
-
(typeof deepCopy?.threshold === 'number' && iteration >= deepCopy.threshold)) {
|
|
331
|
-
return sourceObject;
|
|
332
|
-
}
|
|
333
|
-
const targetObject = Array.isArray(sourceObject) ? [] : {};
|
|
334
|
-
const sourceObjectKeys = Object.keys(sourceObject).filter((key) => !internalUse ||
|
|
335
|
-
!ignore ||
|
|
336
|
-
(Array.isArray(ignore) && !ignore.includes(key)) ||
|
|
337
|
-
(typeof ignore === 'function' && !ignore(key)));
|
|
338
|
-
const stringifyValue = (key, value) => {
|
|
339
|
-
targetObject[key] = typeof value?.toString === 'function' ? value.toString() : JSON.stringify(value);
|
|
340
|
-
};
|
|
341
|
-
for (const key of sourceObjectKeys) {
|
|
342
|
-
const value = sourceObject[key];
|
|
343
|
-
const modulated = typeof modulate === 'function' ? modulate(value) : undefined;
|
|
344
|
-
if (modulated !== undefined) {
|
|
345
|
-
targetObject[key] = modulated;
|
|
346
|
-
}
|
|
347
|
-
else if (convertExtensions && key === 'extensions' && Array.isArray(value)) {
|
|
348
|
-
const extensionConversions = extensionsToAttributes(value);
|
|
349
|
-
Object.assign(targetObject, ...extensionConversions);
|
|
350
|
-
}
|
|
351
|
-
else if (removeExtensions && key === 'extensions') {
|
|
352
|
-
targetObject[key] = [];
|
|
353
|
-
}
|
|
354
|
-
else if (Array.isArray(stringify) && stringify.includes(key)) {
|
|
355
|
-
stringifyValue(key, value);
|
|
356
|
-
}
|
|
357
|
-
else if (Array.isArray(toJSON) && toJSON.includes(key) && typeof value?.toJSON === 'function') {
|
|
358
|
-
targetObject[key] = value.toJSON();
|
|
359
|
-
}
|
|
360
|
-
else if (value === null) {
|
|
361
|
-
targetObject[key] = undefined;
|
|
362
|
-
}
|
|
363
|
-
else if (isDateObject(value)) {
|
|
364
|
-
targetObject[key] = new Date(value).toISOString();
|
|
365
|
-
}
|
|
366
|
-
else {
|
|
367
|
-
targetObject[key] = makeDeepCopy(value, convertExtensions, internalUse, removeExtensions, iteration + 1);
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
return targetObject;
|
|
371
|
-
}
|
|
372
|
-
function extensionsToAttributes(extensions) {
|
|
373
|
-
return extensions
|
|
374
|
-
?.map((extension) => {
|
|
375
|
-
const { name, value } = extension;
|
|
376
|
-
return name && value && { [`_${name}`]: value };
|
|
377
|
-
})
|
|
378
|
-
.filter(Boolean);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
function getAccessorValue({ element, accessor }) {
|
|
382
|
-
if (typeof accessor !== 'string')
|
|
383
|
-
return { values: [] };
|
|
384
|
-
const targetElement = makeDeepCopy(element);
|
|
385
|
-
const attributes = accessor.split('.');
|
|
386
|
-
const values = [];
|
|
387
|
-
let value;
|
|
388
|
-
processKeys({ targetElement, attributes });
|
|
389
|
-
const result = { value };
|
|
390
|
-
if (values.length)
|
|
391
|
-
result.values = values;
|
|
392
|
-
return result;
|
|
393
|
-
function processKeys({ targetElement, attributes = [], significantCharacters }) {
|
|
394
|
-
for (const [index, attribute] of attributes.entries()) {
|
|
395
|
-
if (targetElement?.[attribute]) {
|
|
396
|
-
const remainingKeys = attributes.slice(index + 1);
|
|
397
|
-
if (!remainingKeys.length) {
|
|
398
|
-
if (!value)
|
|
399
|
-
value = targetElement[attribute];
|
|
400
|
-
if (!values.includes(targetElement[attribute])) {
|
|
401
|
-
values.push(targetElement[attribute]);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
else if (Array.isArray(targetElement[attribute])) {
|
|
405
|
-
const values = targetElement[attribute];
|
|
406
|
-
values.forEach((nestedTarget) => processKeys({
|
|
407
|
-
targetElement: nestedTarget,
|
|
408
|
-
attributes: remainingKeys,
|
|
409
|
-
}));
|
|
410
|
-
}
|
|
411
|
-
else {
|
|
412
|
-
targetElement = targetElement[attribute];
|
|
413
|
-
checkValue({ targetElement, index });
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
function checkValue({ targetElement, index }) {
|
|
418
|
-
if (targetElement && index === attributes.length - 1 && ['string', 'number'].includes(typeof targetElement)) {
|
|
419
|
-
const extractedValue = significantCharacters ? targetElement.slice(0, significantCharacters) : targetElement;
|
|
420
|
-
if (value) {
|
|
421
|
-
if (!values.includes(extractedValue)) {
|
|
422
|
-
values.push(extractedValue);
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
else {
|
|
426
|
-
value = extractedValue;
|
|
427
|
-
values.push(extractedValue);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
6
|
+
return '2.0.24';
|
|
432
7
|
}
|
|
433
8
|
|
|
434
9
|
function isFunction(obj) {
|
|
@@ -468,18 +43,6 @@ function createMap(objectArray, attribute) {
|
|
|
468
43
|
.filter(Boolean));
|
|
469
44
|
}
|
|
470
45
|
const hasAttributeValues = (a) => (o) => Object.keys(a).every((key) => o[key] === a[key]);
|
|
471
|
-
const extractAttributes = (accessor) => (element) => !accessor || typeof element !== 'object'
|
|
472
|
-
? undefined
|
|
473
|
-
: (Array.isArray(accessor) &&
|
|
474
|
-
accessor.map((a) => ({
|
|
475
|
-
[a]: getAccessorValue({ element, accessor: a })?.value,
|
|
476
|
-
}))) ||
|
|
477
|
-
(typeof accessor === 'object' &&
|
|
478
|
-
Object.keys(accessor).map((key) => ({
|
|
479
|
-
[key]: getAccessorValue({ element, accessor: key })?.value,
|
|
480
|
-
}))) ||
|
|
481
|
-
(typeof accessor === 'string' && getAccessorValue({ element, accessor }))?.value;
|
|
482
|
-
const xa = extractAttributes;
|
|
483
46
|
function undefinedToNull(obj, shallow) {
|
|
484
47
|
if (obj === undefined)
|
|
485
48
|
return null;
|
|
@@ -1966,7 +1529,7 @@ function timeKeeper(action = 'reset', timer = 'default') {
|
|
|
1966
1529
|
return globalState.timers[timer];
|
|
1967
1530
|
}
|
|
1968
1531
|
function setGlobalLog(loggingFx) {
|
|
1969
|
-
if (
|
|
1532
|
+
if (isFunction(loggingFx)) {
|
|
1970
1533
|
globalState.globalLog = loggingFx;
|
|
1971
1534
|
}
|
|
1972
1535
|
else {
|
|
@@ -2022,7 +1585,7 @@ function setGlobalMethods(params) {
|
|
|
2022
1585
|
if (typeof params !== 'object')
|
|
2023
1586
|
return { error: INVALID_VALUES };
|
|
2024
1587
|
Object.keys(params).forEach((methodName) => {
|
|
2025
|
-
if (
|
|
1588
|
+
if (!isFunction(params[methodName]))
|
|
2026
1589
|
return;
|
|
2027
1590
|
globalState.globalMethods[methodName] = params[methodName];
|
|
2028
1591
|
});
|
|
@@ -2087,7 +1650,7 @@ function getProvider() {
|
|
|
2087
1650
|
return _globalStateProvider;
|
|
2088
1651
|
}
|
|
2089
1652
|
function handleCaughtError({ engineName, methodName, params, err }) {
|
|
2090
|
-
const caughtErrorHandler = (
|
|
1653
|
+
const caughtErrorHandler = (isFunction(_globalStateProvider.handleCaughtError) && _globalStateProvider.handleCaughtError) ||
|
|
2091
1654
|
syncGlobalState$1.handleCaughtError;
|
|
2092
1655
|
return caughtErrorHandler({
|
|
2093
1656
|
engineName,
|
|
@@ -2244,6 +1807,7 @@ const UUIDS$1 = 'uuids';
|
|
|
2244
1807
|
const AVERAGE_MATCHUP_MINUTES = 'averageMatchUpMinutes';
|
|
2245
1808
|
const RECOVERY_MINUTES = 'recoveryMinutes';
|
|
2246
1809
|
const PERIOD_LENGTH = 'periodLength';
|
|
1810
|
+
const NUMBER = 'number';
|
|
2247
1811
|
const OBJECT = 'object';
|
|
2248
1812
|
const ARRAY = 'array';
|
|
2249
1813
|
const VALIDATE = '_validate';
|
|
@@ -2495,6 +2059,378 @@ function attributeFilter(params) {
|
|
|
2495
2059
|
}
|
|
2496
2060
|
}
|
|
2497
2061
|
|
|
2062
|
+
const validDateString = /^[\d]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][\d]|3[0-1])$/;
|
|
2063
|
+
const validTimeString = /^((0[\d]|1[\d]|2[0-3]):[0-5][\d](:[0-5][\d])?)([.,][0-9]{3})?$/;
|
|
2064
|
+
const dateValidation = /^([\d]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][\d]|3[0-1]))([ T](0[\d]|1[\d]|2[0-3]):[0-5][\d](:[0-5][\d])?)?([.,][\d]{3})?Z?$/;
|
|
2065
|
+
const timeValidation = /^([\d]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][\d]|3[0-1]))?([ T]?(0[\d]|1[\d]|2[0-3]):[0-5][\d](:[0-5][\d])?)?([.,][\d]{3})?Z?$/;
|
|
2066
|
+
|
|
2067
|
+
function getIsoDateString(schedule) {
|
|
2068
|
+
let { scheduledDate } = schedule;
|
|
2069
|
+
if (!scheduledDate && schedule.scheduledTime)
|
|
2070
|
+
scheduledDate = extractDate(schedule.scheduledTime);
|
|
2071
|
+
if (!scheduledDate)
|
|
2072
|
+
return;
|
|
2073
|
+
const extractedTime = extractTime(schedule.scheduledTime);
|
|
2074
|
+
let isoDateString = extractDate(scheduledDate);
|
|
2075
|
+
if (isoDateString && extractedTime)
|
|
2076
|
+
isoDateString += `T${extractedTime}`;
|
|
2077
|
+
return isoDateString;
|
|
2078
|
+
}
|
|
2079
|
+
function isDateObject(value) {
|
|
2080
|
+
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
2081
|
+
return false;
|
|
2082
|
+
}
|
|
2083
|
+
else {
|
|
2084
|
+
const datePrototype = Object.prototype.toString.call(value);
|
|
2085
|
+
return datePrototype === '[object Date]';
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
function validTimeValue(value) {
|
|
2089
|
+
const spaceSplit = typeof value === 'string' ? value?.split(' ') : [];
|
|
2090
|
+
if (value && spaceSplit?.length > 1 && !['AM', 'PM'].includes(spaceSplit[1].toUpperCase()))
|
|
2091
|
+
return false;
|
|
2092
|
+
return !!(!value || timeValidation.test(convertTime(value, true, true)));
|
|
2093
|
+
}
|
|
2094
|
+
function isValidDateString(scheduleDate) {
|
|
2095
|
+
return isISODateString(scheduleDate) || validDateString.test(scheduleDate);
|
|
2096
|
+
}
|
|
2097
|
+
function DateHHMM(date) {
|
|
2098
|
+
const dt = new Date(date);
|
|
2099
|
+
const secs = dt.getSeconds() + 60 * dt.getMinutes() + 60 * 60 * dt.getHours();
|
|
2100
|
+
return HHMMSS(secs, { displaySeconds: false });
|
|
2101
|
+
}
|
|
2102
|
+
function HHMMSS(s, format) {
|
|
2103
|
+
const secondNumber = parseInt(s, 10);
|
|
2104
|
+
const hours = Math.floor(secondNumber / 3600);
|
|
2105
|
+
const minutes = Math.floor((secondNumber - hours * 3600) / 60);
|
|
2106
|
+
const seconds = secondNumber - hours * 3600 - minutes * 60;
|
|
2107
|
+
const displaySeconds = !format || format?.displaySeconds;
|
|
2108
|
+
const timeString = displaySeconds ? hours + ':' + minutes + ':' + seconds : hours + ':' + minutes;
|
|
2109
|
+
return timeString.split(':').map(zeroPad).join(':');
|
|
2110
|
+
}
|
|
2111
|
+
const getUTCdateString = (date) => {
|
|
2112
|
+
const dateDate = isDate(date) || isISODateString(date) ? new Date(date) : new Date();
|
|
2113
|
+
const monthNumber = dateDate.getUTCMonth() + 1;
|
|
2114
|
+
const utcMonth = monthNumber < 10 ? `0${monthNumber}` : `${monthNumber}`;
|
|
2115
|
+
return `${dateDate.getUTCFullYear()}-${zeroPad(utcMonth)}-${zeroPad(dateDate.getUTCDate())}`;
|
|
2116
|
+
};
|
|
2117
|
+
function timeUTC(date) {
|
|
2118
|
+
const dateDate = isDate(date) || isISODateString(date) ? new Date(date) : new Date();
|
|
2119
|
+
return Date.UTC(dateDate.getFullYear(), dateDate.getMonth(), dateDate.getDate());
|
|
2120
|
+
}
|
|
2121
|
+
function formatDate(date, separator = '-', format = 'YMD') {
|
|
2122
|
+
if (!date)
|
|
2123
|
+
return '';
|
|
2124
|
+
if (typeof date === 'string' && date.indexOf('T') < 0)
|
|
2125
|
+
date = date + 'T00:00';
|
|
2126
|
+
const d = new Date(date);
|
|
2127
|
+
let month = '' + (d.getMonth() + 1);
|
|
2128
|
+
let day = '' + d.getDate();
|
|
2129
|
+
const year = d.getFullYear();
|
|
2130
|
+
if (month.length < 2)
|
|
2131
|
+
month = '0' + month;
|
|
2132
|
+
if (day.length < 2)
|
|
2133
|
+
day = '0' + day;
|
|
2134
|
+
if (format === 'DMY')
|
|
2135
|
+
return [day, month, year].join(separator);
|
|
2136
|
+
if (format === 'MDY')
|
|
2137
|
+
return [month, day, year].join(separator);
|
|
2138
|
+
if (format === 'YDM')
|
|
2139
|
+
return [year, day, month].join(separator);
|
|
2140
|
+
if (format === 'DYM')
|
|
2141
|
+
return [day, year, month].join(separator);
|
|
2142
|
+
if (format === 'MYD')
|
|
2143
|
+
return [month, year, day].join(separator);
|
|
2144
|
+
return [year, month, day].join(separator);
|
|
2145
|
+
}
|
|
2146
|
+
function offsetDate(date) {
|
|
2147
|
+
const targetTime = date ? new Date(date) : new Date();
|
|
2148
|
+
const tzDifference = targetTime.getTimezoneOffset();
|
|
2149
|
+
return new Date(targetTime.getTime() - tzDifference * 60 * 1000);
|
|
2150
|
+
}
|
|
2151
|
+
function offsetTime(date) {
|
|
2152
|
+
return offsetDate(date).getTime();
|
|
2153
|
+
}
|
|
2154
|
+
function isDate(dateArg) {
|
|
2155
|
+
if (typeof dateArg == 'boolean')
|
|
2156
|
+
return false;
|
|
2157
|
+
const t = (dateArg instanceof Date && dateArg) || (!isNaN(dateArg) && new Date(dateArg)) || false;
|
|
2158
|
+
return t && !isNaN(t.valueOf());
|
|
2159
|
+
}
|
|
2160
|
+
function generateDateRange(startDt, endDt) {
|
|
2161
|
+
if (!isValidDateString(startDt) || !isValidDateString(endDt))
|
|
2162
|
+
return [];
|
|
2163
|
+
const startDateString = extractDate(startDt) + 'T00:00';
|
|
2164
|
+
const endDateString = extractDate(endDt) + 'T00:00';
|
|
2165
|
+
const startDate = new Date(startDateString);
|
|
2166
|
+
const endDate = new Date(endDateString);
|
|
2167
|
+
const process = isDate(endDate) && isDate(startDate) && isValidDateRange(startDate, endDate);
|
|
2168
|
+
const between = [];
|
|
2169
|
+
let iterations = 0;
|
|
2170
|
+
if (process) {
|
|
2171
|
+
const currentDate = startDate;
|
|
2172
|
+
let dateSecs = currentDate.getTime();
|
|
2173
|
+
while (dateSecs <= endDate.getTime() && iterations < 300) {
|
|
2174
|
+
iterations += 1;
|
|
2175
|
+
between.push(new Date(currentDate));
|
|
2176
|
+
dateSecs = currentDate.setDate(currentDate.getDate() + 1);
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
return between.map((date) => formatDate(date));
|
|
2180
|
+
function isValidDateRange(minDate, maxDate) {
|
|
2181
|
+
return minDate <= maxDate;
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
const re = /^([+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([.,]\d+(?!:))?)?(\17[0-5]\d([.,]\d+)?)?([zZ]|([+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;
|
|
2185
|
+
function isISODateString(dateString) {
|
|
2186
|
+
if (typeof dateString !== 'string')
|
|
2187
|
+
return false;
|
|
2188
|
+
return re.test(dateString);
|
|
2189
|
+
}
|
|
2190
|
+
function isTimeString(timeString) {
|
|
2191
|
+
if (typeof timeString !== 'string')
|
|
2192
|
+
return false;
|
|
2193
|
+
const noZ = timeString.split('Z')[0];
|
|
2194
|
+
const parts = noZ.split(':');
|
|
2195
|
+
const isNumeric = parts.every((part) => !isNaN(parseInt(part)));
|
|
2196
|
+
const invalid = parts.length < 2 || !isNumeric || parseInt(parts[0]) > 23 || parseInt(parts[1]) > 60;
|
|
2197
|
+
return !invalid;
|
|
2198
|
+
}
|
|
2199
|
+
function timeStringMinutes(timeString) {
|
|
2200
|
+
const validTimeString = extractTime(timeString);
|
|
2201
|
+
if (!validTimeString)
|
|
2202
|
+
return 0;
|
|
2203
|
+
const [hours, minutes] = validTimeString.split(':').map((value) => parseInt(value));
|
|
2204
|
+
return hours * 60 + minutes;
|
|
2205
|
+
}
|
|
2206
|
+
function dayMinutesToTimeString(totalMinutes) {
|
|
2207
|
+
let hours = Math.floor(totalMinutes / 60);
|
|
2208
|
+
const minutes = totalMinutes - hours * 60;
|
|
2209
|
+
if (hours > 23)
|
|
2210
|
+
hours = hours % 24;
|
|
2211
|
+
return [zeroPad(hours), zeroPad(minutes)].join(':');
|
|
2212
|
+
}
|
|
2213
|
+
function tidyTime(timeString) {
|
|
2214
|
+
return isTimeString(timeString) ? timeString.split(':').slice(0, 2).map(zeroPad).join(':') : undefined;
|
|
2215
|
+
}
|
|
2216
|
+
function extractTime(dateString) {
|
|
2217
|
+
return isISODateString(dateString) && dateString.indexOf('T') > 0
|
|
2218
|
+
? tidyTime(dateString.split('T').reverse()[0])
|
|
2219
|
+
: tidyTime(dateString);
|
|
2220
|
+
}
|
|
2221
|
+
function extractDate(dateString) {
|
|
2222
|
+
return isISODateString(dateString) || dateValidation.test(dateString) ? dateString.split('T')[0] : undefined;
|
|
2223
|
+
}
|
|
2224
|
+
function dateStringDaysChange(dateString, daysChange) {
|
|
2225
|
+
const date = new Date(dateString);
|
|
2226
|
+
date.setDate(date.getDate() + daysChange);
|
|
2227
|
+
return extractDate(date.toISOString());
|
|
2228
|
+
}
|
|
2229
|
+
function splitTime(value) {
|
|
2230
|
+
value = typeof value !== 'string' ? '00:00' : value;
|
|
2231
|
+
const o = {}, time = {};
|
|
2232
|
+
({ 0: o.time, 1: o.ampm } = value.split(' ') || []);
|
|
2233
|
+
({ 0: time.hours, 1: time.minutes } = o.time.split(':') || []);
|
|
2234
|
+
time.ampm = o.ampm;
|
|
2235
|
+
if (isNaN(time.hours) || isNaN(time.minutes) || (time.ampm && !['AM', 'PM'].includes(time.ampm.toUpperCase())))
|
|
2236
|
+
return {};
|
|
2237
|
+
return time;
|
|
2238
|
+
}
|
|
2239
|
+
function militaryTime(value) {
|
|
2240
|
+
const time = splitTime(value);
|
|
2241
|
+
if (time.ampm && time.hours) {
|
|
2242
|
+
if (time.ampm.toLowerCase() === 'pm' && parseInt(time.hours) < 12)
|
|
2243
|
+
time.hours = ((time.hours && parseInt(time.hours)) || 0) + 12;
|
|
2244
|
+
if (time.ampm.toLowerCase() === 'am' && time.hours === '12')
|
|
2245
|
+
time.hours = '00';
|
|
2246
|
+
}
|
|
2247
|
+
const timeString = `${time.hours || '12'}:${time.minutes || '00'}`;
|
|
2248
|
+
return timeString.split(':').map(zeroPad).join(':');
|
|
2249
|
+
}
|
|
2250
|
+
function regularTime(value) {
|
|
2251
|
+
const time = splitTime(value);
|
|
2252
|
+
if (typeof time === 'object' && !Object.keys(time).length)
|
|
2253
|
+
return undefined;
|
|
2254
|
+
if (time.ampm)
|
|
2255
|
+
return value;
|
|
2256
|
+
if (time.hours > 12) {
|
|
2257
|
+
time.hours -= 12;
|
|
2258
|
+
time.ampm = 'PM';
|
|
2259
|
+
}
|
|
2260
|
+
else if (time.hours === '12') {
|
|
2261
|
+
time.ampm = 'PM';
|
|
2262
|
+
}
|
|
2263
|
+
else if (time.hours === '00') {
|
|
2264
|
+
time.hours = '12';
|
|
2265
|
+
time.ampm = 'AM';
|
|
2266
|
+
}
|
|
2267
|
+
else {
|
|
2268
|
+
time.ampm = 'AM';
|
|
2269
|
+
}
|
|
2270
|
+
if (time.hours?.[0] === '0') {
|
|
2271
|
+
time.hours = time.hours.slice(1);
|
|
2272
|
+
}
|
|
2273
|
+
return `${time.hours || '12'}:${time.minutes || '00'} ${time.ampm}`;
|
|
2274
|
+
}
|
|
2275
|
+
function convertTime(value, time24, keepDate) {
|
|
2276
|
+
const hasDate = extractDate(value);
|
|
2277
|
+
const timeString = extractTime(value);
|
|
2278
|
+
const timeValue = hasDate ? timeString : value;
|
|
2279
|
+
return !value
|
|
2280
|
+
? undefined
|
|
2281
|
+
: (time24 && ((hasDate && keepDate && value) || militaryTime(timeValue))) || regularTime(timeValue);
|
|
2282
|
+
}
|
|
2283
|
+
function timeSort(a, b) {
|
|
2284
|
+
const as = splitTime(a);
|
|
2285
|
+
const bs = splitTime(b);
|
|
2286
|
+
if (parseInt(as.hours) < parseInt(bs.hours))
|
|
2287
|
+
return -1;
|
|
2288
|
+
if (parseInt(as.hours) > parseInt(bs.hours))
|
|
2289
|
+
return 1;
|
|
2290
|
+
if (as.hours === bs.hours) {
|
|
2291
|
+
if (parseInt(as.minutes) < parseInt(bs.minutes))
|
|
2292
|
+
return -1;
|
|
2293
|
+
if (parseInt(as.minutes) > parseInt(bs.minutes))
|
|
2294
|
+
return 1;
|
|
2295
|
+
}
|
|
2296
|
+
return 0;
|
|
2297
|
+
}
|
|
2298
|
+
function addDays(date, days = 7) {
|
|
2299
|
+
const universalDate = extractDate(date) + 'T00:00';
|
|
2300
|
+
const now = new Date(universalDate);
|
|
2301
|
+
const adjustedDate = new Date(now.setDate(now.getDate() + days));
|
|
2302
|
+
return formatDate(adjustedDate);
|
|
2303
|
+
}
|
|
2304
|
+
function addWeek(date) {
|
|
2305
|
+
return addDays(date);
|
|
2306
|
+
}
|
|
2307
|
+
function getDateByWeek(week, year, dateFormat, sunday = false) {
|
|
2308
|
+
const date = new Date(year, 0, 1 + (week - 1) * 7);
|
|
2309
|
+
const startValue = sunday ? 0 : 1;
|
|
2310
|
+
date.setDate(date.getDate() + (startValue - date.getDay()));
|
|
2311
|
+
return formatDate(date, dateFormat);
|
|
2312
|
+
}
|
|
2313
|
+
function dateFromDay(year, day, dateFormat) {
|
|
2314
|
+
const date = new Date(year, 0);
|
|
2315
|
+
return formatDate(new Date(date.setDate(day)), dateFormat);
|
|
2316
|
+
}
|
|
2317
|
+
function timeToDate(timeString, date = undefined) {
|
|
2318
|
+
const [hours, minutes] = (timeString || '00:00').split(':').map(zeroPad);
|
|
2319
|
+
const milliseconds = offsetDate(date).setHours(hours, minutes, 0, 0);
|
|
2320
|
+
return offsetDate(milliseconds);
|
|
2321
|
+
}
|
|
2322
|
+
function minutesDifference(date1, date2, absolute = true) {
|
|
2323
|
+
const dt1 = new Date(date1);
|
|
2324
|
+
const dt2 = new Date(date2);
|
|
2325
|
+
const diff = (dt2.getTime() - dt1.getTime()) / 1000 / 60;
|
|
2326
|
+
return absolute ? Math.abs(Math.round(diff)) : Math.round(diff);
|
|
2327
|
+
}
|
|
2328
|
+
function addMinutesToTimeString(timeString, minutes) {
|
|
2329
|
+
const validTimeString = extractTime(timeString);
|
|
2330
|
+
if (!validTimeString)
|
|
2331
|
+
return '00:00';
|
|
2332
|
+
const minutesToAdd = isNaN(minutes) ? 0 : minutes;
|
|
2333
|
+
return extractTime(addMinutes(timeToDate(validTimeString), minutesToAdd).toISOString());
|
|
2334
|
+
}
|
|
2335
|
+
function addMinutes(startDate, minutes) {
|
|
2336
|
+
const date = new Date(startDate);
|
|
2337
|
+
return new Date(date.getTime() + minutes * 60000);
|
|
2338
|
+
}
|
|
2339
|
+
function zeroPad(number) {
|
|
2340
|
+
return number.toString()[1] ? number : '0' + number;
|
|
2341
|
+
}
|
|
2342
|
+
function sameDay(date1, date2) {
|
|
2343
|
+
const d1 = new Date(date1);
|
|
2344
|
+
const d2 = new Date(date2);
|
|
2345
|
+
return d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() === d2.getDate();
|
|
2346
|
+
}
|
|
2347
|
+
const dateTime = {
|
|
2348
|
+
addDays,
|
|
2349
|
+
addWeek,
|
|
2350
|
+
addMinutesToTimeString,
|
|
2351
|
+
convertTime,
|
|
2352
|
+
getIsoDateString,
|
|
2353
|
+
getUTCdateString,
|
|
2354
|
+
DateHHMM,
|
|
2355
|
+
extractDate,
|
|
2356
|
+
extractTime,
|
|
2357
|
+
formatDate,
|
|
2358
|
+
getDateByWeek,
|
|
2359
|
+
isISODateString,
|
|
2360
|
+
isDate,
|
|
2361
|
+
isTimeString,
|
|
2362
|
+
offsetDate,
|
|
2363
|
+
offsetTime,
|
|
2364
|
+
sameDay,
|
|
2365
|
+
timeStringMinutes,
|
|
2366
|
+
timeToDate,
|
|
2367
|
+
timeUTC,
|
|
2368
|
+
validTimeValue,
|
|
2369
|
+
validDateString,
|
|
2370
|
+
timeValidation,
|
|
2371
|
+
dateValidation,
|
|
2372
|
+
};
|
|
2373
|
+
|
|
2374
|
+
function makeDeepCopy(sourceObject, convertExtensions, internalUse, removeExtensions, iteration = 0) {
|
|
2375
|
+
if (getProvider().makeDeepCopy)
|
|
2376
|
+
return getProvider().makeDeepCopy(sourceObject, convertExtensions, internalUse, removeExtensions);
|
|
2377
|
+
const deepCopy = deepCopyEnabled();
|
|
2378
|
+
const { stringify, toJSON, ignore, modulate } = deepCopy || {};
|
|
2379
|
+
if ((!deepCopy?.enabled && !internalUse) ||
|
|
2380
|
+
typeof sourceObject !== 'object' ||
|
|
2381
|
+
isFunction(sourceObject) ||
|
|
2382
|
+
sourceObject === null ||
|
|
2383
|
+
(typeof deepCopy?.threshold === 'number' && iteration >= deepCopy.threshold)) {
|
|
2384
|
+
return sourceObject;
|
|
2385
|
+
}
|
|
2386
|
+
const targetObject = Array.isArray(sourceObject) ? [] : {};
|
|
2387
|
+
const sourceObjectKeys = Object.keys(sourceObject).filter((key) => !internalUse ||
|
|
2388
|
+
!ignore ||
|
|
2389
|
+
(Array.isArray(ignore) && !ignore.includes(key)) ||
|
|
2390
|
+
(isFunction(ignore) && !ignore(key)));
|
|
2391
|
+
const stringifyValue = (key, value) => {
|
|
2392
|
+
targetObject[key] = isFunction(value?.toString) ? value.toString() : JSON.stringify(value);
|
|
2393
|
+
};
|
|
2394
|
+
for (const key of sourceObjectKeys) {
|
|
2395
|
+
const value = sourceObject[key];
|
|
2396
|
+
const modulated = isFunction(modulate) ? modulate(value) : undefined;
|
|
2397
|
+
if (modulated !== undefined) {
|
|
2398
|
+
targetObject[key] = modulated;
|
|
2399
|
+
}
|
|
2400
|
+
else if (convertExtensions && key === 'extensions' && Array.isArray(value)) {
|
|
2401
|
+
const extensionConversions = extensionsToAttributes(value);
|
|
2402
|
+
Object.assign(targetObject, ...extensionConversions);
|
|
2403
|
+
}
|
|
2404
|
+
else if (removeExtensions && key === 'extensions') {
|
|
2405
|
+
targetObject[key] = [];
|
|
2406
|
+
}
|
|
2407
|
+
else if (Array.isArray(stringify) && stringify.includes(key)) {
|
|
2408
|
+
stringifyValue(key, value);
|
|
2409
|
+
}
|
|
2410
|
+
else if (Array.isArray(toJSON) && toJSON.includes(key) && isFunction(value?.toJSON)) {
|
|
2411
|
+
targetObject[key] = value.toJSON();
|
|
2412
|
+
}
|
|
2413
|
+
else if (value === null) {
|
|
2414
|
+
targetObject[key] = undefined;
|
|
2415
|
+
}
|
|
2416
|
+
else if (isDateObject(value)) {
|
|
2417
|
+
targetObject[key] = new Date(value).toISOString();
|
|
2418
|
+
}
|
|
2419
|
+
else {
|
|
2420
|
+
targetObject[key] = makeDeepCopy(value, convertExtensions, internalUse, removeExtensions, iteration + 1);
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
return targetObject;
|
|
2424
|
+
}
|
|
2425
|
+
function extensionsToAttributes(extensions) {
|
|
2426
|
+
return extensions
|
|
2427
|
+
?.map((extension) => {
|
|
2428
|
+
const { name, value } = extension;
|
|
2429
|
+
return name && value && { [`_${name}`]: value };
|
|
2430
|
+
})
|
|
2431
|
+
.filter(Boolean);
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2498
2434
|
const POLICY_TYPE_VOLUNTARY_CONSOLATION = 'voluntaryConsolation';
|
|
2499
2435
|
const POLICY_TYPE_COMPETITIVE_BANDS = 'competitiveBands';
|
|
2500
2436
|
const POLICY_TYPE_ROUND_ROBIN_TALLY = 'roundRobinTally';
|
|
@@ -3930,6 +3866,72 @@ function getRoundMatchUps({ matchUps = [], interpolate }) {
|
|
|
3930
3866
|
};
|
|
3931
3867
|
}
|
|
3932
3868
|
|
|
3869
|
+
function getAccessorValue({ element, accessor }) {
|
|
3870
|
+
if (typeof accessor !== 'string')
|
|
3871
|
+
return { values: [] };
|
|
3872
|
+
const targetElement = makeDeepCopy(element);
|
|
3873
|
+
const attributes = accessor.split('.');
|
|
3874
|
+
const values = [];
|
|
3875
|
+
let value;
|
|
3876
|
+
processKeys({ targetElement, attributes });
|
|
3877
|
+
const result = { value };
|
|
3878
|
+
if (values.length)
|
|
3879
|
+
result.values = values;
|
|
3880
|
+
return result;
|
|
3881
|
+
function processKeys({ targetElement, attributes = [], significantCharacters }) {
|
|
3882
|
+
for (const [index, attribute] of attributes.entries()) {
|
|
3883
|
+
if (targetElement?.[attribute]) {
|
|
3884
|
+
const remainingKeys = attributes.slice(index + 1);
|
|
3885
|
+
if (!remainingKeys.length) {
|
|
3886
|
+
if (!value)
|
|
3887
|
+
value = targetElement[attribute];
|
|
3888
|
+
if (!values.includes(targetElement[attribute])) {
|
|
3889
|
+
values.push(targetElement[attribute]);
|
|
3890
|
+
}
|
|
3891
|
+
}
|
|
3892
|
+
else if (Array.isArray(targetElement[attribute])) {
|
|
3893
|
+
const values = targetElement[attribute];
|
|
3894
|
+
values.forEach((nestedTarget) => processKeys({
|
|
3895
|
+
targetElement: nestedTarget,
|
|
3896
|
+
attributes: remainingKeys,
|
|
3897
|
+
}));
|
|
3898
|
+
}
|
|
3899
|
+
else {
|
|
3900
|
+
targetElement = targetElement[attribute];
|
|
3901
|
+
checkValue({ targetElement, index });
|
|
3902
|
+
}
|
|
3903
|
+
}
|
|
3904
|
+
}
|
|
3905
|
+
function checkValue({ targetElement, index }) {
|
|
3906
|
+
if (targetElement && index === attributes.length - 1 && ['string', 'number'].includes(typeof targetElement)) {
|
|
3907
|
+
const extractedValue = significantCharacters ? targetElement.slice(0, significantCharacters) : targetElement;
|
|
3908
|
+
if (value) {
|
|
3909
|
+
if (!values.includes(extractedValue)) {
|
|
3910
|
+
values.push(extractedValue);
|
|
3911
|
+
}
|
|
3912
|
+
}
|
|
3913
|
+
else {
|
|
3914
|
+
value = extractedValue;
|
|
3915
|
+
values.push(extractedValue);
|
|
3916
|
+
}
|
|
3917
|
+
}
|
|
3918
|
+
}
|
|
3919
|
+
}
|
|
3920
|
+
}
|
|
3921
|
+
|
|
3922
|
+
const extractAttributes = (accessor) => (element) => !accessor || typeof element !== 'object'
|
|
3923
|
+
? undefined
|
|
3924
|
+
: (Array.isArray(accessor) &&
|
|
3925
|
+
accessor.map((a) => ({
|
|
3926
|
+
[a]: getAccessorValue({ element, accessor: a })?.value,
|
|
3927
|
+
}))) ||
|
|
3928
|
+
(typeof accessor === 'object' &&
|
|
3929
|
+
Object.keys(accessor).map((key) => ({
|
|
3930
|
+
[key]: getAccessorValue({ element, accessor: key })?.value,
|
|
3931
|
+
}))) ||
|
|
3932
|
+
(typeof accessor === 'string' && getAccessorValue({ element, accessor }))?.value;
|
|
3933
|
+
const xa = extractAttributes;
|
|
3934
|
+
|
|
3933
3935
|
function addFinishingRounds({ finishingPositionOffset = 0, finishingPositionLimit, positionsFed, roundsCount, roundLimit, matchUps, lucky, fmlc, }) {
|
|
3934
3936
|
if (!validMatchUps(matchUps))
|
|
3935
3937
|
return [];
|
|
@@ -5001,6 +5003,109 @@ function matchUpAssignedVenueId({ visibilityThreshold, timeStamp, schedule, matc
|
|
|
5001
5003
|
: schedule;
|
|
5002
5004
|
}
|
|
5003
5005
|
|
|
5006
|
+
function matchUpTimeModifiers({ visibilityThreshold, timeStamp, schedule, matchUp }) {
|
|
5007
|
+
const { itemValue: timeModifiers, timeStamp: itemTimeStamp } = latestVisibleTimeItemValue({
|
|
5008
|
+
timeItems: matchUp?.timeItems || [],
|
|
5009
|
+
itemType: TIME_MODIFIERS,
|
|
5010
|
+
visibilityThreshold,
|
|
5011
|
+
});
|
|
5012
|
+
return !schedule || (itemTimeStamp && timeStamp && new Date(itemTimeStamp).getTime() > new Date(timeStamp).getTime())
|
|
5013
|
+
? { timeModifiers }
|
|
5014
|
+
: schedule;
|
|
5015
|
+
}
|
|
5016
|
+
|
|
5017
|
+
function timeDate$1(value) {
|
|
5018
|
+
if (validTimeString.test(value)) {
|
|
5019
|
+
const dateString = getUTCdateString();
|
|
5020
|
+
return new Date(`${dateString}T${value}`);
|
|
5021
|
+
}
|
|
5022
|
+
else {
|
|
5023
|
+
return new Date(value);
|
|
5024
|
+
}
|
|
5025
|
+
}
|
|
5026
|
+
function matchUpDuration({ matchUp }) {
|
|
5027
|
+
if (!matchUp)
|
|
5028
|
+
return { error: MISSING_MATCHUP };
|
|
5029
|
+
if (!matchUp.timeItems)
|
|
5030
|
+
return { error: MISSING_TIME_ITEMS };
|
|
5031
|
+
const relevantTimeItems = matchUp.timeItems
|
|
5032
|
+
.filter((timeItem) => [START_TIME, STOP_TIME, RESUME_TIME, END_TIME].includes(timeItem?.itemType))
|
|
5033
|
+
.sort((a, b) => timeDate$1(a.itemValue).getTime() - timeDate$1(b.itemValue).getTime());
|
|
5034
|
+
const elapsed = relevantTimeItems.reduce((elapsed, timeItem) => {
|
|
5035
|
+
let milliseconds;
|
|
5036
|
+
const itemTypeComponents = timeItem?.itemType?.split('.');
|
|
5037
|
+
const timeType = timeItem?.itemType?.startsWith('SCHEDULE.TIME') && itemTypeComponents[2];
|
|
5038
|
+
const scheduleType = `SCHEDULE.TIME.${timeType}`;
|
|
5039
|
+
switch (scheduleType) {
|
|
5040
|
+
case START_TIME:
|
|
5041
|
+
milliseconds = 0;
|
|
5042
|
+
break;
|
|
5043
|
+
case END_TIME:
|
|
5044
|
+
if (elapsed.lastValue && [START_TIME, RESUME_TIME].includes(elapsed.lastType)) {
|
|
5045
|
+
const interval = timeDate$1(timeItem.itemValue).getTime() - timeDate$1(elapsed.lastValue).getTime();
|
|
5046
|
+
milliseconds = elapsed.milliseconds + interval;
|
|
5047
|
+
}
|
|
5048
|
+
else {
|
|
5049
|
+
milliseconds = elapsed.milliseconds;
|
|
5050
|
+
}
|
|
5051
|
+
break;
|
|
5052
|
+
case STOP_TIME:
|
|
5053
|
+
if ([START_TIME, 'SCHECULE.TIME.RESUME'].includes(elapsed.lastType)) {
|
|
5054
|
+
const interval = timeDate$1(timeItem.itemValue).getTime() - timeDate$1(elapsed.lastValue).getTime();
|
|
5055
|
+
milliseconds = elapsed.milliseconds + interval;
|
|
5056
|
+
}
|
|
5057
|
+
else {
|
|
5058
|
+
milliseconds = elapsed.milliseconds;
|
|
5059
|
+
}
|
|
5060
|
+
break;
|
|
5061
|
+
default:
|
|
5062
|
+
milliseconds = elapsed.milliseconds;
|
|
5063
|
+
break;
|
|
5064
|
+
}
|
|
5065
|
+
return {
|
|
5066
|
+
milliseconds,
|
|
5067
|
+
lastType: scheduleType,
|
|
5068
|
+
lastValue: timeItem.itemValue,
|
|
5069
|
+
};
|
|
5070
|
+
}, { milliseconds: 0, lastType: undefined, lastValue: undefined });
|
|
5071
|
+
if ([START_TIME, RESUME_TIME].includes(elapsed.lastType)) {
|
|
5072
|
+
const interval = new Date().getTime() - timeDate$1(elapsed.lastValue).getTime();
|
|
5073
|
+
elapsed.milliseconds += interval;
|
|
5074
|
+
}
|
|
5075
|
+
return {
|
|
5076
|
+
milliseconds: elapsed.milliseconds,
|
|
5077
|
+
time: msToTime(elapsed.milliseconds),
|
|
5078
|
+
relevantTimeItems,
|
|
5079
|
+
};
|
|
5080
|
+
}
|
|
5081
|
+
function msToTime(s) {
|
|
5082
|
+
const pad = (n, z = 2) => ('00' + n).slice(-z);
|
|
5083
|
+
return pad((s / 3.6e6) | 0) + ':' + pad(((s % 3.6e6) / 6e4) | 0) + ':' + pad(((s % 6e4) / 1000) | 0);
|
|
5084
|
+
}
|
|
5085
|
+
|
|
5086
|
+
function matchUpCourtOrder({ visibilityThreshold, timeStamp, schedule, matchUp }) {
|
|
5087
|
+
const { itemValue: courtOrder, timeStamp: itemTimeStamp } = latestVisibleTimeItemValue({
|
|
5088
|
+
timeItems: matchUp?.timeItems || [],
|
|
5089
|
+
itemType: COURT_ORDER,
|
|
5090
|
+
visibilityThreshold,
|
|
5091
|
+
});
|
|
5092
|
+
return !schedule || (itemTimeStamp && timeStamp && new Date(itemTimeStamp).getTime() > new Date(timeStamp).getTime())
|
|
5093
|
+
? { courtOrder }
|
|
5094
|
+
: schedule;
|
|
5095
|
+
}
|
|
5096
|
+
|
|
5097
|
+
function matchUpStartTime({ matchUp }) {
|
|
5098
|
+
const timeItems = matchUp?.timeItems || [];
|
|
5099
|
+
const getTimeStamp = (item) => (!item.createdAt ? 0 : new Date(item.createdAt).getTime());
|
|
5100
|
+
const startTimeItem = timeItems.reduce((startTimeItem, timeItem) => {
|
|
5101
|
+
const startTimeCandidate = timeItem.itemType === START_TIME && timeItem;
|
|
5102
|
+
const earlierStartTimeItem = startTimeCandidate && (!startTimeItem || getTimeStamp(startTimeCandidate) < getTimeStamp(startTimeItem));
|
|
5103
|
+
return earlierStartTimeItem ? startTimeCandidate : startTimeItem;
|
|
5104
|
+
}, undefined);
|
|
5105
|
+
const startTime = startTimeItem?.itemValue;
|
|
5106
|
+
return { startTime };
|
|
5107
|
+
}
|
|
5108
|
+
|
|
5004
5109
|
function UUIDS(count = 1) {
|
|
5005
5110
|
return generateRange(0, count).map(UUID);
|
|
5006
5111
|
}
|
|
@@ -5218,84 +5323,16 @@ function getVenueData({ tournamentRecord, venueId }) {
|
|
|
5218
5323
|
return { ...SUCCESS, venueData: makeDeepCopy(venueData, false, true) };
|
|
5219
5324
|
}
|
|
5220
5325
|
|
|
5221
|
-
function
|
|
5222
|
-
const
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
}
|
|
5231
|
-
|
|
5232
|
-
function timeDate$1(value) {
|
|
5233
|
-
if (validTimeString.test(value)) {
|
|
5234
|
-
const dateString = getUTCdateString();
|
|
5235
|
-
return new Date(`${dateString}T${value}`);
|
|
5236
|
-
}
|
|
5237
|
-
else {
|
|
5238
|
-
return new Date(value);
|
|
5239
|
-
}
|
|
5240
|
-
}
|
|
5241
|
-
function matchUpDuration({ matchUp }) {
|
|
5242
|
-
if (!matchUp)
|
|
5243
|
-
return { error: MISSING_MATCHUP };
|
|
5244
|
-
if (!matchUp.timeItems)
|
|
5245
|
-
return { error: MISSING_TIME_ITEMS };
|
|
5246
|
-
const relevantTimeItems = matchUp.timeItems
|
|
5247
|
-
.filter((timeItem) => [START_TIME, STOP_TIME, RESUME_TIME, END_TIME].includes(timeItem?.itemType))
|
|
5248
|
-
.sort((a, b) => timeDate$1(a.itemValue).getTime() - timeDate$1(b.itemValue).getTime());
|
|
5249
|
-
const elapsed = relevantTimeItems.reduce((elapsed, timeItem) => {
|
|
5250
|
-
let milliseconds;
|
|
5251
|
-
const itemTypeComponents = timeItem?.itemType?.split('.');
|
|
5252
|
-
const timeType = timeItem?.itemType?.startsWith('SCHEDULE.TIME') && itemTypeComponents[2];
|
|
5253
|
-
const scheduleType = `SCHEDULE.TIME.${timeType}`;
|
|
5254
|
-
switch (scheduleType) {
|
|
5255
|
-
case START_TIME:
|
|
5256
|
-
milliseconds = 0;
|
|
5257
|
-
break;
|
|
5258
|
-
case END_TIME:
|
|
5259
|
-
if (elapsed.lastValue && [START_TIME, RESUME_TIME].includes(elapsed.lastType)) {
|
|
5260
|
-
const interval = timeDate$1(timeItem.itemValue).getTime() - timeDate$1(elapsed.lastValue).getTime();
|
|
5261
|
-
milliseconds = elapsed.milliseconds + interval;
|
|
5262
|
-
}
|
|
5263
|
-
else {
|
|
5264
|
-
milliseconds = elapsed.milliseconds;
|
|
5265
|
-
}
|
|
5266
|
-
break;
|
|
5267
|
-
case STOP_TIME:
|
|
5268
|
-
if ([START_TIME, 'SCHECULE.TIME.RESUME'].includes(elapsed.lastType)) {
|
|
5269
|
-
const interval = timeDate$1(timeItem.itemValue).getTime() - timeDate$1(elapsed.lastValue).getTime();
|
|
5270
|
-
milliseconds = elapsed.milliseconds + interval;
|
|
5271
|
-
}
|
|
5272
|
-
else {
|
|
5273
|
-
milliseconds = elapsed.milliseconds;
|
|
5274
|
-
}
|
|
5275
|
-
break;
|
|
5276
|
-
default:
|
|
5277
|
-
milliseconds = elapsed.milliseconds;
|
|
5278
|
-
break;
|
|
5279
|
-
}
|
|
5280
|
-
return {
|
|
5281
|
-
milliseconds,
|
|
5282
|
-
lastType: scheduleType,
|
|
5283
|
-
lastValue: timeItem.itemValue,
|
|
5284
|
-
};
|
|
5285
|
-
}, { milliseconds: 0, lastType: undefined, lastValue: undefined });
|
|
5286
|
-
if ([START_TIME, RESUME_TIME].includes(elapsed.lastType)) {
|
|
5287
|
-
const interval = new Date().getTime() - timeDate$1(elapsed.lastValue).getTime();
|
|
5288
|
-
elapsed.milliseconds += interval;
|
|
5289
|
-
}
|
|
5290
|
-
return {
|
|
5291
|
-
milliseconds: elapsed.milliseconds,
|
|
5292
|
-
time: msToTime(elapsed.milliseconds),
|
|
5293
|
-
relevantTimeItems,
|
|
5294
|
-
};
|
|
5295
|
-
}
|
|
5296
|
-
function msToTime(s) {
|
|
5297
|
-
const pad = (n, z = 2) => ('00' + n).slice(-z);
|
|
5298
|
-
return pad((s / 3.6e6) | 0) + ':' + pad(((s % 3.6e6) / 6e4) | 0) + ':' + pad(((s % 6e4) / 1000) | 0);
|
|
5326
|
+
function matchUpEndTime({ matchUp }) {
|
|
5327
|
+
const timeItems = matchUp?.timeItems || [];
|
|
5328
|
+
const getTimeStamp = (item) => (!item.createdAt ? 0 : new Date(item.createdAt).getTime());
|
|
5329
|
+
const endTimeItem = timeItems.reduce((endTimeItem, timeItem) => {
|
|
5330
|
+
const endTimeCandidate = timeItem.itemType === END_TIME && timeItem;
|
|
5331
|
+
const earlierStartTimeItem = endTimeCandidate && (!endTimeItem || getTimeStamp(endTimeCandidate) > getTimeStamp(endTimeItem));
|
|
5332
|
+
return earlierStartTimeItem ? endTimeCandidate : endTimeItem;
|
|
5333
|
+
}, undefined);
|
|
5334
|
+
const endTime = endTimeItem?.itemValue;
|
|
5335
|
+
return { endTime };
|
|
5299
5336
|
}
|
|
5300
5337
|
|
|
5301
5338
|
function getFlightProfile({ event, eventId }) {
|
|
@@ -5391,41 +5428,6 @@ function findEvent(params) {
|
|
|
5391
5428
|
};
|
|
5392
5429
|
}
|
|
5393
5430
|
|
|
5394
|
-
function matchUpCourtOrder({ visibilityThreshold, timeStamp, schedule, matchUp }) {
|
|
5395
|
-
const { itemValue: courtOrder, timeStamp: itemTimeStamp } = latestVisibleTimeItemValue({
|
|
5396
|
-
timeItems: matchUp?.timeItems || [],
|
|
5397
|
-
itemType: COURT_ORDER,
|
|
5398
|
-
visibilityThreshold,
|
|
5399
|
-
});
|
|
5400
|
-
return !schedule || (itemTimeStamp && timeStamp && new Date(itemTimeStamp).getTime() > new Date(timeStamp).getTime())
|
|
5401
|
-
? { courtOrder }
|
|
5402
|
-
: schedule;
|
|
5403
|
-
}
|
|
5404
|
-
|
|
5405
|
-
function matchUpStartTime({ matchUp }) {
|
|
5406
|
-
const timeItems = matchUp?.timeItems || [];
|
|
5407
|
-
const getTimeStamp = (item) => (!item.createdAt ? 0 : new Date(item.createdAt).getTime());
|
|
5408
|
-
const startTimeItem = timeItems.reduce((startTimeItem, timeItem) => {
|
|
5409
|
-
const startTimeCandidate = timeItem.itemType === START_TIME && timeItem;
|
|
5410
|
-
const earlierStartTimeItem = startTimeCandidate && (!startTimeItem || getTimeStamp(startTimeCandidate) < getTimeStamp(startTimeItem));
|
|
5411
|
-
return earlierStartTimeItem ? startTimeCandidate : startTimeItem;
|
|
5412
|
-
}, undefined);
|
|
5413
|
-
const startTime = startTimeItem?.itemValue;
|
|
5414
|
-
return { startTime };
|
|
5415
|
-
}
|
|
5416
|
-
|
|
5417
|
-
function matchUpEndTime({ matchUp }) {
|
|
5418
|
-
const timeItems = matchUp?.timeItems || [];
|
|
5419
|
-
const getTimeStamp = (item) => (!item.createdAt ? 0 : new Date(item.createdAt).getTime());
|
|
5420
|
-
const endTimeItem = timeItems.reduce((endTimeItem, timeItem) => {
|
|
5421
|
-
const endTimeCandidate = timeItem.itemType === END_TIME && timeItem;
|
|
5422
|
-
const earlierStartTimeItem = endTimeCandidate && (!endTimeItem || getTimeStamp(endTimeCandidate) > getTimeStamp(endTimeItem));
|
|
5423
|
-
return earlierStartTimeItem ? endTimeCandidate : endTimeItem;
|
|
5424
|
-
}, undefined);
|
|
5425
|
-
const endTime = endTimeItem?.itemValue;
|
|
5426
|
-
return { endTime };
|
|
5427
|
-
}
|
|
5428
|
-
|
|
5429
5431
|
function getMatchUpScheduleDetails(params) {
|
|
5430
5432
|
let event = params.event;
|
|
5431
5433
|
let matchUpType = params.matchUpType;
|
|
@@ -5762,159 +5764,6 @@ function getContextContent({ policyDefinitions, tournamentRecord, contextProfile
|
|
|
5762
5764
|
return contextContent;
|
|
5763
5765
|
}
|
|
5764
5766
|
|
|
5765
|
-
const NORMAL = 'normal';
|
|
5766
|
-
const TIMED = 'timed';
|
|
5767
|
-
const FINAL = 'final';
|
|
5768
|
-
const NOAD = 'NOAD';
|
|
5769
|
-
const SET = 'SET';
|
|
5770
|
-
const setTypes$1 = {
|
|
5771
|
-
S: NORMAL,
|
|
5772
|
-
F: FINAL,
|
|
5773
|
-
};
|
|
5774
|
-
|
|
5775
|
-
function parse(matchUpFormatCode) {
|
|
5776
|
-
if (typeof matchUpFormatCode === 'string') {
|
|
5777
|
-
const type = (matchUpFormatCode.startsWith('T') && TIMED) || (matchUpFormatCode.startsWith(SET) && SET) || '';
|
|
5778
|
-
if (type === TIMED) {
|
|
5779
|
-
const setFormat = parseTimedSet(matchUpFormatCode);
|
|
5780
|
-
const parsedFormat = {
|
|
5781
|
-
simplified: true,
|
|
5782
|
-
setFormat,
|
|
5783
|
-
bestOf: 1,
|
|
5784
|
-
};
|
|
5785
|
-
if (setFormat)
|
|
5786
|
-
return parsedFormat;
|
|
5787
|
-
}
|
|
5788
|
-
if (type === SET)
|
|
5789
|
-
return setsMatch(matchUpFormatCode);
|
|
5790
|
-
}
|
|
5791
|
-
return undefined;
|
|
5792
|
-
}
|
|
5793
|
-
function setsMatch(formatstring) {
|
|
5794
|
-
const parts = formatstring.split('-');
|
|
5795
|
-
const setsCount = getNumber$1(parts[0].slice(3));
|
|
5796
|
-
const bestOf = setsCount === 1 || setsCount % 2 !== 0 ? setsCount : undefined;
|
|
5797
|
-
const exactly = setsCount !== 1 && setsCount % 2 === 0 ? setsCount : undefined;
|
|
5798
|
-
const setFormat = parts && parseSetFormat(parts[1]);
|
|
5799
|
-
const finalSetFormat = parts && parseSetFormat(parts[2]);
|
|
5800
|
-
const timed = (setFormat && setFormat.timed) || (finalSetFormat && finalSetFormat.timed);
|
|
5801
|
-
const validSetsCount = (bestOf && bestOf < 6) || (timed && exactly);
|
|
5802
|
-
const validFinalSet = !parts[2] || finalSetFormat;
|
|
5803
|
-
const validSetsFormat = setFormat;
|
|
5804
|
-
const result = definedAttributes({
|
|
5805
|
-
setFormat,
|
|
5806
|
-
exactly,
|
|
5807
|
-
bestOf,
|
|
5808
|
-
});
|
|
5809
|
-
if (finalSetFormat)
|
|
5810
|
-
result.finalSetFormat = finalSetFormat;
|
|
5811
|
-
if (validSetsCount && validSetsFormat && validFinalSet)
|
|
5812
|
-
return result;
|
|
5813
|
-
}
|
|
5814
|
-
function parseSetFormat(formatstring) {
|
|
5815
|
-
if (formatstring?.[1] === ':') {
|
|
5816
|
-
const parts = formatstring.split(':');
|
|
5817
|
-
const setType = setTypes$1[parts[0]];
|
|
5818
|
-
const setFormatString = parts[1];
|
|
5819
|
-
if (setType && setFormatString) {
|
|
5820
|
-
const isTiebreakSet = setFormatString.startsWith('TB');
|
|
5821
|
-
if (isTiebreakSet) {
|
|
5822
|
-
const tiebreakSet = parseTiebreakFormat(setFormatString);
|
|
5823
|
-
if (tiebreakSet === false)
|
|
5824
|
-
return false;
|
|
5825
|
-
return typeof tiebreakSet === 'object' ? { tiebreakSet } : undefined;
|
|
5826
|
-
}
|
|
5827
|
-
const timedSet = setFormatString.startsWith('T');
|
|
5828
|
-
if (timedSet)
|
|
5829
|
-
return parseTimedSet(setFormatString);
|
|
5830
|
-
const parts = formatstring.match(/^[FS]:(\d+)([A-Za-z]*)/);
|
|
5831
|
-
const NoAD = (parts && isNoAD(parts[2])) || false;
|
|
5832
|
-
const validNoAD = !parts?.[2] || NoAD;
|
|
5833
|
-
const setTo = parts ? getNumber$1(parts[1]) : undefined;
|
|
5834
|
-
const tiebreakAtValue = parseTiebreakAt(setFormatString);
|
|
5835
|
-
const validTiebreakAt = tiebreakAtValue !== false;
|
|
5836
|
-
const tiebreakAt = (validTiebreakAt && tiebreakAtValue) || setTo;
|
|
5837
|
-
const tiebreakFormat = parseTiebreakFormat(setFormatString.split('/')[1]);
|
|
5838
|
-
const validTiebreak = tiebreakFormat !== false;
|
|
5839
|
-
const result = { setTo };
|
|
5840
|
-
if (NoAD)
|
|
5841
|
-
result.NoAD = true;
|
|
5842
|
-
if (tiebreakFormat) {
|
|
5843
|
-
result.tiebreakFormat = tiebreakFormat;
|
|
5844
|
-
result.tiebreakAt = tiebreakAt;
|
|
5845
|
-
}
|
|
5846
|
-
else {
|
|
5847
|
-
result.noTiebreak = true;
|
|
5848
|
-
}
|
|
5849
|
-
return (setTo && validNoAD && validTiebreak && validTiebreakAt && result) || false;
|
|
5850
|
-
}
|
|
5851
|
-
}
|
|
5852
|
-
return undefined;
|
|
5853
|
-
}
|
|
5854
|
-
function parseTiebreakAt(setFormatString, expectNumber = true) {
|
|
5855
|
-
const tiebreakAtValue = setFormatString?.indexOf('@') > 0 && setFormatString.split('@');
|
|
5856
|
-
if (tiebreakAtValue) {
|
|
5857
|
-
const tiebreakAt = expectNumber ? getNumber$1(tiebreakAtValue[1]) : tiebreakAtValue[1];
|
|
5858
|
-
return tiebreakAt || false;
|
|
5859
|
-
}
|
|
5860
|
-
return undefined;
|
|
5861
|
-
}
|
|
5862
|
-
function parseTiebreakFormat(formatstring) {
|
|
5863
|
-
if (formatstring) {
|
|
5864
|
-
if (formatstring.startsWith('TB')) {
|
|
5865
|
-
const modifier = parseTiebreakAt(formatstring, false);
|
|
5866
|
-
const parts = formatstring.match(/^TB(\d+)([A-Za-z]*)/);
|
|
5867
|
-
const tiebreakToString = parts?.[1];
|
|
5868
|
-
const NoAD = parts && isNoAD(parts[2]);
|
|
5869
|
-
const validNoAD = !parts?.[2] || NoAD;
|
|
5870
|
-
const tiebreakTo = getNumber$1(tiebreakToString);
|
|
5871
|
-
if (tiebreakTo && validNoAD) {
|
|
5872
|
-
const result = { tiebreakTo };
|
|
5873
|
-
if (modifier && typeof modifier === 'string' && !isConvertableInteger(modifier)) {
|
|
5874
|
-
result.modifier = modifier;
|
|
5875
|
-
}
|
|
5876
|
-
if (NoAD)
|
|
5877
|
-
result.NoAD = true;
|
|
5878
|
-
return result;
|
|
5879
|
-
}
|
|
5880
|
-
else {
|
|
5881
|
-
return false;
|
|
5882
|
-
}
|
|
5883
|
-
}
|
|
5884
|
-
else {
|
|
5885
|
-
return false;
|
|
5886
|
-
}
|
|
5887
|
-
}
|
|
5888
|
-
return undefined;
|
|
5889
|
-
}
|
|
5890
|
-
function parseTimedSet(formatstring) {
|
|
5891
|
-
const timestring = formatstring.slice(1);
|
|
5892
|
-
const parts = timestring.match(/^(\d+)(@?[A-Za-z]*)/);
|
|
5893
|
-
const minutes = getNumber$1(parts?.[1]);
|
|
5894
|
-
if (!minutes)
|
|
5895
|
-
return;
|
|
5896
|
-
const setFormat = { timed: true, minutes };
|
|
5897
|
-
const based = parts?.[2];
|
|
5898
|
-
const validModifier = [undefined, 'P', 'G'].includes(based);
|
|
5899
|
-
if (based && !validModifier) {
|
|
5900
|
-
const modifier = timestring.match(/^(\d+)(@)([A-Za-z]+)$/)?.[3];
|
|
5901
|
-
if (modifier) {
|
|
5902
|
-
setFormat.modifier = modifier;
|
|
5903
|
-
return setFormat;
|
|
5904
|
-
}
|
|
5905
|
-
return;
|
|
5906
|
-
}
|
|
5907
|
-
if (based)
|
|
5908
|
-
setFormat.based = parts[2];
|
|
5909
|
-
return setFormat;
|
|
5910
|
-
}
|
|
5911
|
-
function isNoAD(formatstring) {
|
|
5912
|
-
return formatstring && formatstring.indexOf(NOAD) >= 0;
|
|
5913
|
-
}
|
|
5914
|
-
function getNumber$1(formatstring) {
|
|
5915
|
-
return !isNaN(Number(formatstring)) ? Number(formatstring) : 0;
|
|
5916
|
-
}
|
|
5917
|
-
|
|
5918
5767
|
function getOrderedDrawPositions({ drawPositions, roundProfile, roundNumber }) {
|
|
5919
5768
|
const unassignedDrawPositions = [undefined, undefined];
|
|
5920
5769
|
if (noNumeric(drawPositions)) {
|
|
@@ -6338,6 +6187,159 @@ function getMatchUpType(params) {
|
|
|
6338
6187
|
return { matchUpType };
|
|
6339
6188
|
}
|
|
6340
6189
|
|
|
6190
|
+
const NORMAL = 'normal';
|
|
6191
|
+
const TIMED = 'timed';
|
|
6192
|
+
const FINAL = 'final';
|
|
6193
|
+
const NOAD = 'NOAD';
|
|
6194
|
+
const SET = 'SET';
|
|
6195
|
+
const setTypes$1 = {
|
|
6196
|
+
S: NORMAL,
|
|
6197
|
+
F: FINAL,
|
|
6198
|
+
};
|
|
6199
|
+
|
|
6200
|
+
function parse(matchUpFormatCode) {
|
|
6201
|
+
if (typeof matchUpFormatCode === 'string') {
|
|
6202
|
+
const type = (matchUpFormatCode.startsWith('T') && TIMED) || (matchUpFormatCode.startsWith(SET) && SET) || '';
|
|
6203
|
+
if (type === TIMED) {
|
|
6204
|
+
const setFormat = parseTimedSet(matchUpFormatCode);
|
|
6205
|
+
const parsedFormat = {
|
|
6206
|
+
simplified: true,
|
|
6207
|
+
setFormat,
|
|
6208
|
+
bestOf: 1,
|
|
6209
|
+
};
|
|
6210
|
+
if (setFormat)
|
|
6211
|
+
return parsedFormat;
|
|
6212
|
+
}
|
|
6213
|
+
if (type === SET)
|
|
6214
|
+
return setsMatch(matchUpFormatCode);
|
|
6215
|
+
}
|
|
6216
|
+
return undefined;
|
|
6217
|
+
}
|
|
6218
|
+
function setsMatch(formatstring) {
|
|
6219
|
+
const parts = formatstring.split('-');
|
|
6220
|
+
const setsCount = getNumber$1(parts[0].slice(3));
|
|
6221
|
+
const bestOf = setsCount === 1 || setsCount % 2 !== 0 ? setsCount : undefined;
|
|
6222
|
+
const exactly = setsCount !== 1 && setsCount % 2 === 0 ? setsCount : undefined;
|
|
6223
|
+
const setFormat = parts && parseSetFormat(parts[1]);
|
|
6224
|
+
const finalSetFormat = parts && parseSetFormat(parts[2]);
|
|
6225
|
+
const timed = (setFormat && setFormat.timed) || (finalSetFormat && finalSetFormat.timed);
|
|
6226
|
+
const validSetsCount = (bestOf && bestOf < 6) || (timed && exactly);
|
|
6227
|
+
const validFinalSet = !parts[2] || finalSetFormat;
|
|
6228
|
+
const validSetsFormat = setFormat;
|
|
6229
|
+
const result = definedAttributes({
|
|
6230
|
+
setFormat,
|
|
6231
|
+
exactly,
|
|
6232
|
+
bestOf,
|
|
6233
|
+
});
|
|
6234
|
+
if (finalSetFormat)
|
|
6235
|
+
result.finalSetFormat = finalSetFormat;
|
|
6236
|
+
if (validSetsCount && validSetsFormat && validFinalSet)
|
|
6237
|
+
return result;
|
|
6238
|
+
}
|
|
6239
|
+
function parseSetFormat(formatstring) {
|
|
6240
|
+
if (formatstring?.[1] === ':') {
|
|
6241
|
+
const parts = formatstring.split(':');
|
|
6242
|
+
const setType = setTypes$1[parts[0]];
|
|
6243
|
+
const setFormatString = parts[1];
|
|
6244
|
+
if (setType && setFormatString) {
|
|
6245
|
+
const isTiebreakSet = setFormatString.startsWith('TB');
|
|
6246
|
+
if (isTiebreakSet) {
|
|
6247
|
+
const tiebreakSet = parseTiebreakFormat(setFormatString);
|
|
6248
|
+
if (tiebreakSet === false)
|
|
6249
|
+
return false;
|
|
6250
|
+
return typeof tiebreakSet === 'object' ? { tiebreakSet } : undefined;
|
|
6251
|
+
}
|
|
6252
|
+
const timedSet = setFormatString.startsWith('T');
|
|
6253
|
+
if (timedSet)
|
|
6254
|
+
return parseTimedSet(setFormatString);
|
|
6255
|
+
const parts = formatstring.match(/^[FS]:(\d+)([A-Za-z]*)/);
|
|
6256
|
+
const NoAD = (parts && isNoAD(parts[2])) || false;
|
|
6257
|
+
const validNoAD = !parts?.[2] || NoAD;
|
|
6258
|
+
const setTo = parts ? getNumber$1(parts[1]) : undefined;
|
|
6259
|
+
const tiebreakAtValue = parseTiebreakAt(setFormatString);
|
|
6260
|
+
const validTiebreakAt = tiebreakAtValue !== false;
|
|
6261
|
+
const tiebreakAt = (validTiebreakAt && tiebreakAtValue) || setTo;
|
|
6262
|
+
const tiebreakFormat = parseTiebreakFormat(setFormatString.split('/')[1]);
|
|
6263
|
+
const validTiebreak = tiebreakFormat !== false;
|
|
6264
|
+
const result = { setTo };
|
|
6265
|
+
if (NoAD)
|
|
6266
|
+
result.NoAD = true;
|
|
6267
|
+
if (tiebreakFormat) {
|
|
6268
|
+
result.tiebreakFormat = tiebreakFormat;
|
|
6269
|
+
result.tiebreakAt = tiebreakAt;
|
|
6270
|
+
}
|
|
6271
|
+
else {
|
|
6272
|
+
result.noTiebreak = true;
|
|
6273
|
+
}
|
|
6274
|
+
return (setTo && validNoAD && validTiebreak && validTiebreakAt && result) || false;
|
|
6275
|
+
}
|
|
6276
|
+
}
|
|
6277
|
+
return undefined;
|
|
6278
|
+
}
|
|
6279
|
+
function parseTiebreakAt(setFormatString, expectNumber = true) {
|
|
6280
|
+
const tiebreakAtValue = setFormatString?.indexOf('@') > 0 && setFormatString.split('@');
|
|
6281
|
+
if (tiebreakAtValue) {
|
|
6282
|
+
const tiebreakAt = expectNumber ? getNumber$1(tiebreakAtValue[1]) : tiebreakAtValue[1];
|
|
6283
|
+
return tiebreakAt || false;
|
|
6284
|
+
}
|
|
6285
|
+
return undefined;
|
|
6286
|
+
}
|
|
6287
|
+
function parseTiebreakFormat(formatstring) {
|
|
6288
|
+
if (formatstring) {
|
|
6289
|
+
if (formatstring.startsWith('TB')) {
|
|
6290
|
+
const modifier = parseTiebreakAt(formatstring, false);
|
|
6291
|
+
const parts = formatstring.match(/^TB(\d+)([A-Za-z]*)/);
|
|
6292
|
+
const tiebreakToString = parts?.[1];
|
|
6293
|
+
const NoAD = parts && isNoAD(parts[2]);
|
|
6294
|
+
const validNoAD = !parts?.[2] || NoAD;
|
|
6295
|
+
const tiebreakTo = getNumber$1(tiebreakToString);
|
|
6296
|
+
if (tiebreakTo && validNoAD) {
|
|
6297
|
+
const result = { tiebreakTo };
|
|
6298
|
+
if (modifier && typeof modifier === 'string' && !isConvertableInteger(modifier)) {
|
|
6299
|
+
result.modifier = modifier;
|
|
6300
|
+
}
|
|
6301
|
+
if (NoAD)
|
|
6302
|
+
result.NoAD = true;
|
|
6303
|
+
return result;
|
|
6304
|
+
}
|
|
6305
|
+
else {
|
|
6306
|
+
return false;
|
|
6307
|
+
}
|
|
6308
|
+
}
|
|
6309
|
+
else {
|
|
6310
|
+
return false;
|
|
6311
|
+
}
|
|
6312
|
+
}
|
|
6313
|
+
return undefined;
|
|
6314
|
+
}
|
|
6315
|
+
function parseTimedSet(formatstring) {
|
|
6316
|
+
const timestring = formatstring.slice(1);
|
|
6317
|
+
const parts = timestring.match(/^(\d+)(@?[A-Za-z]*)/);
|
|
6318
|
+
const minutes = getNumber$1(parts?.[1]);
|
|
6319
|
+
if (!minutes)
|
|
6320
|
+
return;
|
|
6321
|
+
const setFormat = { timed: true, minutes };
|
|
6322
|
+
const based = parts?.[2];
|
|
6323
|
+
const validModifier = [undefined, 'P', 'G'].includes(based);
|
|
6324
|
+
if (based && !validModifier) {
|
|
6325
|
+
const modifier = timestring.match(/^(\d+)(@)([A-Za-z]+)$/)?.[3];
|
|
6326
|
+
if (modifier) {
|
|
6327
|
+
setFormat.modifier = modifier;
|
|
6328
|
+
return setFormat;
|
|
6329
|
+
}
|
|
6330
|
+
return;
|
|
6331
|
+
}
|
|
6332
|
+
if (based)
|
|
6333
|
+
setFormat.based = parts[2];
|
|
6334
|
+
return setFormat;
|
|
6335
|
+
}
|
|
6336
|
+
function isNoAD(formatstring) {
|
|
6337
|
+
return formatstring && formatstring.indexOf(NOAD) >= 0;
|
|
6338
|
+
}
|
|
6339
|
+
function getNumber$1(formatstring) {
|
|
6340
|
+
return !isNaN(Number(formatstring)) ? Number(formatstring) : 0;
|
|
6341
|
+
}
|
|
6342
|
+
|
|
6341
6343
|
function includesMatchUpEventType(types, matchUpEventType) {
|
|
6342
6344
|
if (!Array.isArray(types) || !isString(matchUpEventType))
|
|
6343
6345
|
return false;
|
|
@@ -15237,6 +15239,69 @@ function alternateDrawPositionAssignment(params) {
|
|
|
15237
15239
|
return alternateDrawPositionAssignment$1(params);
|
|
15238
15240
|
}
|
|
15239
15241
|
|
|
15242
|
+
function modifyMappedMatchUps({ params, modMap, structure }) {
|
|
15243
|
+
const { tournamentRecord, drawDefinition, event } = params;
|
|
15244
|
+
for (const matchUp of structure.matchUps) {
|
|
15245
|
+
if (modMap[matchUp.matchUpId]) {
|
|
15246
|
+
matchUp.roundNumber = modMap[matchUp.matchUpId];
|
|
15247
|
+
modifyMatchUpNotice({
|
|
15248
|
+
tournamentId: tournamentRecord?.tournamentId,
|
|
15249
|
+
eventId: event?.eventId,
|
|
15250
|
+
drawDefinition,
|
|
15251
|
+
matchUp,
|
|
15252
|
+
});
|
|
15253
|
+
}
|
|
15254
|
+
}
|
|
15255
|
+
}
|
|
15256
|
+
|
|
15257
|
+
function checkRoundsArgs(params, additionalChecks) {
|
|
15258
|
+
const checks = [{ drawDefinition: true, structureId: true }];
|
|
15259
|
+
if (Array.isArray(additionalChecks))
|
|
15260
|
+
checks.push(...additionalChecks);
|
|
15261
|
+
const paramsCheck = checkRequiredParameters(params, checks);
|
|
15262
|
+
if (paramsCheck.error)
|
|
15263
|
+
return paramsCheck;
|
|
15264
|
+
const result = findStructure(params);
|
|
15265
|
+
if (result.error)
|
|
15266
|
+
return result;
|
|
15267
|
+
const structure = result.structure;
|
|
15268
|
+
const structureIsAdHoc = isAdHoc({ structure });
|
|
15269
|
+
if (!structureIsAdHoc)
|
|
15270
|
+
return decorateResult({ result: { error: INVALID_STRUCTURE, message: 'structure must be adHoc' } });
|
|
15271
|
+
const { roundMatchUps = [], roundNumbers } = getRoundMatchUps({ matchUps: structure?.matchUps });
|
|
15272
|
+
if (!roundNumbers?.length)
|
|
15273
|
+
return { error: MISSING_MATCHUPS };
|
|
15274
|
+
return { valid: true, structure, roundMatchUps, roundNumbers };
|
|
15275
|
+
}
|
|
15276
|
+
|
|
15277
|
+
function shiftAdHocRounds(params) {
|
|
15278
|
+
const check = checkRoundsArgs(params, [
|
|
15279
|
+
{
|
|
15280
|
+
targetRoundNumber: true,
|
|
15281
|
+
roundNumber: true,
|
|
15282
|
+
[OF_TYPE]: NUMBER,
|
|
15283
|
+
},
|
|
15284
|
+
]);
|
|
15285
|
+
if (check.error)
|
|
15286
|
+
return check;
|
|
15287
|
+
const { structure, roundMatchUps, roundNumbers } = check;
|
|
15288
|
+
const { targetRoundNumber, roundNumber } = params;
|
|
15289
|
+
if (!roundNumbers?.includes(roundNumber) || !roundNumbers?.includes(targetRoundNumber)) {
|
|
15290
|
+
return decorateResult({ result: { error: INVALID_VALUES }, info: 'roundNumbers must be valid rounds' });
|
|
15291
|
+
}
|
|
15292
|
+
const downShift = targetRoundNumber > roundNumber;
|
|
15293
|
+
const collateralShifts = downShift
|
|
15294
|
+
? generateRange(roundNumber + 1, targetRoundNumber + 1)
|
|
15295
|
+
: generateRange(targetRoundNumber, roundNumber);
|
|
15296
|
+
const modMap = {};
|
|
15297
|
+
collateralShifts.forEach((roundNumber) => (roundMatchUps?.[roundNumber] ?? []).forEach(({ matchUpId }) => {
|
|
15298
|
+
modMap[matchUpId] = roundNumber - (downShift ? 1 : -1);
|
|
15299
|
+
}));
|
|
15300
|
+
roundMatchUps?.[roundNumber]?.forEach(({ matchUpId }) => (modMap[matchUpId] = targetRoundNumber));
|
|
15301
|
+
modifyMappedMatchUps({ params, modMap, structure });
|
|
15302
|
+
return { ...SUCCESS };
|
|
15303
|
+
}
|
|
15304
|
+
|
|
15240
15305
|
function setPositionAssignments({ structurePositionAssignments, provisionalPositioning, tournamentRecord, drawDefinition, event, }) {
|
|
15241
15306
|
if (!drawDefinition)
|
|
15242
15307
|
return { error: MISSING_DRAW_DEFINITION };
|
|
@@ -15327,6 +15392,28 @@ function setPositionAssignments({ structurePositionAssignments, provisionalPosit
|
|
|
15327
15392
|
return { ...SUCCESS };
|
|
15328
15393
|
}
|
|
15329
15394
|
|
|
15395
|
+
function swapAdHocRounds(params) {
|
|
15396
|
+
const check = checkRoundsArgs(params, [
|
|
15397
|
+
{
|
|
15398
|
+
roundNumbers: true,
|
|
15399
|
+
[OF_TYPE]: ARRAY,
|
|
15400
|
+
[VALIDATE]: (value) => value.length === 2 && value.every(isNumeric),
|
|
15401
|
+
},
|
|
15402
|
+
]);
|
|
15403
|
+
if (check.error)
|
|
15404
|
+
return check;
|
|
15405
|
+
const { structure, roundMatchUps, roundNumbers } = check;
|
|
15406
|
+
if (!params.roundNumbers.every((roundNumber) => roundNumbers?.includes(roundNumber))) {
|
|
15407
|
+
return decorateResult({ result: { error: INVALID_VALUES, message: 'roundNumbers must be valid rounds' } });
|
|
15408
|
+
}
|
|
15409
|
+
const modMap = {};
|
|
15410
|
+
params.roundNumbers.forEach((roundNumber, i) => (roundMatchUps?.[roundNumber] ?? []).forEach(({ matchUpId }) => {
|
|
15411
|
+
modMap[matchUpId] = params.roundNumbers[1 - i];
|
|
15412
|
+
}));
|
|
15413
|
+
modifyMappedMatchUps({ params, modMap, structure });
|
|
15414
|
+
return { ...SUCCESS };
|
|
15415
|
+
}
|
|
15416
|
+
|
|
15330
15417
|
function qualifierDrawPositionAssignment$1({ qualifyingParticipantId, tournamentRecord, drawDefinition, drawPosition, structureId, }) {
|
|
15331
15418
|
return positionParticipantAction({
|
|
15332
15419
|
positionActionName: 'qualifierDrawPositionAssignment',
|
|
@@ -17704,20 +17791,78 @@ function addDrawDefinitionTimeItem({ drawDefinition, timeItem }) {
|
|
|
17704
17791
|
return { ...SUCCESS };
|
|
17705
17792
|
}
|
|
17706
17793
|
|
|
17707
|
-
function removeStructure(
|
|
17708
|
-
|
|
17709
|
-
|
|
17710
|
-
if (
|
|
17711
|
-
return
|
|
17712
|
-
if (!structureId)
|
|
17713
|
-
return { error: MISSING_STRUCTURE_ID };
|
|
17794
|
+
function removeStructure(params) {
|
|
17795
|
+
const { tournamentRecord, drawDefinition, structureId, event } = params;
|
|
17796
|
+
const checkParams = checkRequiredParameters(params, [{ drawDefinition: true, structureId: true }]);
|
|
17797
|
+
if (checkParams.error)
|
|
17798
|
+
return checkParams;
|
|
17714
17799
|
const structures = drawDefinition.structures ?? [];
|
|
17715
|
-
const removedStructureIds = [];
|
|
17716
17800
|
const structure = structures.find((structure) => structure.structureId === structureId);
|
|
17717
17801
|
if (!structure)
|
|
17718
17802
|
return { error: STRUCTURE_NOT_FOUND };
|
|
17719
|
-
const
|
|
17720
|
-
const
|
|
17803
|
+
const mainStageSequence1 = structures.find(({ stage, stageSequence }) => stage === MAIN && stageSequence === 1);
|
|
17804
|
+
const isMainStageSequence1 = structureId === mainStageSequence1?.structureId;
|
|
17805
|
+
const qualifyingStructureIds = structures.filter(({ stage }) => stage === QUALIFYING).map(xa('structureId'));
|
|
17806
|
+
if (isMainStageSequence1 && !qualifyingStructureIds.length)
|
|
17807
|
+
return { error: CANNOT_REMOVE_MAIN_STRUCTURE };
|
|
17808
|
+
const isQualifyingStructure = qualifyingStructureIds.includes(structureId);
|
|
17809
|
+
const policyResult = policyCheck({ isQualifyingStructure, structure, ...params });
|
|
17810
|
+
if (policyResult?.error)
|
|
17811
|
+
return policyResult;
|
|
17812
|
+
const { structureIdsToRemove, relatedStructureIdsMap } = getIdsToRemove({
|
|
17813
|
+
qualifyingStructureIds,
|
|
17814
|
+
isQualifyingStructure,
|
|
17815
|
+
isMainStageSequence1,
|
|
17816
|
+
mainStageSequence1,
|
|
17817
|
+
drawDefinition,
|
|
17818
|
+
structureId,
|
|
17819
|
+
});
|
|
17820
|
+
const { removedMatchUpIds, removedStructureIds } = removeMatchUpsAndStructures({
|
|
17821
|
+
relatedStructureIdsMap,
|
|
17822
|
+
qualifyingStructureIds,
|
|
17823
|
+
isMainStageSequence1,
|
|
17824
|
+
mainStageSequence1,
|
|
17825
|
+
drawDefinition,
|
|
17826
|
+
structureIdsToRemove,
|
|
17827
|
+
structureId,
|
|
17828
|
+
});
|
|
17829
|
+
removeReferencesToRemovedMatchUps({ removedMatchUpIds, drawDefinition });
|
|
17830
|
+
if (isMainStageSequence1) {
|
|
17831
|
+
const mainStageSequence1MatchUpIds = (mainStageSequence1.matchUps ?? [])?.map(xa('matchUpId'));
|
|
17832
|
+
removedMatchUpIds.push(...mainStageSequence1MatchUpIds);
|
|
17833
|
+
mainStageSequence1.positionAssignments = [];
|
|
17834
|
+
mainStageSequence1.seedAssignments = [];
|
|
17835
|
+
mainStageSequence1.matchUps = [];
|
|
17836
|
+
if (mainStageSequence1.extensions) {
|
|
17837
|
+
mainStageSequence1.extensions = [];
|
|
17838
|
+
}
|
|
17839
|
+
}
|
|
17840
|
+
isQualifyingStructure && resequenceStructures({ drawDefinition });
|
|
17841
|
+
deleteMatchUpsNotice({
|
|
17842
|
+
tournamentId: tournamentRecord?.tournamentId,
|
|
17843
|
+
matchUpIds: removedMatchUpIds,
|
|
17844
|
+
action: 'removeStructure',
|
|
17845
|
+
eventId: event?.eventId,
|
|
17846
|
+
drawDefinition,
|
|
17847
|
+
});
|
|
17848
|
+
modifyDrawNotice({ drawDefinition, eventId: event?.eventId });
|
|
17849
|
+
return { ...SUCCESS, removedMatchUpIds, removedStructureIds };
|
|
17850
|
+
}
|
|
17851
|
+
function policyCheck({ isQualifyingStructure, tournamentRecord, drawDefinition, structureId, structure, event, force, }) {
|
|
17852
|
+
const structureIdsToFilter = [structureId];
|
|
17853
|
+
if (isQualifyingStructure) {
|
|
17854
|
+
const getSourceLink = (structureId) => drawDefinition.links?.find((link) => link.target.structureId === structureId);
|
|
17855
|
+
let sourceStructureId = getSourceLink(structureId)?.source.structureId;
|
|
17856
|
+
while (sourceStructureId) {
|
|
17857
|
+
structureIdsToFilter.push(sourceStructureId);
|
|
17858
|
+
sourceStructureId = getSourceLink(sourceStructureId)?.source.structureId;
|
|
17859
|
+
}
|
|
17860
|
+
}
|
|
17861
|
+
const relevantMatchUps = getAllDrawMatchUps({
|
|
17862
|
+
matchUpFilters: { structureIds: structureIdsToFilter },
|
|
17863
|
+
drawDefinition,
|
|
17864
|
+
}).matchUps;
|
|
17865
|
+
const scoresPresent = relevantMatchUps?.some(({ score }) => checkScoreHasValue({ score }));
|
|
17721
17866
|
if (scoresPresent) {
|
|
17722
17867
|
const appliedPolicies = getAppliedPolicies({
|
|
17723
17868
|
tournamentRecord,
|
|
@@ -17729,14 +17874,22 @@ function removeStructure({ tournamentRecord, drawDefinition, structureId, event,
|
|
|
17729
17874
|
if (!allowDeletionWithScoresPresent)
|
|
17730
17875
|
return { error: SCORES_PRESENT };
|
|
17731
17876
|
}
|
|
17732
|
-
|
|
17733
|
-
|
|
17734
|
-
|
|
17735
|
-
|
|
17736
|
-
|
|
17737
|
-
|
|
17877
|
+
return { ...SUCCESS };
|
|
17878
|
+
}
|
|
17879
|
+
function removeReferencesToRemovedMatchUps({ removedMatchUpIds, drawDefinition }) {
|
|
17880
|
+
const { matchUps } = getAllDrawMatchUps({ drawDefinition });
|
|
17881
|
+
matchUps?.forEach((matchUp) => {
|
|
17882
|
+
if (matchUp.winnerMatchUpId && removedMatchUpIds.includes(matchUp.winnerMatchUpId)) {
|
|
17883
|
+
delete matchUp.winnerMatchUpId;
|
|
17884
|
+
}
|
|
17885
|
+
if (matchUp.loserMatchUpId && removedMatchUpIds.includes(matchUp.loserMatchUpId)) {
|
|
17886
|
+
delete matchUp.loserMatchUpId;
|
|
17887
|
+
}
|
|
17888
|
+
});
|
|
17889
|
+
}
|
|
17890
|
+
function getIdsToRemove({ qualifyingStructureIds, isQualifyingStructure, isMainStageSequence1, mainStageSequence1, drawDefinition, structureId, }) {
|
|
17891
|
+
const structures = drawDefinition.structures ?? [];
|
|
17738
17892
|
const structureIds = structures.map(xa('structureId'));
|
|
17739
|
-
const removedMatchUpIds = [];
|
|
17740
17893
|
const getTargetedStructureIds = (structureId) => drawDefinition.links
|
|
17741
17894
|
?.map((link) => link.source.structureId === structureId &&
|
|
17742
17895
|
link.target.structureId !== mainStageSequence1?.structureId &&
|
|
@@ -17747,66 +17900,64 @@ function removeStructure({ tournamentRecord, drawDefinition, structureId, event,
|
|
|
17747
17900
|
link.target.structureId === structureId &&
|
|
17748
17901
|
link.source.structureId)
|
|
17749
17902
|
.filter(Boolean) ?? [];
|
|
17750
|
-
const isQualifyingStructure = qualifyingStructureIds.includes(structureId);
|
|
17751
17903
|
const relatedStructureIdsMap = new Map();
|
|
17752
17904
|
structureIds.forEach((id) => relatedStructureIdsMap.set(id, isQualifyingStructure
|
|
17753
17905
|
? getQualifyingSourceStructureIds(id)
|
|
17754
17906
|
: getTargetedStructureIds(id)));
|
|
17755
|
-
const
|
|
17756
|
-
|
|
17757
|
-
|
|
17758
|
-
|
|
17759
|
-
|
|
17907
|
+
const structureIdsToRemove = isMainStageSequence1 ? relatedStructureIdsMap.get(structureId) : [structureId];
|
|
17908
|
+
return { structureIdsToRemove, relatedStructureIdsMap };
|
|
17909
|
+
}
|
|
17910
|
+
function removeMatchUpsAndStructures({ relatedStructureIdsMap, qualifyingStructureIds, isMainStageSequence1, mainStageSequence1, drawDefinition, structureIdsToRemove, structureId, }) {
|
|
17911
|
+
const removedStructureIds = [];
|
|
17912
|
+
const removedMatchUpIds = [];
|
|
17913
|
+
while (structureIdsToRemove?.length) {
|
|
17914
|
+
const idBeingRemoved = structureIdsToRemove.pop();
|
|
17915
|
+
removedMatchUpIds.push(...getRemovedMatchUpIds({ idBeingRemoved, drawDefinition }));
|
|
17916
|
+
const result = pruneLinksAndStructures({
|
|
17917
|
+
qualifyingStructureIds,
|
|
17918
|
+
isMainStageSequence1,
|
|
17919
|
+
idBeingRemoved,
|
|
17760
17920
|
drawDefinition,
|
|
17921
|
+
structureId,
|
|
17922
|
+
});
|
|
17923
|
+
removedStructureIds.push(...result.removedStructureIds);
|
|
17924
|
+
const targetedStructureIds = getTargetedStructureIds({
|
|
17925
|
+
relatedStructureIdsMap,
|
|
17926
|
+
mainStageSequence1,
|
|
17927
|
+
idBeingRemoved,
|
|
17928
|
+
structureId,
|
|
17761
17929
|
});
|
|
17762
|
-
const matchUps = getAllStructureMatchUps({ structure }).matchUps;
|
|
17763
|
-
const matchUpIds = getMatchUpIds(matchUps);
|
|
17764
|
-
removedMatchUpIds.push(...matchUpIds);
|
|
17765
|
-
drawDefinition.links =
|
|
17766
|
-
drawDefinition.links?.filter((link) => link.source.structureId !== idBeingRemoved && link.target.structureId !== idBeingRemoved) ?? [];
|
|
17767
|
-
if (!isMainStageSequence1 ||
|
|
17768
|
-
(isMainStageSequence1 && qualifyingStructureIds.length) ||
|
|
17769
|
-
idBeingRemoved !== structureId) {
|
|
17770
|
-
drawDefinition.structures = (drawDefinition.structures ?? []).filter((structure) => {
|
|
17771
|
-
if (idBeingRemoved && idBeingRemoved === structure.structureId)
|
|
17772
|
-
removedStructureIds.push(idBeingRemoved);
|
|
17773
|
-
return structure.structureId !== idBeingRemoved;
|
|
17774
|
-
});
|
|
17775
|
-
}
|
|
17776
|
-
const targetedStructureIds = idBeingRemoved &&
|
|
17777
|
-
relatedStructureIdsMap.get(idBeingRemoved)?.filter((id) => id !== mainStageSequence1?.structureId || structureId === mainStageSequence1.structureId);
|
|
17778
17930
|
if (targetedStructureIds?.length)
|
|
17779
|
-
|
|
17931
|
+
structureIdsToRemove.push(...targetedStructureIds);
|
|
17780
17932
|
}
|
|
17781
|
-
|
|
17782
|
-
|
|
17783
|
-
|
|
17784
|
-
|
|
17785
|
-
|
|
17786
|
-
|
|
17787
|
-
|
|
17788
|
-
|
|
17789
|
-
|
|
17790
|
-
|
|
17791
|
-
|
|
17792
|
-
|
|
17793
|
-
|
|
17794
|
-
|
|
17795
|
-
|
|
17796
|
-
|
|
17797
|
-
|
|
17798
|
-
}
|
|
17933
|
+
return { removedMatchUpIds, removedStructureIds };
|
|
17934
|
+
}
|
|
17935
|
+
function getTargetedStructureIds({ idBeingRemoved, relatedStructureIdsMap, mainStageSequence1, structureId }) {
|
|
17936
|
+
return (idBeingRemoved &&
|
|
17937
|
+
relatedStructureIdsMap.get(idBeingRemoved)?.filter((id) => id !== mainStageSequence1?.structureId || structureId === mainStageSequence1.structureId));
|
|
17938
|
+
}
|
|
17939
|
+
function pruneLinksAndStructures({ qualifyingStructureIds, isMainStageSequence1, idBeingRemoved, drawDefinition, structureId, }) {
|
|
17940
|
+
const removedStructureIds = [];
|
|
17941
|
+
drawDefinition.links =
|
|
17942
|
+
drawDefinition.links?.filter((link) => link.source.structureId !== idBeingRemoved && link.target.structureId !== idBeingRemoved) ?? [];
|
|
17943
|
+
if (!isMainStageSequence1 ||
|
|
17944
|
+
(isMainStageSequence1 && qualifyingStructureIds.length) ||
|
|
17945
|
+
idBeingRemoved !== structureId) {
|
|
17946
|
+
drawDefinition.structures = (drawDefinition.structures ?? []).filter((structure) => {
|
|
17947
|
+
if (idBeingRemoved && idBeingRemoved === structure.structureId)
|
|
17948
|
+
removedStructureIds.push(idBeingRemoved);
|
|
17949
|
+
return structure.structureId !== idBeingRemoved;
|
|
17950
|
+
});
|
|
17799
17951
|
}
|
|
17800
|
-
|
|
17801
|
-
|
|
17802
|
-
|
|
17803
|
-
|
|
17804
|
-
|
|
17805
|
-
eventId: event?.eventId,
|
|
17952
|
+
return { removedStructureIds };
|
|
17953
|
+
}
|
|
17954
|
+
function getRemovedMatchUpIds({ idBeingRemoved, drawDefinition }) {
|
|
17955
|
+
const { structure } = findStructure({
|
|
17956
|
+
structureId: idBeingRemoved,
|
|
17806
17957
|
drawDefinition,
|
|
17807
17958
|
});
|
|
17808
|
-
|
|
17809
|
-
return
|
|
17959
|
+
const matchUps = getAllStructureMatchUps({ structure }).matchUps;
|
|
17960
|
+
return getMatchUpIds(matchUps);
|
|
17810
17961
|
}
|
|
17811
17962
|
|
|
17812
17963
|
function setStageDrawSize({ stageSequence = 1, drawDefinition, drawSize, stage }) {
|
|
@@ -23206,6 +23357,8 @@ var mutate$c = {
|
|
|
23206
23357
|
setPositionAssignments: setPositionAssignments,
|
|
23207
23358
|
setStructureOrder: setStructureOrder,
|
|
23208
23359
|
setSubOrder: setSubOrder,
|
|
23360
|
+
shiftAdHocRounds: shiftAdHocRounds,
|
|
23361
|
+
swapAdHocRounds: swapAdHocRounds,
|
|
23209
23362
|
swapDrawPositionAssignments: swapDrawPositionAssignments,
|
|
23210
23363
|
updateTeamLineUp: updateTeamLineUp,
|
|
23211
23364
|
withdrawParticipantAtDrawPosition: withdrawParticipantAtDrawPosition
|
|
@@ -25913,6 +26066,462 @@ function generateDrawTypeAndModifyDrawDefinition(params) {
|
|
|
25913
26066
|
};
|
|
25914
26067
|
}
|
|
25915
26068
|
|
|
26069
|
+
function getParticipantScaleItem(params) {
|
|
26070
|
+
const { tournamentRecord, scaleAttributes, participantId } = params;
|
|
26071
|
+
const tournamentRecords = params.tournamentRecords ||
|
|
26072
|
+
(tournamentRecord && {
|
|
26073
|
+
[tournamentRecord.tournamentId]: tournamentRecord,
|
|
26074
|
+
}) ||
|
|
26075
|
+
{};
|
|
26076
|
+
if (!participantId)
|
|
26077
|
+
return { error: MISSING_PARTICIPANT_ID };
|
|
26078
|
+
const { participant, tournamentId } = findTournamentParticipant({
|
|
26079
|
+
tournamentRecords,
|
|
26080
|
+
tournamentRecord,
|
|
26081
|
+
participantId,
|
|
26082
|
+
});
|
|
26083
|
+
if (!participant)
|
|
26084
|
+
return { error: PARTICIPANT_NOT_FOUND };
|
|
26085
|
+
return {
|
|
26086
|
+
...participantScaleItem({ participant, scaleAttributes }),
|
|
26087
|
+
tournamentId,
|
|
26088
|
+
};
|
|
26089
|
+
}
|
|
26090
|
+
|
|
26091
|
+
function setParticipantScaleItem(params) {
|
|
26092
|
+
const { removePriorValues, tournamentRecord, participantId, scaleItem } = params;
|
|
26093
|
+
let equivalentValue, participant;
|
|
26094
|
+
if (!isValidScaleItem({ scaleItem }))
|
|
26095
|
+
return { error: INVALID_SCALE_ITEM };
|
|
26096
|
+
if (participantId && Array.isArray(tournamentRecord.participants)) {
|
|
26097
|
+
participant = tournamentRecord.participants.find((participant) => participant.participantId === participantId);
|
|
26098
|
+
if (participant) {
|
|
26099
|
+
const result = addParticipantScaleItem({
|
|
26100
|
+
removePriorValues,
|
|
26101
|
+
participant,
|
|
26102
|
+
scaleItem,
|
|
26103
|
+
});
|
|
26104
|
+
if (result.error)
|
|
26105
|
+
return result;
|
|
26106
|
+
equivalentValue = !result.valueChanged;
|
|
26107
|
+
const { topics } = getTopics();
|
|
26108
|
+
if (topics.includes(MODIFY_PARTICIPANTS)) {
|
|
26109
|
+
addNotice({
|
|
26110
|
+
topic: MODIFY_PARTICIPANTS,
|
|
26111
|
+
payload: {
|
|
26112
|
+
tournamentId: tournamentRecord.tournamentId,
|
|
26113
|
+
participants: [participant],
|
|
26114
|
+
},
|
|
26115
|
+
});
|
|
26116
|
+
}
|
|
26117
|
+
}
|
|
26118
|
+
}
|
|
26119
|
+
return ((equivalentValue && {
|
|
26120
|
+
...SUCCESS,
|
|
26121
|
+
info: VALUE_UNCHANGED,
|
|
26122
|
+
existingValue: scaleItem?.scaleValue,
|
|
26123
|
+
}) ||
|
|
26124
|
+
(participant && { ...SUCCESS, newValue: scaleItem?.scaleValue }) || {
|
|
26125
|
+
error: PARTICIPANT_NOT_FOUND,
|
|
26126
|
+
});
|
|
26127
|
+
}
|
|
26128
|
+
function setParticipantScaleItems(params) {
|
|
26129
|
+
const { scaleItemsWithParticipantIds = [], removePriorValues, tournamentRecord, auditData, context } = params;
|
|
26130
|
+
if (!tournamentRecord)
|
|
26131
|
+
return { error: MISSING_TOURNAMENT_RECORD };
|
|
26132
|
+
if (!tournamentRecord.participants)
|
|
26133
|
+
return { error: MISSING_PARTICIPANTS };
|
|
26134
|
+
let modificationsApplied = 0;
|
|
26135
|
+
const participantScaleItemsMap = {};
|
|
26136
|
+
const modifiedParticipants = [];
|
|
26137
|
+
for (const item of scaleItemsWithParticipantIds) {
|
|
26138
|
+
const participantId = item?.participantId;
|
|
26139
|
+
if (Array.isArray(item?.scaleItems)) {
|
|
26140
|
+
for (const scaleItem of item.scaleItems) {
|
|
26141
|
+
if (isValidScaleItem({ scaleItem })) {
|
|
26142
|
+
if (!Array.isArray(participantScaleItemsMap[participantId])) {
|
|
26143
|
+
participantScaleItemsMap[participantId] = [];
|
|
26144
|
+
}
|
|
26145
|
+
participantScaleItemsMap[participantId].push(scaleItem);
|
|
26146
|
+
}
|
|
26147
|
+
else {
|
|
26148
|
+
return { error: INVALID_SCALE_ITEM };
|
|
26149
|
+
}
|
|
26150
|
+
}
|
|
26151
|
+
}
|
|
26152
|
+
}
|
|
26153
|
+
tournamentRecord.participants.forEach((participant) => {
|
|
26154
|
+
const { participantId } = participant || {};
|
|
26155
|
+
if (Array.isArray(participantScaleItemsMap[participantId])) {
|
|
26156
|
+
participantScaleItemsMap[participantId].forEach((scaleItem) => {
|
|
26157
|
+
addParticipantScaleItem({ participant, scaleItem, removePriorValues });
|
|
26158
|
+
modifiedParticipants.push(participant);
|
|
26159
|
+
modificationsApplied++;
|
|
26160
|
+
});
|
|
26161
|
+
}
|
|
26162
|
+
});
|
|
26163
|
+
const info = !modificationsApplied ? NO_MODIFICATIONS_APPLIED : undefined;
|
|
26164
|
+
const { topics } = getTopics();
|
|
26165
|
+
if (topics.includes(MODIFY_PARTICIPANTS) && modificationsApplied) {
|
|
26166
|
+
addNotice({
|
|
26167
|
+
topic: MODIFY_PARTICIPANTS,
|
|
26168
|
+
payload: {
|
|
26169
|
+
tournamentId: tournamentRecord.tournamentId,
|
|
26170
|
+
participants: modifiedParticipants,
|
|
26171
|
+
},
|
|
26172
|
+
});
|
|
26173
|
+
}
|
|
26174
|
+
if (context) {
|
|
26175
|
+
const { eventId, drawId, ...itemValue } = context;
|
|
26176
|
+
const itemSubTypes = itemValue.scaleAttributes?.scaleType && [itemValue.scaleAttributes.scaleType];
|
|
26177
|
+
if (Object.keys(itemValue).length) {
|
|
26178
|
+
const timeItem = {
|
|
26179
|
+
itemType: ADD_SCALE_ITEMS,
|
|
26180
|
+
itemValue,
|
|
26181
|
+
};
|
|
26182
|
+
if (itemSubTypes)
|
|
26183
|
+
timeItem.itemSubTypes = itemSubTypes;
|
|
26184
|
+
if (drawId || eventId) {
|
|
26185
|
+
const { drawDefinition, event } = findEvent({
|
|
26186
|
+
tournamentRecord,
|
|
26187
|
+
eventId,
|
|
26188
|
+
drawId,
|
|
26189
|
+
});
|
|
26190
|
+
if (drawId) {
|
|
26191
|
+
addDrawDefinitionTimeItem({ drawDefinition, timeItem });
|
|
26192
|
+
}
|
|
26193
|
+
if (eventId) {
|
|
26194
|
+
addEventTimeItem({ event, timeItem });
|
|
26195
|
+
}
|
|
26196
|
+
}
|
|
26197
|
+
else {
|
|
26198
|
+
addTournamentTimeItem({ tournamentRecord, timeItem });
|
|
26199
|
+
}
|
|
26200
|
+
}
|
|
26201
|
+
}
|
|
26202
|
+
if (auditData && topics.includes(AUDIT)) {
|
|
26203
|
+
addNotice({ topic: AUDIT, payload: auditData });
|
|
26204
|
+
}
|
|
26205
|
+
return definedAttributes({ ...SUCCESS, modificationsApplied, info });
|
|
26206
|
+
}
|
|
26207
|
+
function isValidScaleItem({ scaleItem }) {
|
|
26208
|
+
const scaleItemAttributes = scaleItem && Object.keys(scaleItem);
|
|
26209
|
+
const requiredAttributes = ['scaleType', 'eventType', 'scaleName'];
|
|
26210
|
+
const validScaleItem = requiredAttributes.filter((attribute) => scaleItemAttributes?.includes(attribute)).length ===
|
|
26211
|
+
requiredAttributes.length;
|
|
26212
|
+
return !!validScaleItem;
|
|
26213
|
+
}
|
|
26214
|
+
function addParticipantScaleItem({ removePriorValues, participant, scaleItem }) {
|
|
26215
|
+
if (!participant) {
|
|
26216
|
+
return { error: MISSING_PARTICIPANT };
|
|
26217
|
+
}
|
|
26218
|
+
const scaleItemAttributes = scaleItem && Object.keys(scaleItem);
|
|
26219
|
+
const requiredAttributes = ['scaleType', 'eventType', 'scaleName'];
|
|
26220
|
+
const validScaleItem = requiredAttributes.filter((attribute) => scaleItemAttributes.includes(attribute) && scaleItem[attribute]).length ===
|
|
26221
|
+
requiredAttributes.length;
|
|
26222
|
+
if (!validScaleItem)
|
|
26223
|
+
return { error: INVALID_SCALE_ITEM };
|
|
26224
|
+
const createdAt = new Date().toISOString();
|
|
26225
|
+
if (!participant.timeItems)
|
|
26226
|
+
participant.timeItems = [];
|
|
26227
|
+
const { scaleItem: existingScaleItem } = participantScaleItem({
|
|
26228
|
+
scaleAttributes: scaleItem,
|
|
26229
|
+
participant,
|
|
26230
|
+
});
|
|
26231
|
+
const isUndefined = (value) => [undefined, null, ''].includes(value);
|
|
26232
|
+
const valueChanged = !(isUndefined(existingScaleItem?.scaleValue) && isUndefined(scaleItem.scaleValue)) &&
|
|
26233
|
+
JSON.stringify(existingScaleItem?.scaleValue) !== JSON.stringify(scaleItem.scaleValue);
|
|
26234
|
+
if (valueChanged) {
|
|
26235
|
+
const { scaleType, eventType, scaleName } = scaleItem;
|
|
26236
|
+
const itemType = [SCALE$1, scaleType, eventType, scaleName].join('.');
|
|
26237
|
+
const timeItem = definedAttributes({
|
|
26238
|
+
itemValue: scaleItem.scaleValue,
|
|
26239
|
+
itemDate: scaleItem.scaleDate,
|
|
26240
|
+
createdAt,
|
|
26241
|
+
itemType,
|
|
26242
|
+
});
|
|
26243
|
+
if (scaleItem.scaleId) {
|
|
26244
|
+
timeItem.itemSubTypes = [scaleItem.scaleId];
|
|
26245
|
+
}
|
|
26246
|
+
if (removePriorValues) {
|
|
26247
|
+
participant.timeItems = participant.timeItems.filter((timeItem) => timeItem.itemType !== itemType);
|
|
26248
|
+
}
|
|
26249
|
+
participant.timeItems.push(timeItem);
|
|
26250
|
+
}
|
|
26251
|
+
return { ...SUCCESS, valueChanged, newValue: scaleItem.scaleValue };
|
|
26252
|
+
}
|
|
26253
|
+
|
|
26254
|
+
const ELO = 'ELO';
|
|
26255
|
+
const NTRP = 'NTRP';
|
|
26256
|
+
const TRN = 'TRN';
|
|
26257
|
+
const UTR = 'UTR';
|
|
26258
|
+
const WTN = 'WTN';
|
|
26259
|
+
const ratingConstants = {
|
|
26260
|
+
ELO,
|
|
26261
|
+
NTRP,
|
|
26262
|
+
TRN,
|
|
26263
|
+
UTR,
|
|
26264
|
+
WTN,
|
|
26265
|
+
};
|
|
26266
|
+
|
|
26267
|
+
const ratingsParameters = {
|
|
26268
|
+
[ELO]: {
|
|
26269
|
+
defaultInitialization: 1500,
|
|
26270
|
+
decimalsCount: 0,
|
|
26271
|
+
range: [0, 3000],
|
|
26272
|
+
ascending: true,
|
|
26273
|
+
},
|
|
26274
|
+
[NTRP]: {
|
|
26275
|
+
accessors: ['ntrpRating', 'dntrpRatingHundredths'],
|
|
26276
|
+
attributes: { ustaRatingType: '' },
|
|
26277
|
+
accessor: 'dntrpRatingHundredths',
|
|
26278
|
+
defaultInitialization: 3,
|
|
26279
|
+
decimalsCount: 1,
|
|
26280
|
+
ascending: true,
|
|
26281
|
+
range: [1, 7],
|
|
26282
|
+
},
|
|
26283
|
+
[UTR]: {
|
|
26284
|
+
defaultInitialization: 6,
|
|
26285
|
+
accessors: ['utrRating'],
|
|
26286
|
+
accessor: 'utrRating',
|
|
26287
|
+
decimalsCount: 2,
|
|
26288
|
+
ascending: true,
|
|
26289
|
+
range: [1, 16],
|
|
26290
|
+
},
|
|
26291
|
+
[WTN]: {
|
|
26292
|
+
attributes: { confidence: { generator: true, range: [60, 100] } },
|
|
26293
|
+
accessors: ['wtnRating', 'confidence'],
|
|
26294
|
+
defaultInitialization: 23,
|
|
26295
|
+
accessor: 'wtnRating',
|
|
26296
|
+
ascending: false,
|
|
26297
|
+
decimalsCount: 2,
|
|
26298
|
+
range: [40, 1],
|
|
26299
|
+
},
|
|
26300
|
+
};
|
|
26301
|
+
|
|
26302
|
+
const k538 = (countables) => 250 / Math.pow(countables + 5, 0.4);
|
|
26303
|
+
const kDefault = () => 1;
|
|
26304
|
+
function kSet(maxCountables = 3, counted = 2) {
|
|
26305
|
+
const kset = maxCountables / counted;
|
|
26306
|
+
return isNaN(kset) ? eloConfig.kDefault() : kset;
|
|
26307
|
+
}
|
|
26308
|
+
const eloConfig = {
|
|
26309
|
+
nSpread: 400,
|
|
26310
|
+
diffThreshold: 0.125,
|
|
26311
|
+
kCalc: k538,
|
|
26312
|
+
kMultiplier: kSet,
|
|
26313
|
+
kDefault,
|
|
26314
|
+
};
|
|
26315
|
+
function calculateNewRatings(params) {
|
|
26316
|
+
let { winnerRating, loserRating, ratingRange } = params;
|
|
26317
|
+
const { ratings = ratingsParameters, winnerCountables = 1, loserCountables = 0, ratingType = ELO, maxCountables, countables, } = params || {};
|
|
26318
|
+
const ratingParameters = ratings?.[ratingType];
|
|
26319
|
+
if (!ratingParameters)
|
|
26320
|
+
return { error: MISSING_VALUE };
|
|
26321
|
+
ratingRange = ratingParameters.range || ratingRange;
|
|
26322
|
+
winnerRating = winnerRating || ratingParameters.defaultInitialization;
|
|
26323
|
+
loserRating = loserRating || ratingParameters.defaultInitialization;
|
|
26324
|
+
const invertedScale = ratingRange[0] > ratingRange[1];
|
|
26325
|
+
const decimalPlaces = ratingParameters.decimalsCount || 0;
|
|
26326
|
+
const consideredRange = invertedScale ? ratingRange.slice().reverse() : ratingRange;
|
|
26327
|
+
const inRange = (range, value) => parseFloat(value) >= Math.min(...range) && parseFloat(value) <= Math.max(...range);
|
|
26328
|
+
if (!inRange(ratingRange, winnerRating) || !inRange(ratingRange, loserRating)) {
|
|
26329
|
+
if (!inRange(ratingRange, winnerRating))
|
|
26330
|
+
winnerRating = ratingParameters.defaultInitialization;
|
|
26331
|
+
if (!inRange(ratingRange, loserRating))
|
|
26332
|
+
loserRating = ratingParameters.defaultInitialization;
|
|
26333
|
+
}
|
|
26334
|
+
const convertRange = ({ value, sourceRange, targetRange }) => ((value - sourceRange[0]) * (targetRange[1] - targetRange[0])) / (sourceRange[1] - sourceRange[0]) + targetRange[0];
|
|
26335
|
+
const convertedWinnerRating = convertRange({
|
|
26336
|
+
targetRange: ratingsParameters[ELO].range,
|
|
26337
|
+
sourceRange: consideredRange,
|
|
26338
|
+
value: invertedScale ? ratingRange[0] - winnerRating : winnerRating,
|
|
26339
|
+
});
|
|
26340
|
+
const convertedLoserRating = convertRange({
|
|
26341
|
+
targetRange: ratingsParameters[ELO].range,
|
|
26342
|
+
sourceRange: consideredRange,
|
|
26343
|
+
value: invertedScale ? ratingRange[0] - loserRating : loserRating,
|
|
26344
|
+
});
|
|
26345
|
+
const getExpectation = (playerRating, opponentRating) => 1 / (1 + Math.pow(10, (opponentRating - playerRating) / eloConfig.nSpread));
|
|
26346
|
+
const winnerExpectation = getExpectation(convertedWinnerRating, convertedLoserRating);
|
|
26347
|
+
const loserExpectation = getExpectation(convertedLoserRating, convertedWinnerRating);
|
|
26348
|
+
const winnerKValue = eloConfig.kCalc(winnerCountables);
|
|
26349
|
+
const loserKValue = eloConfig.kCalc(loserCountables);
|
|
26350
|
+
const k = eloConfig.kMultiplier(maxCountables, countables);
|
|
26351
|
+
const winnerUpdatedConvertedRating = convertedWinnerRating + k * winnerKValue * (1 - winnerExpectation);
|
|
26352
|
+
const loserUpdatedConvertedRating = convertedLoserRating + k * loserKValue * (0 - loserExpectation);
|
|
26353
|
+
const convertedUpdatedWinnerRating = convertRange({
|
|
26354
|
+
sourceRange: ratingsParameters[ELO].range,
|
|
26355
|
+
value: winnerUpdatedConvertedRating,
|
|
26356
|
+
targetRange: consideredRange,
|
|
26357
|
+
});
|
|
26358
|
+
const convertedUpdatedLoserRating = convertRange({
|
|
26359
|
+
sourceRange: ratingsParameters[ELO].range,
|
|
26360
|
+
value: loserUpdatedConvertedRating,
|
|
26361
|
+
targetRange: consideredRange,
|
|
26362
|
+
});
|
|
26363
|
+
const updatedWinnerRating = invertedScale
|
|
26364
|
+
? ratingRange[0] - convertedUpdatedWinnerRating
|
|
26365
|
+
: convertedUpdatedWinnerRating;
|
|
26366
|
+
let newWinnerRating = parseFloat(parseFloat(updatedWinnerRating).toFixed(decimalPlaces));
|
|
26367
|
+
const updatedLoserRating = invertedScale ? ratingRange[0] - convertedUpdatedLoserRating : convertedUpdatedLoserRating;
|
|
26368
|
+
let newLoserRating = parseFloat(parseFloat(updatedLoserRating).toFixed(decimalPlaces));
|
|
26369
|
+
const percentageDifference = Math.max(...ratingRange)
|
|
26370
|
+
? Math.abs(winnerRating - loserRating) / Math.max(...ratingRange)
|
|
26371
|
+
: 0;
|
|
26372
|
+
if ((convertedUpdatedWinnerRating > convertedUpdatedLoserRating && percentageDifference > eloConfig.diffThreshold) ||
|
|
26373
|
+
newWinnerRating < 0 ||
|
|
26374
|
+
newLoserRating < 0) {
|
|
26375
|
+
newWinnerRating = winnerRating;
|
|
26376
|
+
newLoserRating = loserRating;
|
|
26377
|
+
}
|
|
26378
|
+
return { newWinnerRating, newLoserRating };
|
|
26379
|
+
}
|
|
26380
|
+
|
|
26381
|
+
const aggregateSets = (sets) => {
|
|
26382
|
+
return (sets?.reduce((aggregate, set) => {
|
|
26383
|
+
if (set.winningSide)
|
|
26384
|
+
aggregate[set.winningSide - 1] += 1;
|
|
26385
|
+
return aggregate;
|
|
26386
|
+
}, [0, 0]) || [0, 0]);
|
|
26387
|
+
};
|
|
26388
|
+
|
|
26389
|
+
function generateDynamicRatings(params) {
|
|
26390
|
+
const { removePriorValues = true, tournamentRecord, ratingType = ELO, considerGames, matchUpIds, asDynamic } = params;
|
|
26391
|
+
if (!tournamentRecord)
|
|
26392
|
+
return { error: MISSING_TOURNAMENT_RECORD };
|
|
26393
|
+
if (!Array.isArray(matchUpIds))
|
|
26394
|
+
return { error: MISSING_MATCHUPS };
|
|
26395
|
+
if (typeof ratingType !== 'string')
|
|
26396
|
+
return { error: INVALID_VALUES, ratingType };
|
|
26397
|
+
if (!ratingsParameters[ratingType])
|
|
26398
|
+
return { error: INVALID_VALUES };
|
|
26399
|
+
const ratingParameter = ratingsParameters[ratingType];
|
|
26400
|
+
const { accessor } = ratingParameter;
|
|
26401
|
+
const modifiedScaleValues = {};
|
|
26402
|
+
const matchUps = params.matchUps ??
|
|
26403
|
+
allTournamentMatchUps({
|
|
26404
|
+
matchUpFilters: { matchUpIds, matchUpStatuses: completedMatchUpStatuses },
|
|
26405
|
+
tournamentRecord,
|
|
26406
|
+
inContext: true,
|
|
26407
|
+
}).matchUps ??
|
|
26408
|
+
[];
|
|
26409
|
+
matchUps.sort(matchUpSort);
|
|
26410
|
+
for (const matchUp of matchUps) {
|
|
26411
|
+
const { endDate, matchUpFormat, score, sides, winningSide } = matchUp;
|
|
26412
|
+
const matchUpType = matchUp.matchUpType;
|
|
26413
|
+
const scaleAttributes = {
|
|
26414
|
+
eventType: matchUpType,
|
|
26415
|
+
scaleName: ratingType,
|
|
26416
|
+
scaleType: RATING$1,
|
|
26417
|
+
};
|
|
26418
|
+
const dynamicScaleName = `${ratingType}.${DYNAMIC}`;
|
|
26419
|
+
const dynamicScaleAttributes = {
|
|
26420
|
+
scaleName: dynamicScaleName,
|
|
26421
|
+
eventType: matchUpType,
|
|
26422
|
+
scaleType: RATING$1,
|
|
26423
|
+
};
|
|
26424
|
+
const sideParticipantIds = Object.assign({}, ...(sides ?? []).map((side) => {
|
|
26425
|
+
const { sideNumber, participant } = side;
|
|
26426
|
+
return (sideNumber && {
|
|
26427
|
+
[sideNumber]: [participant?.participantId, ...(participant?.individualParticipantIds ?? [])]
|
|
26428
|
+
.filter(Boolean)
|
|
26429
|
+
.flat(),
|
|
26430
|
+
});
|
|
26431
|
+
}));
|
|
26432
|
+
const outputScaleName = asDynamic ? dynamicScaleName : ratingType;
|
|
26433
|
+
const scaleItemMap = Object.assign({}, ...Object.values(sideParticipantIds)
|
|
26434
|
+
.flat()
|
|
26435
|
+
.map((participantId) => {
|
|
26436
|
+
const { scaleItem: dynamicScaleItem } = getParticipantScaleItem({
|
|
26437
|
+
scaleAttributes: dynamicScaleAttributes,
|
|
26438
|
+
tournamentRecord,
|
|
26439
|
+
participantId,
|
|
26440
|
+
});
|
|
26441
|
+
const { scaleItem } = getParticipantScaleItem({
|
|
26442
|
+
tournamentRecord,
|
|
26443
|
+
scaleAttributes,
|
|
26444
|
+
participantId,
|
|
26445
|
+
});
|
|
26446
|
+
const scaleValue = accessor ? { [accessor]: undefined } : undefined;
|
|
26447
|
+
return (participantId && {
|
|
26448
|
+
[participantId]: dynamicScaleItem ??
|
|
26449
|
+
scaleItem ?? {
|
|
26450
|
+
scaleName: outputScaleName,
|
|
26451
|
+
eventType: matchUpType,
|
|
26452
|
+
scaleDate: endDate,
|
|
26453
|
+
scaleType: RATING$1,
|
|
26454
|
+
scaleValue,
|
|
26455
|
+
},
|
|
26456
|
+
});
|
|
26457
|
+
}));
|
|
26458
|
+
const parsedFormat = matchUpFormat ? parse(matchUpFormat) : {};
|
|
26459
|
+
const bestOf = parsedFormat?.bestOf || 1;
|
|
26460
|
+
const setsTo = parsedFormat?.setsTo || 1;
|
|
26461
|
+
const maxCountables = considerGames ? bestOf & setsTo : bestOf;
|
|
26462
|
+
const countables = (score?.sets && aggregateSets(score.sets)) || (winningSide === 1 && [1, 0]) || [0, 1];
|
|
26463
|
+
const winningSideParticipantIds = winningSide ? sideParticipantIds[winningSide] : [];
|
|
26464
|
+
const losingSideParticipantIds = winningSide ? sideParticipantIds[3 - winningSide] : [];
|
|
26465
|
+
for (const winnerParticipantId of winningSideParticipantIds) {
|
|
26466
|
+
const winnerScaleValue = scaleItemMap[winnerParticipantId]?.scaleValue;
|
|
26467
|
+
const winnerRating = typeof winnerScaleValue === 'object' ? winnerScaleValue[accessor] : winnerScaleValue;
|
|
26468
|
+
for (const loserParticipantId of losingSideParticipantIds) {
|
|
26469
|
+
const loserScaleValue = scaleItemMap[loserParticipantId]?.scaleValue;
|
|
26470
|
+
const loserRating = typeof loserScaleValue === 'object' ? loserScaleValue[accessor] : loserScaleValue;
|
|
26471
|
+
const winnerCountables = winningSide ? countables[winningSide] : [0, 0];
|
|
26472
|
+
const loserCountables = winningSide ? countables[3 - winningSide] : [0, 0];
|
|
26473
|
+
const { newWinnerRating, newLoserRating } = calculateNewRatings({
|
|
26474
|
+
winnerCountables,
|
|
26475
|
+
loserCountables,
|
|
26476
|
+
maxCountables,
|
|
26477
|
+
winnerRating,
|
|
26478
|
+
loserRating,
|
|
26479
|
+
ratingType,
|
|
26480
|
+
});
|
|
26481
|
+
const newWinnerScaleValue = accessor
|
|
26482
|
+
? {
|
|
26483
|
+
...winnerScaleValue,
|
|
26484
|
+
[accessor]: newWinnerRating,
|
|
26485
|
+
}
|
|
26486
|
+
: newWinnerRating;
|
|
26487
|
+
const newLoserScaleValue = accessor
|
|
26488
|
+
? {
|
|
26489
|
+
...loserScaleValue,
|
|
26490
|
+
[accessor]: newLoserRating,
|
|
26491
|
+
}
|
|
26492
|
+
: newLoserRating;
|
|
26493
|
+
scaleItemMap[winnerParticipantId].scaleValue = newWinnerScaleValue;
|
|
26494
|
+
scaleItemMap[loserParticipantId].scaleValue = newLoserScaleValue;
|
|
26495
|
+
let result = setParticipantScaleItem({
|
|
26496
|
+
participantId: winnerParticipantId,
|
|
26497
|
+
removePriorValues,
|
|
26498
|
+
tournamentRecord,
|
|
26499
|
+
scaleItem: {
|
|
26500
|
+
...scaleItemMap[winnerParticipantId],
|
|
26501
|
+
scaleName: outputScaleName,
|
|
26502
|
+
},
|
|
26503
|
+
});
|
|
26504
|
+
if (result.error)
|
|
26505
|
+
return result;
|
|
26506
|
+
result = setParticipantScaleItem({
|
|
26507
|
+
participantId: loserParticipantId,
|
|
26508
|
+
removePriorValues,
|
|
26509
|
+
tournamentRecord,
|
|
26510
|
+
scaleItem: {
|
|
26511
|
+
...scaleItemMap[loserParticipantId],
|
|
26512
|
+
scaleName: outputScaleName,
|
|
26513
|
+
},
|
|
26514
|
+
});
|
|
26515
|
+
if (result.error)
|
|
26516
|
+
return result;
|
|
26517
|
+
}
|
|
26518
|
+
}
|
|
26519
|
+
Object.assign(modifiedScaleValues, scaleItemMap);
|
|
26520
|
+
}
|
|
26521
|
+
const processedMatchUpIds = matchUps.map(({ matchUpId }) => matchUpId);
|
|
26522
|
+
return { ...SUCCESS, modifiedScaleValues, processedMatchUpIds };
|
|
26523
|
+
}
|
|
26524
|
+
|
|
25916
26525
|
function generateAdHocMatchUps(params) {
|
|
25917
26526
|
const { matchUpIds = [], drawDefinition, roundNumber, newRound, isMock, event } = params;
|
|
25918
26527
|
if (typeof drawDefinition !== 'object')
|
|
@@ -26150,54 +26759,6 @@ function getParticipantPairingValues({ possiblePairings, valueObjects }) {
|
|
|
26150
26759
|
return { pairingValues };
|
|
26151
26760
|
}
|
|
26152
26761
|
|
|
26153
|
-
const ELO = 'ELO';
|
|
26154
|
-
const NTRP = 'NTRP';
|
|
26155
|
-
const TRN = 'TRN';
|
|
26156
|
-
const UTR = 'UTR';
|
|
26157
|
-
const WTN = 'WTN';
|
|
26158
|
-
const ratingConstants = {
|
|
26159
|
-
ELO,
|
|
26160
|
-
NTRP,
|
|
26161
|
-
TRN,
|
|
26162
|
-
UTR,
|
|
26163
|
-
WTN,
|
|
26164
|
-
};
|
|
26165
|
-
|
|
26166
|
-
const ratingsParameters = {
|
|
26167
|
-
[ELO]: {
|
|
26168
|
-
defaultInitialization: 1500,
|
|
26169
|
-
decimalsCount: 0,
|
|
26170
|
-
range: [0, 3000],
|
|
26171
|
-
ascending: true,
|
|
26172
|
-
},
|
|
26173
|
-
[NTRP]: {
|
|
26174
|
-
accessors: ['ntrpRating', 'dntrpRatingHundredths'],
|
|
26175
|
-
attributes: { ustaRatingType: '' },
|
|
26176
|
-
accessor: 'dntrpRatingHundredths',
|
|
26177
|
-
defaultInitialization: 3,
|
|
26178
|
-
decimalsCount: 1,
|
|
26179
|
-
ascending: true,
|
|
26180
|
-
range: [1, 7],
|
|
26181
|
-
},
|
|
26182
|
-
[UTR]: {
|
|
26183
|
-
defaultInitialization: 6,
|
|
26184
|
-
accessors: ['utrRating'],
|
|
26185
|
-
accessor: 'utrRating',
|
|
26186
|
-
decimalsCount: 2,
|
|
26187
|
-
ascending: true,
|
|
26188
|
-
range: [1, 16],
|
|
26189
|
-
},
|
|
26190
|
-
[WTN]: {
|
|
26191
|
-
attributes: { confidence: { generator: true, range: [60, 100] } },
|
|
26192
|
-
accessors: ['wtnRating', 'confidence'],
|
|
26193
|
-
defaultInitialization: 23,
|
|
26194
|
-
accessor: 'wtnRating',
|
|
26195
|
-
ascending: false,
|
|
26196
|
-
decimalsCount: 2,
|
|
26197
|
-
range: [40, 1],
|
|
26198
|
-
},
|
|
26199
|
-
};
|
|
26200
|
-
|
|
26201
26762
|
const DEFAULT_RATING = 0;
|
|
26202
26763
|
function getSideRatings({ tournamentParticipants, adHocRatings, eventType, scaleName, pairing }) {
|
|
26203
26764
|
const defaultRating = ratingsParameters[scaleName]?.defaultInitialization ?? DEFAULT_RATING;
|
|
@@ -26259,7 +26820,7 @@ function getPairings({ tournamentParticipants, adHocRatings = {}, possiblePairin
|
|
|
26259
26820
|
const ENCOUNTER_VALUE = 100;
|
|
26260
26821
|
const SAME_TEAM_VALUE = 100;
|
|
26261
26822
|
const MAX_ITERATIONS = 4000;
|
|
26262
|
-
function generateDrawMaticRound({ encounterValue = ENCOUNTER_VALUE, sameTeamValue = SAME_TEAM_VALUE, maxIterations = MAX_ITERATIONS, generateMatchUps = true, ignoreLastRoundNumber, iterationMatchUps, tournamentRecord, participantIds, drawDefinition, adHocRatings, salted = 0.5, roundNumber, structureId, matchUpIds, eventType, structure, scaleName, idPrefix, isMock, event, }) {
|
|
26823
|
+
function generateDrawMaticRound({ encounterValue = ENCOUNTER_VALUE, sameTeamValue = SAME_TEAM_VALUE, maxIterations = MAX_ITERATIONS, generateMatchUps = true, ignoreLastRoundNumber, iterationMatchUps, tournamentRecord, dynamicRatings, participantIds, drawDefinition, adHocRatings, salted = 0.5, roundNumber, structureId, matchUpIds, eventType, structure, scaleName, idPrefix, isMock, event, }) {
|
|
26263
26824
|
if (!drawDefinition)
|
|
26264
26825
|
return { error: MISSING_DRAW_DEFINITION };
|
|
26265
26826
|
if (!structure && !structureId)
|
|
@@ -26269,12 +26830,26 @@ function generateDrawMaticRound({ encounterValue = ENCOUNTER_VALUE, sameTeamValu
|
|
|
26269
26830
|
}
|
|
26270
26831
|
if (!isObject(structure))
|
|
26271
26832
|
return { error: MISSING_STRUCTURE };
|
|
26272
|
-
if (!participantIds?.length)
|
|
26833
|
+
if (!participantIds?.length)
|
|
26273
26834
|
return { error: MISSING_PARTICIPANT_IDS };
|
|
26274
|
-
}
|
|
26275
26835
|
const consideredMatchUps = [...(iterationMatchUps ?? []), ...(structure?.matchUps ?? [])];
|
|
26276
26836
|
const { encounters } = getEncounters({ matchUps: consideredMatchUps });
|
|
26277
26837
|
const tournamentParticipants = tournamentRecord?.participants ?? [];
|
|
26838
|
+
if (dynamicRatings) {
|
|
26839
|
+
const roundNumbers = unique(structure?.matchUps ? structure.matchUps.map(({ roundNumber }) => roundNumber) : []);
|
|
26840
|
+
const lastRoundNumber = Math.max(...roundNumbers, 0);
|
|
26841
|
+
if (lastRoundNumber) {
|
|
26842
|
+
const matchUpIds = structure?.matchUps
|
|
26843
|
+
?.filter(({ roundNumber }) => roundNumber === lastRoundNumber)
|
|
26844
|
+
.map(({ matchUpId }) => matchUpId);
|
|
26845
|
+
generateDynamicRatings({
|
|
26846
|
+
ratingType: scaleName || event?.category?.ratingType,
|
|
26847
|
+
tournamentRecord,
|
|
26848
|
+
asDynamic: true,
|
|
26849
|
+
matchUpIds,
|
|
26850
|
+
});
|
|
26851
|
+
}
|
|
26852
|
+
}
|
|
26278
26853
|
const { valueObjects } = getValueObjects({
|
|
26279
26854
|
tournamentParticipants,
|
|
26280
26855
|
encounterValue,
|
|
@@ -26630,28 +27205,6 @@ function getParticipantSchedules({ participantFilters = {}, tournamentRecord })
|
|
|
26630
27205
|
};
|
|
26631
27206
|
}
|
|
26632
27207
|
|
|
26633
|
-
function getParticipantScaleItem(params) {
|
|
26634
|
-
const { tournamentRecord, scaleAttributes, participantId } = params;
|
|
26635
|
-
const tournamentRecords = params.tournamentRecords ||
|
|
26636
|
-
(tournamentRecord && {
|
|
26637
|
-
[tournamentRecord.tournamentId]: tournamentRecord,
|
|
26638
|
-
}) ||
|
|
26639
|
-
{};
|
|
26640
|
-
if (!participantId)
|
|
26641
|
-
return { error: MISSING_PARTICIPANT_ID };
|
|
26642
|
-
const { participant, tournamentId } = findTournamentParticipant({
|
|
26643
|
-
tournamentRecords,
|
|
26644
|
-
tournamentRecord,
|
|
26645
|
-
participantId,
|
|
26646
|
-
});
|
|
26647
|
-
if (!participant)
|
|
26648
|
-
return { error: PARTICIPANT_NOT_FOUND };
|
|
26649
|
-
return {
|
|
26650
|
-
...participantScaleItem({ participant, scaleAttributes }),
|
|
26651
|
-
tournamentId,
|
|
26652
|
-
};
|
|
26653
|
-
}
|
|
26654
|
-
|
|
26655
27208
|
function getParticipantSignInStatus({ tournamentRecord, participantId }) {
|
|
26656
27209
|
if (!tournamentRecord)
|
|
26657
27210
|
return { error: MISSING_TOURNAMENT_RECORD };
|
|
@@ -35639,6 +36192,45 @@ function generateAdHocRounds(params) {
|
|
|
35639
36192
|
return { matchUps };
|
|
35640
36193
|
}
|
|
35641
36194
|
|
|
36195
|
+
function getAdHocRatings(params) {
|
|
36196
|
+
const { tournamentRecord, participantIds, scaleName, eventType, adHocRatings = {} } = params;
|
|
36197
|
+
const scaleAccessor = params.scaleAccessor ?? ratingsParameters[scaleName]?.accessor;
|
|
36198
|
+
const tournamentParticipants = tournamentRecord.participants ?? [];
|
|
36199
|
+
for (const participantId of participantIds ?? []) {
|
|
36200
|
+
const participant = tournamentParticipants?.find((participant) => participant.participantId === participantId);
|
|
36201
|
+
let scaleValue = getScaleValue({
|
|
36202
|
+
scaleName: `${scaleName}.${DYNAMIC}`,
|
|
36203
|
+
participant,
|
|
36204
|
+
eventType,
|
|
36205
|
+
});
|
|
36206
|
+
if (!scaleValue && scaleName) {
|
|
36207
|
+
scaleValue = getScaleValue({
|
|
36208
|
+
scaleAccessor,
|
|
36209
|
+
participant,
|
|
36210
|
+
scaleName,
|
|
36211
|
+
eventType,
|
|
36212
|
+
});
|
|
36213
|
+
}
|
|
36214
|
+
if (scaleValue && !adHocRatings[participantId])
|
|
36215
|
+
adHocRatings[participantId] = scaleValue;
|
|
36216
|
+
}
|
|
36217
|
+
return adHocRatings;
|
|
36218
|
+
}
|
|
36219
|
+
function getScaleValue({ scaleType = RATING$1, scaleAccessor, participant, scaleName, eventType }) {
|
|
36220
|
+
const scaleAttributes = {
|
|
36221
|
+
eventType: eventType ?? SINGLES_EVENT,
|
|
36222
|
+
scaleType,
|
|
36223
|
+
scaleName,
|
|
36224
|
+
};
|
|
36225
|
+
const result = participant &&
|
|
36226
|
+
participantScaleItem({
|
|
36227
|
+
scaleAttributes,
|
|
36228
|
+
participant,
|
|
36229
|
+
});
|
|
36230
|
+
const scaleValue = result?.scaleItem?.scaleValue;
|
|
36231
|
+
return scaleAccessor && isObject(scaleValue) ? scaleValue[scaleAccessor] : scaleValue;
|
|
36232
|
+
}
|
|
36233
|
+
|
|
35642
36234
|
function drawMatic(params) {
|
|
35643
36235
|
const paramsCheck = checkParams(params);
|
|
35644
36236
|
if (paramsCheck?.error)
|
|
@@ -35646,7 +36238,7 @@ function drawMatic(params) {
|
|
|
35646
36238
|
const idsResult = getParticipantIds(params);
|
|
35647
36239
|
if (idsResult.error)
|
|
35648
36240
|
return idsResult;
|
|
35649
|
-
const structureResult =
|
|
36241
|
+
const structureResult = getAdHocStructure(params);
|
|
35650
36242
|
if (structureResult.error)
|
|
35651
36243
|
return structureResult;
|
|
35652
36244
|
const adHocRatings = getAdHocRatings(params);
|
|
@@ -35678,45 +36270,7 @@ function drawMatic(params) {
|
|
|
35678
36270
|
}
|
|
35679
36271
|
return { ...SUCCESS, matchUps, roundResults };
|
|
35680
36272
|
}
|
|
35681
|
-
function
|
|
35682
|
-
const scaleAttributes = {
|
|
35683
|
-
eventType: eventType ?? SINGLES_EVENT,
|
|
35684
|
-
scaleType,
|
|
35685
|
-
scaleName,
|
|
35686
|
-
};
|
|
35687
|
-
const result = participant &&
|
|
35688
|
-
participantScaleItem({
|
|
35689
|
-
scaleAttributes,
|
|
35690
|
-
participant,
|
|
35691
|
-
});
|
|
35692
|
-
const scaleValue = result?.scaleItem?.scaleValue;
|
|
35693
|
-
return scaleAccessor && isObject(scaleValue) ? scaleValue[scaleAccessor] : scaleValue;
|
|
35694
|
-
}
|
|
35695
|
-
function getAdHocRatings(params) {
|
|
35696
|
-
const { tournamentRecord, participantIds, scaleAccessor, scaleName, eventType, adHocRatings = {} } = params;
|
|
35697
|
-
const tournamentParticipants = tournamentRecord.participants ?? [];
|
|
35698
|
-
for (const participantId of participantIds ?? []) {
|
|
35699
|
-
const participant = tournamentParticipants?.find((participant) => participant.participantId === participantId);
|
|
35700
|
-
let scaleValue = getScaleValue({
|
|
35701
|
-
scaleName: `${scaleName}.${DYNAMIC}`,
|
|
35702
|
-
scaleAccessor,
|
|
35703
|
-
participant,
|
|
35704
|
-
eventType,
|
|
35705
|
-
});
|
|
35706
|
-
if (!scaleValue && scaleName) {
|
|
35707
|
-
scaleValue = getScaleValue({
|
|
35708
|
-
scaleAccessor,
|
|
35709
|
-
participant,
|
|
35710
|
-
scaleName,
|
|
35711
|
-
eventType,
|
|
35712
|
-
});
|
|
35713
|
-
}
|
|
35714
|
-
if (scaleValue && !adHocRatings[participantId])
|
|
35715
|
-
adHocRatings[participantId] = scaleValue;
|
|
35716
|
-
}
|
|
35717
|
-
return adHocRatings;
|
|
35718
|
-
}
|
|
35719
|
-
function getStructure(params) {
|
|
36273
|
+
function getAdHocStructure(params) {
|
|
35720
36274
|
if (params.structureId)
|
|
35721
36275
|
return params.structureId;
|
|
35722
36276
|
const drawDefinition = params.drawDefinition;
|
|
@@ -35784,17 +36338,18 @@ function generateAdHoc(params) {
|
|
|
35784
36338
|
return { ...SUCCESS };
|
|
35785
36339
|
}
|
|
35786
36340
|
function automateAdHoc(params) {
|
|
35787
|
-
const { restrictEntryStatus, generateMatchUps, structureId, matchUpIds, scaleName } = params.drawMatic ?? {};
|
|
36341
|
+
const { restrictEntryStatus, generateMatchUps, structureId, matchUpIds, scaleName, scaleAccessor } = params.drawMatic ?? {};
|
|
35788
36342
|
const result = drawMatic({
|
|
35789
36343
|
...params,
|
|
35790
36344
|
eventType: params.drawMatic?.eventType ?? params.matchUpType,
|
|
35791
36345
|
generateMatchUps: generateMatchUps ?? true,
|
|
36346
|
+
scaleAccessor: scaleAccessor ?? params.scaleAccessor,
|
|
36347
|
+
scaleName: scaleName ?? params.scaleName,
|
|
35792
36348
|
participantIds: params.participantIds,
|
|
35793
36349
|
roundsCount: params.roundsCount,
|
|
35794
36350
|
restrictEntryStatus,
|
|
35795
36351
|
structureId,
|
|
35796
36352
|
matchUpIds,
|
|
35797
|
-
scaleName,
|
|
35798
36353
|
});
|
|
35799
36354
|
if (result.error)
|
|
35800
36355
|
return result;
|
|
@@ -36706,6 +37261,8 @@ var index$e = {
|
|
|
36706
37261
|
setPositionAssignments: setPositionAssignments,
|
|
36707
37262
|
setStructureOrder: setStructureOrder,
|
|
36708
37263
|
setSubOrder: setSubOrder,
|
|
37264
|
+
shiftAdHocRounds: shiftAdHocRounds,
|
|
37265
|
+
swapAdHocRounds: swapAdHocRounds,
|
|
36709
37266
|
swapDrawPositionAssignments: swapDrawPositionAssignments,
|
|
36710
37267
|
updateTeamLineUp: updateTeamLineUp,
|
|
36711
37268
|
withdrawParticipantAtDrawPosition: withdrawParticipantAtDrawPosition
|
|
@@ -47172,169 +47729,6 @@ function getStageParticipants({ allUniqueParticipantIds, stageParticipantsCount,
|
|
|
47172
47729
|
return { stageParticipants };
|
|
47173
47730
|
}
|
|
47174
47731
|
|
|
47175
|
-
function setParticipantScaleItem(params) {
|
|
47176
|
-
const { removePriorValues, tournamentRecord, participantId, scaleItem } = params;
|
|
47177
|
-
let equivalentValue, participant;
|
|
47178
|
-
if (!isValidScaleItem({ scaleItem }))
|
|
47179
|
-
return { error: INVALID_SCALE_ITEM };
|
|
47180
|
-
if (participantId && Array.isArray(tournamentRecord.participants)) {
|
|
47181
|
-
participant = tournamentRecord.participants.find((participant) => participant.participantId === participantId);
|
|
47182
|
-
if (participant) {
|
|
47183
|
-
const result = addParticipantScaleItem({
|
|
47184
|
-
removePriorValues,
|
|
47185
|
-
participant,
|
|
47186
|
-
scaleItem,
|
|
47187
|
-
});
|
|
47188
|
-
if (result.error)
|
|
47189
|
-
return result;
|
|
47190
|
-
equivalentValue = !result.valueChanged;
|
|
47191
|
-
const { topics } = getTopics();
|
|
47192
|
-
if (topics.includes(MODIFY_PARTICIPANTS)) {
|
|
47193
|
-
addNotice({
|
|
47194
|
-
topic: MODIFY_PARTICIPANTS,
|
|
47195
|
-
payload: {
|
|
47196
|
-
tournamentId: tournamentRecord.tournamentId,
|
|
47197
|
-
participants: [participant],
|
|
47198
|
-
},
|
|
47199
|
-
});
|
|
47200
|
-
}
|
|
47201
|
-
}
|
|
47202
|
-
}
|
|
47203
|
-
return ((equivalentValue && {
|
|
47204
|
-
...SUCCESS,
|
|
47205
|
-
info: VALUE_UNCHANGED,
|
|
47206
|
-
existingValue: scaleItem?.scaleValue,
|
|
47207
|
-
}) ||
|
|
47208
|
-
(participant && { ...SUCCESS, newValue: scaleItem?.scaleValue }) || {
|
|
47209
|
-
error: PARTICIPANT_NOT_FOUND,
|
|
47210
|
-
});
|
|
47211
|
-
}
|
|
47212
|
-
function setParticipantScaleItems(params) {
|
|
47213
|
-
const { scaleItemsWithParticipantIds = [], removePriorValues, tournamentRecord, auditData, context } = params;
|
|
47214
|
-
if (!tournamentRecord)
|
|
47215
|
-
return { error: MISSING_TOURNAMENT_RECORD };
|
|
47216
|
-
if (!tournamentRecord.participants)
|
|
47217
|
-
return { error: MISSING_PARTICIPANTS };
|
|
47218
|
-
let modificationsApplied = 0;
|
|
47219
|
-
const participantScaleItemsMap = {};
|
|
47220
|
-
const modifiedParticipants = [];
|
|
47221
|
-
for (const item of scaleItemsWithParticipantIds) {
|
|
47222
|
-
const participantId = item?.participantId;
|
|
47223
|
-
if (Array.isArray(item?.scaleItems)) {
|
|
47224
|
-
for (const scaleItem of item.scaleItems) {
|
|
47225
|
-
if (isValidScaleItem({ scaleItem })) {
|
|
47226
|
-
if (!Array.isArray(participantScaleItemsMap[participantId])) {
|
|
47227
|
-
participantScaleItemsMap[participantId] = [];
|
|
47228
|
-
}
|
|
47229
|
-
participantScaleItemsMap[participantId].push(scaleItem);
|
|
47230
|
-
}
|
|
47231
|
-
else {
|
|
47232
|
-
return { error: INVALID_SCALE_ITEM };
|
|
47233
|
-
}
|
|
47234
|
-
}
|
|
47235
|
-
}
|
|
47236
|
-
}
|
|
47237
|
-
tournamentRecord.participants.forEach((participant) => {
|
|
47238
|
-
const { participantId } = participant || {};
|
|
47239
|
-
if (Array.isArray(participantScaleItemsMap[participantId])) {
|
|
47240
|
-
participantScaleItemsMap[participantId].forEach((scaleItem) => {
|
|
47241
|
-
addParticipantScaleItem({ participant, scaleItem, removePriorValues });
|
|
47242
|
-
modifiedParticipants.push(participant);
|
|
47243
|
-
modificationsApplied++;
|
|
47244
|
-
});
|
|
47245
|
-
}
|
|
47246
|
-
});
|
|
47247
|
-
const info = !modificationsApplied ? NO_MODIFICATIONS_APPLIED : undefined;
|
|
47248
|
-
const { topics } = getTopics();
|
|
47249
|
-
if (topics.includes(MODIFY_PARTICIPANTS) && modificationsApplied) {
|
|
47250
|
-
addNotice({
|
|
47251
|
-
topic: MODIFY_PARTICIPANTS,
|
|
47252
|
-
payload: {
|
|
47253
|
-
tournamentId: tournamentRecord.tournamentId,
|
|
47254
|
-
participants: modifiedParticipants,
|
|
47255
|
-
},
|
|
47256
|
-
});
|
|
47257
|
-
}
|
|
47258
|
-
if (context) {
|
|
47259
|
-
const { eventId, drawId, ...itemValue } = context;
|
|
47260
|
-
const itemSubTypes = itemValue.scaleAttributes?.scaleType && [itemValue.scaleAttributes.scaleType];
|
|
47261
|
-
if (Object.keys(itemValue).length) {
|
|
47262
|
-
const timeItem = {
|
|
47263
|
-
itemType: ADD_SCALE_ITEMS,
|
|
47264
|
-
itemValue,
|
|
47265
|
-
};
|
|
47266
|
-
if (itemSubTypes)
|
|
47267
|
-
timeItem.itemSubTypes = itemSubTypes;
|
|
47268
|
-
if (drawId || eventId) {
|
|
47269
|
-
const { drawDefinition, event } = findEvent({
|
|
47270
|
-
tournamentRecord,
|
|
47271
|
-
eventId,
|
|
47272
|
-
drawId,
|
|
47273
|
-
});
|
|
47274
|
-
if (drawId) {
|
|
47275
|
-
addDrawDefinitionTimeItem({ drawDefinition, timeItem });
|
|
47276
|
-
}
|
|
47277
|
-
if (eventId) {
|
|
47278
|
-
addEventTimeItem({ event, timeItem });
|
|
47279
|
-
}
|
|
47280
|
-
}
|
|
47281
|
-
else {
|
|
47282
|
-
addTournamentTimeItem({ tournamentRecord, timeItem });
|
|
47283
|
-
}
|
|
47284
|
-
}
|
|
47285
|
-
}
|
|
47286
|
-
if (auditData && topics.includes(AUDIT)) {
|
|
47287
|
-
addNotice({ topic: AUDIT, payload: auditData });
|
|
47288
|
-
}
|
|
47289
|
-
return definedAttributes({ ...SUCCESS, modificationsApplied, info });
|
|
47290
|
-
}
|
|
47291
|
-
function isValidScaleItem({ scaleItem }) {
|
|
47292
|
-
const scaleItemAttributes = scaleItem && Object.keys(scaleItem);
|
|
47293
|
-
const requiredAttributes = ['scaleType', 'eventType', 'scaleName'];
|
|
47294
|
-
const validScaleItem = requiredAttributes.filter((attribute) => scaleItemAttributes?.includes(attribute)).length ===
|
|
47295
|
-
requiredAttributes.length;
|
|
47296
|
-
return !!validScaleItem;
|
|
47297
|
-
}
|
|
47298
|
-
function addParticipantScaleItem({ removePriorValues, participant, scaleItem }) {
|
|
47299
|
-
if (!participant) {
|
|
47300
|
-
return { error: MISSING_PARTICIPANT };
|
|
47301
|
-
}
|
|
47302
|
-
const scaleItemAttributes = scaleItem && Object.keys(scaleItem);
|
|
47303
|
-
const requiredAttributes = ['scaleType', 'eventType', 'scaleName'];
|
|
47304
|
-
const validScaleItem = requiredAttributes.filter((attribute) => scaleItemAttributes.includes(attribute) && scaleItem[attribute]).length ===
|
|
47305
|
-
requiredAttributes.length;
|
|
47306
|
-
if (!validScaleItem)
|
|
47307
|
-
return { error: INVALID_SCALE_ITEM };
|
|
47308
|
-
const createdAt = new Date().toISOString();
|
|
47309
|
-
if (!participant.timeItems)
|
|
47310
|
-
participant.timeItems = [];
|
|
47311
|
-
const { scaleItem: existingScaleItem } = participantScaleItem({
|
|
47312
|
-
scaleAttributes: scaleItem,
|
|
47313
|
-
participant,
|
|
47314
|
-
});
|
|
47315
|
-
const isUndefined = (value) => [undefined, null, ''].includes(value);
|
|
47316
|
-
const valueChanged = !(isUndefined(existingScaleItem?.scaleValue) && isUndefined(scaleItem.scaleValue)) &&
|
|
47317
|
-
JSON.stringify(existingScaleItem?.scaleValue) !== JSON.stringify(scaleItem.scaleValue);
|
|
47318
|
-
if (valueChanged) {
|
|
47319
|
-
const { scaleType, eventType, scaleName } = scaleItem;
|
|
47320
|
-
const itemType = [SCALE$1, scaleType, eventType, scaleName].join('.');
|
|
47321
|
-
const timeItem = definedAttributes({
|
|
47322
|
-
itemValue: scaleItem.scaleValue,
|
|
47323
|
-
itemDate: scaleItem.scaleDate,
|
|
47324
|
-
createdAt,
|
|
47325
|
-
itemType,
|
|
47326
|
-
});
|
|
47327
|
-
if (scaleItem.scaleId) {
|
|
47328
|
-
timeItem.itemSubTypes = [scaleItem.scaleId];
|
|
47329
|
-
}
|
|
47330
|
-
if (removePriorValues) {
|
|
47331
|
-
participant.timeItems = participant.timeItems.filter((timeItem) => timeItem.itemType !== itemType);
|
|
47332
|
-
}
|
|
47333
|
-
participant.timeItems.push(timeItem);
|
|
47334
|
-
}
|
|
47335
|
-
return { ...SUCCESS, valueChanged, newValue: scaleItem.scaleValue };
|
|
47336
|
-
}
|
|
47337
|
-
|
|
47338
47732
|
const defaultStatusProfile = {
|
|
47339
47733
|
[WALKOVER$2]: 2,
|
|
47340
47734
|
[DOUBLE_WALKOVER]: 1,
|
|
@@ -55652,7 +56046,7 @@ function JSON2CSV(arrayOfJSON, config) {
|
|
|
55652
56046
|
context?.[columnName] ||
|
|
55653
56047
|
'';
|
|
55654
56048
|
const mappedValue = valuesMap[columnName]?.[value] || value;
|
|
55655
|
-
const fxValue =
|
|
56049
|
+
const fxValue = isFunction(functionMap[columnName]) ? functionMap[columnName](mappedValue) : mappedValue;
|
|
55656
56050
|
columnsMap[columnName] = withDelimiter(fxValue);
|
|
55657
56051
|
if (fxValue) {
|
|
55658
56052
|
columnValueCounts[columnIndex] = (columnValueCounts[columnIndex] || 0) + 1;
|
|
@@ -56791,226 +57185,6 @@ const rankingsGovernor = {
|
|
|
56791
57185
|
getTournamentPoints,
|
|
56792
57186
|
};
|
|
56793
57187
|
|
|
56794
|
-
const k538 = (countables) => 250 / Math.pow(countables + 5, 0.4);
|
|
56795
|
-
const kDefault = () => 1;
|
|
56796
|
-
function kSet(maxCountables = 3, counted = 2) {
|
|
56797
|
-
const kset = maxCountables / counted;
|
|
56798
|
-
return isNaN(kset) ? eloConfig.kDefault() : kset;
|
|
56799
|
-
}
|
|
56800
|
-
const eloConfig = {
|
|
56801
|
-
nSpread: 400,
|
|
56802
|
-
diffThreshold: 0.125,
|
|
56803
|
-
kCalc: k538,
|
|
56804
|
-
kMultiplier: kSet,
|
|
56805
|
-
kDefault,
|
|
56806
|
-
};
|
|
56807
|
-
function calculateNewRatings(params) {
|
|
56808
|
-
let { winnerRating, loserRating, ratingRange } = params;
|
|
56809
|
-
const { ratings = ratingsParameters, winnerCountables = 1, loserCountables = 0, ratingType = ELO, maxCountables, countables, } = params || {};
|
|
56810
|
-
const ratingParameters = ratings?.[ratingType];
|
|
56811
|
-
if (!ratingParameters)
|
|
56812
|
-
return { error: MISSING_VALUE };
|
|
56813
|
-
ratingRange = ratingParameters.range || ratingRange;
|
|
56814
|
-
winnerRating = winnerRating || ratingParameters.defaultInitialization;
|
|
56815
|
-
loserRating = loserRating || ratingParameters.defaultInitialization;
|
|
56816
|
-
const invertedScale = ratingRange[0] > ratingRange[1];
|
|
56817
|
-
const decimalPlaces = ratingParameters.decimalsCount || 0;
|
|
56818
|
-
const consideredRange = invertedScale ? ratingRange.slice().reverse() : ratingRange;
|
|
56819
|
-
const inRange = (range, value) => parseFloat(value) >= Math.min(...range) && parseFloat(value) <= Math.max(...range);
|
|
56820
|
-
if (!inRange(ratingRange, winnerRating) || !inRange(ratingRange, loserRating)) {
|
|
56821
|
-
if (!inRange(ratingRange, winnerRating))
|
|
56822
|
-
winnerRating = ratingParameters.defaultInitialization;
|
|
56823
|
-
if (!inRange(ratingRange, loserRating))
|
|
56824
|
-
loserRating = ratingParameters.defaultInitialization;
|
|
56825
|
-
}
|
|
56826
|
-
const convertRange = ({ value, sourceRange, targetRange }) => ((value - sourceRange[0]) * (targetRange[1] - targetRange[0])) / (sourceRange[1] - sourceRange[0]) + targetRange[0];
|
|
56827
|
-
const convertedWinnerRating = convertRange({
|
|
56828
|
-
targetRange: ratingsParameters[ELO].range,
|
|
56829
|
-
sourceRange: consideredRange,
|
|
56830
|
-
value: invertedScale ? ratingRange[0] - winnerRating : winnerRating,
|
|
56831
|
-
});
|
|
56832
|
-
const convertedLoserRating = convertRange({
|
|
56833
|
-
targetRange: ratingsParameters[ELO].range,
|
|
56834
|
-
sourceRange: consideredRange,
|
|
56835
|
-
value: invertedScale ? ratingRange[0] - loserRating : loserRating,
|
|
56836
|
-
});
|
|
56837
|
-
const getExpectation = (playerRating, opponentRating) => 1 / (1 + Math.pow(10, (opponentRating - playerRating) / eloConfig.nSpread));
|
|
56838
|
-
const winnerExpectation = getExpectation(convertedWinnerRating, convertedLoserRating);
|
|
56839
|
-
const loserExpectation = getExpectation(convertedLoserRating, convertedWinnerRating);
|
|
56840
|
-
const winnerKValue = eloConfig.kCalc(winnerCountables);
|
|
56841
|
-
const loserKValue = eloConfig.kCalc(loserCountables);
|
|
56842
|
-
const k = eloConfig.kMultiplier(maxCountables, countables);
|
|
56843
|
-
const winnerUpdatedConvertedRating = convertedWinnerRating + k * winnerKValue * (1 - winnerExpectation);
|
|
56844
|
-
const loserUpdatedConvertedRating = convertedLoserRating + k * loserKValue * (0 - loserExpectation);
|
|
56845
|
-
const convertedUpdatedWinnerRating = convertRange({
|
|
56846
|
-
sourceRange: ratingsParameters[ELO].range,
|
|
56847
|
-
value: winnerUpdatedConvertedRating,
|
|
56848
|
-
targetRange: consideredRange,
|
|
56849
|
-
});
|
|
56850
|
-
const convertedUpdatedLoserRating = convertRange({
|
|
56851
|
-
sourceRange: ratingsParameters[ELO].range,
|
|
56852
|
-
value: loserUpdatedConvertedRating,
|
|
56853
|
-
targetRange: consideredRange,
|
|
56854
|
-
});
|
|
56855
|
-
const updatedWinnerRating = invertedScale
|
|
56856
|
-
? ratingRange[0] - convertedUpdatedWinnerRating
|
|
56857
|
-
: convertedUpdatedWinnerRating;
|
|
56858
|
-
let newWinnerRating = parseFloat(parseFloat(updatedWinnerRating).toFixed(decimalPlaces));
|
|
56859
|
-
const updatedLoserRating = invertedScale ? ratingRange[0] - convertedUpdatedLoserRating : convertedUpdatedLoserRating;
|
|
56860
|
-
let newLoserRating = parseFloat(parseFloat(updatedLoserRating).toFixed(decimalPlaces));
|
|
56861
|
-
const percentageDifference = Math.max(...ratingRange)
|
|
56862
|
-
? Math.abs(winnerRating - loserRating) / Math.max(...ratingRange)
|
|
56863
|
-
: 0;
|
|
56864
|
-
if ((convertedUpdatedWinnerRating > convertedUpdatedLoserRating && percentageDifference > eloConfig.diffThreshold) ||
|
|
56865
|
-
newWinnerRating < 0 ||
|
|
56866
|
-
newLoserRating < 0) {
|
|
56867
|
-
newWinnerRating = winnerRating;
|
|
56868
|
-
newLoserRating = loserRating;
|
|
56869
|
-
}
|
|
56870
|
-
return { newWinnerRating, newLoserRating };
|
|
56871
|
-
}
|
|
56872
|
-
|
|
56873
|
-
const aggregateSets = (sets) => {
|
|
56874
|
-
return (sets?.reduce((aggregate, set) => {
|
|
56875
|
-
if (set.winningSide)
|
|
56876
|
-
aggregate[set.winningSide - 1] += 1;
|
|
56877
|
-
return aggregate;
|
|
56878
|
-
}, [0, 0]) || [0, 0]);
|
|
56879
|
-
};
|
|
56880
|
-
|
|
56881
|
-
function generateDynamicRatings({ removePriorValues = true, tournamentRecord, ratingType = ELO, considerGames, matchUpIds, asDynamic, }) {
|
|
56882
|
-
if (!tournamentRecord)
|
|
56883
|
-
return { error: MISSING_TOURNAMENT_RECORD };
|
|
56884
|
-
if (!Array.isArray(matchUpIds))
|
|
56885
|
-
return { error: MISSING_MATCHUPS };
|
|
56886
|
-
if (typeof ratingType !== 'string')
|
|
56887
|
-
return { error: INVALID_VALUES, ratingType };
|
|
56888
|
-
if (!ratingsParameters[ratingType])
|
|
56889
|
-
return { error: INVALID_VALUES };
|
|
56890
|
-
const ratingParameter = ratingsParameters[ratingType];
|
|
56891
|
-
const { accessor } = ratingParameter;
|
|
56892
|
-
const modifiedScaleValues = {};
|
|
56893
|
-
const matchUps = allTournamentMatchUps({
|
|
56894
|
-
matchUpFilters: { matchUpIds, matchUpStatuses: completedMatchUpStatuses },
|
|
56895
|
-
tournamentRecord,
|
|
56896
|
-
inContext: true,
|
|
56897
|
-
}).matchUps ?? [];
|
|
56898
|
-
matchUps.sort(matchUpSort);
|
|
56899
|
-
for (const matchUp of matchUps) {
|
|
56900
|
-
const { endDate, matchUpFormat, score, sides, winningSide } = matchUp;
|
|
56901
|
-
const matchUpType = matchUp.matchUpType;
|
|
56902
|
-
const scaleAttributes = {
|
|
56903
|
-
eventType: matchUpType,
|
|
56904
|
-
scaleName: ratingType,
|
|
56905
|
-
scaleType: RATING$1,
|
|
56906
|
-
};
|
|
56907
|
-
const dynamicScaleName = `${ratingType}.${DYNAMIC}`;
|
|
56908
|
-
const dynamicScaleAttributes = {
|
|
56909
|
-
scaleName: dynamicScaleName,
|
|
56910
|
-
eventType: matchUpType,
|
|
56911
|
-
scaleType: RATING$1,
|
|
56912
|
-
};
|
|
56913
|
-
const sideParticipantIds = Object.assign({}, ...(sides ?? []).map((side) => {
|
|
56914
|
-
const { sideNumber, participant } = side;
|
|
56915
|
-
return (sideNumber && {
|
|
56916
|
-
[sideNumber]: [participant?.participantId, ...(participant?.individualParticipantIds ?? [])]
|
|
56917
|
-
.filter(Boolean)
|
|
56918
|
-
.flat(),
|
|
56919
|
-
});
|
|
56920
|
-
}));
|
|
56921
|
-
const outputScaleName = asDynamic ? dynamicScaleName : ratingType;
|
|
56922
|
-
const scaleItemMap = Object.assign({}, ...Object.values(sideParticipantIds)
|
|
56923
|
-
.flat()
|
|
56924
|
-
.map((participantId) => {
|
|
56925
|
-
const { scaleItem: dynamicScaleItem } = getParticipantScaleItem({
|
|
56926
|
-
scaleAttributes: dynamicScaleAttributes,
|
|
56927
|
-
tournamentRecord,
|
|
56928
|
-
participantId,
|
|
56929
|
-
});
|
|
56930
|
-
const { scaleItem } = getParticipantScaleItem({
|
|
56931
|
-
tournamentRecord,
|
|
56932
|
-
scaleAttributes,
|
|
56933
|
-
participantId,
|
|
56934
|
-
});
|
|
56935
|
-
const scaleValue = accessor ? { [accessor]: undefined } : undefined;
|
|
56936
|
-
return (participantId && {
|
|
56937
|
-
[participantId]: dynamicScaleItem ??
|
|
56938
|
-
scaleItem ?? {
|
|
56939
|
-
scaleName: outputScaleName,
|
|
56940
|
-
eventType: matchUpType,
|
|
56941
|
-
scaleDate: endDate,
|
|
56942
|
-
scaleType: RATING$1,
|
|
56943
|
-
scaleValue,
|
|
56944
|
-
},
|
|
56945
|
-
});
|
|
56946
|
-
}));
|
|
56947
|
-
const parsedFormat = matchUpFormat ? parse(matchUpFormat) : {};
|
|
56948
|
-
const bestOf = parsedFormat?.bestOf || 1;
|
|
56949
|
-
const setsTo = parsedFormat?.setsTo || 1;
|
|
56950
|
-
const maxCountables = considerGames ? bestOf & setsTo : bestOf;
|
|
56951
|
-
const countables = (score?.sets && aggregateSets(score.sets)) || (winningSide === 1 && [1, 0]) || [0, 1];
|
|
56952
|
-
const winningSideParticipantIds = winningSide ? sideParticipantIds[winningSide] : [];
|
|
56953
|
-
const losingSideParticipantIds = winningSide ? sideParticipantIds[3 - winningSide] : [];
|
|
56954
|
-
for (const winnerParticipantId of winningSideParticipantIds) {
|
|
56955
|
-
const winnerScaleValue = scaleItemMap[winnerParticipantId]?.scaleValue;
|
|
56956
|
-
const winnerRating = typeof winnerScaleValue === 'object' ? winnerScaleValue[accessor] : winnerScaleValue;
|
|
56957
|
-
for (const loserParticipantId of losingSideParticipantIds) {
|
|
56958
|
-
const loserScaleValue = scaleItemMap[loserParticipantId]?.scaleValue;
|
|
56959
|
-
const loserRating = typeof loserScaleValue === 'object' ? loserScaleValue[accessor] : loserScaleValue;
|
|
56960
|
-
const winnerCountables = winningSide ? countables[winningSide] : [0, 0];
|
|
56961
|
-
const loserCountables = winningSide ? countables[3 - winningSide] : [0, 0];
|
|
56962
|
-
const { newWinnerRating, newLoserRating } = calculateNewRatings({
|
|
56963
|
-
winnerCountables,
|
|
56964
|
-
loserCountables,
|
|
56965
|
-
maxCountables,
|
|
56966
|
-
winnerRating,
|
|
56967
|
-
loserRating,
|
|
56968
|
-
ratingType,
|
|
56969
|
-
});
|
|
56970
|
-
const newWinnerScaleValue = accessor
|
|
56971
|
-
? {
|
|
56972
|
-
...winnerScaleValue,
|
|
56973
|
-
[accessor]: newWinnerRating,
|
|
56974
|
-
}
|
|
56975
|
-
: newWinnerRating;
|
|
56976
|
-
const newLoserScaleValue = accessor
|
|
56977
|
-
? {
|
|
56978
|
-
...loserScaleValue,
|
|
56979
|
-
[accessor]: newLoserRating,
|
|
56980
|
-
}
|
|
56981
|
-
: newLoserRating;
|
|
56982
|
-
scaleItemMap[winnerParticipantId].scaleValue = newWinnerScaleValue;
|
|
56983
|
-
scaleItemMap[loserParticipantId].scaleValue = newLoserScaleValue;
|
|
56984
|
-
let result = setParticipantScaleItem({
|
|
56985
|
-
participantId: winnerParticipantId,
|
|
56986
|
-
removePriorValues,
|
|
56987
|
-
tournamentRecord,
|
|
56988
|
-
scaleItem: {
|
|
56989
|
-
...scaleItemMap[winnerParticipantId],
|
|
56990
|
-
scaleName: outputScaleName,
|
|
56991
|
-
},
|
|
56992
|
-
});
|
|
56993
|
-
if (result.error)
|
|
56994
|
-
return result;
|
|
56995
|
-
result = setParticipantScaleItem({
|
|
56996
|
-
participantId: loserParticipantId,
|
|
56997
|
-
removePriorValues,
|
|
56998
|
-
tournamentRecord,
|
|
56999
|
-
scaleItem: {
|
|
57000
|
-
...scaleItemMap[loserParticipantId],
|
|
57001
|
-
scaleName: outputScaleName,
|
|
57002
|
-
},
|
|
57003
|
-
});
|
|
57004
|
-
if (result.error)
|
|
57005
|
-
return result;
|
|
57006
|
-
}
|
|
57007
|
-
}
|
|
57008
|
-
Object.assign(modifiedScaleValues, scaleItemMap);
|
|
57009
|
-
}
|
|
57010
|
-
const processedMatchUpIds = matchUps.map(({ matchUpId }) => matchUpId);
|
|
57011
|
-
return { ...SUCCESS, modifiedScaleValues, processedMatchUpIds };
|
|
57012
|
-
}
|
|
57013
|
-
|
|
57014
57188
|
const governor = {
|
|
57015
57189
|
calculateNewRatings,
|
|
57016
57190
|
generateDynamicRatings,
|