overtime-utils 0.2.46 → 0.2.47

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.
@@ -1,526 +1,528 @@
1
- import {
2
- AWAY_TEAM_MARKET_TYPES,
3
- AWAY_TEAM_TOTAL_MARKET_TYPES,
4
- BASKETBALL_MARKET_TYPES,
5
- BOTH_TEAMS_TO_SCORE_MARKET_TYPES,
6
- CARDS_MARKET_TYPES,
7
- COMBINED_POSITIONS_MARKET_TYPES,
8
- CORNERS_MARKET_TYPES,
9
- CORRECT_SCORE_MARKET_TYPES,
10
- CRICKET_MARKET_TYPES,
11
- DARTS_MARKET_TYPES,
12
- DOUBLE_CHANCE_MARKET_TYPES,
13
- EIGHTH_PERIOD_MARKET_TYPES,
14
- ESPORTS_MARKET_TYPES,
15
- FIFTH_PERIOD_MARKET_TYPES,
16
- FIRST_FIVE_INNINGS_MARKET_TYPES,
17
- FIRST_PERIOD_MARKET_TYPES,
18
- FIRST_PERIOD_MARKET_TYPES2,
19
- FIRST_SEVEN_INNINGS_MARKET_TYPES,
20
- FIRST_THREE_INNINGS_MARKET_TYPES,
21
- FOOTBALL_MARKET_TYPES,
22
- FOURTH_PERIOD_MARKET_TYPES,
23
- FUTURES_MARKET_TYPES,
24
- HALFTIME_FULLTIME_MARKET_TYPES,
25
- HIGHEST_SCORING_HALF_MARKET_TYPES,
26
- HOME_TEAM_MARKET_TYPES,
27
- HOME_TEAM_TOTAL_MARKET_TYPES,
28
- NINTH_PERIOD_MARKET_TYPES,
29
- ONE_SIDE_EXTENDED_PLAYER_PROPS_MARKET_TYPES,
30
- ONE_SIDE_PLAYER_PROPS_MARKET_TYPES,
31
- OTHER_YES_NO_MARKET_TYPES,
32
- PERIOD_MARKET_TYPES,
33
- PLAYER_PROPS_MARKET_TYPES,
34
- RACE_TO_MARKET_TYPES,
35
- SCORE_MARKET_TYPES,
36
- SECOND_PERIOD_MARKET_TYPES,
37
- SECOND_PERIOD_MARKET_TYPES2,
38
- SEVENTH_PERIOD_MARKET_TYPES,
39
- SGP_BUILDER_MARKET_TYPES,
40
- SGP_NOT_SUPPORTED_MARKET_TYPES,
41
- SIXTH_PERIOD_MARKET_TYPES,
42
- SOCCER_METHOD_OF_VICTORY_MARKET_TYPES,
43
- SOCCER_SPECIFIC_MARKET_TYPES,
44
- SOCCER_TOTAL_MARKET_TYPES,
45
- SPREAD_MARKET_TYPES,
46
- THIRD_PERIOD_MARKET_TYPES,
47
- TOTAL_EXACT_MARKET_TYPES,
48
- TOTAL_MARKET_TYPES,
49
- TOTAL_ODD_EVEN_MARKET_TYPES,
50
- UFC_ENDING_METHOD_MARKET_TYPES,
51
- UFC_METHOD_OF_VICTORY_MARKET_TYPES,
52
- UFC_SPECIFIC_MARKET_TYPES,
53
- UFC_WINNING_ROUND_MARKET_TYPES,
54
- WINNER_MARKET_TYPES,
55
- YES_NO_PLAYER_PROPS_MARKET_TYPES,
56
- } from '../constants/marketTypes';
57
- import { MarketType } from '../enums/marketTypes';
58
- import { League, Sport } from '../enums/sports';
59
- import { SgpBlocker, SgpBlockerMarket } from '../types/sgp';
60
- import { getLeagueSport } from './sports';
61
-
62
- export const isWinnerMarket = (marketType: MarketType) => WINNER_MARKET_TYPES.includes(marketType);
63
-
64
- export const isTotalMarket = (marketType: MarketType) => TOTAL_MARKET_TYPES.includes(marketType);
65
- export const isHomeTeamTotalMarket = (marketType: MarketType) => HOME_TEAM_TOTAL_MARKET_TYPES.includes(marketType);
66
- export const isAwayTeamTotalMarket = (marketType: MarketType) => AWAY_TEAM_TOTAL_MARKET_TYPES.includes(marketType);
67
- export const isTotalOddEvenMarket = (marketType: MarketType) => TOTAL_ODD_EVEN_MARKET_TYPES.includes(marketType);
68
- export const isTotalExactMarket = (marketType: MarketType) => TOTAL_EXACT_MARKET_TYPES.includes(marketType);
69
-
70
- export const isSpreadMarket = (marketType: MarketType) => SPREAD_MARKET_TYPES.includes(marketType);
71
-
72
- export const isPlayerPropsMarket = (marketType: MarketType) => PLAYER_PROPS_MARKET_TYPES.includes(marketType);
73
-
74
- export const isCombinedPositionsMarket = (marketType: MarketType) =>
75
- COMBINED_POSITIONS_MARKET_TYPES.includes(marketType);
76
-
77
- export const isHalftimeFulltimeMarket = (marketType: MarketType) => HALFTIME_FULLTIME_MARKET_TYPES.includes(marketType);
78
-
79
- export const isFuturesMarket = (marketType: MarketType) => FUTURES_MARKET_TYPES.includes(marketType);
80
-
81
- export const isOneSideMarket = (league: League, marketType: MarketType) =>
82
- getLeagueSport(league) === Sport.MOTOSPORT ||
83
- league == League.US_ELECTION ||
84
- marketType === MarketType.TO_MAKE_FINAL_FOUR;
85
-
86
- export const isOneSidePlayerPropsMarket = (marketType: MarketType) =>
87
- ONE_SIDE_PLAYER_PROPS_MARKET_TYPES.includes(marketType);
88
-
89
- export const isOneSideExtendedPlayerPropsMarket = (marketType: MarketType) =>
90
- ONE_SIDE_EXTENDED_PLAYER_PROPS_MARKET_TYPES.includes(marketType);
91
-
92
- export const isYesNoPlayerPropsMarket = (marketType: MarketType) =>
93
- YES_NO_PLAYER_PROPS_MARKET_TYPES.includes(marketType);
94
-
95
- export const isBothTeamsToScoreMarket = (marketType: MarketType) =>
96
- BOTH_TEAMS_TO_SCORE_MARKET_TYPES.includes(marketType);
97
-
98
- export const isOtherYesNoMarket = (marketType: MarketType) => OTHER_YES_NO_MARKET_TYPES.includes(marketType);
99
-
100
- export const isDoubleChanceMarket = (marketType: MarketType) => DOUBLE_CHANCE_MARKET_TYPES.includes(marketType);
101
-
102
- export const isCorrectScoreMarket = (marketType: MarketType) => CORRECT_SCORE_MARKET_TYPES.includes(marketType);
103
-
104
- export const isDrawAvailableMarket = (marketType: MarketType) =>
105
- WINNER_MARKET_TYPES.includes(marketType) ||
106
- SCORE_MARKET_TYPES.includes(marketType) ||
107
- RACE_TO_MARKET_TYPES.includes(marketType) ||
108
- HIGHEST_SCORING_HALF_MARKET_TYPES.includes(marketType);
109
-
110
- export const isPeriodMarket = (marketType: MarketType) => PERIOD_MARKET_TYPES.includes(marketType);
111
-
112
- export const isPeriod2Market = (marketType: MarketType) => {
113
- return (
114
- (marketType >= MarketType.FIRST_PERIOD_WINNER2 && marketType <= MarketType.NINTH_PERIOD_WINNER2) ||
115
- (marketType >= MarketType.FIRST_PERIOD_TOTAL2 && marketType <= MarketType.NINTH_PERIOD_TOTAL2) ||
116
- (marketType >= MarketType.FIRST_PERIOD_SPREAD2 && marketType <= MarketType.NINTH_PERIOD_SPREAD2) ||
117
- (marketType >= MarketType.FIRST_PERIOD_TOTAL2_ODD_EVEN &&
118
- marketType <= MarketType.NINTH_PERIOD_TOTAL2_ODD_EVEN) ||
119
- FIRST_PERIOD_MARKET_TYPES2.includes(marketType) ||
120
- SECOND_PERIOD_MARKET_TYPES2.includes(marketType)
121
- );
122
- };
123
-
124
- export const isHomeTeamMarket = (marketType: MarketType) => HOME_TEAM_MARKET_TYPES.includes(marketType);
125
-
126
- export const isAwayTeamMarket = (marketType: MarketType) => AWAY_TEAM_MARKET_TYPES.includes(marketType);
127
-
128
- export const isScoreMarket = (marketType: MarketType) => SCORE_MARKET_TYPES.includes(marketType);
129
-
130
- export const isRaceToMarket = (marketType: MarketType) => RACE_TO_MARKET_TYPES.includes(marketType);
131
-
132
- export const isHighestScoringHalfMarket = (marketType: MarketType) =>
133
- HIGHEST_SCORING_HALF_MARKET_TYPES.includes(marketType);
134
-
135
- export const isOnlyOverPlayerPropsMarket = (marketType: MarketType, odds: number[]) =>
136
- isPlayerPropsMarket(marketType) && odds.length === 1;
137
-
138
- export const isUfcSpecificMarket = (marketType: MarketType) => UFC_SPECIFIC_MARKET_TYPES.includes(marketType);
139
- export const isUfcWinningMarket = (marketType: MarketType) => UFC_WINNING_ROUND_MARKET_TYPES.includes(marketType);
140
- export const isEndingUfcMarket = (marketType: MarketType) => UFC_ENDING_METHOD_MARKET_TYPES.includes(marketType);
141
- export const isUfcVictoryMarket = (marketType: MarketType) => UFC_METHOD_OF_VICTORY_MARKET_TYPES.includes(marketType);
142
-
143
- export const isSoccerSpecificMarket = (marketType: MarketType) => SOCCER_SPECIFIC_MARKET_TYPES.includes(marketType);
144
- export const isSoccerMethodOfVictoryMarket = (marketType: MarketType) => SOCCER_METHOD_OF_VICTORY_MARKET_TYPES.includes(marketType);
145
-
146
- export const isContractResultView = (marketType: MarketType) =>
147
- CORNERS_MARKET_TYPES.includes(marketType) ||
148
- CARDS_MARKET_TYPES.includes(marketType) ||
149
- CRICKET_MARKET_TYPES.includes(marketType) ||
150
- FOOTBALL_MARKET_TYPES.includes(marketType) ||
151
- DARTS_MARKET_TYPES.includes(marketType) ||
152
- BASKETBALL_MARKET_TYPES.includes(marketType) ||
153
- ESPORTS_MARKET_TYPES.includes(marketType) ||
154
- SOCCER_TOTAL_MARKET_TYPES.includes(marketType);
155
-
156
- export const isTotalOrSpreadWithWholeLine = (marketType: MarketType, line: number) =>
157
- (isTotalMarket(marketType) || isSpreadMarket(marketType)) && line % 1 === 0;
158
-
159
- // market: SportMarket
160
- export const isStalePausedMarket = (market: any, maxDelaySec = 300) =>
161
- market.isPaused && market.pausedAt && Date.now() - market.pausedAt >= maxDelaySec * 1000;
162
-
163
- export const isSgpBuilderMarket = (marketType: MarketType) => SGP_BUILDER_MARKET_TYPES.includes(marketType);
164
-
165
- export const isMarketNotSupportedForSgp = (marketType: MarketType) =>
166
- SGP_NOT_SUPPORTED_MARKET_TYPES.includes(marketType);
167
-
168
- /*
169
- Blocking rules for SGP markets combination:
170
-
171
- 0. Block if markets have same type id and player id, block two markets on the SGP in same direction (both over or both under)
172
- 1. Block halftime-fulltime combining with moneyline
173
- 2. Block same playerId and same typeId for points and PR or PRA combinations
174
- Block DD and Triple Double on a player with any other prop on that player
175
- Disalowed props combos (for same playerID > 0):
176
- - Triple double not allowed with any other prop
177
- - Double double not allowed with any other prop
178
- - PRA not allowed with PR, PA and points, rebounds or assist props
179
- - PR not allowed with points or rebounds
180
- - PA not allowed with points or assists
181
- 3. Block moneyline and spread on the same team
182
- Disalowed props for same position (player ID is 0):
183
- - Moneyline and Spread full time
184
- - Moneyline and Spread first period
185
- - Moneyline and Spread second period
186
- - Moneyline and Spread secondary first period ...
187
- - Both teams to score on football and over goals per team
188
- 4. Block moneyline with betting on each period individually on the same team
189
- (e.g. betting on a team to win each period and win moneyline, the first implied the other)
190
- 5. Block over points on each period and over on the whole game
191
- */
192
-
193
- const getBlockers = (sgpBlockers: SgpBlocker[], blockerGroup: number) =>
194
- sgpBlockers.filter((data) => data.blockerGroup === blockerGroup);
195
-
196
- const getBlocker = (sgpBlockers: SgpBlocker[], blockerGroup: number, blockerNumber: number) =>
197
- sgpBlockers.find((data) => data.blockerGroup === blockerGroup && data.blockerNumber === blockerNumber);
198
-
199
- const getBlockerMessage = (blockerGroup: number, blockerNumber: number) =>
200
- `Blocker group ${blockerGroup}, #${blockerNumber}`;
201
-
202
- // Rule #0
203
- const validateMarketsWithSameDirection = (markets: SgpBlockerMarket[], sgpBlockers: SgpBlocker[]) => {
204
- const BLOCKER_GROUP = 0;
205
-
206
- const blockers = getBlockers(sgpBlockers, BLOCKER_GROUP);
207
-
208
- let message = '';
209
-
210
- if (blockers.length) {
211
- const blockerNumber = 0;
212
- const blocker = getBlocker(blockers, BLOCKER_GROUP, blockerNumber);
213
-
214
- if (blocker && blocker.enabled) {
215
- for (let index = 0; index < markets.length; index++) {
216
- const market = markets[index];
217
-
218
- const sport = getLeagueSport(market.leagueId);
219
- const leagueId = market.leagueId;
220
- const typeId = market.typeId;
221
- const playerId = market.playerId;
222
- const position = market.position;
223
-
224
- const otherMarkets = markets.filter((_, i) => i !== index && markets[i].gameId === market.gameId);
225
- const isSameMarketDirection = otherMarkets.some(
226
- (otherMarket) =>
227
- (!blocker.sport || blocker.sport === sport) &&
228
- (!blocker.leagueId || blocker.leagueId === leagueId) &&
229
- otherMarket.typeId === typeId &&
230
- otherMarket.playerId === playerId &&
231
- otherMarket.position === position
232
- );
233
-
234
- if (isSameMarketDirection) {
235
- message =
236
- getBlocker(sgpBlockers, BLOCKER_GROUP, blockerNumber)?.message ||
237
- `Blocker group ${BLOCKER_GROUP}, #${blockerNumber}`;
238
- break;
239
- }
240
- }
241
- }
242
- }
243
-
244
- return message;
245
- };
246
-
247
- // Rule #1
248
- const validateSomeBlockerWithSomeCombined = (markets: SgpBlockerMarket[], sgpBlockers: SgpBlocker[]) => {
249
- const BLOCKER_GROUP = 1;
250
-
251
- const blockers = getBlockers(sgpBlockers, BLOCKER_GROUP);
252
-
253
- let message = '';
254
-
255
- for (let blockerIndex = 0; blockerIndex < blockers.length; blockerIndex++) {
256
- const blocker = getBlocker(blockers, BLOCKER_GROUP, blockerIndex);
257
-
258
- if (blocker && blocker.enabled) {
259
- for (let index = 0; index < markets.length; index++) {
260
- const market = markets[index];
261
- const otherMarkets = markets.filter((_, i) => i !== index && markets[i].gameId === market.gameId);
262
-
263
- const hasSomeBlocker =
264
- (!blocker.sport || blocker.sport === getLeagueSport(market.leagueId)) &&
265
- (!blocker.leagueId || blocker.leagueId === market.leagueId) &&
266
- blocker.blockerTypeIds.includes(market.typeId);
267
-
268
- if (hasSomeBlocker) {
269
- const hasSomeCombined = otherMarkets.some(
270
- (otherMarket) =>
271
- (!blocker.sport || blocker.sport === getLeagueSport(otherMarket.leagueId)) &&
272
- (!blocker.leagueId || blocker.leagueId === otherMarket.leagueId) &&
273
- blocker.combineWithTypeIds.includes(otherMarket.typeId)
274
- );
275
-
276
- if (hasSomeCombined) {
277
- message = blocker?.message || getBlockerMessage(BLOCKER_GROUP, blockerIndex);
278
- break;
279
- }
280
- }
281
- }
282
- }
283
- }
284
-
285
- return message;
286
- };
287
-
288
- // Rule #2
289
- const validatePlayerPropsCombinations = (markets: SgpBlockerMarket[], sgpBlockers: SgpBlocker[]) => {
290
- const BLOCKER_GROUP = 2;
291
-
292
- const blockers = getBlockers(sgpBlockers, BLOCKER_GROUP);
293
-
294
- let message = '';
295
-
296
- for (let blockerIndex = 0; blockerIndex < blockers.length; blockerIndex++) {
297
- const blocker = getBlocker(blockers, BLOCKER_GROUP, blockerIndex);
298
-
299
- if (blocker && blocker.enabled) {
300
- for (let marketIndex = 0; marketIndex < markets.length; marketIndex++) {
301
- const market = markets[marketIndex];
302
- const otherMarkets = markets.filter((_, i) => i !== marketIndex && markets[i].gameId === market.gameId);
303
-
304
- const hasBlockerTypeId =
305
- (!blocker.sport || blocker.sport === getLeagueSport(market.leagueId)) &&
306
- (!blocker.leagueId || blocker.leagueId === market.leagueId) &&
307
- blocker.blockerTypeIds.includes(market.typeId);
308
-
309
- if (hasBlockerTypeId) {
310
- const hasCombineWithTypeIds = otherMarkets.some(
311
- (otherMarket) =>
312
- (!blocker.combineWithTypeIds.length ||
313
- blocker.combineWithTypeIds.includes(otherMarket.typeId)) &&
314
- otherMarket.playerId > 0 &&
315
- otherMarket.playerId === market.playerId
316
- );
317
- if (hasCombineWithTypeIds) {
318
- message = blocker?.message || getBlockerMessage(BLOCKER_GROUP, blockerIndex);
319
- break;
320
- }
321
- }
322
- }
323
- }
324
- }
325
-
326
- return message;
327
- };
328
-
329
- // Rule #3
330
- const validateSomeBlockerWithSomeCombinedForSamePosition = (markets: SgpBlockerMarket[], sgpBlockers: SgpBlocker[]) => {
331
- const BLOCKER_GROUP = 3;
332
-
333
- const blockers = getBlockers(sgpBlockers, BLOCKER_GROUP);
334
-
335
- let message = '';
336
-
337
- for (let blockerIndex = 0; blockerIndex < blockers.length; blockerIndex++) {
338
- const blocker = getBlocker(blockers, BLOCKER_GROUP, blockerIndex);
339
-
340
- if (blocker && blocker.enabled) {
341
- for (let marketIndex = 0; marketIndex < markets.length; marketIndex++) {
342
- const market = markets[marketIndex];
343
- const otherMarkets = markets.filter((_, i) => i !== marketIndex && markets[i].gameId === market.gameId);
344
-
345
- const hasBlockerTypeId =
346
- (!blocker.sport || blocker.sport === getLeagueSport(market.leagueId)) &&
347
- (!blocker.leagueId || blocker.leagueId === market.leagueId) &&
348
- blocker.blockerTypeIds.includes(market.typeId);
349
-
350
- if (hasBlockerTypeId) {
351
- const hasCombineWithTypeIds = otherMarkets.some(
352
- (otherMarket) =>
353
- blocker.combineWithTypeIds.length &&
354
- blocker.combineWithTypeIds.includes(otherMarket.typeId) &&
355
- otherMarket.playerId === 0 &&
356
- otherMarket.position === market.position
357
- );
358
- if (hasCombineWithTypeIds) {
359
- message = blocker?.message || getBlockerMessage(BLOCKER_GROUP, blockerIndex);
360
- break;
361
- }
362
- }
363
- }
364
- }
365
- }
366
-
367
- return message;
368
- };
369
-
370
- // Rule #4
371
- const validateSomeBlockerWithEveryCombinedForSamePosition = (
372
- markets: SgpBlockerMarket[],
373
- sgpBlockers: SgpBlocker[]
374
- ) => {
375
- const BLOCKER_GROUP = 4;
376
-
377
- const blockers = getBlockers(sgpBlockers, BLOCKER_GROUP);
378
-
379
- let message = '';
380
-
381
- for (let blockerIndex = 0; blockerIndex < blockers.length; blockerIndex++) {
382
- const blocker = getBlocker(blockers, BLOCKER_GROUP, blockerIndex);
383
-
384
- if (blocker && blocker.enabled) {
385
- for (let marketIndex = 0; marketIndex < markets.length; marketIndex++) {
386
- const market = markets[marketIndex];
387
- const otherMarkets = markets.filter((_, i) => i !== marketIndex && markets[i].gameId === market.gameId);
388
-
389
- const hasBlockerTypeId =
390
- (!blocker.sport || blocker.sport === getLeagueSport(market.leagueId)) &&
391
- (!blocker.leagueId || blocker.leagueId === market.leagueId) &&
392
- blocker.blockerTypeIds.includes(market.typeId);
393
-
394
- if (hasBlockerTypeId) {
395
- const hasCombineWithTypeIds =
396
- blocker.combineWithTypeIds.length &&
397
- blocker.combineWithTypeIds.every((combinedTypeId) =>
398
- otherMarkets.some(
399
- (otherMarket) =>
400
- otherMarket.typeId === combinedTypeId &&
401
- otherMarket.playerId === 0 &&
402
- otherMarket.position === market.position
403
- )
404
- );
405
- if (hasCombineWithTypeIds) {
406
- message = blocker?.message || getBlockerMessage(BLOCKER_GROUP, blockerIndex);
407
- break;
408
- }
409
- }
410
- }
411
- }
412
- }
413
-
414
- return message;
415
- };
416
-
417
- // Rule #5
418
- const validateSomeBlockerWithEveryCombined = (markets: SgpBlockerMarket[], sgpBlockers: SgpBlocker[]) => {
419
- const BLOCKER_GROUP = 5;
420
-
421
- const blockers = getBlockers(sgpBlockers, BLOCKER_GROUP);
422
-
423
- let message = '';
424
-
425
- for (let blockerIndex = 0; blockerIndex < blockers.length; blockerIndex++) {
426
- const blocker = getBlocker(blockers, BLOCKER_GROUP, blockerIndex);
427
-
428
- if (blocker && blocker.enabled) {
429
- for (let marketIndex = 0; marketIndex < markets.length; marketIndex++) {
430
- const market = markets[marketIndex];
431
- const otherMarkets = markets.filter((_, i) => i !== marketIndex && markets[i].gameId === market.gameId);
432
-
433
- const hasBlockerTypeId =
434
- (!blocker.sport || blocker.sport === getLeagueSport(market.leagueId)) &&
435
- (!blocker.leagueId || blocker.leagueId === market.leagueId) &&
436
- blocker.blockerTypeIds.includes(market.typeId);
437
-
438
- if (hasBlockerTypeId) {
439
- const hasCombineWithTypeIds =
440
- blocker.combineWithTypeIds.length &&
441
- blocker.combineWithTypeIds.every((combinedTypeId) =>
442
- otherMarkets.some(
443
- (otherMarket) => otherMarket.typeId === combinedTypeId && otherMarket.playerId === 0
444
- )
445
- );
446
- if (hasCombineWithTypeIds) {
447
- message = blocker?.message || getBlockerMessage(BLOCKER_GROUP, blockerIndex);
448
- break;
449
- }
450
- }
451
- }
452
- }
453
- }
454
-
455
- return message;
456
- };
457
-
458
- export const getSgpMarketsCombinationAllowed = (markets: SgpBlockerMarket[], sgpBlockers: SgpBlocker[]) => {
459
- const enabledSgpBlockers = sgpBlockers.filter((sgpBlocker) => sgpBlocker.enabled);
460
-
461
- const message = enabledSgpBlockers.length
462
- ? validateMarketsWithSameDirection(markets, enabledSgpBlockers) ||
463
- validateSomeBlockerWithSomeCombined(markets, enabledSgpBlockers) ||
464
- validatePlayerPropsCombinations(markets, enabledSgpBlockers) ||
465
- validateSomeBlockerWithSomeCombinedForSamePosition(markets, enabledSgpBlockers) ||
466
- validateSomeBlockerWithEveryCombinedForSamePosition(markets, enabledSgpBlockers) ||
467
- validateSomeBlockerWithEveryCombined(markets, enabledSgpBlockers) ||
468
- ''
469
- : '';
470
-
471
- return {
472
- isAllowed: !message,
473
- message,
474
- };
475
- };
476
-
477
- export const getPeriodsForResultView = (marketType: MarketType, leagueId: League) => {
478
- if (FIRST_PERIOD_MARKET_TYPES.includes(marketType)) {
479
- return [1];
480
- }
481
- if (SECOND_PERIOD_MARKET_TYPES.includes(marketType)) {
482
- return [2];
483
- }
484
- if (THIRD_PERIOD_MARKET_TYPES.includes(marketType)) {
485
- return [3];
486
- }
487
- if (FOURTH_PERIOD_MARKET_TYPES.includes(marketType)) {
488
- return [4];
489
- }
490
- if (FIFTH_PERIOD_MARKET_TYPES.includes(marketType)) {
491
- return [5];
492
- }
493
- if (SIXTH_PERIOD_MARKET_TYPES.includes(marketType)) {
494
- return [6];
495
- }
496
- if (SEVENTH_PERIOD_MARKET_TYPES.includes(marketType)) {
497
- return [7];
498
- }
499
- if (EIGHTH_PERIOD_MARKET_TYPES.includes(marketType)) {
500
- return [8];
501
- }
502
- if (NINTH_PERIOD_MARKET_TYPES.includes(marketType)) {
503
- return [9];
504
- }
505
- if (FIRST_THREE_INNINGS_MARKET_TYPES.includes(marketType)) {
506
- return [1, 2, 3];
507
- }
508
- if (FIRST_FIVE_INNINGS_MARKET_TYPES.includes(marketType)) {
509
- return [1, 2, 3, 4, 5];
510
- }
511
- if (FIRST_SEVEN_INNINGS_MARKET_TYPES.includes(marketType)) {
512
- return [1, 2, 3, 4, 5, 6, 7];
513
- }
514
- if (FIRST_PERIOD_MARKET_TYPES2.includes(marketType)) {
515
- const sport = getLeagueSport(leagueId);
516
- if (sport === Sport.BASEBALL) {
517
- return [1, 2, 3, 4, 5];
518
- } else {
519
- return [1, 2];
520
- }
521
- }
522
- if (SECOND_PERIOD_MARKET_TYPES2.includes(marketType)) {
523
- return [3, 4];
524
- }
525
- return [];
526
- };
1
+ import {
2
+ AWAY_TEAM_MARKET_TYPES,
3
+ AWAY_TEAM_TOTAL_MARKET_TYPES,
4
+ BASKETBALL_MARKET_TYPES,
5
+ BOTH_TEAMS_TO_SCORE_MARKET_TYPES,
6
+ CARDS_MARKET_TYPES,
7
+ COMBINED_POSITIONS_MARKET_TYPES,
8
+ CORNERS_MARKET_TYPES,
9
+ CORRECT_SCORE_MARKET_TYPES,
10
+ CRICKET_MARKET_TYPES,
11
+ DARTS_MARKET_TYPES,
12
+ DOUBLE_CHANCE_MARKET_TYPES,
13
+ EIGHTH_PERIOD_MARKET_TYPES,
14
+ ESPORTS_MARKET_TYPES,
15
+ FIFTH_PERIOD_MARKET_TYPES,
16
+ FIRST_FIVE_INNINGS_MARKET_TYPES,
17
+ FIRST_PERIOD_MARKET_TYPES,
18
+ FIRST_PERIOD_MARKET_TYPES2,
19
+ FIRST_SEVEN_INNINGS_MARKET_TYPES,
20
+ FIRST_THREE_INNINGS_MARKET_TYPES,
21
+ FOOTBALL_MARKET_TYPES,
22
+ FOURTH_PERIOD_MARKET_TYPES,
23
+ FUTURES_MARKET_TYPES,
24
+ HALFTIME_FULLTIME_MARKET_TYPES,
25
+ HIGHEST_SCORING_HALF_MARKET_TYPES,
26
+ HOME_TEAM_MARKET_TYPES,
27
+ HOME_TEAM_TOTAL_MARKET_TYPES,
28
+ NINTH_PERIOD_MARKET_TYPES,
29
+ ONE_SIDE_EXTENDED_PLAYER_PROPS_MARKET_TYPES,
30
+ ONE_SIDE_PLAYER_PROPS_MARKET_TYPES,
31
+ OTHER_YES_NO_MARKET_TYPES,
32
+ PERIOD_MARKET_TYPES,
33
+ PLAYER_PROPS_MARKET_TYPES,
34
+ RACE_TO_MARKET_TYPES,
35
+ SCORE_MARKET_TYPES,
36
+ SECOND_PERIOD_MARKET_TYPES,
37
+ SECOND_PERIOD_MARKET_TYPES2,
38
+ SEVENTH_PERIOD_MARKET_TYPES,
39
+ SGP_BUILDER_MARKET_TYPES,
40
+ SGP_NOT_SUPPORTED_MARKET_TYPES,
41
+ SIXTH_PERIOD_MARKET_TYPES,
42
+ SOCCER_METHOD_OF_VICTORY_MARKET_TYPES,
43
+ SOCCER_SPECIFIC_MARKET_TYPES,
44
+ SOCCER_TOTAL_MARKET_TYPES,
45
+ SPREAD_MARKET_TYPES,
46
+ THIRD_PERIOD_MARKET_TYPES,
47
+ TOTAL_EXACT_MARKET_TYPES,
48
+ TOTAL_MARKET_TYPES,
49
+ TOTAL_ODD_EVEN_MARKET_TYPES,
50
+ TWO_WAY_WINNER_MARKET_TYPES,
51
+ UFC_ENDING_METHOD_MARKET_TYPES,
52
+ UFC_METHOD_OF_VICTORY_MARKET_TYPES,
53
+ UFC_SPECIFIC_MARKET_TYPES,
54
+ UFC_WINNING_ROUND_MARKET_TYPES,
55
+ WINNER_MARKET_TYPES,
56
+ YES_NO_PLAYER_PROPS_MARKET_TYPES,
57
+ } from '../constants/marketTypes';
58
+ import { MarketType } from '../enums/marketTypes';
59
+ import { League, Sport } from '../enums/sports';
60
+ import { SgpBlocker, SgpBlockerMarket } from '../types/sgp';
61
+ import { getLeagueSport } from './sports';
62
+
63
+ export const isWinnerMarket = (marketType: MarketType) => WINNER_MARKET_TYPES.includes(marketType);
64
+
65
+ export const isTotalMarket = (marketType: MarketType) => TOTAL_MARKET_TYPES.includes(marketType);
66
+ export const isHomeTeamTotalMarket = (marketType: MarketType) => HOME_TEAM_TOTAL_MARKET_TYPES.includes(marketType);
67
+ export const isAwayTeamTotalMarket = (marketType: MarketType) => AWAY_TEAM_TOTAL_MARKET_TYPES.includes(marketType);
68
+ export const isTotalOddEvenMarket = (marketType: MarketType) => TOTAL_ODD_EVEN_MARKET_TYPES.includes(marketType);
69
+ export const isTotalExactMarket = (marketType: MarketType) => TOTAL_EXACT_MARKET_TYPES.includes(marketType);
70
+
71
+ export const isSpreadMarket = (marketType: MarketType) => SPREAD_MARKET_TYPES.includes(marketType);
72
+
73
+ export const isPlayerPropsMarket = (marketType: MarketType) => PLAYER_PROPS_MARKET_TYPES.includes(marketType);
74
+
75
+ export const isCombinedPositionsMarket = (marketType: MarketType) =>
76
+ COMBINED_POSITIONS_MARKET_TYPES.includes(marketType);
77
+
78
+ export const isHalftimeFulltimeMarket = (marketType: MarketType) => HALFTIME_FULLTIME_MARKET_TYPES.includes(marketType);
79
+
80
+ export const isFuturesMarket = (marketType: MarketType) => FUTURES_MARKET_TYPES.includes(marketType);
81
+
82
+ export const isOneSideMarket = (league: League, marketType: MarketType) =>
83
+ getLeagueSport(league) === Sport.MOTOSPORT ||
84
+ league == League.US_ELECTION ||
85
+ marketType === MarketType.TO_MAKE_FINAL_FOUR;
86
+
87
+ export const isOneSidePlayerPropsMarket = (marketType: MarketType) =>
88
+ ONE_SIDE_PLAYER_PROPS_MARKET_TYPES.includes(marketType);
89
+
90
+ export const isOneSideExtendedPlayerPropsMarket = (marketType: MarketType) =>
91
+ ONE_SIDE_EXTENDED_PLAYER_PROPS_MARKET_TYPES.includes(marketType);
92
+
93
+ export const isYesNoPlayerPropsMarket = (marketType: MarketType) =>
94
+ YES_NO_PLAYER_PROPS_MARKET_TYPES.includes(marketType);
95
+
96
+ export const isBothTeamsToScoreMarket = (marketType: MarketType) =>
97
+ BOTH_TEAMS_TO_SCORE_MARKET_TYPES.includes(marketType);
98
+
99
+ export const isOtherYesNoMarket = (marketType: MarketType) => OTHER_YES_NO_MARKET_TYPES.includes(marketType);
100
+
101
+ export const isDoubleChanceMarket = (marketType: MarketType) => DOUBLE_CHANCE_MARKET_TYPES.includes(marketType);
102
+
103
+ export const isCorrectScoreMarket = (marketType: MarketType) => CORRECT_SCORE_MARKET_TYPES.includes(marketType);
104
+
105
+ export const isDrawAvailableMarket = (marketType: MarketType) =>
106
+ !TWO_WAY_WINNER_MARKET_TYPES.includes(marketType) &&
107
+ (WINNER_MARKET_TYPES.includes(marketType) ||
108
+ SCORE_MARKET_TYPES.includes(marketType) ||
109
+ RACE_TO_MARKET_TYPES.includes(marketType) ||
110
+ HIGHEST_SCORING_HALF_MARKET_TYPES.includes(marketType));
111
+
112
+ export const isPeriodMarket = (marketType: MarketType) => PERIOD_MARKET_TYPES.includes(marketType);
113
+
114
+ export const isPeriod2Market = (marketType: MarketType) => {
115
+ return (
116
+ (marketType >= MarketType.FIRST_PERIOD_WINNER2 && marketType <= MarketType.NINTH_PERIOD_WINNER2) ||
117
+ (marketType >= MarketType.FIRST_PERIOD_TOTAL2 && marketType <= MarketType.NINTH_PERIOD_TOTAL2) ||
118
+ (marketType >= MarketType.FIRST_PERIOD_SPREAD2 && marketType <= MarketType.NINTH_PERIOD_SPREAD2) ||
119
+ (marketType >= MarketType.FIRST_PERIOD_TOTAL2_ODD_EVEN &&
120
+ marketType <= MarketType.NINTH_PERIOD_TOTAL2_ODD_EVEN) ||
121
+ FIRST_PERIOD_MARKET_TYPES2.includes(marketType) ||
122
+ SECOND_PERIOD_MARKET_TYPES2.includes(marketType)
123
+ );
124
+ };
125
+
126
+ export const isHomeTeamMarket = (marketType: MarketType) => HOME_TEAM_MARKET_TYPES.includes(marketType);
127
+
128
+ export const isAwayTeamMarket = (marketType: MarketType) => AWAY_TEAM_MARKET_TYPES.includes(marketType);
129
+
130
+ export const isScoreMarket = (marketType: MarketType) => SCORE_MARKET_TYPES.includes(marketType);
131
+
132
+ export const isRaceToMarket = (marketType: MarketType) => RACE_TO_MARKET_TYPES.includes(marketType);
133
+
134
+ export const isHighestScoringHalfMarket = (marketType: MarketType) =>
135
+ HIGHEST_SCORING_HALF_MARKET_TYPES.includes(marketType);
136
+
137
+ export const isOnlyOverPlayerPropsMarket = (marketType: MarketType, odds: number[]) =>
138
+ isPlayerPropsMarket(marketType) && odds.length === 1;
139
+
140
+ export const isUfcSpecificMarket = (marketType: MarketType) => UFC_SPECIFIC_MARKET_TYPES.includes(marketType);
141
+ export const isUfcWinningMarket = (marketType: MarketType) => UFC_WINNING_ROUND_MARKET_TYPES.includes(marketType);
142
+ export const isEndingUfcMarket = (marketType: MarketType) => UFC_ENDING_METHOD_MARKET_TYPES.includes(marketType);
143
+ export const isUfcVictoryMarket = (marketType: MarketType) => UFC_METHOD_OF_VICTORY_MARKET_TYPES.includes(marketType);
144
+
145
+ export const isSoccerSpecificMarket = (marketType: MarketType) => SOCCER_SPECIFIC_MARKET_TYPES.includes(marketType);
146
+ export const isSoccerMethodOfVictoryMarket = (marketType: MarketType) => SOCCER_METHOD_OF_VICTORY_MARKET_TYPES.includes(marketType);
147
+
148
+ export const isContractResultView = (marketType: MarketType) =>
149
+ CORNERS_MARKET_TYPES.includes(marketType) ||
150
+ CARDS_MARKET_TYPES.includes(marketType) ||
151
+ CRICKET_MARKET_TYPES.includes(marketType) ||
152
+ FOOTBALL_MARKET_TYPES.includes(marketType) ||
153
+ DARTS_MARKET_TYPES.includes(marketType) ||
154
+ BASKETBALL_MARKET_TYPES.includes(marketType) ||
155
+ ESPORTS_MARKET_TYPES.includes(marketType) ||
156
+ SOCCER_TOTAL_MARKET_TYPES.includes(marketType);
157
+
158
+ export const isTotalOrSpreadWithWholeLine = (marketType: MarketType, line: number) =>
159
+ (isTotalMarket(marketType) || isSpreadMarket(marketType)) && line % 1 === 0;
160
+
161
+ // market: SportMarket
162
+ export const isStalePausedMarket = (market: any, maxDelaySec = 300) =>
163
+ market.isPaused && market.pausedAt && Date.now() - market.pausedAt >= maxDelaySec * 1000;
164
+
165
+ export const isSgpBuilderMarket = (marketType: MarketType) => SGP_BUILDER_MARKET_TYPES.includes(marketType);
166
+
167
+ export const isMarketNotSupportedForSgp = (marketType: MarketType) =>
168
+ SGP_NOT_SUPPORTED_MARKET_TYPES.includes(marketType);
169
+
170
+ /*
171
+ Blocking rules for SGP markets combination:
172
+
173
+ 0. Block if markets have same type id and player id, block two markets on the SGP in same direction (both over or both under)
174
+ 1. Block halftime-fulltime combining with moneyline
175
+ 2. Block same playerId and same typeId for points and PR or PRA combinations
176
+ Block DD and Triple Double on a player with any other prop on that player
177
+ Disalowed props combos (for same playerID > 0):
178
+ - Triple double not allowed with any other prop
179
+ - Double double not allowed with any other prop
180
+ - PRA not allowed with PR, PA and points, rebounds or assist props
181
+ - PR not allowed with points or rebounds
182
+ - PA not allowed with points or assists
183
+ 3. Block moneyline and spread on the same team
184
+ Disalowed props for same position (player ID is 0):
185
+ - Moneyline and Spread full time
186
+ - Moneyline and Spread first period
187
+ - Moneyline and Spread second period
188
+ - Moneyline and Spread secondary first period ...
189
+ - Both teams to score on football and over goals per team
190
+ 4. Block moneyline with betting on each period individually on the same team
191
+ (e.g. betting on a team to win each period and win moneyline, the first implied the other)
192
+ 5. Block over points on each period and over on the whole game
193
+ */
194
+
195
+ const getBlockers = (sgpBlockers: SgpBlocker[], blockerGroup: number) =>
196
+ sgpBlockers.filter((data) => data.blockerGroup === blockerGroup);
197
+
198
+ const getBlocker = (sgpBlockers: SgpBlocker[], blockerGroup: number, blockerNumber: number) =>
199
+ sgpBlockers.find((data) => data.blockerGroup === blockerGroup && data.blockerNumber === blockerNumber);
200
+
201
+ const getBlockerMessage = (blockerGroup: number, blockerNumber: number) =>
202
+ `Blocker group ${blockerGroup}, #${blockerNumber}`;
203
+
204
+ // Rule #0
205
+ const validateMarketsWithSameDirection = (markets: SgpBlockerMarket[], sgpBlockers: SgpBlocker[]) => {
206
+ const BLOCKER_GROUP = 0;
207
+
208
+ const blockers = getBlockers(sgpBlockers, BLOCKER_GROUP);
209
+
210
+ let message = '';
211
+
212
+ if (blockers.length) {
213
+ const blockerNumber = 0;
214
+ const blocker = getBlocker(blockers, BLOCKER_GROUP, blockerNumber);
215
+
216
+ if (blocker && blocker.enabled) {
217
+ for (let index = 0; index < markets.length; index++) {
218
+ const market = markets[index];
219
+
220
+ const sport = getLeagueSport(market.leagueId);
221
+ const leagueId = market.leagueId;
222
+ const typeId = market.typeId;
223
+ const playerId = market.playerId;
224
+ const position = market.position;
225
+
226
+ const otherMarkets = markets.filter((_, i) => i !== index && markets[i].gameId === market.gameId);
227
+ const isSameMarketDirection = otherMarkets.some(
228
+ (otherMarket) =>
229
+ (!blocker.sport || blocker.sport === sport) &&
230
+ (!blocker.leagueId || blocker.leagueId === leagueId) &&
231
+ otherMarket.typeId === typeId &&
232
+ otherMarket.playerId === playerId &&
233
+ otherMarket.position === position
234
+ );
235
+
236
+ if (isSameMarketDirection) {
237
+ message =
238
+ getBlocker(sgpBlockers, BLOCKER_GROUP, blockerNumber)?.message ||
239
+ `Blocker group ${BLOCKER_GROUP}, #${blockerNumber}`;
240
+ break;
241
+ }
242
+ }
243
+ }
244
+ }
245
+
246
+ return message;
247
+ };
248
+
249
+ // Rule #1
250
+ const validateSomeBlockerWithSomeCombined = (markets: SgpBlockerMarket[], sgpBlockers: SgpBlocker[]) => {
251
+ const BLOCKER_GROUP = 1;
252
+
253
+ const blockers = getBlockers(sgpBlockers, BLOCKER_GROUP);
254
+
255
+ let message = '';
256
+
257
+ for (let blockerIndex = 0; blockerIndex < blockers.length; blockerIndex++) {
258
+ const blocker = getBlocker(blockers, BLOCKER_GROUP, blockerIndex);
259
+
260
+ if (blocker && blocker.enabled) {
261
+ for (let index = 0; index < markets.length; index++) {
262
+ const market = markets[index];
263
+ const otherMarkets = markets.filter((_, i) => i !== index && markets[i].gameId === market.gameId);
264
+
265
+ const hasSomeBlocker =
266
+ (!blocker.sport || blocker.sport === getLeagueSport(market.leagueId)) &&
267
+ (!blocker.leagueId || blocker.leagueId === market.leagueId) &&
268
+ blocker.blockerTypeIds.includes(market.typeId);
269
+
270
+ if (hasSomeBlocker) {
271
+ const hasSomeCombined = otherMarkets.some(
272
+ (otherMarket) =>
273
+ (!blocker.sport || blocker.sport === getLeagueSport(otherMarket.leagueId)) &&
274
+ (!blocker.leagueId || blocker.leagueId === otherMarket.leagueId) &&
275
+ blocker.combineWithTypeIds.includes(otherMarket.typeId)
276
+ );
277
+
278
+ if (hasSomeCombined) {
279
+ message = blocker?.message || getBlockerMessage(BLOCKER_GROUP, blockerIndex);
280
+ break;
281
+ }
282
+ }
283
+ }
284
+ }
285
+ }
286
+
287
+ return message;
288
+ };
289
+
290
+ // Rule #2
291
+ const validatePlayerPropsCombinations = (markets: SgpBlockerMarket[], sgpBlockers: SgpBlocker[]) => {
292
+ const BLOCKER_GROUP = 2;
293
+
294
+ const blockers = getBlockers(sgpBlockers, BLOCKER_GROUP);
295
+
296
+ let message = '';
297
+
298
+ for (let blockerIndex = 0; blockerIndex < blockers.length; blockerIndex++) {
299
+ const blocker = getBlocker(blockers, BLOCKER_GROUP, blockerIndex);
300
+
301
+ if (blocker && blocker.enabled) {
302
+ for (let marketIndex = 0; marketIndex < markets.length; marketIndex++) {
303
+ const market = markets[marketIndex];
304
+ const otherMarkets = markets.filter((_, i) => i !== marketIndex && markets[i].gameId === market.gameId);
305
+
306
+ const hasBlockerTypeId =
307
+ (!blocker.sport || blocker.sport === getLeagueSport(market.leagueId)) &&
308
+ (!blocker.leagueId || blocker.leagueId === market.leagueId) &&
309
+ blocker.blockerTypeIds.includes(market.typeId);
310
+
311
+ if (hasBlockerTypeId) {
312
+ const hasCombineWithTypeIds = otherMarkets.some(
313
+ (otherMarket) =>
314
+ (!blocker.combineWithTypeIds.length ||
315
+ blocker.combineWithTypeIds.includes(otherMarket.typeId)) &&
316
+ otherMarket.playerId > 0 &&
317
+ otherMarket.playerId === market.playerId
318
+ );
319
+ if (hasCombineWithTypeIds) {
320
+ message = blocker?.message || getBlockerMessage(BLOCKER_GROUP, blockerIndex);
321
+ break;
322
+ }
323
+ }
324
+ }
325
+ }
326
+ }
327
+
328
+ return message;
329
+ };
330
+
331
+ // Rule #3
332
+ const validateSomeBlockerWithSomeCombinedForSamePosition = (markets: SgpBlockerMarket[], sgpBlockers: SgpBlocker[]) => {
333
+ const BLOCKER_GROUP = 3;
334
+
335
+ const blockers = getBlockers(sgpBlockers, BLOCKER_GROUP);
336
+
337
+ let message = '';
338
+
339
+ for (let blockerIndex = 0; blockerIndex < blockers.length; blockerIndex++) {
340
+ const blocker = getBlocker(blockers, BLOCKER_GROUP, blockerIndex);
341
+
342
+ if (blocker && blocker.enabled) {
343
+ for (let marketIndex = 0; marketIndex < markets.length; marketIndex++) {
344
+ const market = markets[marketIndex];
345
+ const otherMarkets = markets.filter((_, i) => i !== marketIndex && markets[i].gameId === market.gameId);
346
+
347
+ const hasBlockerTypeId =
348
+ (!blocker.sport || blocker.sport === getLeagueSport(market.leagueId)) &&
349
+ (!blocker.leagueId || blocker.leagueId === market.leagueId) &&
350
+ blocker.blockerTypeIds.includes(market.typeId);
351
+
352
+ if (hasBlockerTypeId) {
353
+ const hasCombineWithTypeIds = otherMarkets.some(
354
+ (otherMarket) =>
355
+ blocker.combineWithTypeIds.length &&
356
+ blocker.combineWithTypeIds.includes(otherMarket.typeId) &&
357
+ otherMarket.playerId === 0 &&
358
+ otherMarket.position === market.position
359
+ );
360
+ if (hasCombineWithTypeIds) {
361
+ message = blocker?.message || getBlockerMessage(BLOCKER_GROUP, blockerIndex);
362
+ break;
363
+ }
364
+ }
365
+ }
366
+ }
367
+ }
368
+
369
+ return message;
370
+ };
371
+
372
+ // Rule #4
373
+ const validateSomeBlockerWithEveryCombinedForSamePosition = (
374
+ markets: SgpBlockerMarket[],
375
+ sgpBlockers: SgpBlocker[]
376
+ ) => {
377
+ const BLOCKER_GROUP = 4;
378
+
379
+ const blockers = getBlockers(sgpBlockers, BLOCKER_GROUP);
380
+
381
+ let message = '';
382
+
383
+ for (let blockerIndex = 0; blockerIndex < blockers.length; blockerIndex++) {
384
+ const blocker = getBlocker(blockers, BLOCKER_GROUP, blockerIndex);
385
+
386
+ if (blocker && blocker.enabled) {
387
+ for (let marketIndex = 0; marketIndex < markets.length; marketIndex++) {
388
+ const market = markets[marketIndex];
389
+ const otherMarkets = markets.filter((_, i) => i !== marketIndex && markets[i].gameId === market.gameId);
390
+
391
+ const hasBlockerTypeId =
392
+ (!blocker.sport || blocker.sport === getLeagueSport(market.leagueId)) &&
393
+ (!blocker.leagueId || blocker.leagueId === market.leagueId) &&
394
+ blocker.blockerTypeIds.includes(market.typeId);
395
+
396
+ if (hasBlockerTypeId) {
397
+ const hasCombineWithTypeIds =
398
+ blocker.combineWithTypeIds.length &&
399
+ blocker.combineWithTypeIds.every((combinedTypeId) =>
400
+ otherMarkets.some(
401
+ (otherMarket) =>
402
+ otherMarket.typeId === combinedTypeId &&
403
+ otherMarket.playerId === 0 &&
404
+ otherMarket.position === market.position
405
+ )
406
+ );
407
+ if (hasCombineWithTypeIds) {
408
+ message = blocker?.message || getBlockerMessage(BLOCKER_GROUP, blockerIndex);
409
+ break;
410
+ }
411
+ }
412
+ }
413
+ }
414
+ }
415
+
416
+ return message;
417
+ };
418
+
419
+ // Rule #5
420
+ const validateSomeBlockerWithEveryCombined = (markets: SgpBlockerMarket[], sgpBlockers: SgpBlocker[]) => {
421
+ const BLOCKER_GROUP = 5;
422
+
423
+ const blockers = getBlockers(sgpBlockers, BLOCKER_GROUP);
424
+
425
+ let message = '';
426
+
427
+ for (let blockerIndex = 0; blockerIndex < blockers.length; blockerIndex++) {
428
+ const blocker = getBlocker(blockers, BLOCKER_GROUP, blockerIndex);
429
+
430
+ if (blocker && blocker.enabled) {
431
+ for (let marketIndex = 0; marketIndex < markets.length; marketIndex++) {
432
+ const market = markets[marketIndex];
433
+ const otherMarkets = markets.filter((_, i) => i !== marketIndex && markets[i].gameId === market.gameId);
434
+
435
+ const hasBlockerTypeId =
436
+ (!blocker.sport || blocker.sport === getLeagueSport(market.leagueId)) &&
437
+ (!blocker.leagueId || blocker.leagueId === market.leagueId) &&
438
+ blocker.blockerTypeIds.includes(market.typeId);
439
+
440
+ if (hasBlockerTypeId) {
441
+ const hasCombineWithTypeIds =
442
+ blocker.combineWithTypeIds.length &&
443
+ blocker.combineWithTypeIds.every((combinedTypeId) =>
444
+ otherMarkets.some(
445
+ (otherMarket) => otherMarket.typeId === combinedTypeId && otherMarket.playerId === 0
446
+ )
447
+ );
448
+ if (hasCombineWithTypeIds) {
449
+ message = blocker?.message || getBlockerMessage(BLOCKER_GROUP, blockerIndex);
450
+ break;
451
+ }
452
+ }
453
+ }
454
+ }
455
+ }
456
+
457
+ return message;
458
+ };
459
+
460
+ export const getSgpMarketsCombinationAllowed = (markets: SgpBlockerMarket[], sgpBlockers: SgpBlocker[]) => {
461
+ const enabledSgpBlockers = sgpBlockers.filter((sgpBlocker) => sgpBlocker.enabled);
462
+
463
+ const message = enabledSgpBlockers.length
464
+ ? validateMarketsWithSameDirection(markets, enabledSgpBlockers) ||
465
+ validateSomeBlockerWithSomeCombined(markets, enabledSgpBlockers) ||
466
+ validatePlayerPropsCombinations(markets, enabledSgpBlockers) ||
467
+ validateSomeBlockerWithSomeCombinedForSamePosition(markets, enabledSgpBlockers) ||
468
+ validateSomeBlockerWithEveryCombinedForSamePosition(markets, enabledSgpBlockers) ||
469
+ validateSomeBlockerWithEveryCombined(markets, enabledSgpBlockers) ||
470
+ ''
471
+ : '';
472
+
473
+ return {
474
+ isAllowed: !message,
475
+ message,
476
+ };
477
+ };
478
+
479
+ export const getPeriodsForResultView = (marketType: MarketType, leagueId: League) => {
480
+ if (FIRST_PERIOD_MARKET_TYPES.includes(marketType)) {
481
+ return [1];
482
+ }
483
+ if (SECOND_PERIOD_MARKET_TYPES.includes(marketType)) {
484
+ return [2];
485
+ }
486
+ if (THIRD_PERIOD_MARKET_TYPES.includes(marketType)) {
487
+ return [3];
488
+ }
489
+ if (FOURTH_PERIOD_MARKET_TYPES.includes(marketType)) {
490
+ return [4];
491
+ }
492
+ if (FIFTH_PERIOD_MARKET_TYPES.includes(marketType)) {
493
+ return [5];
494
+ }
495
+ if (SIXTH_PERIOD_MARKET_TYPES.includes(marketType)) {
496
+ return [6];
497
+ }
498
+ if (SEVENTH_PERIOD_MARKET_TYPES.includes(marketType)) {
499
+ return [7];
500
+ }
501
+ if (EIGHTH_PERIOD_MARKET_TYPES.includes(marketType)) {
502
+ return [8];
503
+ }
504
+ if (NINTH_PERIOD_MARKET_TYPES.includes(marketType)) {
505
+ return [9];
506
+ }
507
+ if (FIRST_THREE_INNINGS_MARKET_TYPES.includes(marketType)) {
508
+ return [1, 2, 3];
509
+ }
510
+ if (FIRST_FIVE_INNINGS_MARKET_TYPES.includes(marketType)) {
511
+ return [1, 2, 3, 4, 5];
512
+ }
513
+ if (FIRST_SEVEN_INNINGS_MARKET_TYPES.includes(marketType)) {
514
+ return [1, 2, 3, 4, 5, 6, 7];
515
+ }
516
+ if (FIRST_PERIOD_MARKET_TYPES2.includes(marketType)) {
517
+ const sport = getLeagueSport(leagueId);
518
+ if (sport === Sport.BASEBALL) {
519
+ return [1, 2, 3, 4, 5];
520
+ } else {
521
+ return [1, 2];
522
+ }
523
+ }
524
+ if (SECOND_PERIOD_MARKET_TYPES2.includes(marketType)) {
525
+ return [3, 4];
526
+ }
527
+ return [];
528
+ };