volleyballsimtypes 0.0.508 → 0.0.510

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.
@@ -35,13 +35,13 @@ function computeMatchRallyAggregates(input) {
35
35
  });
36
36
  return { rallyMetrics, breakdown };
37
37
  }
38
- // A block scores a point in exactly ONE place in the sim (reception-simulator: a dig of a block fails
39
- // and the block landed in-court, i.e. target >= 7). Each such rally is ONE block point regardless of how
40
- // many blockers were on it; the box score records it as one `block_assists` per blocker (or one
41
- // `block_solo`), which is why summing solo+assists over-counts block points. We rebuild the true count
42
- // from the rallies. blockSolo / blockAssists must reconstruct box.block.solo and box.block.assists
43
- // exactly (the correctness gate). `teamOf(playerId)` returns a player's team id (or null); the scoring
44
- // team is the blockers' team.
38
+ // A block scores a point when the block lands in-court (target >= 7): the positional engine ends the rally
39
+ // on that BLOCK event; the zone engine ends it on the failed dig (RECEPTION) right after the BLOCK. Each
40
+ // such rally is ONE block point regardless of how many blockers were on it; the box score records it as one
41
+ // `block_assists` per blocker (or one `block_solo`), which is why summing solo+assists over-counts block
42
+ // points. We rebuild the true count from the rallies. blockSolo / blockAssists must reconstruct box.block.solo
43
+ // and box.block.assists exactly (the correctness gate). `teamOf(playerId)` returns a player's team id (or
44
+ // null); the scoring team is the blockers' team.
45
45
  function tallyBlockPoints(rallies, teamOf) {
46
46
  const out = new Map();
47
47
  const tallyFor = (team) => {
@@ -56,17 +56,22 @@ function tallyBlockPoints(rallies, teamOf) {
56
56
  // Ignore substitutions / libero replacements (eventType < SERVE) when locating the terminal action.
57
57
  const inPlay = rally.events.filter(e => e.eventType >= event_1.EventTypeEnum.SERVE);
58
58
  const last = inPlay[inPlay.length - 1];
59
- const prev = inPlay[inPlay.length - 2];
60
- if (last == null || prev == null)
59
+ if (last == null)
61
60
  continue;
62
- // Block point signature: the rally ends on a failed RECEPTION (dig) whose previous event is a BLOCK
63
- // that landed in-court (target >= 7). target < 7 is a deflection -> the ATTACKER's kill, not a block.
64
- if (last.eventType !== event_1.EventTypeEnum.RECEPTION || last.failure <= 0)
65
- continue;
66
- if (prev.eventType !== event_1.EventTypeEnum.BLOCK)
67
- continue;
68
- const block = prev;
69
- if (block.target < 7)
61
+ // A block point lands in-court (target >= 7); a deflection / tool-out (target < 7) is the ATTACKER's kill.
62
+ // Two engines end a block point in different shapes, both counted here:
63
+ // - positional: the rally ENDS on the BLOCK itself (the stuff kills the ball outright);
64
+ // - zone: the rally ends on a failed RECEPTION (dig) whose previous event is the BLOCK.
65
+ let block;
66
+ if (last.eventType === event_1.EventTypeEnum.BLOCK) {
67
+ block = last;
68
+ }
69
+ else if (last.eventType === event_1.EventTypeEnum.RECEPTION && last.failure > 0) {
70
+ const prev = inPlay[inPlay.length - 2];
71
+ if (prev != null && prev.eventType === event_1.EventTypeEnum.BLOCK)
72
+ block = prev;
73
+ }
74
+ if (block == null || block.target < 7)
70
75
  continue;
71
76
  const team = teamOf(block.blockers[0] ?? block.playerId);
72
77
  if (team == null)
@@ -30,6 +30,14 @@ const teamOf = (id) => id.startsWith('h') ? 'HOME' : id.startsWith('a') ? 'AWAY'
30
30
  const t = (0, point_breakdown_1.tallyBlockPoints)([rally([blockEvent('h1', 8, ['h1', 'h2']), receptionEvent('a3', 0), spikeEvent('a3')])], teamOf);
31
31
  (0, globals_1.expect)(t.size).toBe(0);
32
32
  });
33
+ (0, globals_1.it)('counts a POSITIONAL stuff that ENDS on the BLOCK (no trailing dig)', () => {
34
+ const t = (0, point_breakdown_1.tallyBlockPoints)([rally([spikeEvent('a1'), blockEvent('h1', 9, ['h1', 'h2'])])], teamOf);
35
+ (0, globals_1.expect)(t.get('HOME')).toEqual({ blockPoints: 1, blockSolo: 0, blockAssists: 2 });
36
+ });
37
+ (0, globals_1.it)('does NOT count a terminal touch / tool-out block (target < 7)', () => {
38
+ const t = (0, point_breakdown_1.tallyBlockPoints)([rally([spikeEvent('a1'), blockEvent('h1', 0, ['h1'])])], teamOf);
39
+ (0, globals_1.expect)(t.size).toBe(0);
40
+ });
33
41
  (0, globals_1.it)('reconstructs box block.solo and block.assists across a mix (incl. a triple block)', () => {
34
42
  const t = (0, point_breakdown_1.tallyBlockPoints)([
35
43
  rally([blockEvent('h1', 8, ['h1', 'h2']), receptionEvent('a3', 1)]), // double: +2 assists
@@ -2,89 +2,90 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.defaultReceiveMap = defaultReceiveMap;
4
4
  exports.defaultBaseConfig = defaultBaseConfig;
5
+ const rotation_system_1 = require("./rotation-system");
5
6
  const lineup_function_1 = require("./lineup-function");
6
7
  const player_1 = require("../player");
7
8
  const match_1 = require("../match");
8
9
  const COORDS = {
9
10
  SERVE: {
10
- 1: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
11
- 2: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
12
- 3: { 1: { d: 10.00, r: -3.50 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 6.50, r: 0.00 } },
13
- 4: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
14
- 5: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
15
- 6: { 1: { d: 10.00, r: -3.50 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 6.50, r: 0.00 } }
11
+ 1: { 1: { d: 10, r: 3.5 }, 2: { d: 0.5, r: -2.5 }, 3: { d: 0.5, r: 0 }, 4: { d: 0.5, r: 2.5 }, 5: { d: 6.5, r: 0 }, 6: { d: 5, r: -2.5 } },
12
+ 2: { 1: { d: 9.8, r: -2.7 }, 2: { d: 0.6, r: 2.35 }, 3: { d: 0.6, r: -2.55 }, 4: { d: 0.5, r: -0.2 }, 5: { d: 5, r: 3.25 }, 6: { d: 7.4, r: 0.15 } },
13
+ 3: { 1: { d: 9.85, r: 3.3 }, 2: { d: 0.55, r: -0.05 }, 3: { d: 0.6, r: 2.45 }, 4: { d: 0.6, r: -2.7 }, 5: { d: 5.3, r: -2.75 }, 6: { d: 5.3, r: 2.7 } },
14
+ 4: { 1: { d: 10, r: 3.5 }, 2: { d: 0.5, r: -2.5 }, 3: { d: 0.5, r: 0 }, 4: { d: 0.5, r: 2.4 }, 5: { d: 6.5, r: 0 }, 6: { d: 5, r: -2.5 } },
15
+ 5: { 1: { d: 9.75, r: 3.25 }, 2: { d: 0.65, r: 2.8 }, 3: { d: 0.8, r: -2.85 }, 4: { d: 0.6, r: 0.05 }, 5: { d: 4.75, r: 2.85 }, 6: { d: 6.95, r: 0 } },
16
+ 6: { 1: { d: 9.8, r: 3.05 }, 2: { d: 0.45, r: 0.05 }, 3: { d: 0.5, r: 2.45 }, 4: { d: 0.45, r: -2.8 }, 5: { d: 4.6, r: -2.65 }, 6: { d: 4.7, r: 3 } }
16
17
  },
17
18
  RECEIVE: {
18
- 1: { 1: { d: 6.50, r: 3.50 }, 2: { d: 6.00, r: 3.00 }, 3: { d: 3.00, r: -3.50 }, 4: { d: 3.50, r: -4.00 }, 5: { d: 6.00, r: -3.00 }, 6: { d: 6.50, r: 0.00 } },
19
- 2: { 1: { d: 6.00, r: 3.00 }, 2: { d: 3.00, r: 4.00 }, 3: { d: 0.50, r: 0.50 }, 4: { d: 6.00, r: -3.00 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 1.25, r: 0.75 } },
20
- 3: { 1: { d: 6.00, r: 3.00 }, 2: { d: 3.00, r: 4.00 }, 3: { d: 6.00, r: -3.00 }, 4: { d: 0.95, r: -4.00 }, 5: { d: 1.00, r: -1.00 }, 6: { d: 6.50, r: 0.00 } },
21
- 4: { 1: { d: 8.50, r: 4.00 }, 2: { d: 6.00, r: -3.00 }, 3: { d: 1.25, r: -4.00 }, 4: { d: 0.75, r: -4.05 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 6.00, r: 3.00 } },
22
- 5: { 1: { d: 6.00, r: 3.00 }, 2: { d: 2.50, r: 4.00 }, 3: { d: 1.00, r: 1.50 }, 4: { d: 6.00, r: -3.00 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 8.50, r: 1.50 } },
23
- 6: { 1: { d: 6.00, r: 3.00 }, 2: { d: 1.00, r: 1.50 }, 3: { d: 6.00, r: -3.00 }, 4: { d: 3.00, r: -4.00 }, 5: { d: 8.50, r: -1.50 }, 6: { d: 6.50, r: 0.00 } }
19
+ 1: { 1: { d: 6.5, r: 3.5 }, 2: { d: 6, r: 3 }, 3: { d: 3, r: -3.5 }, 4: { d: 3.5, r: -4 }, 5: { d: 6, r: -3 }, 6: { d: 6.5, r: 0 } },
20
+ 2: { 1: { d: 5.65, r: 2.3 }, 2: { d: 0.65, r: 2.1 }, 3: { d: 6, r: -2.3 }, 4: { d: 2.75, r: -3.9 }, 5: { d: 7.85, r: -1.7 }, 6: { d: 6.75, r: 0.1 } },
21
+ 3: { 1: { d: 6, r: 3 }, 2: { d: 2.5, r: 3.95 }, 3: { d: 0.75, r: 1 }, 4: { d: 5.55, r: -2.75 }, 5: { d: 6.1, r: 0.1 }, 6: { d: 7.8, r: 1.65 } },
22
+ 4: { 1: { d: 8.5, r: 4 }, 2: { d: 6, r: -3 }, 3: { d: 1.25, r: -4 }, 4: { d: 0.75, r: -4.05 }, 5: { d: 6.5, r: 0 }, 6: { d: 6, r: 3 } },
23
+ 5: { 1: { d: 6.1, r: 2.6 }, 2: { d: 3.25, r: 3.9 }, 3: { d: 5.8, r: -2.75 }, 4: { d: 0.75, r: -3.85 }, 5: { d: 1.9, r: -1.7 }, 6: { d: 6.75, r: -0.1 } },
24
+ 6: { 1: { d: 6, r: 3 }, 2: { d: 2.6, r: 3.85 }, 3: { d: 0.5, r: 0.4 }, 4: { d: 5.9, r: -2.9 }, 5: { d: 6.55, r: 0 }, 6: { d: 1.6, r: 0.9 } }
24
25
  },
25
26
  DEFENCE: {
26
- 1: { 1: { d: 5.00, r: 3.00 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -3.00 } },
27
- 2: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -3.00 }, 6: { d: 5.00, r: 3.00 } },
28
- 3: { 1: { d: 5.00, r: -3.00 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 3.00 }, 6: { d: 7.00, r: 0.00 } },
29
- 4: { 1: { d: 5.00, r: 3.00 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -3.00 } },
30
- 5: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -3.00 }, 6: { d: 5.00, r: 3.00 } },
31
- 6: { 1: { d: 5.00, r: -3.00 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 3.00 }, 6: { d: 7.00, r: 0.00 } }
27
+ 1: { 1: { d: 5, r: 3 }, 2: { d: 0.5, r: -2.5 }, 3: { d: 0.5, r: 0 }, 4: { d: 0.5, r: 2.5 }, 5: { d: 7, r: 0 }, 6: { d: 5, r: -3 } },
28
+ 2: { 1: { d: 4.9, r: -3 }, 2: { d: 0.6, r: 2.65 }, 3: { d: 0.65, r: -3 }, 4: { d: 0.65, r: -0.1 }, 5: { d: 5, r: 3.05 }, 6: { d: 6.75, r: 0.2 } },
29
+ 3: { 1: { d: 7, r: 0.05 }, 2: { d: 0.5, r: 0.2 }, 3: { d: 0.6, r: 2.65 }, 4: { d: 0.5, r: -2.7 }, 5: { d: 4.7, r: -2.3 }, 6: { d: 4.85, r: 2.6 } },
30
+ 4: { 1: { d: 5, r: 3 }, 2: { d: 0.5, r: -2.5 }, 3: { d: 0.5, r: 0 }, 4: { d: 0.5, r: 2.5 }, 5: { d: 7, r: 0 }, 6: { d: 5, r: -3 } },
31
+ 5: { 1: { d: 4.8, r: -3.15 }, 2: { d: 0.6, r: 2.5 }, 3: { d: 0.65, r: -2.85 }, 4: { d: 0.65, r: -0.15 }, 5: { d: 5, r: 2.75 }, 6: { d: 6.75, r: 0.05 } },
32
+ 6: { 1: { d: 7.2, r: -0.05 }, 2: { d: 0.45, r: -0.4 }, 3: { d: 0.55, r: 2.45 }, 4: { d: 0.55, r: -3 }, 5: { d: 4.85, r: -2.85 }, 6: { d: 4.8, r: 2.25 } }
32
33
  },
33
34
  DEF_L: {
34
- 1: { 1: { d: 5.00, r: 1.50 }, 2: { d: 0.25, r: -4.00 }, 3: { d: 0.25, r: -3.25 }, 4: { d: 1.75, r: 1.25 }, 5: { d: 8.00, r: -0.50 }, 6: { d: 5.00, r: -4.20 } },
35
- 2: { 1: { d: 8.00, r: -0.50 }, 2: { d: 0.25, r: -3.25 }, 3: { d: 1.75, r: 1.25 }, 4: { d: 0.25, r: -4.00 }, 5: { d: 5.00, r: -4.20 }, 6: { d: 5.00, r: 1.50 } },
36
- 3: { 1: { d: 5.00, r: -4.20 }, 2: { d: 1.75, r: 1.25 }, 3: { d: 0.25, r: -4.00 }, 4: { d: 0.25, r: -3.25 }, 5: { d: 5.00, r: 1.50 }, 6: { d: 8.00, r: -0.50 } },
37
- 4: { 1: { d: 5.00, r: 1.50 }, 2: { d: 0.25, r: -4.00 }, 3: { d: 0.25, r: -3.25 }, 4: { d: 1.75, r: 1.25 }, 5: { d: 8.00, r: -0.50 }, 6: { d: 5.00, r: -4.20 } },
38
- 5: { 1: { d: 8.00, r: -0.50 }, 2: { d: 0.25, r: -3.25 }, 3: { d: 1.75, r: 1.25 }, 4: { d: 0.25, r: -4.00 }, 5: { d: 5.00, r: -4.20 }, 6: { d: 5.00, r: 1.50 } },
39
- 6: { 1: { d: 5.00, r: -4.20 }, 2: { d: 1.75, r: 1.25 }, 3: { d: 0.25, r: -4.00 }, 4: { d: 0.25, r: -3.25 }, 5: { d: 5.00, r: 1.50 }, 6: { d: 8.00, r: -0.50 } }
35
+ 1: { 1: { d: 5, r: 1.5 }, 2: { d: 0.25, r: -4 }, 3: { d: 0.25, r: -3.25 }, 4: { d: 1.75, r: 1.25 }, 5: { d: 8, r: -0.5 }, 6: { d: 5, r: -4.2 } },
36
+ 2: { 1: { d: 4.45, r: -3.95 }, 2: { d: 1.9, r: 1.3 }, 3: { d: 0.4, r: -3.8 }, 4: { d: 0.4, r: -2.9 }, 5: { d: 5.05, r: 2.45 }, 6: { d: 7.6, r: -0.05 } },
37
+ 3: { 1: { d: 8.2, r: -0.7 }, 2: { d: 0.4, r: -2.65 }, 3: { d: 2.1, r: 0.8 }, 4: { d: 0.45, r: -3.8 }, 5: { d: 5.1, r: -3.85 }, 6: { d: 5.2, r: 1.8 } },
38
+ 4: { 1: { d: 5, r: 1.5 }, 2: { d: 0.25, r: -4 }, 3: { d: 0.25, r: -3.25 }, 4: { d: 1.75, r: 1.25 }, 5: { d: 8, r: -0.5 }, 6: { d: 5, r: -4.2 } },
39
+ 5: { 1: { d: 5.05, r: -3.9 }, 2: { d: 2.2, r: 0.65 }, 3: { d: 0.65, r: -3.8 }, 4: { d: 0.65, r: -2.75 }, 5: { d: 4.65, r: 1.1 }, 6: { d: 7.7, r: -0.75 } },
40
+ 6: { 1: { d: 7.15, r: 0.25 }, 2: { d: 0.5, r: -2.7 }, 3: { d: 1.8, r: 1.1 }, 4: { d: 0.5, r: -3.8 }, 5: { d: 4.75, r: -3.85 }, 6: { d: 4.95, r: 1.6 } }
40
41
  },
41
42
  DEF_M: {
42
- 1: { 1: { d: 5.00, r: 2.50 }, 2: { d: 1.75, r: -2.50 }, 3: { d: 0.25, r: 0.00 }, 4: { d: 1.75, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
43
- 2: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.25, r: 0.00 }, 3: { d: 1.75, r: 2.50 }, 4: { d: 1.75, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
44
- 3: { 1: { d: 5.00, r: -2.50 }, 2: { d: 1.75, r: 2.50 }, 3: { d: 1.75, r: -2.50 }, 4: { d: 0.25, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 7.00, r: 0.00 } },
45
- 4: { 1: { d: 5.00, r: 2.50 }, 2: { d: 1.75, r: -2.50 }, 3: { d: 0.25, r: 0.00 }, 4: { d: 1.75, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
46
- 5: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.25, r: 0.00 }, 3: { d: 1.75, r: 2.50 }, 4: { d: 1.75, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
47
- 6: { 1: { d: 5.00, r: -2.50 }, 2: { d: 1.75, r: 2.50 }, 3: { d: 1.75, r: -2.50 }, 4: { d: 0.25, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 7.00, r: 0.00 } }
43
+ 1: { 1: { d: 5, r: 2.5 }, 2: { d: 1.75, r: -2.5 }, 3: { d: 0.25, r: 0 }, 4: { d: 1.75, r: 2.5 }, 5: { d: 7, r: 0 }, 6: { d: 5, r: -2.5 } },
44
+ 2: { 1: { d: 5, r: -2.8 }, 2: { d: 1.85, r: 2.5 }, 3: { d: 1.85, r: -2.4 }, 4: { d: 0.4, r: 0.15 }, 5: { d: 5, r: 2.65 }, 6: { d: 7, r: 0.05 } },
45
+ 3: { 1: { d: 7.15, r: 0.1 }, 2: { d: 0.5, r: 0.1 }, 3: { d: 1.95, r: 2.45 }, 4: { d: 1.8, r: -2.55 }, 5: { d: 5.25, r: -2.45 }, 6: { d: 5.2, r: 2.8 } },
46
+ 4: { 1: { d: 5, r: 2.5 }, 2: { d: 1.75, r: -2.5 }, 3: { d: 0.25, r: 0 }, 4: { d: 1.75, r: 2.5 }, 5: { d: 7, r: 0 }, 6: { d: 5, r: -2.5 } },
47
+ 5: { 1: { d: 4.9, r: -2.35 }, 2: { d: 1.95, r: 2.4 }, 3: { d: 1.85, r: -2.6 }, 4: { d: 0.55, r: -0.2 }, 5: { d: 4.9, r: 2.45 }, 6: { d: 6.7, r: -0.1 } },
48
+ 6: { 1: { d: 7.35, r: 0.05 }, 2: { d: 0.6, r: 0.1 }, 3: { d: 2, r: 2.45 }, 4: { d: 2.25, r: -1.95 }, 5: { d: 5.2, r: -2.05 }, 6: { d: 5.3, r: 2.5 } }
48
49
  },
49
50
  DEF_R: {
50
- 1: { 1: { d: 5.00, r: 4.20 }, 2: { d: 1.75, r: -1.25 }, 3: { d: 0.25, r: 3.25 }, 4: { d: 0.25, r: 4.00 }, 5: { d: 8.00, r: 0.50 }, 6: { d: 5.00, r: -1.50 } },
51
- 2: { 1: { d: 8.00, r: 0.50 }, 2: { d: 0.25, r: 3.25 }, 3: { d: 0.25, r: 4.00 }, 4: { d: 1.75, r: -1.25 }, 5: { d: 5.00, r: -1.50 }, 6: { d: 5.00, r: 4.20 } },
52
- 3: { 1: { d: 5.00, r: -1.50 }, 2: { d: 0.25, r: 4.00 }, 3: { d: 1.75, r: -1.25 }, 4: { d: 0.25, r: 3.25 }, 5: { d: 5.00, r: 4.20 }, 6: { d: 8.00, r: 0.50 } },
53
- 4: { 1: { d: 5.00, r: 4.20 }, 2: { d: 1.75, r: -1.25 }, 3: { d: 0.25, r: 3.25 }, 4: { d: 0.25, r: 4.00 }, 5: { d: 8.00, r: 0.50 }, 6: { d: 5.00, r: -1.50 } },
54
- 5: { 1: { d: 8.00, r: 0.50 }, 2: { d: 0.25, r: 3.25 }, 3: { d: 0.25, r: 4.00 }, 4: { d: 1.75, r: -1.25 }, 5: { d: 5.00, r: -1.50 }, 6: { d: 5.00, r: 4.20 } },
55
- 6: { 1: { d: 5.00, r: -1.50 }, 2: { d: 0.25, r: 4.00 }, 3: { d: 1.75, r: -1.25 }, 4: { d: 0.25, r: 3.25 }, 5: { d: 5.00, r: 4.20 }, 6: { d: 8.00, r: 0.50 } }
51
+ 1: { 1: { d: 5, r: 4.2 }, 2: { d: 1.75, r: -1.25 }, 3: { d: 0.25, r: 3.25 }, 4: { d: 0.25, r: 4 }, 5: { d: 8, r: 0.5 }, 6: { d: 5, r: -1.5 } },
52
+ 2: { 1: { d: 4.65, r: -1 }, 2: { d: 0.25, r: 3.85 }, 3: { d: 1.75, r: -1.4 }, 4: { d: 0.3, r: 2.95 }, 5: { d: 4.3, r: 3.95 }, 6: { d: 8.15, r: 0.5 } },
53
+ 3: { 1: { d: 8.05, r: 0.4 }, 2: { d: 0.4, r: 2.95 }, 3: { d: 0.4, r: 3.85 }, 4: { d: 2, r: -2 }, 5: { d: 4.65, r: -1.15 }, 6: { d: 4.75, r: 4 } },
54
+ 4: { 1: { d: 5, r: 4.2 }, 2: { d: 1.75, r: -1.25 }, 3: { d: 0.25, r: 3.25 }, 4: { d: 0.25, r: 4 }, 5: { d: 8, r: 0.5 }, 6: { d: 5, r: -1.5 } },
55
+ 5: { 1: { d: 5.35, r: -2 }, 2: { d: 0.5, r: 3.65 }, 3: { d: 2.1, r: -1.25 }, 4: { d: 0.5, r: 2.6 }, 5: { d: 5.4, r: 3.85 }, 6: { d: 7.75, r: -0.15 } },
56
+ 6: { 1: { d: 7.8, r: 0.75 }, 2: { d: 0.45, r: 2.9 }, 3: { d: 0.45, r: 3.95 }, 4: { d: 1.75, r: -0.25 }, 5: { d: 5.15, r: -1.4 }, 6: { d: 4.9, r: 4 } }
56
57
  },
57
58
  ATTACK: {
58
- 1: { 1: { d: 0.50, r: 1.50 }, 2: { d: 3.75, r: -5.00 }, 3: { d: 3.00, r: 0.25 }, 4: { d: 3.75, r: 5.00 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 4.50, r: -2.50 } },
59
- 2: { 1: { d: 6.50, r: 0.00 }, 2: { d: 3.00, r: 0.25 }, 3: { d: 3.75, r: 5.00 }, 4: { d: 3.75, r: -5.00 }, 5: { d: 4.50, r: -2.50 }, 6: { d: 0.50, r: 1.50 } },
60
- 3: { 1: { d: 4.50, r: -2.50 }, 2: { d: 3.75, r: 5.00 }, 3: { d: 3.75, r: -5.00 }, 4: { d: 3.00, r: 0.25 }, 5: { d: 0.50, r: 1.50 }, 6: { d: 6.50, r: 0.00 } },
61
- 4: { 1: { d: 6.50, r: 4.90 }, 2: { d: 3.75, r: -5.00 }, 3: { d: 3.00, r: 0.25 }, 4: { d: 0.50, r: 1.50 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 4.50, r: -2.50 } },
62
- 5: { 1: { d: 6.50, r: 0.00 }, 2: { d: 3.00, r: 0.25 }, 3: { d: 0.50, r: 1.50 }, 4: { d: 3.75, r: -5.00 }, 5: { d: 4.50, r: -2.50 }, 6: { d: 6.50, r: 4.90 } },
63
- 6: { 1: { d: 4.50, r: -2.50 }, 2: { d: 0.50, r: 1.50 }, 3: { d: 3.75, r: -5.00 }, 4: { d: 3.00, r: 0.25 }, 5: { d: 6.50, r: 4.90 }, 6: { d: 6.50, r: 0.00 } }
59
+ 1: { 1: { d: 0.5, r: 1.5 }, 2: { d: 3.75, r: -5 }, 3: { d: 3, r: 0.25 }, 4: { d: 3.75, r: 5 }, 5: { d: 6.5, r: 0 }, 6: { d: 4.5, r: -2.5 } },
60
+ 2: { 1: { d: 5.1, r: -2 }, 2: { d: 0.45, r: 1.55 }, 3: { d: 3.6, r: -5.2 }, 4: { d: 2.8, r: 0.2 }, 5: { d: 6.4, r: 5.05 }, 6: { d: 6.55, r: -0.6 } },
61
+ 3: { 1: { d: 6.5, r: -0.15 }, 2: { d: 3, r: 0.35 }, 3: { d: 0.5, r: 1.6 }, 4: { d: 2.4, r: -5.15 }, 5: { d: 4.6, r: -2.55 }, 6: { d: 5.4, r: 5.2 } },
62
+ 4: { 1: { d: 6.5, r: 4.9 }, 2: { d: 3.75, r: -5 }, 3: { d: 3, r: 0.25 }, 4: { d: 0.5, r: 1.5 }, 5: { d: 6.5, r: 0 }, 6: { d: 4.5, r: -2.5 } },
63
+ 5: { 1: { d: 4.65, r: -2.35 }, 2: { d: 3.65, r: 4.8 }, 3: { d: 2.9, r: -5.15 }, 4: { d: 3.05, r: 0.4 }, 5: { d: 0.75, r: 1.7 }, 6: { d: 6.4, r: -0.05 } },
64
+ 6: { 1: { d: 6.2, r: -0.4 }, 2: { d: 3, r: 0.2 }, 3: { d: 3.65, r: 5.2 }, 4: { d: 3.55, r: -5.2 }, 5: { d: 4.5, r: -2.45 }, 6: { d: 0.65, r: 1.3 } }
64
65
  },
65
66
  ATK_L: {
66
- 1: { 1: { d: 0.75, r: 0.00 }, 2: { d: 0.50, r: -4.00 }, 3: { d: 1.00, r: -2.50 }, 4: { d: 3.50, r: 0.75 }, 5: { d: 6.25, r: -0.75 }, 6: { d: 3.50, r: -4.00 } },
67
- 2: { 1: { d: 6.25, r: -0.75 }, 2: { d: 1.00, r: -2.50 }, 3: { d: 3.50, r: 0.75 }, 4: { d: 0.50, r: -4.00 }, 5: { d: 3.50, r: -4.00 }, 6: { d: 0.75, r: 0.00 } },
68
- 3: { 1: { d: 3.50, r: -4.00 }, 2: { d: 3.50, r: 0.75 }, 3: { d: 0.50, r: -4.00 }, 4: { d: 1.00, r: -2.50 }, 5: { d: 0.75, r: 0.00 }, 6: { d: 6.25, r: -0.75 } },
69
- 4: { 1: { d: 3.50, r: 0.75 }, 2: { d: 0.50, r: -4.00 }, 3: { d: 1.00, r: -2.50 }, 4: { d: 0.75, r: 0.00 }, 5: { d: 6.25, r: -0.75 }, 6: { d: 3.50, r: -4.00 } },
70
- 5: { 1: { d: 6.25, r: -0.75 }, 2: { d: 1.00, r: -2.50 }, 3: { d: 0.75, r: 0.00 }, 4: { d: 0.50, r: -4.00 }, 5: { d: 3.50, r: -4.00 }, 6: { d: 3.50, r: 0.75 } },
71
- 6: { 1: { d: 3.50, r: -4.00 }, 2: { d: 0.75, r: 0.00 }, 3: { d: 0.50, r: -4.00 }, 4: { d: 1.00, r: -2.50 }, 5: { d: 3.50, r: 0.75 }, 6: { d: 6.25, r: -0.75 } }
67
+ 1: { 1: { d: 0.75, r: 0 }, 2: { d: 0.5, r: -4 }, 3: { d: 1, r: -2.5 }, 4: { d: 3.5, r: 0.75 }, 5: { d: 6.25, r: -0.75 }, 6: { d: 3.5, r: -4 } },
68
+ 2: { 1: { d: 3.4, r: -4.05 }, 2: { d: 0.75, r: 0 }, 3: { d: 0.9, r: -4.15 }, 4: { d: 1.8, r: -2.5 }, 5: { d: 3.4, r: 0.5 }, 6: { d: 6.5, r: -1.15 } },
69
+ 3: { 1: { d: 6.35, r: -0.1 }, 2: { d: 2.1, r: -2.45 }, 3: { d: 0.9, r: 0 }, 4: { d: 0.8, r: -3.95 }, 5: { d: 4.6, r: -3.75 }, 6: { d: 3.6, r: 1.45 } },
70
+ 4: { 1: { d: 3.5, r: 0.75 }, 2: { d: 0.5, r: -4 }, 3: { d: 1, r: -2.5 }, 4: { d: 0.75, r: 0 }, 5: { d: 6.25, r: -0.75 }, 6: { d: 3.5, r: -4 } },
71
+ 5: { 1: { d: 4.25, r: -3.85 }, 2: { d: 3.55, r: 0.75 }, 3: { d: 1, r: -4.1 }, 4: { d: 2.05, r: -2.65 }, 5: { d: 0.85, r: -0.15 }, 6: { d: 6, r: -0.8 } },
72
+ 6: { 1: { d: 5.9, r: -1 }, 2: { d: 1.05, r: -2.5 }, 3: { d: 3.45, r: 0.9 }, 4: { d: 0.7, r: -3.9 }, 5: { d: 3.4, r: -4.05 }, 6: { d: 0.75, r: -0.2 } }
72
73
  },
73
74
  ATK_M: {
74
- 1: { 1: { d: 0.75, r: 1.25 }, 2: { d: 1.25, r: -2.00 }, 3: { d: 0.75, r: 0.50 }, 4: { d: 2.25, r: 2.60 }, 5: { d: 6.50, r: 1.50 }, 6: { d: 4.00, r: -1.50 } },
75
- 2: { 1: { d: 6.50, r: 1.50 }, 2: { d: 0.75, r: 0.50 }, 3: { d: 2.25, r: 2.60 }, 4: { d: 1.25, r: -2.00 }, 5: { d: 4.00, r: -1.50 }, 6: { d: 0.75, r: 1.25 } },
76
- 3: { 1: { d: 4.00, r: -1.50 }, 2: { d: 2.25, r: 2.60 }, 3: { d: 1.25, r: -2.00 }, 4: { d: 0.75, r: 0.50 }, 5: { d: 0.75, r: 1.25 }, 6: { d: 6.50, r: 1.50 } },
77
- 4: { 1: { d: 2.25, r: 2.60 }, 2: { d: 1.25, r: -2.00 }, 3: { d: 0.75, r: 0.50 }, 4: { d: 0.75, r: 1.25 }, 5: { d: 6.50, r: 1.50 }, 6: { d: 4.00, r: -1.50 } },
78
- 5: { 1: { d: 6.50, r: 1.50 }, 2: { d: 0.75, r: 0.50 }, 3: { d: 0.75, r: 1.25 }, 4: { d: 1.25, r: -2.00 }, 5: { d: 4.00, r: -1.50 }, 6: { d: 2.25, r: 2.60 } },
79
- 6: { 1: { d: 4.00, r: -1.50 }, 2: { d: 0.75, r: 1.25 }, 3: { d: 1.25, r: -2.00 }, 4: { d: 0.75, r: 0.50 }, 5: { d: 2.25, r: 2.60 }, 6: { d: 6.50, r: 1.50 } }
75
+ 1: { 1: { d: 0.75, r: 1.25 }, 2: { d: 1.25, r: -2 }, 3: { d: 0.75, r: 0.5 }, 4: { d: 2.25, r: 2.6 }, 5: { d: 6.5, r: 1.5 }, 6: { d: 4, r: -1.5 } },
76
+ 2: { 1: { d: 4.5, r: -2.2 }, 2: { d: 0.7, r: 1.25 }, 3: { d: 1.8, r: -2.45 }, 4: { d: 0.9, r: 0.05 }, 5: { d: 2.75, r: 3.05 }, 6: { d: 5.75, r: 0 } },
77
+ 3: { 1: { d: 6.55, r: 1.15 }, 2: { d: 0.9, r: 0.3 }, 3: { d: 0.85, r: 1.45 }, 4: { d: 1.7, r: -2.7 }, 5: { d: 3.95, r: -1.75 }, 6: { d: 2.25, r: 3.2 } },
78
+ 4: { 1: { d: 2.25, r: 2.6 }, 2: { d: 1.25, r: -2 }, 3: { d: 0.75, r: 0.5 }, 4: { d: 0.75, r: 1.25 }, 5: { d: 6.5, r: 1.5 }, 6: { d: 4, r: -1.5 } },
79
+ 5: { 1: { d: 4.35, r: -1.5 }, 2: { d: 2.25, r: 2.85 }, 3: { d: 1.9, r: -2.55 }, 4: { d: 0.8, r: 0.35 }, 5: { d: 0.6, r: 1.45 }, 6: { d: 5.55, r: 1.45 } },
80
+ 6: { 1: { d: 5.2, r: 1.1 }, 2: { d: 0.8, r: 0.35 }, 3: { d: 2.4, r: 3 }, 4: { d: 1.8, r: -2.15 }, 5: { d: 4.5, r: -1.7 }, 6: { d: 0.8, r: 1.35 } }
80
81
  },
81
82
  ATK_R: {
82
- 1: { 1: { d: 1.75, r: 2.50 }, 2: { d: 1.50, r: -1.75 }, 3: { d: 0.75, r: 1.75 }, 4: { d: 0.50, r: 4.00 }, 5: { d: 5.00, r: 3.25 }, 6: { d: 5.75, r: -2.00 } },
83
- 2: { 1: { d: 5.00, r: 3.25 }, 2: { d: 0.75, r: 1.75 }, 3: { d: 0.50, r: 4.00 }, 4: { d: 1.50, r: -1.75 }, 5: { d: 5.75, r: -2.00 }, 6: { d: 1.75, r: 2.50 } },
84
- 3: { 1: { d: 5.75, r: -2.00 }, 2: { d: 0.50, r: 4.00 }, 3: { d: 1.50, r: -1.75 }, 4: { d: 0.75, r: 1.75 }, 5: { d: 1.75, r: 2.50 }, 6: { d: 5.00, r: 3.25 } },
85
- 4: { 1: { d: 2.25, r: 4.00 }, 2: { d: 2.25, r: -1.75 }, 3: { d: 0.75, r: 1.50 }, 4: { d: 1.50, r: 2.25 }, 5: { d: 6.00, r: 2.25 }, 6: { d: 5.00, r: -0.75 } },
86
- 5: { 1: { d: 6.00, r: 2.25 }, 2: { d: 0.75, r: 1.50 }, 3: { d: 1.50, r: 2.25 }, 4: { d: 2.25, r: -1.75 }, 5: { d: 5.00, r: -0.75 }, 6: { d: 2.25, r: 4.00 } },
87
- 6: { 1: { d: 5.00, r: -0.75 }, 2: { d: 1.50, r: 2.25 }, 3: { d: 2.25, r: -1.75 }, 4: { d: 0.75, r: 1.50 }, 5: { d: 2.25, r: 4.00 }, 6: { d: 6.00, r: 2.25 } }
83
+ 1: { 1: { d: 1.75, r: 2.5 }, 2: { d: 1.5, r: -1.75 }, 3: { d: 0.75, r: 1.75 }, 4: { d: 0.5, r: 4 }, 5: { d: 5, r: 3.25 }, 6: { d: 5.75, r: -2 } },
84
+ 2: { 1: { d: 4.65, r: -0.8 }, 2: { d: 0.75, r: 1.75 }, 3: { d: 1.85, r: -1.75 }, 4: { d: 1.7, r: 2.2 }, 5: { d: 2.15, r: 4.25 }, 6: { d: 6.25, r: 2 } },
85
+ 3: { 1: { d: 5.1, r: 3.15 }, 2: { d: 1.85, r: 2.6 }, 3: { d: 0.8, r: 1.75 }, 4: { d: 2.15, r: -1.7 }, 5: { d: 4.9, r: -1.25 }, 6: { d: 1.9, r: 4.15 } },
86
+ 4: { 1: { d: 2.25, r: 4 }, 2: { d: 2.25, r: -1.75 }, 3: { d: 0.75, r: 1.5 }, 4: { d: 1.5, r: 2.25 }, 5: { d: 6, r: 2.25 }, 6: { d: 5, r: -0.75 } },
87
+ 5: { 1: { d: 5.95, r: -2 }, 2: { d: 0.9, r: 3.7 }, 3: { d: 2.2, r: -1.6 }, 4: { d: 2, r: 2.35 }, 5: { d: 0.9, r: 1.15 }, 6: { d: 6, r: 1.9 } },
88
+ 6: { 1: { d: 5.35, r: 2.35 }, 2: { d: 2.05, r: 2.1 }, 3: { d: 0.8, r: 4 }, 4: { d: 2.1, r: -1.95 }, 5: { d: 4.9, r: -1.4 }, 6: { d: 0.4, r: 1.3 } }
88
89
  }
89
90
  };
90
91
  // The default coordinate table as a BaseConfig.coords (jsonb string keys). Shared, readonly; materialized (and so
@@ -101,36 +102,47 @@ const DEFAULT_COORDS = (() => {
101
102
  }
102
103
  return out;
103
104
  })();
104
- // The owner's authored per-point-of-attack block map for the 5-1 (owner 2026-08-07), keyed
105
+ // The owner's corrected per-point-of-attack block map for the 5-1 (exported 2026-08-09), keyed
105
106
  // [DEF_L|DEF_M|DEF_R][rotation][zone] -> canBlock. `false` = that front-row zone sits OUT of the block for an attack
106
- // from that side; `true` = reads/joins the wall. Only front-row zones (2/3/4) are tagged. Same rotation convention
107
- // as DEFAULT_COORDS. Generated from the finalized 5-1 sr-mapper preset's Def L/M/R block/noblock tags.
107
+ // from that side; `true` = reads/joins the wall. Only the front-row zones in play for the rotation are tagged. Same
108
+ // rotation convention as DEFAULT_COORDS.
108
109
  const DEFAULT_BLOCKING = {
109
110
  DEF_L: {
110
111
  1: { 2: true, 3: true, 4: false },
111
- 2: { 2: true, 3: false, 4: true },
112
- 3: { 2: false, 3: true, 4: true },
112
+ 2: { 2: false, 4: true },
113
+ 3: { 3: false, 4: true },
113
114
  4: { 2: true, 3: true, 4: false },
114
- 5: { 2: true, 3: false, 4: true },
115
- 6: { 2: false, 3: true, 4: true }
115
+ 5: { 2: false, 4: true },
116
+ 6: { 3: false, 4: true }
116
117
  },
117
118
  DEF_M: {
118
119
  1: { 2: false, 3: true, 4: false },
119
- 2: { 2: true, 3: false, 4: false },
120
- 3: { 2: false, 3: false, 4: true },
120
+ 2: { 2: false, 3: false },
121
+ 3: { 3: false, 4: false },
121
122
  4: { 2: false, 3: true, 4: false },
122
- 5: { 2: true, 3: false, 4: false },
123
- 6: { 2: false, 3: false, 4: true }
123
+ 5: { 2: false, 3: false },
124
+ 6: { 3: false, 4: false }
124
125
  },
125
126
  DEF_R: {
126
127
  1: { 2: false, 3: true, 4: true },
127
- 2: { 2: true, 3: true, 4: false },
128
- 3: { 2: true, 3: false, 4: true },
128
+ 2: { 2: true, 3: false },
129
+ 3: { 2: true, 4: false },
129
130
  4: { 2: false, 3: true, 4: true },
130
- 5: { 2: true, 3: true, 4: false },
131
- 6: { 2: true, 3: false, 4: true }
131
+ 5: { 2: true, 3: false },
132
+ 6: { 2: true, 4: false }
132
133
  }
133
134
  };
135
+ // The owner's corrected 5-1 serve-receive participation map (exported 2026-08-09). The 5-1 uses this exact map; the
136
+ // other systems derive their 3-passer map from slot functions (defaultReceiveMap) since their receiving personnel
137
+ // differ. Keyed [rotation][zone] -> passes.
138
+ const DEFAULT_5_1_RECEIVE = {
139
+ 1: { 1: false, 2: true, 3: false, 4: false, 5: true, 6: true },
140
+ 2: { 1: true, 2: false, 3: true, 4: false, 5: false, 6: true },
141
+ 3: { 1: true, 2: false, 3: false, 4: true, 5: true, 6: false },
142
+ 4: { 1: false, 2: true, 3: false, 4: false, 5: true, 6: true },
143
+ 5: { 1: true, 2: false, 3: true, 4: false, 5: false, 6: true },
144
+ 6: { 1: true, 2: false, 3: false, 4: true, 5: true, 6: false }
145
+ };
134
146
  // Rotation index -> the setter's rotational zone (inverse of SETTER_ZONE_TO_ROTATION {1:1,6:2,5:3,4:4,3:5,2:6}).
135
147
  const ROTATION_TO_SETTER_ZONE = { 1: 1, 2: 6, 3: 5, 4: 4, 5: 3, 6: 2 };
136
148
  // The default serve-receive participation map: the standard 3-passer formation. A rotational slot passes iff its
@@ -151,8 +163,9 @@ function defaultReceiveMap(system) {
151
163
  return receive;
152
164
  }
153
165
  // The default base config a team of the given system starts with. Every team always has one (materialized on team
154
- // creation and by the backfill migration); the coordinates are the same 5-1 table for every system, only the
155
- // receive map is derived per system.
166
+ // creation and by the backfill migration). Every system reuses the corrected 5-1 coordinate table and block map; the
167
+ // 5-1 uses the owner's exported receive map, the other systems derive their receive map per system.
156
168
  function defaultBaseConfig(system) {
157
- return { coords: DEFAULT_COORDS, receive: defaultReceiveMap(system), blocking: DEFAULT_BLOCKING };
169
+ const receive = system === rotation_system_1.RotationSystemEnum.FIVE_ONE ? DEFAULT_5_1_RECEIVE : defaultReceiveMap(system);
170
+ return { coords: DEFAULT_COORDS, receive, blocking: DEFAULT_BLOCKING };
158
171
  }
@@ -30,13 +30,13 @@ export function computeMatchRallyAggregates(input) {
30
30
  });
31
31
  return { rallyMetrics, breakdown };
32
32
  }
33
- // A block scores a point in exactly ONE place in the sim (reception-simulator: a dig of a block fails
34
- // and the block landed in-court, i.e. target >= 7). Each such rally is ONE block point regardless of how
35
- // many blockers were on it; the box score records it as one `block_assists` per blocker (or one
36
- // `block_solo`), which is why summing solo+assists over-counts block points. We rebuild the true count
37
- // from the rallies. blockSolo / blockAssists must reconstruct box.block.solo and box.block.assists
38
- // exactly (the correctness gate). `teamOf(playerId)` returns a player's team id (or null); the scoring
39
- // team is the blockers' team.
33
+ // A block scores a point when the block lands in-court (target >= 7): the positional engine ends the rally
34
+ // on that BLOCK event; the zone engine ends it on the failed dig (RECEPTION) right after the BLOCK. Each
35
+ // such rally is ONE block point regardless of how many blockers were on it; the box score records it as one
36
+ // `block_assists` per blocker (or one `block_solo`), which is why summing solo+assists over-counts block
37
+ // points. We rebuild the true count from the rallies. blockSolo / blockAssists must reconstruct box.block.solo
38
+ // and box.block.assists exactly (the correctness gate). `teamOf(playerId)` returns a player's team id (or
39
+ // null); the scoring team is the blockers' team.
40
40
  export function tallyBlockPoints(rallies, teamOf) {
41
41
  const out = new Map();
42
42
  const tallyFor = (team) => {
@@ -51,17 +51,22 @@ export function tallyBlockPoints(rallies, teamOf) {
51
51
  // Ignore substitutions / libero replacements (eventType < SERVE) when locating the terminal action.
52
52
  const inPlay = rally.events.filter(e => e.eventType >= EventTypeEnum.SERVE);
53
53
  const last = inPlay[inPlay.length - 1];
54
- const prev = inPlay[inPlay.length - 2];
55
- if (last == null || prev == null)
54
+ if (last == null)
56
55
  continue;
57
- // Block point signature: the rally ends on a failed RECEPTION (dig) whose previous event is a BLOCK
58
- // that landed in-court (target >= 7). target < 7 is a deflection -> the ATTACKER's kill, not a block.
59
- if (last.eventType !== EventTypeEnum.RECEPTION || last.failure <= 0)
60
- continue;
61
- if (prev.eventType !== EventTypeEnum.BLOCK)
62
- continue;
63
- const block = prev;
64
- if (block.target < 7)
56
+ // A block point lands in-court (target >= 7); a deflection / tool-out (target < 7) is the ATTACKER's kill.
57
+ // Two engines end a block point in different shapes, both counted here:
58
+ // - positional: the rally ENDS on the BLOCK itself (the stuff kills the ball outright);
59
+ // - zone: the rally ends on a failed RECEPTION (dig) whose previous event is the BLOCK.
60
+ let block;
61
+ if (last.eventType === EventTypeEnum.BLOCK) {
62
+ block = last;
63
+ }
64
+ else if (last.eventType === EventTypeEnum.RECEPTION && last.failure > 0) {
65
+ const prev = inPlay[inPlay.length - 2];
66
+ if (prev != null && prev.eventType === EventTypeEnum.BLOCK)
67
+ block = prev;
68
+ }
69
+ if (block == null || block.target < 7)
65
70
  continue;
66
71
  const team = teamOf(block.blockers[0] ?? block.playerId);
67
72
  if (team == null)
@@ -28,6 +28,14 @@ describe('tallyBlockPoints', () => {
28
28
  const t = tallyBlockPoints([rally([blockEvent('h1', 8, ['h1', 'h2']), receptionEvent('a3', 0), spikeEvent('a3')])], teamOf);
29
29
  expect(t.size).toBe(0);
30
30
  });
31
+ it('counts a POSITIONAL stuff that ENDS on the BLOCK (no trailing dig)', () => {
32
+ const t = tallyBlockPoints([rally([spikeEvent('a1'), blockEvent('h1', 9, ['h1', 'h2'])])], teamOf);
33
+ expect(t.get('HOME')).toEqual({ blockPoints: 1, blockSolo: 0, blockAssists: 2 });
34
+ });
35
+ it('does NOT count a terminal touch / tool-out block (target < 7)', () => {
36
+ const t = tallyBlockPoints([rally([spikeEvent('a1'), blockEvent('h1', 0, ['h1'])])], teamOf);
37
+ expect(t.size).toBe(0);
38
+ });
31
39
  it('reconstructs box block.solo and block.assists across a mix (incl. a triple block)', () => {
32
40
  const t = tallyBlockPoints([
33
41
  rally([blockEvent('h1', 8, ['h1', 'h2']), receptionEvent('a3', 1)]), // double: +2 assists
@@ -1,86 +1,87 @@
1
+ import { RotationSystemEnum } from './rotation-system';
1
2
  import { slotFunctionAt } from './lineup-function';
2
3
  import { RoleEnum } from '../player';
3
4
  import { isBackRow } from '../match';
4
5
  const COORDS = {
5
6
  SERVE: {
6
- 1: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
7
- 2: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
8
- 3: { 1: { d: 10.00, r: -3.50 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 6.50, r: 0.00 } },
9
- 4: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
10
- 5: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
11
- 6: { 1: { d: 10.00, r: -3.50 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 6.50, r: 0.00 } }
7
+ 1: { 1: { d: 10, r: 3.5 }, 2: { d: 0.5, r: -2.5 }, 3: { d: 0.5, r: 0 }, 4: { d: 0.5, r: 2.5 }, 5: { d: 6.5, r: 0 }, 6: { d: 5, r: -2.5 } },
8
+ 2: { 1: { d: 9.8, r: -2.7 }, 2: { d: 0.6, r: 2.35 }, 3: { d: 0.6, r: -2.55 }, 4: { d: 0.5, r: -0.2 }, 5: { d: 5, r: 3.25 }, 6: { d: 7.4, r: 0.15 } },
9
+ 3: { 1: { d: 9.85, r: 3.3 }, 2: { d: 0.55, r: -0.05 }, 3: { d: 0.6, r: 2.45 }, 4: { d: 0.6, r: -2.7 }, 5: { d: 5.3, r: -2.75 }, 6: { d: 5.3, r: 2.7 } },
10
+ 4: { 1: { d: 10, r: 3.5 }, 2: { d: 0.5, r: -2.5 }, 3: { d: 0.5, r: 0 }, 4: { d: 0.5, r: 2.4 }, 5: { d: 6.5, r: 0 }, 6: { d: 5, r: -2.5 } },
11
+ 5: { 1: { d: 9.75, r: 3.25 }, 2: { d: 0.65, r: 2.8 }, 3: { d: 0.8, r: -2.85 }, 4: { d: 0.6, r: 0.05 }, 5: { d: 4.75, r: 2.85 }, 6: { d: 6.95, r: 0 } },
12
+ 6: { 1: { d: 9.8, r: 3.05 }, 2: { d: 0.45, r: 0.05 }, 3: { d: 0.5, r: 2.45 }, 4: { d: 0.45, r: -2.8 }, 5: { d: 4.6, r: -2.65 }, 6: { d: 4.7, r: 3 } }
12
13
  },
13
14
  RECEIVE: {
14
- 1: { 1: { d: 6.50, r: 3.50 }, 2: { d: 6.00, r: 3.00 }, 3: { d: 3.00, r: -3.50 }, 4: { d: 3.50, r: -4.00 }, 5: { d: 6.00, r: -3.00 }, 6: { d: 6.50, r: 0.00 } },
15
- 2: { 1: { d: 6.00, r: 3.00 }, 2: { d: 3.00, r: 4.00 }, 3: { d: 0.50, r: 0.50 }, 4: { d: 6.00, r: -3.00 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 1.25, r: 0.75 } },
16
- 3: { 1: { d: 6.00, r: 3.00 }, 2: { d: 3.00, r: 4.00 }, 3: { d: 6.00, r: -3.00 }, 4: { d: 0.95, r: -4.00 }, 5: { d: 1.00, r: -1.00 }, 6: { d: 6.50, r: 0.00 } },
17
- 4: { 1: { d: 8.50, r: 4.00 }, 2: { d: 6.00, r: -3.00 }, 3: { d: 1.25, r: -4.00 }, 4: { d: 0.75, r: -4.05 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 6.00, r: 3.00 } },
18
- 5: { 1: { d: 6.00, r: 3.00 }, 2: { d: 2.50, r: 4.00 }, 3: { d: 1.00, r: 1.50 }, 4: { d: 6.00, r: -3.00 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 8.50, r: 1.50 } },
19
- 6: { 1: { d: 6.00, r: 3.00 }, 2: { d: 1.00, r: 1.50 }, 3: { d: 6.00, r: -3.00 }, 4: { d: 3.00, r: -4.00 }, 5: { d: 8.50, r: -1.50 }, 6: { d: 6.50, r: 0.00 } }
15
+ 1: { 1: { d: 6.5, r: 3.5 }, 2: { d: 6, r: 3 }, 3: { d: 3, r: -3.5 }, 4: { d: 3.5, r: -4 }, 5: { d: 6, r: -3 }, 6: { d: 6.5, r: 0 } },
16
+ 2: { 1: { d: 5.65, r: 2.3 }, 2: { d: 0.65, r: 2.1 }, 3: { d: 6, r: -2.3 }, 4: { d: 2.75, r: -3.9 }, 5: { d: 7.85, r: -1.7 }, 6: { d: 6.75, r: 0.1 } },
17
+ 3: { 1: { d: 6, r: 3 }, 2: { d: 2.5, r: 3.95 }, 3: { d: 0.75, r: 1 }, 4: { d: 5.55, r: -2.75 }, 5: { d: 6.1, r: 0.1 }, 6: { d: 7.8, r: 1.65 } },
18
+ 4: { 1: { d: 8.5, r: 4 }, 2: { d: 6, r: -3 }, 3: { d: 1.25, r: -4 }, 4: { d: 0.75, r: -4.05 }, 5: { d: 6.5, r: 0 }, 6: { d: 6, r: 3 } },
19
+ 5: { 1: { d: 6.1, r: 2.6 }, 2: { d: 3.25, r: 3.9 }, 3: { d: 5.8, r: -2.75 }, 4: { d: 0.75, r: -3.85 }, 5: { d: 1.9, r: -1.7 }, 6: { d: 6.75, r: -0.1 } },
20
+ 6: { 1: { d: 6, r: 3 }, 2: { d: 2.6, r: 3.85 }, 3: { d: 0.5, r: 0.4 }, 4: { d: 5.9, r: -2.9 }, 5: { d: 6.55, r: 0 }, 6: { d: 1.6, r: 0.9 } }
20
21
  },
21
22
  DEFENCE: {
22
- 1: { 1: { d: 5.00, r: 3.00 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -3.00 } },
23
- 2: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -3.00 }, 6: { d: 5.00, r: 3.00 } },
24
- 3: { 1: { d: 5.00, r: -3.00 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 3.00 }, 6: { d: 7.00, r: 0.00 } },
25
- 4: { 1: { d: 5.00, r: 3.00 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -3.00 } },
26
- 5: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -3.00 }, 6: { d: 5.00, r: 3.00 } },
27
- 6: { 1: { d: 5.00, r: -3.00 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 3.00 }, 6: { d: 7.00, r: 0.00 } }
23
+ 1: { 1: { d: 5, r: 3 }, 2: { d: 0.5, r: -2.5 }, 3: { d: 0.5, r: 0 }, 4: { d: 0.5, r: 2.5 }, 5: { d: 7, r: 0 }, 6: { d: 5, r: -3 } },
24
+ 2: { 1: { d: 4.9, r: -3 }, 2: { d: 0.6, r: 2.65 }, 3: { d: 0.65, r: -3 }, 4: { d: 0.65, r: -0.1 }, 5: { d: 5, r: 3.05 }, 6: { d: 6.75, r: 0.2 } },
25
+ 3: { 1: { d: 7, r: 0.05 }, 2: { d: 0.5, r: 0.2 }, 3: { d: 0.6, r: 2.65 }, 4: { d: 0.5, r: -2.7 }, 5: { d: 4.7, r: -2.3 }, 6: { d: 4.85, r: 2.6 } },
26
+ 4: { 1: { d: 5, r: 3 }, 2: { d: 0.5, r: -2.5 }, 3: { d: 0.5, r: 0 }, 4: { d: 0.5, r: 2.5 }, 5: { d: 7, r: 0 }, 6: { d: 5, r: -3 } },
27
+ 5: { 1: { d: 4.8, r: -3.15 }, 2: { d: 0.6, r: 2.5 }, 3: { d: 0.65, r: -2.85 }, 4: { d: 0.65, r: -0.15 }, 5: { d: 5, r: 2.75 }, 6: { d: 6.75, r: 0.05 } },
28
+ 6: { 1: { d: 7.2, r: -0.05 }, 2: { d: 0.45, r: -0.4 }, 3: { d: 0.55, r: 2.45 }, 4: { d: 0.55, r: -3 }, 5: { d: 4.85, r: -2.85 }, 6: { d: 4.8, r: 2.25 } }
28
29
  },
29
30
  DEF_L: {
30
- 1: { 1: { d: 5.00, r: 1.50 }, 2: { d: 0.25, r: -4.00 }, 3: { d: 0.25, r: -3.25 }, 4: { d: 1.75, r: 1.25 }, 5: { d: 8.00, r: -0.50 }, 6: { d: 5.00, r: -4.20 } },
31
- 2: { 1: { d: 8.00, r: -0.50 }, 2: { d: 0.25, r: -3.25 }, 3: { d: 1.75, r: 1.25 }, 4: { d: 0.25, r: -4.00 }, 5: { d: 5.00, r: -4.20 }, 6: { d: 5.00, r: 1.50 } },
32
- 3: { 1: { d: 5.00, r: -4.20 }, 2: { d: 1.75, r: 1.25 }, 3: { d: 0.25, r: -4.00 }, 4: { d: 0.25, r: -3.25 }, 5: { d: 5.00, r: 1.50 }, 6: { d: 8.00, r: -0.50 } },
33
- 4: { 1: { d: 5.00, r: 1.50 }, 2: { d: 0.25, r: -4.00 }, 3: { d: 0.25, r: -3.25 }, 4: { d: 1.75, r: 1.25 }, 5: { d: 8.00, r: -0.50 }, 6: { d: 5.00, r: -4.20 } },
34
- 5: { 1: { d: 8.00, r: -0.50 }, 2: { d: 0.25, r: -3.25 }, 3: { d: 1.75, r: 1.25 }, 4: { d: 0.25, r: -4.00 }, 5: { d: 5.00, r: -4.20 }, 6: { d: 5.00, r: 1.50 } },
35
- 6: { 1: { d: 5.00, r: -4.20 }, 2: { d: 1.75, r: 1.25 }, 3: { d: 0.25, r: -4.00 }, 4: { d: 0.25, r: -3.25 }, 5: { d: 5.00, r: 1.50 }, 6: { d: 8.00, r: -0.50 } }
31
+ 1: { 1: { d: 5, r: 1.5 }, 2: { d: 0.25, r: -4 }, 3: { d: 0.25, r: -3.25 }, 4: { d: 1.75, r: 1.25 }, 5: { d: 8, r: -0.5 }, 6: { d: 5, r: -4.2 } },
32
+ 2: { 1: { d: 4.45, r: -3.95 }, 2: { d: 1.9, r: 1.3 }, 3: { d: 0.4, r: -3.8 }, 4: { d: 0.4, r: -2.9 }, 5: { d: 5.05, r: 2.45 }, 6: { d: 7.6, r: -0.05 } },
33
+ 3: { 1: { d: 8.2, r: -0.7 }, 2: { d: 0.4, r: -2.65 }, 3: { d: 2.1, r: 0.8 }, 4: { d: 0.45, r: -3.8 }, 5: { d: 5.1, r: -3.85 }, 6: { d: 5.2, r: 1.8 } },
34
+ 4: { 1: { d: 5, r: 1.5 }, 2: { d: 0.25, r: -4 }, 3: { d: 0.25, r: -3.25 }, 4: { d: 1.75, r: 1.25 }, 5: { d: 8, r: -0.5 }, 6: { d: 5, r: -4.2 } },
35
+ 5: { 1: { d: 5.05, r: -3.9 }, 2: { d: 2.2, r: 0.65 }, 3: { d: 0.65, r: -3.8 }, 4: { d: 0.65, r: -2.75 }, 5: { d: 4.65, r: 1.1 }, 6: { d: 7.7, r: -0.75 } },
36
+ 6: { 1: { d: 7.15, r: 0.25 }, 2: { d: 0.5, r: -2.7 }, 3: { d: 1.8, r: 1.1 }, 4: { d: 0.5, r: -3.8 }, 5: { d: 4.75, r: -3.85 }, 6: { d: 4.95, r: 1.6 } }
36
37
  },
37
38
  DEF_M: {
38
- 1: { 1: { d: 5.00, r: 2.50 }, 2: { d: 1.75, r: -2.50 }, 3: { d: 0.25, r: 0.00 }, 4: { d: 1.75, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
39
- 2: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.25, r: 0.00 }, 3: { d: 1.75, r: 2.50 }, 4: { d: 1.75, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
40
- 3: { 1: { d: 5.00, r: -2.50 }, 2: { d: 1.75, r: 2.50 }, 3: { d: 1.75, r: -2.50 }, 4: { d: 0.25, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 7.00, r: 0.00 } },
41
- 4: { 1: { d: 5.00, r: 2.50 }, 2: { d: 1.75, r: -2.50 }, 3: { d: 0.25, r: 0.00 }, 4: { d: 1.75, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
42
- 5: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.25, r: 0.00 }, 3: { d: 1.75, r: 2.50 }, 4: { d: 1.75, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
43
- 6: { 1: { d: 5.00, r: -2.50 }, 2: { d: 1.75, r: 2.50 }, 3: { d: 1.75, r: -2.50 }, 4: { d: 0.25, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 7.00, r: 0.00 } }
39
+ 1: { 1: { d: 5, r: 2.5 }, 2: { d: 1.75, r: -2.5 }, 3: { d: 0.25, r: 0 }, 4: { d: 1.75, r: 2.5 }, 5: { d: 7, r: 0 }, 6: { d: 5, r: -2.5 } },
40
+ 2: { 1: { d: 5, r: -2.8 }, 2: { d: 1.85, r: 2.5 }, 3: { d: 1.85, r: -2.4 }, 4: { d: 0.4, r: 0.15 }, 5: { d: 5, r: 2.65 }, 6: { d: 7, r: 0.05 } },
41
+ 3: { 1: { d: 7.15, r: 0.1 }, 2: { d: 0.5, r: 0.1 }, 3: { d: 1.95, r: 2.45 }, 4: { d: 1.8, r: -2.55 }, 5: { d: 5.25, r: -2.45 }, 6: { d: 5.2, r: 2.8 } },
42
+ 4: { 1: { d: 5, r: 2.5 }, 2: { d: 1.75, r: -2.5 }, 3: { d: 0.25, r: 0 }, 4: { d: 1.75, r: 2.5 }, 5: { d: 7, r: 0 }, 6: { d: 5, r: -2.5 } },
43
+ 5: { 1: { d: 4.9, r: -2.35 }, 2: { d: 1.95, r: 2.4 }, 3: { d: 1.85, r: -2.6 }, 4: { d: 0.55, r: -0.2 }, 5: { d: 4.9, r: 2.45 }, 6: { d: 6.7, r: -0.1 } },
44
+ 6: { 1: { d: 7.35, r: 0.05 }, 2: { d: 0.6, r: 0.1 }, 3: { d: 2, r: 2.45 }, 4: { d: 2.25, r: -1.95 }, 5: { d: 5.2, r: -2.05 }, 6: { d: 5.3, r: 2.5 } }
44
45
  },
45
46
  DEF_R: {
46
- 1: { 1: { d: 5.00, r: 4.20 }, 2: { d: 1.75, r: -1.25 }, 3: { d: 0.25, r: 3.25 }, 4: { d: 0.25, r: 4.00 }, 5: { d: 8.00, r: 0.50 }, 6: { d: 5.00, r: -1.50 } },
47
- 2: { 1: { d: 8.00, r: 0.50 }, 2: { d: 0.25, r: 3.25 }, 3: { d: 0.25, r: 4.00 }, 4: { d: 1.75, r: -1.25 }, 5: { d: 5.00, r: -1.50 }, 6: { d: 5.00, r: 4.20 } },
48
- 3: { 1: { d: 5.00, r: -1.50 }, 2: { d: 0.25, r: 4.00 }, 3: { d: 1.75, r: -1.25 }, 4: { d: 0.25, r: 3.25 }, 5: { d: 5.00, r: 4.20 }, 6: { d: 8.00, r: 0.50 } },
49
- 4: { 1: { d: 5.00, r: 4.20 }, 2: { d: 1.75, r: -1.25 }, 3: { d: 0.25, r: 3.25 }, 4: { d: 0.25, r: 4.00 }, 5: { d: 8.00, r: 0.50 }, 6: { d: 5.00, r: -1.50 } },
50
- 5: { 1: { d: 8.00, r: 0.50 }, 2: { d: 0.25, r: 3.25 }, 3: { d: 0.25, r: 4.00 }, 4: { d: 1.75, r: -1.25 }, 5: { d: 5.00, r: -1.50 }, 6: { d: 5.00, r: 4.20 } },
51
- 6: { 1: { d: 5.00, r: -1.50 }, 2: { d: 0.25, r: 4.00 }, 3: { d: 1.75, r: -1.25 }, 4: { d: 0.25, r: 3.25 }, 5: { d: 5.00, r: 4.20 }, 6: { d: 8.00, r: 0.50 } }
47
+ 1: { 1: { d: 5, r: 4.2 }, 2: { d: 1.75, r: -1.25 }, 3: { d: 0.25, r: 3.25 }, 4: { d: 0.25, r: 4 }, 5: { d: 8, r: 0.5 }, 6: { d: 5, r: -1.5 } },
48
+ 2: { 1: { d: 4.65, r: -1 }, 2: { d: 0.25, r: 3.85 }, 3: { d: 1.75, r: -1.4 }, 4: { d: 0.3, r: 2.95 }, 5: { d: 4.3, r: 3.95 }, 6: { d: 8.15, r: 0.5 } },
49
+ 3: { 1: { d: 8.05, r: 0.4 }, 2: { d: 0.4, r: 2.95 }, 3: { d: 0.4, r: 3.85 }, 4: { d: 2, r: -2 }, 5: { d: 4.65, r: -1.15 }, 6: { d: 4.75, r: 4 } },
50
+ 4: { 1: { d: 5, r: 4.2 }, 2: { d: 1.75, r: -1.25 }, 3: { d: 0.25, r: 3.25 }, 4: { d: 0.25, r: 4 }, 5: { d: 8, r: 0.5 }, 6: { d: 5, r: -1.5 } },
51
+ 5: { 1: { d: 5.35, r: -2 }, 2: { d: 0.5, r: 3.65 }, 3: { d: 2.1, r: -1.25 }, 4: { d: 0.5, r: 2.6 }, 5: { d: 5.4, r: 3.85 }, 6: { d: 7.75, r: -0.15 } },
52
+ 6: { 1: { d: 7.8, r: 0.75 }, 2: { d: 0.45, r: 2.9 }, 3: { d: 0.45, r: 3.95 }, 4: { d: 1.75, r: -0.25 }, 5: { d: 5.15, r: -1.4 }, 6: { d: 4.9, r: 4 } }
52
53
  },
53
54
  ATTACK: {
54
- 1: { 1: { d: 0.50, r: 1.50 }, 2: { d: 3.75, r: -5.00 }, 3: { d: 3.00, r: 0.25 }, 4: { d: 3.75, r: 5.00 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 4.50, r: -2.50 } },
55
- 2: { 1: { d: 6.50, r: 0.00 }, 2: { d: 3.00, r: 0.25 }, 3: { d: 3.75, r: 5.00 }, 4: { d: 3.75, r: -5.00 }, 5: { d: 4.50, r: -2.50 }, 6: { d: 0.50, r: 1.50 } },
56
- 3: { 1: { d: 4.50, r: -2.50 }, 2: { d: 3.75, r: 5.00 }, 3: { d: 3.75, r: -5.00 }, 4: { d: 3.00, r: 0.25 }, 5: { d: 0.50, r: 1.50 }, 6: { d: 6.50, r: 0.00 } },
57
- 4: { 1: { d: 6.50, r: 4.90 }, 2: { d: 3.75, r: -5.00 }, 3: { d: 3.00, r: 0.25 }, 4: { d: 0.50, r: 1.50 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 4.50, r: -2.50 } },
58
- 5: { 1: { d: 6.50, r: 0.00 }, 2: { d: 3.00, r: 0.25 }, 3: { d: 0.50, r: 1.50 }, 4: { d: 3.75, r: -5.00 }, 5: { d: 4.50, r: -2.50 }, 6: { d: 6.50, r: 4.90 } },
59
- 6: { 1: { d: 4.50, r: -2.50 }, 2: { d: 0.50, r: 1.50 }, 3: { d: 3.75, r: -5.00 }, 4: { d: 3.00, r: 0.25 }, 5: { d: 6.50, r: 4.90 }, 6: { d: 6.50, r: 0.00 } }
55
+ 1: { 1: { d: 0.5, r: 1.5 }, 2: { d: 3.75, r: -5 }, 3: { d: 3, r: 0.25 }, 4: { d: 3.75, r: 5 }, 5: { d: 6.5, r: 0 }, 6: { d: 4.5, r: -2.5 } },
56
+ 2: { 1: { d: 5.1, r: -2 }, 2: { d: 0.45, r: 1.55 }, 3: { d: 3.6, r: -5.2 }, 4: { d: 2.8, r: 0.2 }, 5: { d: 6.4, r: 5.05 }, 6: { d: 6.55, r: -0.6 } },
57
+ 3: { 1: { d: 6.5, r: -0.15 }, 2: { d: 3, r: 0.35 }, 3: { d: 0.5, r: 1.6 }, 4: { d: 2.4, r: -5.15 }, 5: { d: 4.6, r: -2.55 }, 6: { d: 5.4, r: 5.2 } },
58
+ 4: { 1: { d: 6.5, r: 4.9 }, 2: { d: 3.75, r: -5 }, 3: { d: 3, r: 0.25 }, 4: { d: 0.5, r: 1.5 }, 5: { d: 6.5, r: 0 }, 6: { d: 4.5, r: -2.5 } },
59
+ 5: { 1: { d: 4.65, r: -2.35 }, 2: { d: 3.65, r: 4.8 }, 3: { d: 2.9, r: -5.15 }, 4: { d: 3.05, r: 0.4 }, 5: { d: 0.75, r: 1.7 }, 6: { d: 6.4, r: -0.05 } },
60
+ 6: { 1: { d: 6.2, r: -0.4 }, 2: { d: 3, r: 0.2 }, 3: { d: 3.65, r: 5.2 }, 4: { d: 3.55, r: -5.2 }, 5: { d: 4.5, r: -2.45 }, 6: { d: 0.65, r: 1.3 } }
60
61
  },
61
62
  ATK_L: {
62
- 1: { 1: { d: 0.75, r: 0.00 }, 2: { d: 0.50, r: -4.00 }, 3: { d: 1.00, r: -2.50 }, 4: { d: 3.50, r: 0.75 }, 5: { d: 6.25, r: -0.75 }, 6: { d: 3.50, r: -4.00 } },
63
- 2: { 1: { d: 6.25, r: -0.75 }, 2: { d: 1.00, r: -2.50 }, 3: { d: 3.50, r: 0.75 }, 4: { d: 0.50, r: -4.00 }, 5: { d: 3.50, r: -4.00 }, 6: { d: 0.75, r: 0.00 } },
64
- 3: { 1: { d: 3.50, r: -4.00 }, 2: { d: 3.50, r: 0.75 }, 3: { d: 0.50, r: -4.00 }, 4: { d: 1.00, r: -2.50 }, 5: { d: 0.75, r: 0.00 }, 6: { d: 6.25, r: -0.75 } },
65
- 4: { 1: { d: 3.50, r: 0.75 }, 2: { d: 0.50, r: -4.00 }, 3: { d: 1.00, r: -2.50 }, 4: { d: 0.75, r: 0.00 }, 5: { d: 6.25, r: -0.75 }, 6: { d: 3.50, r: -4.00 } },
66
- 5: { 1: { d: 6.25, r: -0.75 }, 2: { d: 1.00, r: -2.50 }, 3: { d: 0.75, r: 0.00 }, 4: { d: 0.50, r: -4.00 }, 5: { d: 3.50, r: -4.00 }, 6: { d: 3.50, r: 0.75 } },
67
- 6: { 1: { d: 3.50, r: -4.00 }, 2: { d: 0.75, r: 0.00 }, 3: { d: 0.50, r: -4.00 }, 4: { d: 1.00, r: -2.50 }, 5: { d: 3.50, r: 0.75 }, 6: { d: 6.25, r: -0.75 } }
63
+ 1: { 1: { d: 0.75, r: 0 }, 2: { d: 0.5, r: -4 }, 3: { d: 1, r: -2.5 }, 4: { d: 3.5, r: 0.75 }, 5: { d: 6.25, r: -0.75 }, 6: { d: 3.5, r: -4 } },
64
+ 2: { 1: { d: 3.4, r: -4.05 }, 2: { d: 0.75, r: 0 }, 3: { d: 0.9, r: -4.15 }, 4: { d: 1.8, r: -2.5 }, 5: { d: 3.4, r: 0.5 }, 6: { d: 6.5, r: -1.15 } },
65
+ 3: { 1: { d: 6.35, r: -0.1 }, 2: { d: 2.1, r: -2.45 }, 3: { d: 0.9, r: 0 }, 4: { d: 0.8, r: -3.95 }, 5: { d: 4.6, r: -3.75 }, 6: { d: 3.6, r: 1.45 } },
66
+ 4: { 1: { d: 3.5, r: 0.75 }, 2: { d: 0.5, r: -4 }, 3: { d: 1, r: -2.5 }, 4: { d: 0.75, r: 0 }, 5: { d: 6.25, r: -0.75 }, 6: { d: 3.5, r: -4 } },
67
+ 5: { 1: { d: 4.25, r: -3.85 }, 2: { d: 3.55, r: 0.75 }, 3: { d: 1, r: -4.1 }, 4: { d: 2.05, r: -2.65 }, 5: { d: 0.85, r: -0.15 }, 6: { d: 6, r: -0.8 } },
68
+ 6: { 1: { d: 5.9, r: -1 }, 2: { d: 1.05, r: -2.5 }, 3: { d: 3.45, r: 0.9 }, 4: { d: 0.7, r: -3.9 }, 5: { d: 3.4, r: -4.05 }, 6: { d: 0.75, r: -0.2 } }
68
69
  },
69
70
  ATK_M: {
70
- 1: { 1: { d: 0.75, r: 1.25 }, 2: { d: 1.25, r: -2.00 }, 3: { d: 0.75, r: 0.50 }, 4: { d: 2.25, r: 2.60 }, 5: { d: 6.50, r: 1.50 }, 6: { d: 4.00, r: -1.50 } },
71
- 2: { 1: { d: 6.50, r: 1.50 }, 2: { d: 0.75, r: 0.50 }, 3: { d: 2.25, r: 2.60 }, 4: { d: 1.25, r: -2.00 }, 5: { d: 4.00, r: -1.50 }, 6: { d: 0.75, r: 1.25 } },
72
- 3: { 1: { d: 4.00, r: -1.50 }, 2: { d: 2.25, r: 2.60 }, 3: { d: 1.25, r: -2.00 }, 4: { d: 0.75, r: 0.50 }, 5: { d: 0.75, r: 1.25 }, 6: { d: 6.50, r: 1.50 } },
73
- 4: { 1: { d: 2.25, r: 2.60 }, 2: { d: 1.25, r: -2.00 }, 3: { d: 0.75, r: 0.50 }, 4: { d: 0.75, r: 1.25 }, 5: { d: 6.50, r: 1.50 }, 6: { d: 4.00, r: -1.50 } },
74
- 5: { 1: { d: 6.50, r: 1.50 }, 2: { d: 0.75, r: 0.50 }, 3: { d: 0.75, r: 1.25 }, 4: { d: 1.25, r: -2.00 }, 5: { d: 4.00, r: -1.50 }, 6: { d: 2.25, r: 2.60 } },
75
- 6: { 1: { d: 4.00, r: -1.50 }, 2: { d: 0.75, r: 1.25 }, 3: { d: 1.25, r: -2.00 }, 4: { d: 0.75, r: 0.50 }, 5: { d: 2.25, r: 2.60 }, 6: { d: 6.50, r: 1.50 } }
71
+ 1: { 1: { d: 0.75, r: 1.25 }, 2: { d: 1.25, r: -2 }, 3: { d: 0.75, r: 0.5 }, 4: { d: 2.25, r: 2.6 }, 5: { d: 6.5, r: 1.5 }, 6: { d: 4, r: -1.5 } },
72
+ 2: { 1: { d: 4.5, r: -2.2 }, 2: { d: 0.7, r: 1.25 }, 3: { d: 1.8, r: -2.45 }, 4: { d: 0.9, r: 0.05 }, 5: { d: 2.75, r: 3.05 }, 6: { d: 5.75, r: 0 } },
73
+ 3: { 1: { d: 6.55, r: 1.15 }, 2: { d: 0.9, r: 0.3 }, 3: { d: 0.85, r: 1.45 }, 4: { d: 1.7, r: -2.7 }, 5: { d: 3.95, r: -1.75 }, 6: { d: 2.25, r: 3.2 } },
74
+ 4: { 1: { d: 2.25, r: 2.6 }, 2: { d: 1.25, r: -2 }, 3: { d: 0.75, r: 0.5 }, 4: { d: 0.75, r: 1.25 }, 5: { d: 6.5, r: 1.5 }, 6: { d: 4, r: -1.5 } },
75
+ 5: { 1: { d: 4.35, r: -1.5 }, 2: { d: 2.25, r: 2.85 }, 3: { d: 1.9, r: -2.55 }, 4: { d: 0.8, r: 0.35 }, 5: { d: 0.6, r: 1.45 }, 6: { d: 5.55, r: 1.45 } },
76
+ 6: { 1: { d: 5.2, r: 1.1 }, 2: { d: 0.8, r: 0.35 }, 3: { d: 2.4, r: 3 }, 4: { d: 1.8, r: -2.15 }, 5: { d: 4.5, r: -1.7 }, 6: { d: 0.8, r: 1.35 } }
76
77
  },
77
78
  ATK_R: {
78
- 1: { 1: { d: 1.75, r: 2.50 }, 2: { d: 1.50, r: -1.75 }, 3: { d: 0.75, r: 1.75 }, 4: { d: 0.50, r: 4.00 }, 5: { d: 5.00, r: 3.25 }, 6: { d: 5.75, r: -2.00 } },
79
- 2: { 1: { d: 5.00, r: 3.25 }, 2: { d: 0.75, r: 1.75 }, 3: { d: 0.50, r: 4.00 }, 4: { d: 1.50, r: -1.75 }, 5: { d: 5.75, r: -2.00 }, 6: { d: 1.75, r: 2.50 } },
80
- 3: { 1: { d: 5.75, r: -2.00 }, 2: { d: 0.50, r: 4.00 }, 3: { d: 1.50, r: -1.75 }, 4: { d: 0.75, r: 1.75 }, 5: { d: 1.75, r: 2.50 }, 6: { d: 5.00, r: 3.25 } },
81
- 4: { 1: { d: 2.25, r: 4.00 }, 2: { d: 2.25, r: -1.75 }, 3: { d: 0.75, r: 1.50 }, 4: { d: 1.50, r: 2.25 }, 5: { d: 6.00, r: 2.25 }, 6: { d: 5.00, r: -0.75 } },
82
- 5: { 1: { d: 6.00, r: 2.25 }, 2: { d: 0.75, r: 1.50 }, 3: { d: 1.50, r: 2.25 }, 4: { d: 2.25, r: -1.75 }, 5: { d: 5.00, r: -0.75 }, 6: { d: 2.25, r: 4.00 } },
83
- 6: { 1: { d: 5.00, r: -0.75 }, 2: { d: 1.50, r: 2.25 }, 3: { d: 2.25, r: -1.75 }, 4: { d: 0.75, r: 1.50 }, 5: { d: 2.25, r: 4.00 }, 6: { d: 6.00, r: 2.25 } }
79
+ 1: { 1: { d: 1.75, r: 2.5 }, 2: { d: 1.5, r: -1.75 }, 3: { d: 0.75, r: 1.75 }, 4: { d: 0.5, r: 4 }, 5: { d: 5, r: 3.25 }, 6: { d: 5.75, r: -2 } },
80
+ 2: { 1: { d: 4.65, r: -0.8 }, 2: { d: 0.75, r: 1.75 }, 3: { d: 1.85, r: -1.75 }, 4: { d: 1.7, r: 2.2 }, 5: { d: 2.15, r: 4.25 }, 6: { d: 6.25, r: 2 } },
81
+ 3: { 1: { d: 5.1, r: 3.15 }, 2: { d: 1.85, r: 2.6 }, 3: { d: 0.8, r: 1.75 }, 4: { d: 2.15, r: -1.7 }, 5: { d: 4.9, r: -1.25 }, 6: { d: 1.9, r: 4.15 } },
82
+ 4: { 1: { d: 2.25, r: 4 }, 2: { d: 2.25, r: -1.75 }, 3: { d: 0.75, r: 1.5 }, 4: { d: 1.5, r: 2.25 }, 5: { d: 6, r: 2.25 }, 6: { d: 5, r: -0.75 } },
83
+ 5: { 1: { d: 5.95, r: -2 }, 2: { d: 0.9, r: 3.7 }, 3: { d: 2.2, r: -1.6 }, 4: { d: 2, r: 2.35 }, 5: { d: 0.9, r: 1.15 }, 6: { d: 6, r: 1.9 } },
84
+ 6: { 1: { d: 5.35, r: 2.35 }, 2: { d: 2.05, r: 2.1 }, 3: { d: 0.8, r: 4 }, 4: { d: 2.1, r: -1.95 }, 5: { d: 4.9, r: -1.4 }, 6: { d: 0.4, r: 1.3 } }
84
85
  }
85
86
  };
86
87
  // The default coordinate table as a BaseConfig.coords (jsonb string keys). Shared, readonly; materialized (and so
@@ -97,36 +98,47 @@ const DEFAULT_COORDS = (() => {
97
98
  }
98
99
  return out;
99
100
  })();
100
- // The owner's authored per-point-of-attack block map for the 5-1 (owner 2026-08-07), keyed
101
+ // The owner's corrected per-point-of-attack block map for the 5-1 (exported 2026-08-09), keyed
101
102
  // [DEF_L|DEF_M|DEF_R][rotation][zone] -> canBlock. `false` = that front-row zone sits OUT of the block for an attack
102
- // from that side; `true` = reads/joins the wall. Only front-row zones (2/3/4) are tagged. Same rotation convention
103
- // as DEFAULT_COORDS. Generated from the finalized 5-1 sr-mapper preset's Def L/M/R block/noblock tags.
103
+ // from that side; `true` = reads/joins the wall. Only the front-row zones in play for the rotation are tagged. Same
104
+ // rotation convention as DEFAULT_COORDS.
104
105
  const DEFAULT_BLOCKING = {
105
106
  DEF_L: {
106
107
  1: { 2: true, 3: true, 4: false },
107
- 2: { 2: true, 3: false, 4: true },
108
- 3: { 2: false, 3: true, 4: true },
108
+ 2: { 2: false, 4: true },
109
+ 3: { 3: false, 4: true },
109
110
  4: { 2: true, 3: true, 4: false },
110
- 5: { 2: true, 3: false, 4: true },
111
- 6: { 2: false, 3: true, 4: true }
111
+ 5: { 2: false, 4: true },
112
+ 6: { 3: false, 4: true }
112
113
  },
113
114
  DEF_M: {
114
115
  1: { 2: false, 3: true, 4: false },
115
- 2: { 2: true, 3: false, 4: false },
116
- 3: { 2: false, 3: false, 4: true },
116
+ 2: { 2: false, 3: false },
117
+ 3: { 3: false, 4: false },
117
118
  4: { 2: false, 3: true, 4: false },
118
- 5: { 2: true, 3: false, 4: false },
119
- 6: { 2: false, 3: false, 4: true }
119
+ 5: { 2: false, 3: false },
120
+ 6: { 3: false, 4: false }
120
121
  },
121
122
  DEF_R: {
122
123
  1: { 2: false, 3: true, 4: true },
123
- 2: { 2: true, 3: true, 4: false },
124
- 3: { 2: true, 3: false, 4: true },
124
+ 2: { 2: true, 3: false },
125
+ 3: { 2: true, 4: false },
125
126
  4: { 2: false, 3: true, 4: true },
126
- 5: { 2: true, 3: true, 4: false },
127
- 6: { 2: true, 3: false, 4: true }
127
+ 5: { 2: true, 3: false },
128
+ 6: { 2: true, 4: false }
128
129
  }
129
130
  };
131
+ // The owner's corrected 5-1 serve-receive participation map (exported 2026-08-09). The 5-1 uses this exact map; the
132
+ // other systems derive their 3-passer map from slot functions (defaultReceiveMap) since their receiving personnel
133
+ // differ. Keyed [rotation][zone] -> passes.
134
+ const DEFAULT_5_1_RECEIVE = {
135
+ 1: { 1: false, 2: true, 3: false, 4: false, 5: true, 6: true },
136
+ 2: { 1: true, 2: false, 3: true, 4: false, 5: false, 6: true },
137
+ 3: { 1: true, 2: false, 3: false, 4: true, 5: true, 6: false },
138
+ 4: { 1: false, 2: true, 3: false, 4: false, 5: true, 6: true },
139
+ 5: { 1: true, 2: false, 3: true, 4: false, 5: false, 6: true },
140
+ 6: { 1: true, 2: false, 3: false, 4: true, 5: true, 6: false }
141
+ };
130
142
  // Rotation index -> the setter's rotational zone (inverse of SETTER_ZONE_TO_ROTATION {1:1,6:2,5:3,4:4,3:5,2:6}).
131
143
  const ROTATION_TO_SETTER_ZONE = { 1: 1, 2: 6, 3: 5, 4: 4, 5: 3, 6: 2 };
132
144
  // The default serve-receive participation map: the standard 3-passer formation. A rotational slot passes iff its
@@ -147,8 +159,9 @@ export function defaultReceiveMap(system) {
147
159
  return receive;
148
160
  }
149
161
  // The default base config a team of the given system starts with. Every team always has one (materialized on team
150
- // creation and by the backfill migration); the coordinates are the same 5-1 table for every system, only the
151
- // receive map is derived per system.
162
+ // creation and by the backfill migration). Every system reuses the corrected 5-1 coordinate table and block map; the
163
+ // 5-1 uses the owner's exported receive map, the other systems derive their receive map per system.
152
164
  export function defaultBaseConfig(system) {
153
- return { coords: DEFAULT_COORDS, receive: defaultReceiveMap(system), blocking: DEFAULT_BLOCKING };
165
+ const receive = system === RotationSystemEnum.FIVE_ONE ? DEFAULT_5_1_RECEIVE : defaultReceiveMap(system);
166
+ return { coords: DEFAULT_COORDS, receive, blocking: DEFAULT_BLOCKING };
154
167
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volleyballsimtypes",
3
- "version": "0.0.508",
3
+ "version": "0.0.510",
4
4
  "description": "vbsim types",
5
5
  "main": "./dist/cjs/src/index.js",
6
6
  "module": "./dist/esm/src/index.js",