|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Sport::Analytics::NHL::Report::ES;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
20
 | 
 
 | 
 
 | 
  
20
  
 | 
 
 | 
70741
 | 
 use v5.10.1;  | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
178
 | 
    | 
| 
4
 | 
20
 | 
 
 | 
 
 | 
  
20
  
 | 
 
 | 
273
 | 
 use strict;  | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
    | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
522
 | 
    | 
| 
5
 | 
20
 | 
 
 | 
 
 | 
  
20
  
 | 
 
 | 
177
 | 
 use warnings FATAL => 'all';  | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
    | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
668
 | 
    | 
| 
6
 | 
20
 | 
 
 | 
 
 | 
  
20
  
 | 
 
 | 
101
 | 
 use experimental qw(smartmatch);  | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
    | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
113
 | 
    | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
8
 | 
20
 | 
 
 | 
 
 | 
  
20
  
 | 
 
 | 
1315
 | 
 use parent 'Sport::Analytics::NHL::Report';  | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
258
 | 
    | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
106
 | 
    | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
10
 | 
20
 | 
 
 | 
 
 | 
  
20
  
 | 
 
 | 
1187
 | 
 use Sport::Analytics::NHL::Config;  | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
    | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3934
 | 
    | 
| 
11
 | 
20
 | 
 
 | 
 
 | 
  
20
  
 | 
 
 | 
139
 | 
 use Sport::Analytics::NHL::Errors;  | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
205
 | 
    | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3670
 | 
    | 
| 
12
 | 
20
 | 
 
 | 
 
 | 
  
20
  
 | 
 
 | 
243
 | 
 use Sport::Analytics::NHL::Util;  | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
119
 | 
    | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1435
 | 
    | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
14
 | 
20
 | 
 
 | 
 
 | 
  
20
  
 | 
 
 | 
111
 | 
 use Storable qw(dclone);  | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
    | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
888
 | 
    | 
| 
15
 | 
20
 | 
 
 | 
 
 | 
  
20
  
 | 
 
 | 
126
 | 
 use Data::Dumper;  | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
    | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34351
 | 
    | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Sport::Analytics::NHL::Report::ES - Class for the NHL HTML ES report.  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSYS  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Class for the NHL HTML ES report. Should not be constructed directly, but via Sport::Analytics::NHL::Report (q.v.)  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 As with any other HTML report, there are two types: old (pre-2007) and new (2007 and on). Parsers of them may have something in common but may turn out to be completely different more often than not.  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 METHODS  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 2  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item C  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Get the headers of the player tables in the new HTML.  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Arguments: HTML element with the team table  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Returns: the array of headers.  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item C  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Get the headers of the player tables in the old HTML.  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Arguments: HTML element with the team table  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Returns: the array of headers.  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item C  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Cleaning up and standardizing the parsed data.  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Arguments: none  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Returns: void. Everything is in the $self.  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item C  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Parse the ES html tree into a boxscore object  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Arguments: none  | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Returns: void. Everything is in the $self.  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item C  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Parse a team's table in the new HTML.  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Arguments: HTML element with the team table  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Returns: the team hashref.  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item C  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Parse a team's table in the old HTML.  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Arguments: HTML element with the team table  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Returns: the team hashref.  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %NORMAL_FIELDS = (  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	S => {  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		G => 'goals', 'A' => 'assists', P => 'points', FW => 'faceOffWins',  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		PN => 'penalties', FL => 'faceOffLosses', 'F%' => 'faceOffPct',  | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		TOI => 'timeOnIce', AVG => 'averageTimeShift', S => 'shots', MS => 'misses',  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'+/-' => 'plusMinus', 'A/B' => 'attemptsBlocked', HT => 'hits',  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		GV => 'giveaways', TK => 'takeaways', BS => 'blocked', SHF => 'shifts',  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		TOIPP => 'powerPlayTimeOnIce', TOISH => 'shortHandedTimeOnIce', TOITOT => 'timeOnIce',  | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		PP => 'powerPlayTimeOnIce', SH => 'shortHandedTimeOnIce', EV => 'evenTimeOnIce',  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		TOIEV => 'evenTimeOnIce', POS => 'position', 'No.' => 'number', TOI => 'timeOnIce',  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		PIM => 'penaltyMinutes', TOISHF => 'shifts', TOIAVG => 'averageIceTime', SHOTT => 'shots',  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	},  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %LIVE_FIELDS = (  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	S => [qw(shortHandedGoals shortHandedAssists powerPlayGoals powerPlayAssists evenStrengthGoals evenStrengthAssists)],  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	G => [qw(pim goals assists)]  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %FRENCH = (  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'TOIDN/SH' => 'TOISH',  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'TOI' => '14:19',  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'TOIFÃ/EV' => 'TOIEV',  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'TOIMOY' => 'TOIAVG',  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'LB' => 'BS',  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'MG' => 'FW',  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'TOIAN/PP' => 'TOIPP',  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'LANC.' => 'S',  | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'PP' => 'TK',  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'B' => 'G',  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'LR' => 'MS',  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'M%' => 'F%',  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'PUN' => 'PN',  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'MP' => 'FL',  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'MO' => 'FL',  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'TOIPR' => 'TOISHF',  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'R' => 'GV',  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'MIN' => 'PIM',  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'TENT/BL' => 'A/B',  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'MÃ' => 'HT'  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_old_headers ($$;$) {  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
118
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
 	my $self         = shift;  | 
| 
119
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $team_summary = shift;  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
121
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $header_row = $self->get_sub_tree(0, [ 0 ], $team_summary);  | 
| 
122
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $headers_num = scalar @{$header_row->{_content}};  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
123
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my @headers;  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
125
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	for my $h (0..$headers_num-1) {  | 
| 
126
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		for ($h) {  | 
| 
127
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			when (0) {  | 
| 
128
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 				$headers[$h] = 'No.';  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
130
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			when (1) {  | 
| 
131
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 				$headers[$h] = 'POS';  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
133
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			when (2) {  | 
| 
134
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 				$headers[$h] = 'name';  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
136
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			default {  | 
| 
137
 | 
  
0
  
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 				$headers[$h] =  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					$self->get_sub_tree(0, [$h,0,1], $header_row)   ||  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					$self->get_sub_tree(0, [$h,0,0,1], $header_row) ||  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					'';  | 
| 
141
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 				if (ref $headers[$h]) {  | 
| 
142
 | 
  
0
  
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 					$headers[$h] =  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 						$self->get_sub_tree(0, [$h,0,2], $header_row) ||  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 						$self->get_sub_tree(0, [$h,0,0,2], $header_row);  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				}  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
149
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $shots_row = $self->get_sub_tree(0, [1], $team_summary);  | 
| 
150
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $h = 0;  | 
| 
151
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $shot_offset;  | 
| 
152
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	for my $header (@headers) {  | 
| 
153
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		unless ($header) {  | 
| 
154
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$shot_offset = $h;  | 
| 
155
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			last;  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
157
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$h++;  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
159
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	for my $h (2..$#{$shots_row->{_content}}) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
160
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $subshot = $self->get_sub_tree(0, [$h,0,0,0], $shots_row);  | 
| 
161
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		last unless $subshot;  | 
| 
162
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		splice(@headers, $shot_offset-1+$h, 0, "SHOT" . $subshot);  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
164
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	splice(@headers, $shot_offset, 1);  | 
| 
165
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	@headers = grep { /\S/ } @headers;  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
166
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	@headers;  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_new_headers ($$) {  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
171
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
1
  
 | 
8
 | 
 	my $self         = shift;  | 
| 
172
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
 	my $team_summary = shift;  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
174
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
 	my $header_row = $self->get_sub_tree(0, [ 0,0,0 ], $team_summary);  | 
| 
175
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 	my $headers_num = scalar @{$header_row->{_content}};  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
176
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 	my @headers;  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
178
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
 	for my $h (0..$headers_num-1) {  | 
| 
179
 | 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
113
 | 
 		for ($h) {  | 
| 
180
 | 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
106
 | 
 			when (0) {  | 
| 
181
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
 				$headers[$h] = 'name';  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
183
 | 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
89
 | 
 			default {  | 
| 
184
 | 
72
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
164
 | 
 				$headers[$h] =  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					$self->get_sub_tree(0, [$h,0,], $header_row)   ||  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					'';  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
190
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
 	unshift(@headers, qw(No. POS));  | 
| 
191
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
 	my $shots_row = $self->get_sub_tree(0, [0,0,1], $team_summary);  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
193
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
58
 | 
 	for my $h (0..$#{$shots_row->{_content}}) {  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
    | 
| 
194
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
 		my $subcol = $self->get_sub_tree(0, [$h,0], $shots_row);  | 
| 
195
 | 
28
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
87
 | 
 		splice(@headers, 10+$h, 0, "TOI$subcol") if $subcol;  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
197
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 	splice(@headers, 9, 1);  | 
| 
198
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
 	@headers = grep { /\S/ } @headers;  | 
| 
 
 | 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
207
 | 
    | 
| 
199
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
 	for my $header (@headers) {  | 
| 
200
 | 
100
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
168
 | 
 		$header = $FRENCH{$header} if $FRENCH{$header};  | 
| 
201
 | 
100
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
145
 | 
 		$header = 'TOIEV' if $header =~ /TOIF.*EV/;  | 
| 
202
 | 
100
 | 
  
  0
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
269
 | 
 		$header = 'HT' if $header =~ /^M./ && $header ne 'MS' && $header ne 'M%' && $header ne 'MO' && $header ne 'MG';  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
204
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
 	@headers;  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub parse_old_team_summary ($$) {  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
209
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
 	my $self         = shift;  | 
| 
210
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $team_summary = shift;  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
212
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $roster = [];  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
214
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my @headers = $self->get_old_headers($team_summary);  | 
| 
215
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $g = 2;  | 
| 
216
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	while (my $player_row = $self->get_sub_tree(0, [$g], $team_summary)) {  | 
| 
217
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $player = {};  | 
| 
218
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		for my $h (0..$#headers) {  | 
| 
219
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$player->{$headers[$h]} = $self->get_sub_tree(0, [$h,0,0], $player_row);  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
221
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		push(@{$roster}, $player) if  | 
| 
222
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 			$player->{name} && $player->{name} !~ /TOTALS/ && $player->{name} !~ /team penalty/i;  | 
| 
 
 | 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
223
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$g++;  | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
225
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$roster;  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub parse_new_team_summary ($$) {  | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
230
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
1
  
 | 
11
 | 
 	my $self         = shift;  | 
| 
231
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 	my $team_summary = shift;  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
233
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
 	my @headers = $self->get_new_headers($team_summary);  | 
| 
234
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
 	my @rosters;  | 
| 
235
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
 	my $g = 2;  | 
| 
236
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 	my $roster = [];  | 
| 
237
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
 	while (my $player_row = $self->get_sub_tree(0, [0,0,$g], $team_summary)) {  | 
| 
238
 | 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
256
 | 
 		my $player = {};  | 
| 
239
 | 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
321
 | 
 		for my $h (0..$#headers) {  | 
| 
240
 | 
4800
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8264
 | 
 			$player->{$headers[$h]} = $self->get_sub_tree(0, [$h,0], $player_row);  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
242
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
270
 | 
 		push(@{$roster}, $player) if  | 
| 
243
 | 
192
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
985
 | 
 			$player->{'No.'} && $player->{'No.'} =~ /\S/ && $player->{'No.'} !~ /\D/;  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
244
 | 
192
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
489
 | 
 		if ($player->{'No.'} && $player->{'No.'} =~ /TOTALS/) {  | 
| 
245
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
 			push(@rosters, $roster);  | 
| 
246
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
 			$roster = [];  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
248
 | 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
551
 | 
 		$g++;  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
250
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
 	@rosters;  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub parse ($$) {  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
255
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
1
  
 | 
11
 | 
 	my $self = shift;  | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
257
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
 	my $body_size = scalar @{$self->{html}{_content}};  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
    | 
| 
258
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
17
 | 
 	if ($self->{old}) {  | 
| 
259
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $away_summary = $self->get_sub_tree(0, [3,(0)x$#{$self->{head}}]);  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
260
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self->{teams}[0]{roster} = $self->parse_old_team_summary($away_summary);  | 
| 
261
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $home_summary = $self->get_sub_tree(0, [5,(0)x$#{$self->{head}}]);  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
262
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self->{teams}[1]{roster} = $self->parse_old_team_summary($home_summary);  | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	else {  | 
| 
265
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
 		my $summary = $self->get_sub_tree(0, [$body_size/2,7]);  | 
| 
266
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
 		my @rosters = $self->parse_new_team_summary($summary);  | 
| 
267
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1288
 | 
 		$self->{teams}[0]{roster} = dclone $rosters[0];  | 
| 
268
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1226
 | 
 		$self->{teams}[1]{roster} = dclone $rosters[1];  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub normalize ($$) {  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
274
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
1
  
 | 
14
 | 
 	my $self       = shift;  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
276
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
 	for my $team (@{$self->{teams}}) {  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
277
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
 		for my $player (@{$team->{roster}}) {  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
    | 
| 
278
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
301
 | 
 			$player->{'No.'} =~ s/\D//g;  | 
| 
279
 | 
160
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
282
 | 
 			if ($player->{POS} eq 'G') {  | 
| 
280
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
 				delete @{$player}{qw(BS +/- SHF FW FL F% A/B)};  | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
208
 | 
    | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
282
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
185
 | 
 			for my $field (keys %{$player}) {  | 
| 
 
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
563
 | 
    | 
| 
283
 | 
3904
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
5524
 | 
 				$player->{$field} ||= $field eq 'TOIAVG' ? '0:00' : 0;  | 
| 
284
 | 
3904
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4947
 | 
 				$player->{$field} =~ s/^\s+//;  | 
| 
285
 | 
3904
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4753
 | 
 				$player->{$field} =~ s/\s+$//;  | 
| 
286
 | 
3904
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4187
 | 
 				$player->{$field} =~ s/\;/:/g;  | 
| 
287
 | 
3904
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
8681
 | 
 				if ($player->{$field} =~ /:/) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
288
 | 
720
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1898
 | 
 					$player->{$field} =~ s/^(\d+):(\d+)$/$1*60+$2/e;  | 
| 
 
 | 
720
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1775
 | 
    | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				}  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				elsif ($field ne 'name' && $field ne 'POS') {  | 
| 
291
 | 
2864
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
4970
 | 
 					$player->{$field} = 0 if $player->{$field} !~ /\d/;  | 
| 
292
 | 
2864
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3470
 | 
 					$player->{$field} += 0;  | 
| 
293
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				}  | 
| 
294
 | 
3904
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
9445
 | 
 				$player->{$field} += 0 if $player->{$field} =~ /^\-?\d+$/;  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
296
 | 
160
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
855
 | 
 			$player->{name} = "$2 $1" if $player->{name} =~ /^(\S.*\S)\,\s+(\S.*)$/;  | 
| 
297
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
261
 | 
 			$player->{start} = 2;  | 
| 
298
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
211
 | 
 			$player->{status} = 'X';  | 
| 
299
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
218
 | 
 			for my $field (qw(G A PIM)) {  | 
| 
300
 | 
480
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
977
 | 
 				$player->{$field} ||= 0E0;  | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
302
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
169
 | 
 			for my $field (keys %{$NORMAL_FIELDS{S}}) {  | 
| 
 
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
656
 | 
    | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				$player->{$NORMAL_FIELDS{S}->{$field}} = delete $player->{$field}  | 
| 
304
 | 
4960
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
8431
 | 
 					if exists $player->{$field};  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
306
 | 
160
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
403
 | 
 			my $pos = $player->{position} eq 'G' ? 'G' : 'S';  | 
| 
307
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
179
 | 
 			for my $field (@{$LIVE_FIELDS{$pos}}) {  | 
| 
 
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
234
 | 
    | 
| 
308
 | 
912
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
1997
 | 
 				$player->{$field} ||= 0E0;  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
310
 | 
160
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
296
 | 
 			if ($player->{position} ne 'G') {  | 
| 
311
 | 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
193
 | 
 				$player->{faceoffTaken} = $player->{faceOffWins} + $player->{faceOffLosses};  | 
| 
312
 | 
144
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
327
 | 
 				$player->{timeOnIce} = $player->{evenTimeOnIce} + $player->{powerPlayTimeOnIce} + $player->{shortHandedTimeOnIce} if defined $player->{evenTimeOnIce};  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHOR  | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
322
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 More Hockey Stats, C<<  >>  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 BUGS  | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Please report any bugs or feature requests to C, or through  | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the web interface at L.  I will be notified, and then you'll  | 
| 
328
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 automatically be notified of progress on your bug as I make changes.  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SUPPORT  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 You can find documentation for this module with the perldoc command.  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     perldoc Sport::Analytics::NHL::Report::ES  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 You can also look for information at:  | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 4  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item * RT: CPAN's request tracker (report bugs here)  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item * AnnoCPAN: Annotated CPAN documentation  | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
347
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L  | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item * CPAN Ratings  | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
351
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item * Search CPAN  | 
| 
354
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  |