@agg-build/ui 2.5.2 → 2.5.3

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.
@@ -664,6 +664,22 @@ var resolveSportsSectionFilters = (key) => {
664
664
  period: resolvedDefinition.period ? [...resolvedDefinition.period] : void 0
665
665
  };
666
666
  };
667
+ var hasTeamTitledOutcomes = (market) => {
668
+ var _a;
669
+ const titles = ((_a = market.venueMarketOutcomes) != null ? _a : []).map(
670
+ (outcome) => toTrimmedString(outcome.title)
671
+ );
672
+ return titles.length > 1 && titles.every((title) => title && !YES_NO_LABELS.has(title.toLowerCase())) && new Set(titles).size === titles.length;
673
+ };
674
+ var isClusterRelation = (left, right) => {
675
+ var _a, _b;
676
+ return ((_a = left.matchedVenueMarkets) != null ? _a : []).some((market) => market.id === right.id) || ((_b = right.matchedVenueMarkets) != null ? _b : []).some((market) => market.id === left.id);
677
+ };
678
+ var dropDecomposedLegsMergedIntoSingle = (markets) => markets.filter(
679
+ (market) => hasTeamTitledOutcomes(market) || !markets.some(
680
+ (other) => other !== market && hasTeamTitledOutcomes(other) && isClusterRelation(market, other)
681
+ )
682
+ );
667
683
  var resolveSportsSectionMarkets = ({
668
684
  tabKey,
669
685
  eventMarkets,
@@ -693,7 +709,7 @@ var resolveSportsSectionMarkets = ({
693
709
  seenKeys.add(key);
694
710
  dedupedMarkets.push(market);
695
711
  }
696
- return dedupedMarkets;
712
+ return dropDecomposedLegsMergedIntoSingle(dedupedMarkets);
697
713
  };
698
714
  const eventMoneylineMarkets = dedupeEventMarketsOfType("moneyline");
699
715
  const eventToAdvanceMarkets = dedupeEventMarketsOfType("to_advance");
@@ -1387,6 +1403,15 @@ function SportsLineRail({
1387
1403
 
1388
1404
  // src/pages/event-market/sports-market-card.tsx
1389
1405
  import { jsx as jsx3 } from "react/jsx-runtime";
1406
+ var resolveSportsLineOutcomeSide = (outcome) => {
1407
+ var _a;
1408
+ for (const candidate of [outcome.label, outcome.title]) {
1409
+ if (typeof candidate !== "string") continue;
1410
+ const matchedSide = (_a = candidate.trim().toLowerCase().match(/(?:^|\s)(over|under)(?=\s|$)/)) == null ? void 0 : _a[1];
1411
+ if (matchedSide === "over" || matchedSide === "under") return matchedSide;
1412
+ }
1413
+ return null;
1414
+ };
1390
1415
  var SportsMarketCard = ({
1391
1416
  group,
1392
1417
  venueMarkets,
@@ -1549,16 +1574,22 @@ var SportsMarketCard = ({
1549
1574
  setSelectedLineIndex(index);
1550
1575
  const market = (_a2 = slide.stops[index]) == null ? void 0 : _a2.market;
1551
1576
  if (!market) return;
1552
- const isGroupBeingTraded = group.markets.some(
1553
- (groupMarket) => groupMarket.id === (tradingContext == null ? void 0 : tradingContext.selectedMarketId)
1554
- );
1555
- if (!isGroupBeingTraded) return;
1556
1577
  const previousOutcomeIndex = previousMarket ? previousMarket.venueMarketOutcomes.findIndex(
1557
1578
  (outcome) => outcome.id === (tradingContext == null ? void 0 : tradingContext.selectedOutcomeId)
1558
1579
  ) : -1;
1559
- const nextOutcome = (_b2 = previousOutcomeIndex >= 0 ? market.venueMarketOutcomes[previousOutcomeIndex] : void 0) != null ? _b2 : market.venueMarketOutcomes[0];
1580
+ const previousOutcome = previousOutcomeIndex >= 0 ? previousMarket == null ? void 0 : previousMarket.venueMarketOutcomes[previousOutcomeIndex] : void 0;
1581
+ const previousOutcomeSide = previousOutcome ? resolveSportsLineOutcomeSide(previousOutcome) : null;
1582
+ const matchingSideOutcomes = previousOutcomeSide ? market.venueMarketOutcomes.filter(
1583
+ (outcome) => resolveSportsLineOutcomeSide(outcome) === previousOutcomeSide
1584
+ ) : [];
1585
+ const matchingSideOutcome = matchingSideOutcomes.length === 1 ? matchingSideOutcomes[0] : void 0;
1586
+ const nextOutcome = (_b2 = matchingSideOutcome != null ? matchingSideOutcome : previousOutcomeIndex >= 0 ? market.venueMarketOutcomes[previousOutcomeIndex] : void 0) != null ? _b2 : market.venueMarketOutcomes[0];
1560
1587
  if (nextOutcome) {
1561
1588
  tradingContext == null ? void 0 : tradingContext.selectMarketAndOutcome(market.id, nextOutcome.id);
1589
+ onOutcomeSelect == null ? void 0 : onOutcomeSelect(group.id, {
1590
+ marketId: market.id,
1591
+ outcomeId: nextOutcome.id
1592
+ });
1562
1593
  } else {
1563
1594
  tradingContext == null ? void 0 : tradingContext.selectMarket(market.id, market);
1564
1595
  }
package/dist/index.js CHANGED
@@ -25933,6 +25933,22 @@ var resolveSportsSectionFilters = (key) => {
25933
25933
  period: resolvedDefinition.period ? [...resolvedDefinition.period] : void 0
25934
25934
  };
25935
25935
  };
25936
+ var hasTeamTitledOutcomes = (market) => {
25937
+ var _a;
25938
+ const titles = ((_a = market.venueMarketOutcomes) != null ? _a : []).map(
25939
+ (outcome) => toTrimmedString(outcome.title)
25940
+ );
25941
+ return titles.length > 1 && titles.every((title2) => title2 && !YES_NO_LABELS.has(title2.toLowerCase())) && new Set(titles).size === titles.length;
25942
+ };
25943
+ var isClusterRelation = (left, right) => {
25944
+ var _a, _b;
25945
+ return ((_a = left.matchedVenueMarkets) != null ? _a : []).some((market) => market.id === right.id) || ((_b = right.matchedVenueMarkets) != null ? _b : []).some((market) => market.id === left.id);
25946
+ };
25947
+ var dropDecomposedLegsMergedIntoSingle = (markets) => markets.filter(
25948
+ (market) => hasTeamTitledOutcomes(market) || !markets.some(
25949
+ (other) => other !== market && hasTeamTitledOutcomes(other) && isClusterRelation(market, other)
25950
+ )
25951
+ );
25936
25952
  var resolveSportsSectionMarkets = ({
25937
25953
  tabKey,
25938
25954
  eventMarkets,
@@ -25962,7 +25978,7 @@ var resolveSportsSectionMarkets = ({
25962
25978
  seenKeys.add(key);
25963
25979
  dedupedMarkets.push(market);
25964
25980
  }
25965
- return dedupedMarkets;
25981
+ return dropDecomposedLegsMergedIntoSingle(dedupedMarkets);
25966
25982
  };
25967
25983
  const eventMoneylineMarkets = dedupeEventMarketsOfType("moneyline");
25968
25984
  const eventToAdvanceMarkets = dedupeEventMarketsOfType("to_advance");
@@ -26650,6 +26666,15 @@ function SportsLineRail({
26650
26666
 
26651
26667
  // src/pages/event-market/sports-market-card.tsx
26652
26668
  var import_jsx_runtime169 = require("react/jsx-runtime");
26669
+ var resolveSportsLineOutcomeSide = (outcome) => {
26670
+ var _a;
26671
+ for (const candidate of [outcome.label, outcome.title]) {
26672
+ if (typeof candidate !== "string") continue;
26673
+ const matchedSide = (_a = candidate.trim().toLowerCase().match(/(?:^|\s)(over|under)(?=\s|$)/)) == null ? void 0 : _a[1];
26674
+ if (matchedSide === "over" || matchedSide === "under") return matchedSide;
26675
+ }
26676
+ return null;
26677
+ };
26653
26678
  var SportsMarketCard = ({
26654
26679
  group,
26655
26680
  venueMarkets,
@@ -26812,16 +26837,22 @@ var SportsMarketCard = ({
26812
26837
  setSelectedLineIndex(index);
26813
26838
  const market = (_a2 = slide.stops[index]) == null ? void 0 : _a2.market;
26814
26839
  if (!market) return;
26815
- const isGroupBeingTraded = group.markets.some(
26816
- (groupMarket) => groupMarket.id === (tradingContext == null ? void 0 : tradingContext.selectedMarketId)
26817
- );
26818
- if (!isGroupBeingTraded) return;
26819
26840
  const previousOutcomeIndex = previousMarket ? previousMarket.venueMarketOutcomes.findIndex(
26820
26841
  (outcome) => outcome.id === (tradingContext == null ? void 0 : tradingContext.selectedOutcomeId)
26821
26842
  ) : -1;
26822
- const nextOutcome = (_b2 = previousOutcomeIndex >= 0 ? market.venueMarketOutcomes[previousOutcomeIndex] : void 0) != null ? _b2 : market.venueMarketOutcomes[0];
26843
+ const previousOutcome = previousOutcomeIndex >= 0 ? previousMarket == null ? void 0 : previousMarket.venueMarketOutcomes[previousOutcomeIndex] : void 0;
26844
+ const previousOutcomeSide = previousOutcome ? resolveSportsLineOutcomeSide(previousOutcome) : null;
26845
+ const matchingSideOutcomes = previousOutcomeSide ? market.venueMarketOutcomes.filter(
26846
+ (outcome) => resolveSportsLineOutcomeSide(outcome) === previousOutcomeSide
26847
+ ) : [];
26848
+ const matchingSideOutcome = matchingSideOutcomes.length === 1 ? matchingSideOutcomes[0] : void 0;
26849
+ const nextOutcome = (_b2 = matchingSideOutcome != null ? matchingSideOutcome : previousOutcomeIndex >= 0 ? market.venueMarketOutcomes[previousOutcomeIndex] : void 0) != null ? _b2 : market.venueMarketOutcomes[0];
26823
26850
  if (nextOutcome) {
26824
26851
  tradingContext == null ? void 0 : tradingContext.selectMarketAndOutcome(market.id, nextOutcome.id);
26852
+ onOutcomeSelect == null ? void 0 : onOutcomeSelect(group.id, {
26853
+ marketId: market.id,
26854
+ outcomeId: nextOutcome.id
26855
+ });
26825
26856
  } else {
26826
26857
  tradingContext == null ? void 0 : tradingContext.selectMarket(market.id, market);
26827
26858
  }
package/dist/index.mjs CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  UserProfilePage,
12
12
  buildAggTxExplorerHref,
13
13
  useHomePageModals
14
- } from "./chunk-AJJ73RM4.mjs";
14
+ } from "./chunk-AELMIG74.mjs";
15
15
  import {
16
16
  EventList,
17
17
  EventListItem,
package/dist/pages.js CHANGED
@@ -23712,6 +23712,22 @@ var resolveSportsSectionFilters = (key) => {
23712
23712
  period: resolvedDefinition.period ? [...resolvedDefinition.period] : void 0
23713
23713
  };
23714
23714
  };
23715
+ var hasTeamTitledOutcomes = (market) => {
23716
+ var _a;
23717
+ const titles = ((_a = market.venueMarketOutcomes) != null ? _a : []).map(
23718
+ (outcome) => toTrimmedString(outcome.title)
23719
+ );
23720
+ return titles.length > 1 && titles.every((title2) => title2 && !YES_NO_LABELS.has(title2.toLowerCase())) && new Set(titles).size === titles.length;
23721
+ };
23722
+ var isClusterRelation = (left, right) => {
23723
+ var _a, _b;
23724
+ return ((_a = left.matchedVenueMarkets) != null ? _a : []).some((market) => market.id === right.id) || ((_b = right.matchedVenueMarkets) != null ? _b : []).some((market) => market.id === left.id);
23725
+ };
23726
+ var dropDecomposedLegsMergedIntoSingle = (markets) => markets.filter(
23727
+ (market) => hasTeamTitledOutcomes(market) || !markets.some(
23728
+ (other) => other !== market && hasTeamTitledOutcomes(other) && isClusterRelation(market, other)
23729
+ )
23730
+ );
23715
23731
  var resolveSportsSectionMarkets = ({
23716
23732
  tabKey,
23717
23733
  eventMarkets,
@@ -23741,7 +23757,7 @@ var resolveSportsSectionMarkets = ({
23741
23757
  seenKeys.add(key);
23742
23758
  dedupedMarkets.push(market);
23743
23759
  }
23744
- return dedupedMarkets;
23760
+ return dropDecomposedLegsMergedIntoSingle(dedupedMarkets);
23745
23761
  };
23746
23762
  const eventMoneylineMarkets = dedupeEventMarketsOfType("moneyline");
23747
23763
  const eventToAdvanceMarkets = dedupeEventMarketsOfType("to_advance");
@@ -24429,6 +24445,15 @@ function SportsLineRail({
24429
24445
 
24430
24446
  // src/pages/event-market/sports-market-card.tsx
24431
24447
  var import_jsx_runtime161 = require("react/jsx-runtime");
24448
+ var resolveSportsLineOutcomeSide = (outcome) => {
24449
+ var _a;
24450
+ for (const candidate of [outcome.label, outcome.title]) {
24451
+ if (typeof candidate !== "string") continue;
24452
+ const matchedSide = (_a = candidate.trim().toLowerCase().match(/(?:^|\s)(over|under)(?=\s|$)/)) == null ? void 0 : _a[1];
24453
+ if (matchedSide === "over" || matchedSide === "under") return matchedSide;
24454
+ }
24455
+ return null;
24456
+ };
24432
24457
  var SportsMarketCard = ({
24433
24458
  group,
24434
24459
  venueMarkets,
@@ -24591,16 +24616,22 @@ var SportsMarketCard = ({
24591
24616
  setSelectedLineIndex(index);
24592
24617
  const market = (_a2 = slide.stops[index]) == null ? void 0 : _a2.market;
24593
24618
  if (!market) return;
24594
- const isGroupBeingTraded = group.markets.some(
24595
- (groupMarket) => groupMarket.id === (tradingContext == null ? void 0 : tradingContext.selectedMarketId)
24596
- );
24597
- if (!isGroupBeingTraded) return;
24598
24619
  const previousOutcomeIndex = previousMarket ? previousMarket.venueMarketOutcomes.findIndex(
24599
24620
  (outcome) => outcome.id === (tradingContext == null ? void 0 : tradingContext.selectedOutcomeId)
24600
24621
  ) : -1;
24601
- const nextOutcome = (_b2 = previousOutcomeIndex >= 0 ? market.venueMarketOutcomes[previousOutcomeIndex] : void 0) != null ? _b2 : market.venueMarketOutcomes[0];
24622
+ const previousOutcome = previousOutcomeIndex >= 0 ? previousMarket == null ? void 0 : previousMarket.venueMarketOutcomes[previousOutcomeIndex] : void 0;
24623
+ const previousOutcomeSide = previousOutcome ? resolveSportsLineOutcomeSide(previousOutcome) : null;
24624
+ const matchingSideOutcomes = previousOutcomeSide ? market.venueMarketOutcomes.filter(
24625
+ (outcome) => resolveSportsLineOutcomeSide(outcome) === previousOutcomeSide
24626
+ ) : [];
24627
+ const matchingSideOutcome = matchingSideOutcomes.length === 1 ? matchingSideOutcomes[0] : void 0;
24628
+ const nextOutcome = (_b2 = matchingSideOutcome != null ? matchingSideOutcome : previousOutcomeIndex >= 0 ? market.venueMarketOutcomes[previousOutcomeIndex] : void 0) != null ? _b2 : market.venueMarketOutcomes[0];
24602
24629
  if (nextOutcome) {
24603
24630
  tradingContext == null ? void 0 : tradingContext.selectMarketAndOutcome(market.id, nextOutcome.id);
24631
+ onOutcomeSelect == null ? void 0 : onOutcomeSelect(group.id, {
24632
+ marketId: market.id,
24633
+ outcomeId: nextOutcome.id
24634
+ });
24604
24635
  } else {
24605
24636
  tradingContext == null ? void 0 : tradingContext.selectMarket(market.id, market);
24606
24637
  }
package/dist/pages.mjs CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  UserProfilePage,
9
9
  buildAggTxExplorerHref,
10
10
  useHomePageModals
11
- } from "./chunk-AJJ73RM4.mjs";
11
+ } from "./chunk-AELMIG74.mjs";
12
12
  import "./chunk-XAG432PJ.mjs";
13
13
  import {
14
14
  DEPOSIT_MODAL_OPEN_EVENT,
@@ -88,25 +88,6 @@ export declare const resolveSportsSectionFilters: (key: SportsSectionTabKey) =>
88
88
  sportsMarketType?: SportsMarketTypeKey[];
89
89
  period?: SportsPeriodKey[];
90
90
  };
91
- /**
92
- * Resolve the markets a sports section tab should display and group.
93
- *
94
- * Section markets are fetched by `aggKey`, which intentionally spans every
95
- * sibling venue-event for the same real-world game (so cross-venue line ladders
96
- * and prop categories aggregate together). For the Game Lines MONEYLINE
97
- * (match-result) group, that aggregation is wrong: it can surface duplicate
98
- * draws sourced from sibling events, props mis-classified as `moneyline`, and —
99
- * because a sibling's market often wins the cross-venue collapse — it can omit
100
- * THIS event's own outcome markets entirely (e.g. show two "Draw"s and drop the
101
- * "Australia" win).
102
- *
103
- * The event's own curated `venueMarkets` are the authoritative N-way result for
104
- * this event (the same source the non-sports event page renders correctly). So
105
- * on the Game Lines tab we take the moneyline markets from the event and keep
106
- * only the line markets (spread/total) from the aggKey fetch. Every other tab —
107
- * and the spread/total ladders within Game Lines — use the fetched markets
108
- * unchanged.
109
- */
110
91
  export declare const resolveSportsSectionMarkets: ({ tabKey, eventMarkets, sectionMarkets, }: {
111
92
  tabKey: SportsSectionTabKey;
112
93
  eventMarkets: VenueMarket[];
@@ -88,25 +88,6 @@ export declare const resolveSportsSectionFilters: (key: SportsSectionTabKey) =>
88
88
  sportsMarketType?: SportsMarketTypeKey[];
89
89
  period?: SportsPeriodKey[];
90
90
  };
91
- /**
92
- * Resolve the markets a sports section tab should display and group.
93
- *
94
- * Section markets are fetched by `aggKey`, which intentionally spans every
95
- * sibling venue-event for the same real-world game (so cross-venue line ladders
96
- * and prop categories aggregate together). For the Game Lines MONEYLINE
97
- * (match-result) group, that aggregation is wrong: it can surface duplicate
98
- * draws sourced from sibling events, props mis-classified as `moneyline`, and —
99
- * because a sibling's market often wins the cross-venue collapse — it can omit
100
- * THIS event's own outcome markets entirely (e.g. show two "Draw"s and drop the
101
- * "Australia" win).
102
- *
103
- * The event's own curated `venueMarkets` are the authoritative N-way result for
104
- * this event (the same source the non-sports event page renders correctly). So
105
- * on the Game Lines tab we take the moneyline markets from the event and keep
106
- * only the line markets (spread/total) from the aggKey fetch. Every other tab —
107
- * and the spread/total ladders within Game Lines — use the fetched markets
108
- * unchanged.
109
- */
110
91
  export declare const resolveSportsSectionMarkets: ({ tabKey, eventMarkets, sectionMarkets, }: {
111
92
  tabKey: SportsSectionTabKey;
112
93
  eventMarkets: VenueMarket[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agg-build/ui",
3
- "version": "2.5.2",
3
+ "version": "2.5.3",
4
4
  "description": "Pre-built React component library for the AGG prediction market aggregator. Tailwind-based, themeable, with primitives, event surfaces, trading flows, full pages, and modals.",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",