fansunited-data-layer 0.13.0 → 0.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/api/fansunited/constants.js +5 -0
  2. package/api/fansunited/constants.js.map +1 -0
  3. package/api/fansunited/football/competition/index.js +21 -0
  4. package/api/fansunited/football/competition/index.js.map +1 -0
  5. package/api/fansunited/football/competition/transformer.js +41 -0
  6. package/api/fansunited/football/competition/transformer.js.map +1 -0
  7. package/api/fansunited/football/competitions/index.js +56 -0
  8. package/api/fansunited/football/competitions/index.js.map +1 -0
  9. package/api/fansunited/football/competitions/transformer.js +68 -0
  10. package/api/fansunited/football/competitions/transformer.js.map +1 -0
  11. package/api/fansunited/football/http.js +7 -0
  12. package/api/fansunited/football/http.js.map +1 -0
  13. package/api/fansunited/football/matches/index.js +132 -0
  14. package/api/fansunited/football/matches/index.js.map +1 -0
  15. package/api/fansunited/football/matches/transformer.js +148 -0
  16. package/api/fansunited/football/matches/transformer.js.map +1 -0
  17. package/api/fansunited/football/players/index.js +60 -0
  18. package/api/fansunited/football/players/index.js.map +1 -0
  19. package/api/fansunited/football/players/transformer.js +85 -0
  20. package/api/fansunited/football/players/transformer.js.map +1 -0
  21. package/api/fansunited/football/search/index.js +64 -0
  22. package/api/fansunited/football/search/index.js.map +1 -0
  23. package/api/fansunited/football/search/transformer.js +114 -0
  24. package/api/fansunited/football/search/transformer.js.map +1 -0
  25. package/api/fansunited/football/teams/index.js +66 -0
  26. package/api/fansunited/football/teams/index.js.map +1 -0
  27. package/api/fansunited/football/teams/transformer.js +53 -0
  28. package/api/fansunited/football/teams/transformer.js.map +1 -0
  29. package/api/fansunited/http.d.ts.map +1 -1
  30. package/api/fansunited/http.js +70 -0
  31. package/api/fansunited/http.js.map +1 -0
  32. package/api/fansunited/search/constants.js +5 -0
  33. package/api/fansunited/search/constants.js.map +1 -0
  34. package/api/fansunited/search/http.js +7 -0
  35. package/api/fansunited/search/http.js.map +1 -0
  36. package/api/fansunited/search/index.js +308 -0
  37. package/api/fansunited/search/index.js.map +1 -0
  38. package/api/fansunited/search/transformer.js +374 -0
  39. package/api/fansunited/search/transformer.js.map +1 -0
  40. package/api/fansunited-sdk/loyalty/matches.js +21 -0
  41. package/api/fansunited-sdk/loyalty/matches.js.map +1 -0
  42. package/api/fansunited-sdk/loyalty/template.js +52 -0
  43. package/api/fansunited-sdk/loyalty/template.js.map +1 -0
  44. package/api/fansunited-sdk/odds/matches.js +109 -0
  45. package/api/fansunited-sdk/odds/matches.js.map +1 -0
  46. package/api/sportal365-sports/basketball/games/index.js +32 -0
  47. package/api/sportal365-sports/basketball/games/index.js.map +1 -0
  48. package/api/sportal365-sports/basketball/games/transformers/game.js +137 -0
  49. package/api/sportal365-sports/basketball/games/transformers/game.js.map +1 -0
  50. package/api/sportal365-sports/basketball/http.js +7 -0
  51. package/api/sportal365-sports/basketball/http.js.map +1 -0
  52. package/api/sportal365-sports/constants.js +15 -0
  53. package/api/sportal365-sports/constants.js.map +1 -0
  54. package/api/sportal365-sports/football/competitions/index.js +52 -0
  55. package/api/sportal365-sports/football/competitions/index.js.map +1 -0
  56. package/api/sportal365-sports/football/competitions/utils.js +92 -0
  57. package/api/sportal365-sports/football/competitions/utils.js.map +1 -0
  58. package/api/sportal365-sports/football/http.js +7 -0
  59. package/api/sportal365-sports/football/http.js.map +1 -0
  60. package/api/sportal365-sports/football/matches/index.js +206 -0
  61. package/api/sportal365-sports/football/matches/index.js.map +1 -0
  62. package/api/sportal365-sports/football/matches/transformers/commentary.js +27 -0
  63. package/api/sportal365-sports/football/matches/transformers/commentary.js.map +1 -0
  64. package/api/sportal365-sports/football/matches/transformers/lineup.js +74 -0
  65. package/api/sportal365-sports/football/matches/transformers/lineup.js.map +1 -0
  66. package/api/sportal365-sports/football/matches/transformers/match-event.js +60 -0
  67. package/api/sportal365-sports/football/matches/transformers/match-event.js.map +1 -0
  68. package/api/sportal365-sports/football/matches/transformers/match.js +195 -0
  69. package/api/sportal365-sports/football/matches/transformers/match.js.map +1 -0
  70. package/api/sportal365-sports/football/matches/transformers/odds.js +11 -0
  71. package/api/sportal365-sports/football/matches/transformers/odds.js.map +1 -0
  72. package/api/sportal365-sports/football/matches/transformers/statistics.js +41 -0
  73. package/api/sportal365-sports/football/matches/transformers/statistics.js.map +1 -0
  74. package/api/sportal365-sports/football/search/index.js +42 -0
  75. package/api/sportal365-sports/football/search/index.js.map +1 -0
  76. package/api/sportal365-sports/football/search/search.transformer.js +166 -0
  77. package/api/sportal365-sports/football/search/search.transformer.js.map +1 -0
  78. package/api/sportal365-sports/football/standings/index.js +28 -0
  79. package/api/sportal365-sports/football/standings/index.js.map +1 -0
  80. package/api/sportal365-sports/football/standings/standing.transformer.js +107 -0
  81. package/api/sportal365-sports/football/standings/standing.transformer.js.map +1 -0
  82. package/api/sportal365-sports/football/statistics/index.js +154 -0
  83. package/api/sportal365-sports/football/statistics/index.js.map +1 -0
  84. package/api/sportal365-sports/football/statistics/player-career.transformer.js +77 -0
  85. package/api/sportal365-sports/football/statistics/player-career.transformer.js.map +1 -0
  86. package/api/sportal365-sports/football/statistics/player-recent.transformer.js +54 -0
  87. package/api/sportal365-sports/football/statistics/player-recent.transformer.js.map +1 -0
  88. package/api/sportal365-sports/football/statistics/player-season.transformer.js +147 -0
  89. package/api/sportal365-sports/football/statistics/player-season.transformer.js.map +1 -0
  90. package/api/sportal365-sports/football/teams/index.js +73 -0
  91. package/api/sportal365-sports/football/teams/index.js.map +1 -0
  92. package/api/sportal365-sports/football/teams/utils.js +196 -0
  93. package/api/sportal365-sports/football/teams/utils.js.map +1 -0
  94. package/api/sportal365-sports/http.js +58 -0
  95. package/api/sportal365-sports/http.js.map +1 -0
  96. package/api/sportal365-sports/search/http.js +7 -0
  97. package/api/sportal365-sports/search/http.js.map +1 -0
  98. package/api/sportal365-sports/search/index.js +61 -0
  99. package/api/sportal365-sports/search/index.js.map +1 -0
  100. package/api/sportal365-sports/search/search.transformer.js +254 -0
  101. package/api/sportal365-sports/search/search.transformer.js.map +1 -0
  102. package/api/sportal365-sports/shared/odds.transformer.js +65 -0
  103. package/api/sportal365-sports/shared/odds.transformer.js.map +1 -0
  104. package/api/sportal365-sports/shared/providerRef.helper.js +31 -0
  105. package/api/sportal365-sports/shared/providerRef.helper.js.map +1 -0
  106. package/api/sportal365-sports/standings/http.js +7 -0
  107. package/api/sportal365-sports/standings/http.js.map +1 -0
  108. package/api/sportal365-sports/standings/index.js +29 -0
  109. package/api/sportal365-sports/standings/index.js.map +1 -0
  110. package/api/sportal365-sports/standings/standing.transformer.js +185 -0
  111. package/api/sportal365-sports/standings/standing.transformer.js.map +1 -0
  112. package/api/sportal365-sports/statistics/http.js +7 -0
  113. package/api/sportal365-sports/statistics/http.js.map +1 -0
  114. package/api/sportal365-sports/statistics/index.js +25 -0
  115. package/api/sportal365-sports/statistics/index.js.map +1 -0
  116. package/api/sportal365-sports/statistics/team-stats.transformer.js +16 -0
  117. package/api/sportal365-sports/statistics/team-stats.transformer.js.map +1 -0
  118. package/api/sportal365-sports/tennis/http.js +7 -0
  119. package/api/sportal365-sports/tennis/http.js.map +1 -0
  120. package/api/sportal365-sports/tennis/matches/index.js +34 -0
  121. package/api/sportal365-sports/tennis/matches/index.js.map +1 -0
  122. package/api/sportal365-sports/tennis/matches/transformers/match.js +193 -0
  123. package/api/sportal365-sports/tennis/matches/transformers/match.js.map +1 -0
  124. package/cache/cache-manager.js +136 -0
  125. package/cache/cache-manager.js.map +1 -0
  126. package/cache/memory-store.js +29 -0
  127. package/cache/memory-store.js.map +1 -0
  128. package/client.js +38 -12337
  129. package/client.js.map +1 -0
  130. package/config/index.js +20 -0
  131. package/config/index.js.map +1 -0
  132. package/fansunited-data-layer.js +146 -3553
  133. package/fansunited-data-layer.js.map +1 -0
  134. package/helpers/competition.helpers.js +11 -0
  135. package/helpers/competition.helpers.js.map +1 -0
  136. package/helpers/player.helpers.js +165 -0
  137. package/helpers/player.helpers.js.map +1 -0
  138. package/helpers/player.hooks.js +34 -0
  139. package/helpers/player.hooks.js.map +1 -0
  140. package/helpers/team.helpers.js +216 -0
  141. package/helpers/team.helpers.js.map +1 -0
  142. package/package.json +6 -8
  143. package/providers/competition/hooks/useCompetitionStats.js +10 -0
  144. package/providers/competition/hooks/useCompetitionStats.js.map +1 -0
  145. package/providers/competition/hooks/useGoalDistribution.js +23 -0
  146. package/providers/competition/hooks/useGoalDistribution.js.map +1 -0
  147. package/providers/competition/hooks/useMatchHelpers.js +85 -0
  148. package/providers/competition/hooks/useMatchHelpers.js.map +1 -0
  149. package/providers/competition/hooks/useStandingsCalculations.js +89 -0
  150. package/providers/competition/hooks/useStandingsCalculations.js.map +1 -0
  151. package/providers/competition/hooks/useStandingsHelpers.js +61 -0
  152. package/providers/competition/hooks/useStandingsHelpers.js.map +1 -0
  153. package/providers/competition/hooks/useTeamPosition.js +15 -0
  154. package/providers/competition/hooks/useTeamPosition.js.map +1 -0
  155. package/providers/competition/hooks/useTeamResultsTable.js +86 -0
  156. package/providers/competition/hooks/useTeamResultsTable.js.map +1 -0
  157. package/providers/competition/utils/competitionStats.js +109 -0
  158. package/providers/competition/utils/competitionStats.js.map +1 -0
  159. package/providers/competition/utils/goalDistribution.js +64 -0
  160. package/providers/competition/utils/goalDistribution.js.map +1 -0
  161. package/providers/competition/utils/standingsCalculations.js +152 -0
  162. package/providers/competition/utils/standingsCalculations.js.map +1 -0
  163. package/providers/competition.context.js +14 -0
  164. package/providers/competition.context.js.map +1 -0
  165. package/providers/competition.provider.js +187 -0
  166. package/providers/competition.provider.js.map +1 -0
  167. package/providers/fansunited-config.context.js +6 -0
  168. package/providers/fansunited-config.context.js.map +1 -0
  169. package/providers/fansunited-config.hooks.js +20 -0
  170. package/providers/fansunited-config.hooks.js.map +1 -0
  171. package/providers/fansunited-config.provider.js +9 -0
  172. package/providers/fansunited-config.provider.js.map +1 -0
  173. package/providers/fansunited-sdk.hook.js +50 -0
  174. package/providers/fansunited-sdk.hook.js.map +1 -0
  175. package/providers/leaderboard/hooks/useMatchHelpers.js +30 -0
  176. package/providers/leaderboard/hooks/useMatchHelpers.js.map +1 -0
  177. package/providers/leaderboard/hooks/useTemplateHelpers.js +39 -0
  178. package/providers/leaderboard/hooks/useTemplateHelpers.js.map +1 -0
  179. package/providers/leaderboard.context.js +14 -0
  180. package/providers/leaderboard.context.js.map +1 -0
  181. package/providers/leaderboard.provider.js +98 -0
  182. package/providers/leaderboard.provider.js.map +1 -0
  183. package/providers/match/hooks/useBatchMatchOdds.js +72 -0
  184. package/providers/match/hooks/useBatchMatchOdds.js.map +1 -0
  185. package/providers/match/hooks/useEventHelpers.js +46 -0
  186. package/providers/match/hooks/useEventHelpers.js.map +1 -0
  187. package/providers/match/hooks/useHeadToHeadHelpers.js +52 -0
  188. package/providers/match/hooks/useHeadToHeadHelpers.js.map +1 -0
  189. package/providers/match/hooks/useLineupHelpers.js +53 -0
  190. package/providers/match/hooks/useLineupHelpers.js.map +1 -0
  191. package/providers/match/hooks/useMatchStandingsCalculations.js +332 -0
  192. package/providers/match/hooks/useMatchStandingsCalculations.js.map +1 -0
  193. package/providers/match/hooks/useMatchStatus.js +37 -0
  194. package/providers/match/hooks/useMatchStatus.js.map +1 -0
  195. package/providers/match/hooks/useOddsHelpers.js +54 -0
  196. package/providers/match/hooks/useOddsHelpers.js.map +1 -0
  197. package/providers/match/hooks/useScoreHelpers.js +34 -0
  198. package/providers/match/hooks/useScoreHelpers.js.map +1 -0
  199. package/providers/match/hooks/useStandingsHelpers.js +53 -0
  200. package/providers/match/hooks/useStandingsHelpers.js.map +1 -0
  201. package/providers/match/hooks/useStatisticsHelpers.js +40 -0
  202. package/providers/match/hooks/useStatisticsHelpers.js.map +1 -0
  203. package/providers/match/hooks/useTeamHelpers.js +38 -0
  204. package/providers/match/hooks/useTeamHelpers.js.map +1 -0
  205. package/providers/match/hooks/useTeamStatsHelpers.js +141 -0
  206. package/providers/match/hooks/useTeamStatsHelpers.js.map +1 -0
  207. package/providers/match.context.js +14 -0
  208. package/providers/match.context.js.map +1 -0
  209. package/providers/match.provider.js +176 -0
  210. package/providers/match.provider.js.map +1 -0
  211. package/providers/team/hooks/useFormStats.js +116 -0
  212. package/providers/team/hooks/useFormStats.js.map +1 -0
  213. package/providers/team/hooks/useMatchHelpers.js +46 -0
  214. package/providers/team/hooks/useMatchHelpers.js.map +1 -0
  215. package/providers/team/hooks/useSquadHelpers.js +67 -0
  216. package/providers/team/hooks/useSquadHelpers.js.map +1 -0
  217. package/providers/team.context.js +14 -0
  218. package/providers/team.context.js.map +1 -0
  219. package/providers/team.provider.js +98 -0
  220. package/providers/team.provider.js.map +1 -0
  221. package/utilities/stats/core/helpers.js +105 -0
  222. package/utilities/stats/core/helpers.js.map +1 -0
  223. package/utilities/stats/core/types.js +5 -0
  224. package/utilities/stats/core/types.js.map +1 -0
  225. package/utilities/stats/match/headToHead.js +83 -0
  226. package/utilities/stats/match/headToHead.js.map +1 -0
  227. package/utilities/stats/match/homeVsAway.js +140 -0
  228. package/utilities/stats/match/homeVsAway.js.map +1 -0
  229. package/utilities/stats/match/overUnder.js +91 -0
  230. package/utilities/stats/match/overUnder.js.map +1 -0
  231. package/utilities/stats/match/result.js +21 -0
  232. package/utilities/stats/match/result.js.map +1 -0
  233. package/utilities/stats/team/commonOpponents.js +77 -0
  234. package/utilities/stats/team/commonOpponents.js.map +1 -0
  235. package/utilities/stats/team/goalStats.js +50 -0
  236. package/utilities/stats/team/goalStats.js.map +1 -0
  237. package/utilities/stats/team/streaks.js +183 -0
  238. package/utilities/stats/team/streaks.js.map +1 -0
  239. package/client.cjs +0 -8
  240. package/fansunited-data-layer.cjs +0 -1
  241. package/matches-BvHU-bP0.js +0 -1795
  242. package/matches-Ci0Ci_Mw.cjs +0 -1
@@ -0,0 +1,332 @@
1
+ import { useMemo } from "react";
2
+ function computeFormStandings(standings, contextMatches, matchCount, homeAwayFilter) {
3
+ if (!contextMatches || contextMatches.length === 0) {
4
+ return { ...standings, entries: [] };
5
+ }
6
+ const finishedMatches = contextMatches.filter((m) => m.status.type === "FINISHED").sort((a, b) => b.timing.kickoffTime.getTime() - a.timing.kickoffTime.getTime());
7
+ if (finishedMatches.length === 0) {
8
+ return { ...standings, entries: [] };
9
+ }
10
+ const teamStatsMap = /* @__PURE__ */ new Map();
11
+ finishedMatches.forEach((match) => {
12
+ const homeTeamId = match.competitorOne.id;
13
+ const awayTeamId = match.competitorTwo.id;
14
+ if (!teamStatsMap.has(homeTeamId)) {
15
+ teamStatsMap.set(homeTeamId, {
16
+ teamId: homeTeamId,
17
+ teamName: match.competitorOne.name,
18
+ competitor: match.competitorOne,
19
+ matches: [],
20
+ points: 0,
21
+ played: 0
22
+ });
23
+ }
24
+ if (!teamStatsMap.has(awayTeamId)) {
25
+ teamStatsMap.set(awayTeamId, {
26
+ teamId: awayTeamId,
27
+ teamName: match.competitorTwo.name,
28
+ competitor: match.competitorTwo,
29
+ matches: [],
30
+ points: 0,
31
+ played: 0
32
+ });
33
+ }
34
+ teamStatsMap.get(homeTeamId).matches.push(match);
35
+ teamStatsMap.get(awayTeamId).matches.push(match);
36
+ });
37
+ const entriesWithFormPoints = Array.from(teamStatsMap.values()).map((teamData) => {
38
+ const teamId = teamData.teamId;
39
+ let teamMatches = teamData.matches;
40
+ if (homeAwayFilter === "HOME") {
41
+ teamMatches = teamMatches.filter((m) => m.competitorOne.id === teamId);
42
+ } else if (homeAwayFilter === "AWAY") {
43
+ teamMatches = teamMatches.filter((m) => m.competitorTwo.id === teamId);
44
+ }
45
+ teamMatches = teamMatches.sort((a, b) => b.timing.kickoffTime.getTime() - a.timing.kickoffTime.getTime());
46
+ if (matchCount !== void 0) {
47
+ teamMatches = teamMatches.slice(0, matchCount);
48
+ }
49
+ const formPoints = teamMatches.reduce((pts, match) => {
50
+ const isHome = match.competitorOne.id === teamId;
51
+ const teamScore = isHome ? parseInt(match.score?.competitorOne || "0", 10) : parseInt(match.score?.competitorTwo || "0", 10);
52
+ const opponentScore = isHome ? parseInt(match.score?.competitorTwo || "0", 10) : parseInt(match.score?.competitorOne || "0", 10);
53
+ if (teamScore > opponentScore) return pts + 3;
54
+ if (teamScore === opponentScore) return pts + 1;
55
+ return pts;
56
+ }, 0);
57
+ return {
58
+ teamId,
59
+ competitor: teamData.competitor,
60
+ formPoints,
61
+ formPlayed: teamMatches.length
62
+ };
63
+ });
64
+ entriesWithFormPoints.sort((a, b) => {
65
+ if (b.formPoints !== a.formPoints) {
66
+ return b.formPoints - a.formPoints;
67
+ }
68
+ return a.competitor.name.localeCompare(b.competitor.name);
69
+ });
70
+ const formEntries = entriesWithFormPoints.map((item, index) => ({
71
+ rank: index + 1,
72
+ competitor: item.competitor,
73
+ stats: {
74
+ played: item.formPlayed,
75
+ points: item.formPoints,
76
+ wins: 0,
77
+ draws: 0,
78
+ losses: 0,
79
+ goalsFor: 0,
80
+ goalsAgainst: 0,
81
+ goalDifference: 0
82
+ }
83
+ }));
84
+ return {
85
+ ...standings,
86
+ entries: formEntries
87
+ };
88
+ }
89
+ function computeOffenceStandings(standings, contextMatches, matchCount, homeAwayFilter) {
90
+ if (!contextMatches || contextMatches.length === 0) {
91
+ return { ...standings, entries: [] };
92
+ }
93
+ const finishedMatches = contextMatches.filter((m) => m.status.type === "FINISHED").sort((a, b) => b.timing.kickoffTime.getTime() - a.timing.kickoffTime.getTime());
94
+ if (finishedMatches.length === 0) {
95
+ return { ...standings, entries: [] };
96
+ }
97
+ const teamStatsMap = /* @__PURE__ */ new Map();
98
+ finishedMatches.forEach((match) => {
99
+ const homeTeamId = match.competitorOne.id;
100
+ const awayTeamId = match.competitorTwo.id;
101
+ if (!teamStatsMap.has(homeTeamId)) {
102
+ teamStatsMap.set(homeTeamId, {
103
+ teamId: homeTeamId,
104
+ competitor: match.competitorOne,
105
+ matches: []
106
+ });
107
+ }
108
+ if (!teamStatsMap.has(awayTeamId)) {
109
+ teamStatsMap.set(awayTeamId, {
110
+ teamId: awayTeamId,
111
+ competitor: match.competitorTwo,
112
+ matches: []
113
+ });
114
+ }
115
+ teamStatsMap.get(homeTeamId).matches.push(match);
116
+ teamStatsMap.get(awayTeamId).matches.push(match);
117
+ });
118
+ const entriesWithGoals = Array.from(teamStatsMap.values()).map((teamData) => {
119
+ const teamId = teamData.teamId;
120
+ let teamMatches = teamData.matches;
121
+ if (homeAwayFilter === "HOME") {
122
+ teamMatches = teamMatches.filter((m) => m.competitorOne.id === teamId);
123
+ } else if (homeAwayFilter === "AWAY") {
124
+ teamMatches = teamMatches.filter((m) => m.competitorTwo.id === teamId);
125
+ }
126
+ teamMatches = teamMatches.sort((a, b) => b.timing.kickoffTime.getTime() - a.timing.kickoffTime.getTime());
127
+ if (matchCount !== void 0) {
128
+ teamMatches = teamMatches.slice(0, matchCount);
129
+ }
130
+ const goalsScored = teamMatches.reduce((total, match) => {
131
+ const isHome = match.competitorOne.id === teamId;
132
+ const teamScore = isHome ? parseInt(match.score?.competitorOne || "0", 10) : parseInt(match.score?.competitorTwo || "0", 10);
133
+ return total + teamScore;
134
+ }, 0);
135
+ return {
136
+ teamId,
137
+ competitor: teamData.competitor,
138
+ goalsScored,
139
+ played: teamMatches.length
140
+ };
141
+ });
142
+ entriesWithGoals.sort((a, b) => {
143
+ if (b.goalsScored !== a.goalsScored) {
144
+ return b.goalsScored - a.goalsScored;
145
+ }
146
+ return a.competitor.name.localeCompare(b.competitor.name);
147
+ });
148
+ const offenceEntries = entriesWithGoals.map((item, index) => ({
149
+ rank: index + 1,
150
+ competitor: item.competitor,
151
+ stats: {
152
+ played: item.played,
153
+ points: 0,
154
+ wins: 0,
155
+ draws: 0,
156
+ losses: 0,
157
+ goalsFor: item.goalsScored,
158
+ goalsAgainst: 0,
159
+ goalDifference: 0
160
+ }
161
+ }));
162
+ return {
163
+ ...standings,
164
+ entries: offenceEntries
165
+ };
166
+ }
167
+ function computeDefenceStandings(standings, contextMatches, matchCount, homeAwayFilter) {
168
+ if (!contextMatches || contextMatches.length === 0) {
169
+ return { ...standings, entries: [] };
170
+ }
171
+ const finishedMatches = contextMatches.filter((m) => m.status.type === "FINISHED").sort((a, b) => b.timing.kickoffTime.getTime() - a.timing.kickoffTime.getTime());
172
+ if (finishedMatches.length === 0) {
173
+ return { ...standings, entries: [] };
174
+ }
175
+ const teamStatsMap = /* @__PURE__ */ new Map();
176
+ finishedMatches.forEach((match) => {
177
+ const homeTeamId = match.competitorOne.id;
178
+ const awayTeamId = match.competitorTwo.id;
179
+ if (!teamStatsMap.has(homeTeamId)) {
180
+ teamStatsMap.set(homeTeamId, {
181
+ teamId: homeTeamId,
182
+ competitor: match.competitorOne,
183
+ matches: []
184
+ });
185
+ }
186
+ if (!teamStatsMap.has(awayTeamId)) {
187
+ teamStatsMap.set(awayTeamId, {
188
+ teamId: awayTeamId,
189
+ competitor: match.competitorTwo,
190
+ matches: []
191
+ });
192
+ }
193
+ teamStatsMap.get(homeTeamId).matches.push(match);
194
+ teamStatsMap.get(awayTeamId).matches.push(match);
195
+ });
196
+ const entriesWithGoals = Array.from(teamStatsMap.values()).map((teamData) => {
197
+ const teamId = teamData.teamId;
198
+ let teamMatches = teamData.matches;
199
+ if (homeAwayFilter === "HOME") {
200
+ teamMatches = teamMatches.filter((m) => m.competitorOne.id === teamId);
201
+ } else if (homeAwayFilter === "AWAY") {
202
+ teamMatches = teamMatches.filter((m) => m.competitorTwo.id === teamId);
203
+ }
204
+ teamMatches = teamMatches.sort((a, b) => b.timing.kickoffTime.getTime() - a.timing.kickoffTime.getTime());
205
+ if (matchCount !== void 0) {
206
+ teamMatches = teamMatches.slice(0, matchCount);
207
+ }
208
+ const goalsConceded = teamMatches.reduce((total, match) => {
209
+ const isHome = match.competitorOne.id === teamId;
210
+ const opponentScore = isHome ? parseInt(match.score?.competitorTwo || "0", 10) : parseInt(match.score?.competitorOne || "0", 10);
211
+ return total + opponentScore;
212
+ }, 0);
213
+ return {
214
+ teamId,
215
+ competitor: teamData.competitor,
216
+ goalsConceded,
217
+ played: teamMatches.length
218
+ };
219
+ });
220
+ entriesWithGoals.sort((a, b) => {
221
+ if (a.goalsConceded !== b.goalsConceded) {
222
+ return a.goalsConceded - b.goalsConceded;
223
+ }
224
+ return a.competitor.name.localeCompare(b.competitor.name);
225
+ });
226
+ const defenceEntries = entriesWithGoals.map((item, index) => ({
227
+ rank: index + 1,
228
+ competitor: item.competitor,
229
+ stats: {
230
+ played: item.played,
231
+ points: 0,
232
+ wins: 0,
233
+ draws: 0,
234
+ losses: 0,
235
+ goalsFor: 0,
236
+ goalsAgainst: item.goalsConceded,
237
+ goalDifference: 0
238
+ }
239
+ }));
240
+ return {
241
+ ...standings,
242
+ entries: defenceEntries
243
+ };
244
+ }
245
+ function useMatchStandingsCalculations(standings, contextMatches) {
246
+ const getFormTable = useMemo(() => {
247
+ return (matchCount = 8) => {
248
+ if (!standings || !contextMatches || contextMatches.length === 0) return null;
249
+ return computeFormStandings(standings, contextMatches, matchCount);
250
+ };
251
+ }, [standings, contextMatches]);
252
+ const getHomeFormTable = useMemo(() => {
253
+ return (matchCount = 8) => {
254
+ if (!standings || !contextMatches || contextMatches.length === 0) return null;
255
+ return computeFormStandings(standings, contextMatches, matchCount, "HOME");
256
+ };
257
+ }, [standings, contextMatches]);
258
+ const getAwayFormTable = useMemo(() => {
259
+ return (matchCount = 8) => {
260
+ if (!standings || !contextMatches || contextMatches.length === 0) return null;
261
+ return computeFormStandings(standings, contextMatches, matchCount, "AWAY");
262
+ };
263
+ }, [standings, contextMatches]);
264
+ const getOffenceStandings = useMemo(() => {
265
+ return () => {
266
+ if (!standings || !contextMatches || contextMatches.length === 0) return null;
267
+ return computeOffenceStandings(standings, contextMatches);
268
+ };
269
+ }, [standings, contextMatches]);
270
+ const getFormOffenceStandings = useMemo(() => {
271
+ return (matchCount = 8) => {
272
+ if (!standings || !contextMatches || contextMatches.length === 0) return null;
273
+ return computeOffenceStandings(standings, contextMatches, matchCount);
274
+ };
275
+ }, [standings, contextMatches]);
276
+ const getHomeOffenceStandings = useMemo(() => {
277
+ return () => {
278
+ if (!standings || !contextMatches || contextMatches.length === 0) return null;
279
+ return computeOffenceStandings(standings, contextMatches, void 0, "HOME");
280
+ };
281
+ }, [standings, contextMatches]);
282
+ const getAwayOffenceStandings = useMemo(() => {
283
+ return () => {
284
+ if (!standings || !contextMatches || contextMatches.length === 0) return null;
285
+ return computeOffenceStandings(standings, contextMatches, void 0, "AWAY");
286
+ };
287
+ }, [standings, contextMatches]);
288
+ const getDefenceStandings = useMemo(() => {
289
+ return () => {
290
+ if (!standings || !contextMatches || contextMatches.length === 0) return null;
291
+ return computeDefenceStandings(standings, contextMatches);
292
+ };
293
+ }, [standings, contextMatches]);
294
+ const getFormDefenceStandings = useMemo(() => {
295
+ return (matchCount = 8) => {
296
+ if (!standings || !contextMatches || contextMatches.length === 0) return null;
297
+ return computeDefenceStandings(standings, contextMatches, matchCount);
298
+ };
299
+ }, [standings, contextMatches]);
300
+ const getHomeDefenceStandings = useMemo(() => {
301
+ return () => {
302
+ if (!standings || !contextMatches || contextMatches.length === 0) return null;
303
+ return computeDefenceStandings(standings, contextMatches, void 0, "HOME");
304
+ };
305
+ }, [standings, contextMatches]);
306
+ const getAwayDefenceStandings = useMemo(() => {
307
+ return () => {
308
+ if (!standings || !contextMatches || contextMatches.length === 0) return null;
309
+ return computeDefenceStandings(standings, contextMatches, void 0, "AWAY");
310
+ };
311
+ }, [standings, contextMatches]);
312
+ return {
313
+ // Form-based standings
314
+ getFormTable,
315
+ getHomeFormTable,
316
+ getAwayFormTable,
317
+ // Offence standings
318
+ getOffenceStandings,
319
+ getFormOffenceStandings,
320
+ getHomeOffenceStandings,
321
+ getAwayOffenceStandings,
322
+ // Defence standings
323
+ getDefenceStandings,
324
+ getFormDefenceStandings,
325
+ getHomeDefenceStandings,
326
+ getAwayDefenceStandings
327
+ };
328
+ }
329
+ export {
330
+ useMatchStandingsCalculations
331
+ };
332
+ //# sourceMappingURL=useMatchStandingsCalculations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMatchStandingsCalculations.js","sources":["../../../../src/lib/providers/match/hooks/useMatchStandingsCalculations.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport type { FUSportsStandings, FUSportsStandingEntry, FUSportsMatch } from \"../../../types/canonical\";\n\ntype HomeAwayFilter = \"HOME\" | \"AWAY\" | undefined;\n\n/**\n * Compute form standings from context matches ONLY\n * Builds standings table from scratch using only the matches provided\n */\nfunction computeFormStandings(\n standings: FUSportsStandings,\n contextMatches: FUSportsMatch[],\n matchCount?: number,\n homeAwayFilter?: HomeAwayFilter\n): FUSportsStandings {\n if (!contextMatches || contextMatches.length === 0) {\n return { ...standings, entries: [] };\n }\n\n // Get finished matches sorted by date (most recent first)\n const finishedMatches = contextMatches\n .filter((m) => m.status.type === \"FINISHED\")\n .sort((a, b) => b.timing.kickoffTime.getTime() - a.timing.kickoffTime.getTime());\n\n if (finishedMatches.length === 0) {\n return { ...standings, entries: [] };\n }\n\n // Build a map of team stats from matches\n const teamStatsMap = new Map<\n string,\n {\n teamId: string;\n teamName: string;\n competitor: FUSportsMatch[\"competitorOne\"];\n matches: FUSportsMatch[];\n points: number;\n played: number;\n }\n >();\n\n // Process all finished matches\n finishedMatches.forEach((match) => {\n const homeTeamId = match.competitorOne.id;\n const awayTeamId = match.competitorTwo.id;\n\n // Initialize team entries if they don't exist\n if (!teamStatsMap.has(homeTeamId)) {\n teamStatsMap.set(homeTeamId, {\n teamId: homeTeamId,\n teamName: match.competitorOne.name,\n competitor: match.competitorOne,\n matches: [],\n points: 0,\n played: 0,\n });\n }\n if (!teamStatsMap.has(awayTeamId)) {\n teamStatsMap.set(awayTeamId, {\n teamId: awayTeamId,\n teamName: match.competitorTwo.name,\n competitor: match.competitorTwo,\n matches: [],\n points: 0,\n played: 0,\n });\n }\n\n // Add match to both teams\n teamStatsMap.get(homeTeamId)!.matches.push(match);\n teamStatsMap.get(awayTeamId)!.matches.push(match);\n });\n\n // Calculate form points for each team\n const entriesWithFormPoints = Array.from(teamStatsMap.values()).map((teamData) => {\n const teamId = teamData.teamId;\n\n // Get all matches for this team\n let teamMatches = teamData.matches;\n\n // Filter by home/away if specified\n if (homeAwayFilter === \"HOME\") {\n teamMatches = teamMatches.filter((m) => m.competitorOne.id === teamId);\n } else if (homeAwayFilter === \"AWAY\") {\n teamMatches = teamMatches.filter((m) => m.competitorTwo.id === teamId);\n }\n\n // Sort by date (most recent first) and take last N matches\n teamMatches = teamMatches.sort((a, b) => b.timing.kickoffTime.getTime() - a.timing.kickoffTime.getTime());\n\n if (matchCount !== undefined) {\n teamMatches = teamMatches.slice(0, matchCount);\n }\n\n // Calculate points from these matches\n const formPoints = teamMatches.reduce((pts: number, match) => {\n const isHome = match.competitorOne.id === teamId;\n const teamScore = isHome\n ? parseInt(match.score?.competitorOne || \"0\", 10)\n : parseInt(match.score?.competitorTwo || \"0\", 10);\n const opponentScore = isHome\n ? parseInt(match.score?.competitorTwo || \"0\", 10)\n : parseInt(match.score?.competitorOne || \"0\", 10);\n\n if (teamScore > opponentScore) return pts + 3; // Win\n if (teamScore === opponentScore) return pts + 1; // Draw\n return pts; // Loss\n }, 0);\n\n return {\n teamId,\n competitor: teamData.competitor,\n formPoints,\n formPlayed: teamMatches.length,\n };\n });\n\n // Sort by form points (descending), then by team name for ties\n entriesWithFormPoints.sort((a, b) => {\n if (b.formPoints !== a.formPoints) {\n return b.formPoints - a.formPoints;\n }\n return a.competitor.name.localeCompare(b.competitor.name);\n });\n\n // Create new standings entries\n const formEntries: FUSportsStandingEntry[] = entriesWithFormPoints.map((item, index) => ({\n rank: index + 1,\n competitor: item.competitor,\n stats: {\n played: item.formPlayed,\n points: item.formPoints,\n wins: 0,\n draws: 0,\n losses: 0,\n goalsFor: 0,\n goalsAgainst: 0,\n goalDifference: 0,\n },\n }));\n\n return {\n ...standings,\n entries: formEntries,\n };\n}\n\n/**\n * Compute offence standings (sorted by goals scored) from context matches ONLY\n */\nfunction computeOffenceStandings(\n standings: FUSportsStandings,\n contextMatches: FUSportsMatch[],\n matchCount?: number,\n homeAwayFilter?: HomeAwayFilter\n): FUSportsStandings {\n if (!contextMatches || contextMatches.length === 0) {\n return { ...standings, entries: [] };\n }\n\n // Get finished matches sorted by date (most recent first)\n const finishedMatches = contextMatches\n .filter((m) => m.status.type === \"FINISHED\")\n .sort((a, b) => b.timing.kickoffTime.getTime() - a.timing.kickoffTime.getTime());\n\n if (finishedMatches.length === 0) {\n return { ...standings, entries: [] };\n }\n\n // Build a map of team stats from matches\n const teamStatsMap = new Map<\n string,\n {\n teamId: string;\n competitor: FUSportsMatch[\"competitorOne\"];\n matches: FUSportsMatch[];\n }\n >();\n\n // Process all finished matches\n finishedMatches.forEach((match) => {\n const homeTeamId = match.competitorOne.id;\n const awayTeamId = match.competitorTwo.id;\n\n if (!teamStatsMap.has(homeTeamId)) {\n teamStatsMap.set(homeTeamId, {\n teamId: homeTeamId,\n competitor: match.competitorOne,\n matches: [],\n });\n }\n if (!teamStatsMap.has(awayTeamId)) {\n teamStatsMap.set(awayTeamId, {\n teamId: awayTeamId,\n competitor: match.competitorTwo,\n matches: [],\n });\n }\n\n teamStatsMap.get(homeTeamId)!.matches.push(match);\n teamStatsMap.get(awayTeamId)!.matches.push(match);\n });\n\n // Calculate goals for each team\n const entriesWithGoals = Array.from(teamStatsMap.values()).map((teamData) => {\n const teamId = teamData.teamId;\n\n // Get all matches for this team\n let teamMatches = teamData.matches;\n\n // Filter by home/away if specified\n if (homeAwayFilter === \"HOME\") {\n teamMatches = teamMatches.filter((m) => m.competitorOne.id === teamId);\n } else if (homeAwayFilter === \"AWAY\") {\n teamMatches = teamMatches.filter((m) => m.competitorTwo.id === teamId);\n }\n\n // Sort by date and take last N matches\n teamMatches = teamMatches.sort((a, b) => b.timing.kickoffTime.getTime() - a.timing.kickoffTime.getTime());\n\n if (matchCount !== undefined) {\n teamMatches = teamMatches.slice(0, matchCount);\n }\n\n // Calculate goals scored\n const goalsScored = teamMatches.reduce((total, match) => {\n const isHome = match.competitorOne.id === teamId;\n const teamScore = isHome\n ? parseInt(match.score?.competitorOne || \"0\", 10)\n : parseInt(match.score?.competitorTwo || \"0\", 10);\n return total + teamScore;\n }, 0);\n\n return {\n teamId,\n competitor: teamData.competitor,\n goalsScored,\n played: teamMatches.length,\n };\n });\n\n // Sort by goals scored (descending)\n entriesWithGoals.sort((a, b) => {\n if (b.goalsScored !== a.goalsScored) {\n return b.goalsScored - a.goalsScored;\n }\n return a.competitor.name.localeCompare(b.competitor.name);\n });\n\n const offenceEntries: FUSportsStandingEntry[] = entriesWithGoals.map((item, index) => ({\n rank: index + 1,\n competitor: item.competitor,\n stats: {\n played: item.played,\n points: 0,\n wins: 0,\n draws: 0,\n losses: 0,\n goalsFor: item.goalsScored,\n goalsAgainst: 0,\n goalDifference: 0,\n },\n }));\n\n return {\n ...standings,\n entries: offenceEntries,\n };\n}\n\n/**\n * Compute defence standings (sorted by goals conceded, ascending) from context matches ONLY\n */\nfunction computeDefenceStandings(\n standings: FUSportsStandings,\n contextMatches: FUSportsMatch[],\n matchCount?: number,\n homeAwayFilter?: HomeAwayFilter\n): FUSportsStandings {\n if (!contextMatches || contextMatches.length === 0) {\n return { ...standings, entries: [] };\n }\n\n // Get finished matches sorted by date (most recent first)\n const finishedMatches = contextMatches\n .filter((m) => m.status.type === \"FINISHED\")\n .sort((a, b) => b.timing.kickoffTime.getTime() - a.timing.kickoffTime.getTime());\n\n if (finishedMatches.length === 0) {\n return { ...standings, entries: [] };\n }\n\n // Build a map of team stats from matches\n const teamStatsMap = new Map<\n string,\n {\n teamId: string;\n competitor: FUSportsMatch[\"competitorOne\"];\n matches: FUSportsMatch[];\n }\n >();\n\n // Process all finished matches\n finishedMatches.forEach((match) => {\n const homeTeamId = match.competitorOne.id;\n const awayTeamId = match.competitorTwo.id;\n\n if (!teamStatsMap.has(homeTeamId)) {\n teamStatsMap.set(homeTeamId, {\n teamId: homeTeamId,\n competitor: match.competitorOne,\n matches: [],\n });\n }\n if (!teamStatsMap.has(awayTeamId)) {\n teamStatsMap.set(awayTeamId, {\n teamId: awayTeamId,\n competitor: match.competitorTwo,\n matches: [],\n });\n }\n\n teamStatsMap.get(homeTeamId)!.matches.push(match);\n teamStatsMap.get(awayTeamId)!.matches.push(match);\n });\n\n // Calculate goals conceded for each team\n const entriesWithGoals = Array.from(teamStatsMap.values()).map((teamData) => {\n const teamId = teamData.teamId;\n\n // Get all matches for this team\n let teamMatches = teamData.matches;\n\n // Filter by home/away if specified\n if (homeAwayFilter === \"HOME\") {\n teamMatches = teamMatches.filter((m) => m.competitorOne.id === teamId);\n } else if (homeAwayFilter === \"AWAY\") {\n teamMatches = teamMatches.filter((m) => m.competitorTwo.id === teamId);\n }\n\n // Sort by date and take last N matches\n teamMatches = teamMatches.sort((a, b) => b.timing.kickoffTime.getTime() - a.timing.kickoffTime.getTime());\n\n if (matchCount !== undefined) {\n teamMatches = teamMatches.slice(0, matchCount);\n }\n\n // Calculate goals conceded\n const goalsConceded = teamMatches.reduce((total, match) => {\n const isHome = match.competitorOne.id === teamId;\n const opponentScore = isHome\n ? parseInt(match.score?.competitorTwo || \"0\", 10)\n : parseInt(match.score?.competitorOne || \"0\", 10);\n return total + opponentScore;\n }, 0);\n\n return {\n teamId,\n competitor: teamData.competitor,\n goalsConceded,\n played: teamMatches.length,\n };\n });\n\n // Sort by goals conceded (ascending - fewer is better)\n entriesWithGoals.sort((a, b) => {\n if (a.goalsConceded !== b.goalsConceded) {\n return a.goalsConceded - b.goalsConceded;\n }\n return a.competitor.name.localeCompare(b.competitor.name);\n });\n\n const defenceEntries: FUSportsStandingEntry[] = entriesWithGoals.map((item, index) => ({\n rank: index + 1,\n competitor: item.competitor,\n stats: {\n played: item.played,\n points: 0,\n wins: 0,\n draws: 0,\n losses: 0,\n goalsFor: 0,\n goalsAgainst: item.goalsConceded,\n goalDifference: 0,\n },\n }));\n\n return {\n ...standings,\n entries: defenceEntries,\n };\n}\n\n/**\n * Hook to calculate form, offence, and defence tables from context matches\n * Provides overall, home, and away variants for all calculations\n * Uses ALL matches from contextMatches for accurate calculations\n */\nexport function useMatchStandingsCalculations(standings?: FUSportsStandings, contextMatches?: FUSportsMatch[]) {\n // ========================================================================\n // Form-based standings (points)\n // ========================================================================\n\n const getFormTable = useMemo(() => {\n return (matchCount: number = 8): FUSportsStandings | null => {\n if (!standings || !contextMatches || contextMatches.length === 0) return null;\n return computeFormStandings(standings, contextMatches, matchCount);\n };\n }, [standings, contextMatches]);\n\n const getHomeFormTable = useMemo(() => {\n return (matchCount: number = 8): FUSportsStandings | null => {\n if (!standings || !contextMatches || contextMatches.length === 0) return null;\n return computeFormStandings(standings, contextMatches, matchCount, \"HOME\");\n };\n }, [standings, contextMatches]);\n\n const getAwayFormTable = useMemo(() => {\n return (matchCount: number = 8): FUSportsStandings | null => {\n if (!standings || !contextMatches || contextMatches.length === 0) return null;\n return computeFormStandings(standings, contextMatches, matchCount, \"AWAY\");\n };\n }, [standings, contextMatches]);\n\n // ========================================================================\n // Offence standings (goals scored)\n // ========================================================================\n\n const getOffenceStandings = useMemo(() => {\n return (): FUSportsStandings | null => {\n if (!standings || !contextMatches || contextMatches.length === 0) return null;\n return computeOffenceStandings(standings, contextMatches);\n };\n }, [standings, contextMatches]);\n\n const getFormOffenceStandings = useMemo(() => {\n return (matchCount: number = 8): FUSportsStandings | null => {\n if (!standings || !contextMatches || contextMatches.length === 0) return null;\n return computeOffenceStandings(standings, contextMatches, matchCount);\n };\n }, [standings, contextMatches]);\n\n const getHomeOffenceStandings = useMemo(() => {\n return (): FUSportsStandings | null => {\n if (!standings || !contextMatches || contextMatches.length === 0) return null;\n return computeOffenceStandings(standings, contextMatches, undefined, \"HOME\");\n };\n }, [standings, contextMatches]);\n\n const getAwayOffenceStandings = useMemo(() => {\n return (): FUSportsStandings | null => {\n if (!standings || !contextMatches || contextMatches.length === 0) return null;\n return computeOffenceStandings(standings, contextMatches, undefined, \"AWAY\");\n };\n }, [standings, contextMatches]);\n\n // ========================================================================\n // Defence standings (goals conceded)\n // ========================================================================\n\n const getDefenceStandings = useMemo(() => {\n return (): FUSportsStandings | null => {\n if (!standings || !contextMatches || contextMatches.length === 0) return null;\n return computeDefenceStandings(standings, contextMatches);\n };\n }, [standings, contextMatches]);\n\n const getFormDefenceStandings = useMemo(() => {\n return (matchCount: number = 8): FUSportsStandings | null => {\n if (!standings || !contextMatches || contextMatches.length === 0) return null;\n return computeDefenceStandings(standings, contextMatches, matchCount);\n };\n }, [standings, contextMatches]);\n\n const getHomeDefenceStandings = useMemo(() => {\n return (): FUSportsStandings | null => {\n if (!standings || !contextMatches || contextMatches.length === 0) return null;\n return computeDefenceStandings(standings, contextMatches, undefined, \"HOME\");\n };\n }, [standings, contextMatches]);\n\n const getAwayDefenceStandings = useMemo(() => {\n return (): FUSportsStandings | null => {\n if (!standings || !contextMatches || contextMatches.length === 0) return null;\n return computeDefenceStandings(standings, contextMatches, undefined, \"AWAY\");\n };\n }, [standings, contextMatches]);\n\n return {\n // Form-based standings\n getFormTable,\n getHomeFormTable,\n getAwayFormTable,\n\n // Offence standings\n getOffenceStandings,\n getFormOffenceStandings,\n getHomeOffenceStandings,\n getAwayOffenceStandings,\n\n // Defence standings\n getDefenceStandings,\n getFormDefenceStandings,\n getHomeDefenceStandings,\n getAwayDefenceStandings,\n };\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { useCallback, useMemo } from "react";
2
+ function useMatchStatus(match) {
3
+ const isLive = useCallback(() => {
4
+ if (!match) return false;
5
+ const statusType = match.status?.type || "";
6
+ const statusCode = match.status?.code || "";
7
+ return statusType === "LIVE" || statusCode === "live";
8
+ }, [match]);
9
+ const isFinished = useCallback(() => {
10
+ if (!match) return false;
11
+ return match.status?.type === "FINISHED";
12
+ }, [match]);
13
+ const isUpcoming = useCallback(() => {
14
+ if (!match) return false;
15
+ return match.status?.type === "NOT_STARTED";
16
+ }, [match]);
17
+ const getMatchMinute = useCallback(() => {
18
+ return match?.timing?.currentMinute;
19
+ }, [match]);
20
+ const getMatchPeriod = useCallback(() => {
21
+ return match?.timing?.currentPeriod;
22
+ }, [match]);
23
+ return useMemo(
24
+ () => ({
25
+ isLive,
26
+ isFinished,
27
+ isUpcoming,
28
+ getMatchMinute,
29
+ getMatchPeriod
30
+ }),
31
+ [isLive, isFinished, isUpcoming, getMatchMinute, getMatchPeriod]
32
+ );
33
+ }
34
+ export {
35
+ useMatchStatus
36
+ };
37
+ //# sourceMappingURL=useMatchStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMatchStatus.js","sources":["../../../../src/lib/providers/match/hooks/useMatchStatus.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport type { FUSportsMatch } from \"../../../types/canonical\";\n\n/**\n * Hook for match status-related helper functions\n */\nexport function useMatchStatus(match: FUSportsMatch | undefined) {\n const isLive = useCallback(() => {\n if (!match) return false;\n const statusType = match.status?.type || \"\";\n const statusCode = match.status?.code || \"\";\n return statusType === \"LIVE\" || statusCode === \"live\";\n }, [match]);\n\n const isFinished = useCallback(() => {\n if (!match) return false;\n return match.status?.type === \"FINISHED\";\n }, [match]);\n\n const isUpcoming = useCallback(() => {\n if (!match) return false;\n return match.status?.type === \"NOT_STARTED\";\n }, [match]);\n\n const getMatchMinute = useCallback(() => {\n return match?.timing?.currentMinute;\n }, [match]);\n\n const getMatchPeriod = useCallback(() => {\n return match?.timing?.currentPeriod;\n }, [match]);\n\n return useMemo(\n () => ({\n isLive,\n isFinished,\n isUpcoming,\n getMatchMinute,\n getMatchPeriod,\n }),\n [isLive, isFinished, isUpcoming, getMatchMinute, getMatchPeriod]\n );\n}\n"],"names":[],"mappings":";AAMO,SAAS,eAAe,OAAkC;AAC7D,QAAM,SAAS,YAAY,MAAM;AAC7B,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,aAAa,MAAM,QAAQ,QAAQ;AACzC,UAAM,aAAa,MAAM,QAAQ,QAAQ;AACzC,WAAO,eAAe,UAAU,eAAe;AAAA,EACnD,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,aAAa,YAAY,MAAM;AACjC,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,MAAM,QAAQ,SAAS;AAAA,EAClC,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,aAAa,YAAY,MAAM;AACjC,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,MAAM,QAAQ,SAAS;AAAA,EAClC,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,iBAAiB,YAAY,MAAM;AACrC,WAAO,OAAO,QAAQ;AAAA,EAC1B,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,iBAAiB,YAAY,MAAM;AACrC,WAAO,OAAO,QAAQ;AAAA,EAC1B,GAAG,CAAC,KAAK,CAAC;AAEV,SAAO;AAAA,IACH,OAAO;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAEJ,CAAC,QAAQ,YAAY,YAAY,gBAAgB,cAAc;AAAA,EAAA;AAEvE;"}
@@ -0,0 +1,54 @@
1
+ import { useCallback, useMemo } from "react";
2
+ function useOddsHelpers(odds) {
3
+ const getOddsByMarket = useCallback(
4
+ (marketType) => {
5
+ if (!odds) return [];
6
+ const markets = [];
7
+ for (const operator of odds.operators) {
8
+ const market = operator.markets.find((m) => m.type.code === marketType);
9
+ if (market) {
10
+ markets.push(market);
11
+ }
12
+ }
13
+ return markets;
14
+ },
15
+ [odds]
16
+ );
17
+ const getOddsByOperator = useCallback(
18
+ (operatorId) => {
19
+ if (!odds) return void 0;
20
+ return odds.operators.find((op) => op.operator.id === operatorId);
21
+ },
22
+ [odds]
23
+ );
24
+ const getBestOdds = useCallback(
25
+ (marketType, selection) => {
26
+ const markets = getOddsByMarket(marketType);
27
+ if (markets.length === 0) return void 0;
28
+ let bestOdds = void 0;
29
+ for (const market of markets) {
30
+ const sel = market.selections.find((s) => s.name === selection);
31
+ if (sel && sel.odds) {
32
+ const oddsValue = parseFloat(sel.odds);
33
+ if (!bestOdds || oddsValue > bestOdds) {
34
+ bestOdds = oddsValue;
35
+ }
36
+ }
37
+ }
38
+ return bestOdds;
39
+ },
40
+ [getOddsByMarket]
41
+ );
42
+ return useMemo(
43
+ () => ({
44
+ getOddsByMarket,
45
+ getOddsByOperator,
46
+ getBestOdds
47
+ }),
48
+ [getOddsByMarket, getOddsByOperator, getBestOdds]
49
+ );
50
+ }
51
+ export {
52
+ useOddsHelpers
53
+ };
54
+ //# sourceMappingURL=useOddsHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useOddsHelpers.js","sources":["../../../../src/lib/providers/match/hooks/useOddsHelpers.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport type { FUSportsMatchOdds, FUSportsOddMarket, FUSportsBettingOperatorOdds } from \"../../../types/canonical\";\n\n/**\n * Hook for odds-related helper functions\n */\nexport function useOddsHelpers(odds?: FUSportsMatchOdds) {\n const getOddsByMarket = useCallback(\n (marketType: string): FUSportsOddMarket[] => {\n if (!odds) return [];\n\n const markets: FUSportsOddMarket[] = [];\n\n for (const operator of odds.operators) {\n const market = operator.markets.find((m) => m.type.code === marketType);\n if (market) {\n markets.push(market);\n }\n }\n\n return markets;\n },\n [odds]\n );\n\n const getOddsByOperator = useCallback(\n (operatorId: string): FUSportsBettingOperatorOdds | undefined => {\n if (!odds) return undefined;\n return odds.operators.find((op) => op.operator.id === operatorId);\n },\n [odds]\n );\n\n const getBestOdds = useCallback(\n (marketType: string, selection: string): number | undefined => {\n const markets = getOddsByMarket(marketType);\n if (markets.length === 0) return undefined;\n\n let bestOdds: number | undefined = undefined;\n\n for (const market of markets) {\n const sel = market.selections.find((s) => s.name === selection);\n if (sel && sel.odds) {\n const oddsValue = parseFloat(sel.odds);\n if (!bestOdds || oddsValue > bestOdds) {\n bestOdds = oddsValue;\n }\n }\n }\n\n return bestOdds;\n },\n [getOddsByMarket]\n );\n\n return useMemo(\n () => ({\n getOddsByMarket,\n getOddsByOperator,\n getBestOdds,\n }),\n [getOddsByMarket, getOddsByOperator, getBestOdds]\n );\n}\n"],"names":[],"mappings":";AAMO,SAAS,eAAe,MAA0B;AACrD,QAAM,kBAAkB;AAAA,IACpB,CAAC,eAA4C;AACzC,UAAI,CAAC,KAAM,QAAO,CAAA;AAElB,YAAM,UAA+B,CAAA;AAErC,iBAAW,YAAY,KAAK,WAAW;AACnC,cAAM,SAAS,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,KAAK,SAAS,UAAU;AACtE,YAAI,QAAQ;AACR,kBAAQ,KAAK,MAAM;AAAA,QACvB;AAAA,MACJ;AAEA,aAAO;AAAA,IACX;AAAA,IACA,CAAC,IAAI;AAAA,EAAA;AAGT,QAAM,oBAAoB;AAAA,IACtB,CAAC,eAAgE;AAC7D,UAAI,CAAC,KAAM,QAAO;AAClB,aAAO,KAAK,UAAU,KAAK,CAAC,OAAO,GAAG,SAAS,OAAO,UAAU;AAAA,IACpE;AAAA,IACA,CAAC,IAAI;AAAA,EAAA;AAGT,QAAM,cAAc;AAAA,IAChB,CAAC,YAAoB,cAA0C;AAC3D,YAAM,UAAU,gBAAgB,UAAU;AAC1C,UAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,UAAI,WAA+B;AAEnC,iBAAW,UAAU,SAAS;AAC1B,cAAM,MAAM,OAAO,WAAW,KAAK,CAAC,MAAM,EAAE,SAAS,SAAS;AAC9D,YAAI,OAAO,IAAI,MAAM;AACjB,gBAAM,YAAY,WAAW,IAAI,IAAI;AACrC,cAAI,CAAC,YAAY,YAAY,UAAU;AACnC,uBAAW;AAAA,UACf;AAAA,QACJ;AAAA,MACJ;AAEA,aAAO;AAAA,IACX;AAAA,IACA,CAAC,eAAe;AAAA,EAAA;AAGpB,SAAO;AAAA,IACH,OAAO;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAEJ,CAAC,iBAAiB,mBAAmB,WAAW;AAAA,EAAA;AAExD;"}
@@ -0,0 +1,34 @@
1
+ import { useCallback, useMemo } from "react";
2
+ function useScoreHelpers(match) {
3
+ const getScore = useCallback(() => {
4
+ if (!match?.score) return void 0;
5
+ const home = parseInt(match.score.competitorOne || "0", 10);
6
+ const away = parseInt(match.score.competitorTwo || "0", 10);
7
+ return { home, away };
8
+ }, [match]);
9
+ const getHalfTimeScore = useCallback(() => {
10
+ if (!match?.score?.breakdown?.halfTime) return void 0;
11
+ const home = parseInt(match.score.breakdown.halfTime.competitorOne || "0", 10);
12
+ const away = parseInt(match.score.breakdown.halfTime.competitorTwo || "0", 10);
13
+ return { home, away };
14
+ }, [match]);
15
+ const getWinner = useCallback(() => {
16
+ const score = getScore();
17
+ if (!score) return void 0;
18
+ if (score.home > score.away) return "home";
19
+ if (score.away > score.home) return "away";
20
+ return "draw";
21
+ }, [getScore]);
22
+ return useMemo(
23
+ () => ({
24
+ getScore,
25
+ getHalfTimeScore,
26
+ getWinner
27
+ }),
28
+ [getScore, getHalfTimeScore, getWinner]
29
+ );
30
+ }
31
+ export {
32
+ useScoreHelpers
33
+ };
34
+ //# sourceMappingURL=useScoreHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useScoreHelpers.js","sources":["../../../../src/lib/providers/match/hooks/useScoreHelpers.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport type { FUSportsMatch } from \"../../../types/canonical\";\n\n/**\n * Hook for score-related helper functions\n */\nexport function useScoreHelpers(match: FUSportsMatch | undefined) {\n const getScore = useCallback(() => {\n if (!match?.score) return undefined;\n\n const home = parseInt(match.score.competitorOne || \"0\", 10);\n const away = parseInt(match.score.competitorTwo || \"0\", 10);\n\n return { home, away };\n }, [match]);\n\n const getHalfTimeScore = useCallback(() => {\n if (!match?.score?.breakdown?.halfTime) return undefined;\n\n const home = parseInt(match.score.breakdown.halfTime.competitorOne || \"0\", 10);\n const away = parseInt(match.score.breakdown.halfTime.competitorTwo || \"0\", 10);\n\n return { home, away };\n }, [match]);\n\n const getWinner = useCallback((): \"home\" | \"away\" | \"draw\" | undefined => {\n const score = getScore();\n if (!score) return undefined;\n\n if (score.home > score.away) return \"home\";\n if (score.away > score.home) return \"away\";\n return \"draw\";\n }, [getScore]);\n\n return useMemo(\n () => ({\n getScore,\n getHalfTimeScore,\n getWinner,\n }),\n [getScore, getHalfTimeScore, getWinner]\n );\n}\n"],"names":[],"mappings":";AAMO,SAAS,gBAAgB,OAAkC;AAC9D,QAAM,WAAW,YAAY,MAAM;AAC/B,QAAI,CAAC,OAAO,MAAO,QAAO;AAE1B,UAAM,OAAO,SAAS,MAAM,MAAM,iBAAiB,KAAK,EAAE;AAC1D,UAAM,OAAO,SAAS,MAAM,MAAM,iBAAiB,KAAK,EAAE;AAE1D,WAAO,EAAE,MAAM,KAAA;AAAA,EACnB,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,mBAAmB,YAAY,MAAM;AACvC,QAAI,CAAC,OAAO,OAAO,WAAW,SAAU,QAAO;AAE/C,UAAM,OAAO,SAAS,MAAM,MAAM,UAAU,SAAS,iBAAiB,KAAK,EAAE;AAC7E,UAAM,OAAO,SAAS,MAAM,MAAM,UAAU,SAAS,iBAAiB,KAAK,EAAE;AAE7E,WAAO,EAAE,MAAM,KAAA;AAAA,EACnB,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,YAAY,YAAY,MAA4C;AACtE,UAAM,QAAQ,SAAA;AACd,QAAI,CAAC,MAAO,QAAO;AAEnB,QAAI,MAAM,OAAO,MAAM,KAAM,QAAO;AACpC,QAAI,MAAM,OAAO,MAAM,KAAM,QAAO;AACpC,WAAO;AAAA,EACX,GAAG,CAAC,QAAQ,CAAC;AAEb,SAAO;AAAA,IACH,OAAO;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAEJ,CAAC,UAAU,kBAAkB,SAAS;AAAA,EAAA;AAE9C;"}
@@ -0,0 +1,53 @@
1
+ import { useMemo, useCallback } from "react";
2
+ function useStandingsHelpers(standings) {
3
+ const entries = useMemo(() => standings?.entries ?? [], [standings?.entries]);
4
+ const getTeamStanding = useCallback(
5
+ (teamId) => entries.find((entry) => entry.competitor.id === teamId),
6
+ [entries]
7
+ );
8
+ const getTeamRank = useCallback(
9
+ (teamId) => {
10
+ const standing = getTeamStanding(teamId);
11
+ return standing?.rank;
12
+ },
13
+ [getTeamStanding]
14
+ );
15
+ const getTeamSeasonStats = useCallback(
16
+ (teamId) => {
17
+ const standing = getTeamStanding(teamId);
18
+ if (!standing) return void 0;
19
+ return {
20
+ position: standing.rank,
21
+ points: standing.stats.points ?? 0,
22
+ played: standing.stats.played ?? 0,
23
+ won: standing.stats.won ?? 0,
24
+ drawn: standing.stats.drawn ?? 0,
25
+ lost: standing.stats.lost ?? 0,
26
+ goalsFor: standing.stats.goalsFor ?? 0,
27
+ goalsAgainst: standing.stats.goalsAgainst ?? 0,
28
+ goalDifference: standing.stats.goalDifference ?? 0
29
+ };
30
+ },
31
+ [getTeamStanding]
32
+ );
33
+ const getTeamStandingForm = useCallback(
34
+ (teamId) => {
35
+ const standing = getTeamStanding(teamId);
36
+ return standing?.form;
37
+ },
38
+ [getTeamStanding]
39
+ );
40
+ return useMemo(
41
+ () => ({
42
+ getTeamStanding,
43
+ getTeamRank,
44
+ getTeamSeasonStats,
45
+ getTeamStandingForm
46
+ }),
47
+ [getTeamStanding, getTeamRank, getTeamSeasonStats, getTeamStandingForm]
48
+ );
49
+ }
50
+ export {
51
+ useStandingsHelpers
52
+ };
53
+ //# sourceMappingURL=useStandingsHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStandingsHelpers.js","sources":["../../../../src/lib/providers/match/hooks/useStandingsHelpers.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport type { FUSportsStandings } from \"../../../types/canonical\";\n\n/**\n * Hook for basic standings helper functions in match context\n * Simplified version for working with standings data when available\n */\nexport function useStandingsHelpers(standings?: FUSportsStandings) {\n // Memoize the entries array to prevent unnecessary recalculations\n const entries = useMemo(() => standings?.entries ?? [], [standings?.entries]);\n\n const getTeamStanding = useCallback(\n (teamId: string) => entries.find((entry) => entry.competitor.id === teamId),\n [entries]\n );\n\n const getTeamRank = useCallback(\n (teamId: string) => {\n const standing = getTeamStanding(teamId);\n return standing?.rank;\n },\n [getTeamStanding]\n );\n\n /**\n * Get team's season statistics from standings\n * Returns formatted stats including position, points, matches played, wins, losses, draws, goals\n */\n const getTeamSeasonStats = useCallback(\n (teamId: string) => {\n const standing = getTeamStanding(teamId);\n if (!standing) return undefined;\n\n return {\n position: standing.rank,\n points: standing.stats.points ?? 0,\n played: standing.stats.played ?? 0,\n won: standing.stats.won ?? 0,\n drawn: standing.stats.drawn ?? 0,\n lost: standing.stats.lost ?? 0,\n goalsFor: standing.stats.goalsFor ?? 0,\n goalsAgainst: standing.stats.goalsAgainst ?? 0,\n goalDifference: standing.stats.goalDifference ?? 0,\n };\n },\n [getTeamStanding]\n );\n\n /**\n * Get team's form from standings (detailed form with match results)\n */\n const getTeamStandingForm = useCallback(\n (teamId: string) => {\n const standing = getTeamStanding(teamId);\n return standing?.form;\n },\n [getTeamStanding]\n );\n\n return useMemo(\n () => ({\n getTeamStanding,\n getTeamRank,\n getTeamSeasonStats,\n getTeamStandingForm,\n }),\n [getTeamStanding, getTeamRank, getTeamSeasonStats, getTeamStandingForm]\n );\n}\n"],"names":[],"mappings":";AAOO,SAAS,oBAAoB,WAA+B;AAE/D,QAAM,UAAU,QAAQ,MAAM,WAAW,WAAW,IAAI,CAAC,WAAW,OAAO,CAAC;AAE5E,QAAM,kBAAkB;AAAA,IACpB,CAAC,WAAmB,QAAQ,KAAK,CAAC,UAAU,MAAM,WAAW,OAAO,MAAM;AAAA,IAC1E,CAAC,OAAO;AAAA,EAAA;AAGZ,QAAM,cAAc;AAAA,IAChB,CAAC,WAAmB;AAChB,YAAM,WAAW,gBAAgB,MAAM;AACvC,aAAO,UAAU;AAAA,IACrB;AAAA,IACA,CAAC,eAAe;AAAA,EAAA;AAOpB,QAAM,qBAAqB;AAAA,IACvB,CAAC,WAAmB;AAChB,YAAM,WAAW,gBAAgB,MAAM;AACvC,UAAI,CAAC,SAAU,QAAO;AAEtB,aAAO;AAAA,QACH,UAAU,SAAS;AAAA,QACnB,QAAQ,SAAS,MAAM,UAAU;AAAA,QACjC,QAAQ,SAAS,MAAM,UAAU;AAAA,QACjC,KAAK,SAAS,MAAM,OAAO;AAAA,QAC3B,OAAO,SAAS,MAAM,SAAS;AAAA,QAC/B,MAAM,SAAS,MAAM,QAAQ;AAAA,QAC7B,UAAU,SAAS,MAAM,YAAY;AAAA,QACrC,cAAc,SAAS,MAAM,gBAAgB;AAAA,QAC7C,gBAAgB,SAAS,MAAM,kBAAkB;AAAA,MAAA;AAAA,IAEzD;AAAA,IACA,CAAC,eAAe;AAAA,EAAA;AAMpB,QAAM,sBAAsB;AAAA,IACxB,CAAC,WAAmB;AAChB,YAAM,WAAW,gBAAgB,MAAM;AACvC,aAAO,UAAU;AAAA,IACrB;AAAA,IACA,CAAC,eAAe;AAAA,EAAA;AAGpB,SAAO;AAAA,IACH,OAAO;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAEJ,CAAC,iBAAiB,aAAa,oBAAoB,mBAAmB;AAAA,EAAA;AAE9E;"}
@@ -0,0 +1,40 @@
1
+ import { useCallback, useMemo } from "react";
2
+ function useStatisticsHelpers(match, statistics) {
3
+ const getTeamStatistics = useCallback(
4
+ (teamId) => {
5
+ if (!statistics || !match) return void 0;
6
+ const isHome = match.competitorOne.id === teamId;
7
+ return isHome ? statistics.competitorOne : statistics.competitorTwo;
8
+ },
9
+ [statistics, match]
10
+ );
11
+ const getStatistic = useCallback(
12
+ (teamId, key) => {
13
+ const teamStats = getTeamStatistics(teamId);
14
+ return teamStats?.statistics.find((s) => s.key === key);
15
+ },
16
+ [getTeamStatistics]
17
+ );
18
+ const getPossession = useCallback(() => {
19
+ if (!statistics) return void 0;
20
+ const homePossession = statistics.competitorOne.statistics.find((s) => s.key === "possession");
21
+ const awayPossession = statistics.competitorTwo.statistics.find((s) => s.key === "possession");
22
+ if (!homePossession || !awayPossession) return void 0;
23
+ return {
24
+ home: parseInt(homePossession.value, 10),
25
+ away: parseInt(awayPossession.value, 10)
26
+ };
27
+ }, [statistics]);
28
+ return useMemo(
29
+ () => ({
30
+ getTeamStatistics,
31
+ getStatistic,
32
+ getPossession
33
+ }),
34
+ [getTeamStatistics, getStatistic, getPossession]
35
+ );
36
+ }
37
+ export {
38
+ useStatisticsHelpers
39
+ };
40
+ //# sourceMappingURL=useStatisticsHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStatisticsHelpers.js","sources":["../../../../src/lib/providers/match/hooks/useStatisticsHelpers.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport type {\n FUSportsMatch,\n FUSportsMatchStatistics,\n FUSportsCompetitorStatistics,\n FUSportsStatisticEntry,\n} from \"../../../types/canonical\";\n\n/**\n * Hook for statistics-related helper functions\n */\nexport function useStatisticsHelpers(match: FUSportsMatch | undefined, statistics?: FUSportsMatchStatistics) {\n const getTeamStatistics = useCallback(\n (teamId: string): FUSportsCompetitorStatistics | undefined => {\n if (!statistics || !match) return undefined;\n\n const isHome = match.competitorOne.id === teamId;\n return isHome ? statistics.competitorOne : statistics.competitorTwo;\n },\n [statistics, match]\n );\n\n const getStatistic = useCallback(\n (teamId: string, key: string): FUSportsStatisticEntry | undefined => {\n const teamStats = getTeamStatistics(teamId);\n return teamStats?.statistics.find((s) => s.key === key);\n },\n [getTeamStatistics]\n );\n\n const getPossession = useCallback((): { home: number; away: number } | undefined => {\n if (!statistics) return undefined;\n\n const homePossession = statistics.competitorOne.statistics.find((s) => s.key === \"possession\");\n const awayPossession = statistics.competitorTwo.statistics.find((s) => s.key === \"possession\");\n\n if (!homePossession || !awayPossession) return undefined;\n\n return {\n home: parseInt(homePossession.value, 10),\n away: parseInt(awayPossession.value, 10),\n };\n }, [statistics]);\n\n return useMemo(\n () => ({\n getTeamStatistics,\n getStatistic,\n getPossession,\n }),\n [getTeamStatistics, getStatistic, getPossession]\n );\n}\n"],"names":[],"mappings":";AAWO,SAAS,qBAAqB,OAAkC,YAAsC;AACzG,QAAM,oBAAoB;AAAA,IACtB,CAAC,WAA6D;AAC1D,UAAI,CAAC,cAAc,CAAC,MAAO,QAAO;AAElC,YAAM,SAAS,MAAM,cAAc,OAAO;AAC1C,aAAO,SAAS,WAAW,gBAAgB,WAAW;AAAA,IAC1D;AAAA,IACA,CAAC,YAAY,KAAK;AAAA,EAAA;AAGtB,QAAM,eAAe;AAAA,IACjB,CAAC,QAAgB,QAAoD;AACjE,YAAM,YAAY,kBAAkB,MAAM;AAC1C,aAAO,WAAW,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG;AAAA,IAC1D;AAAA,IACA,CAAC,iBAAiB;AAAA,EAAA;AAGtB,QAAM,gBAAgB,YAAY,MAAkD;AAChF,QAAI,CAAC,WAAY,QAAO;AAExB,UAAM,iBAAiB,WAAW,cAAc,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,YAAY;AAC7F,UAAM,iBAAiB,WAAW,cAAc,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,YAAY;AAE7F,QAAI,CAAC,kBAAkB,CAAC,eAAgB,QAAO;AAE/C,WAAO;AAAA,MACH,MAAM,SAAS,eAAe,OAAO,EAAE;AAAA,MACvC,MAAM,SAAS,eAAe,OAAO,EAAE;AAAA,IAAA;AAAA,EAE/C,GAAG,CAAC,UAAU,CAAC;AAEf,SAAO;AAAA,IACH,OAAO;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAEJ,CAAC,mBAAmB,cAAc,aAAa;AAAA,EAAA;AAEvD;"}