|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
79290
 | 
 use 5.006;  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
218
 | 
    | 
| 
2
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
30
 | 
 use strict;  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
187
 | 
    | 
| 
3
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
26
 | 
 use warnings;  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
238
 | 
    | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Data::Freq::Field;  | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Data::Freq::Field - Controls counting with Data::Freq at each level  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
13
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
30
 | 
 use Carp qw(croak);  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
320
 | 
    | 
| 
14
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
4937
 | 
 use Date::Parse qw(str2time);  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43770
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
455
 | 
    | 
| 
15
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
48
 | 
 use Scalar::Util qw(looks_like_number);  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15432
 | 
    | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 require POSIX;  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 METHODS  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 new  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Usage:  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     Data::Freq::Field->new({  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         type    => 'text' , # { 'text' | 'number' | 'date' }  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sort    => 'count', # { 'value' | 'count' | 'first' | 'last' }  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         order   => 'desc' , # { 'asc' | 'desc' }  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         pos     => 0      , # { 0 | 1 | 2 | -1 | -2 | .. | [0, 1, 2] | .. }  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         key     => 'mykey', # { any key(s) for input hash refs }  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         convert => sub {...},  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     });  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Constructs a field object.  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See L for details.  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
40
 | 
287
 | 
 
 | 
 
 | 
  
287
  
 | 
  
1
  
 | 
87377
 | 
     my ($class, $input) = @_;  | 
| 
41
 | 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
948
 | 
     my $self = bless {}, $class;  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
43
 | 
287
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
975
 | 
     if (!ref $input) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
44
 | 
102
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
256
 | 
         $self->_extract_any($input) or croak "invalid argument: $input";  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif (ref $input eq 'HASH') {  | 
| 
46
 | 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
205
 | 
         for my $target (qw(type aggregate sort order pos key)) {  | 
| 
47
 | 
642
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1777
 | 
             if (defined $input->{$target}) {  | 
| 
48
 | 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
543
 | 
                 my $method = "_extract_$target";  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   | 
| 
50
 | 
206
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
563
 | 
                 $self->$method($input->{$target})  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         or croak "invalid $target: $input->{$target}";  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           | 
| 
55
 | 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
204
 | 
         for my $target (qw(offset limit)) {  | 
| 
56
 | 
214
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
564
 | 
             if (defined $input->{$target}) {  | 
| 
57
 | 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
125
 | 
                 $self->{$target} = int($input->{$target});  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           | 
| 
61
 | 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
193
 | 
         for my $target (qw(convert)) {  | 
| 
62
 | 
107
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
336
 | 
             if (defined $input->{$target}) {  | 
| 
63
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
                 $self->{$target} = $input->{$target};  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   | 
| 
65
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
                 if (ref $input->{$target} ne 'CODE') {  | 
| 
66
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     croak "$target must be a CODE ref";  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif (ref $input eq 'ARRAY') {  | 
| 
71
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
147
 | 
         for my $item (@$input) {  | 
| 
72
 | 
173
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
359
 | 
             $self->_extract_any($item) or croak "invalid argument: $item";  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
75
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         croak "invalid field: $input";  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
78
 | 
287
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
654
 | 
     $self->{type} = 'text' unless defined $self->type;  | 
| 
79
 | 
287
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
1358
 | 
     $self->{aggregate} ||= 'count';  | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
81
 | 
287
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
507
 | 
     if ($self->type eq 'text') {  | 
| 
82
 | 
175
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
644
 | 
         $self->{sort} ||= 'score';  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
84
 | 
112
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
602
 | 
         $self->{sort} ||= 'value';  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
87
 | 
287
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1003
 | 
     if ($self->{sort} =~ /^(count|score|last)$/) {  | 
| 
88
 | 
146
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
679
 | 
         $self->{order} ||= 'desc';  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
90
 | 
141
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
1347
 | 
         $self->{order} ||= 'asc';  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
93
 | 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1031
 | 
     return $self;  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 evaluate_record  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Usage:  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $field = Data::Freq::Field->new(...);  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $record = Data::Freq::Record->new(...);  | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $normalized_text = $field->evaluate_record($record);  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Evaluates an input record as a normalized text that will be used for frequency counting,  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 depending on the parameters passed to the L method.  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is intended to be an internal method for L.  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub evaluate_record {  | 
| 
112
 | 
249
 | 
 
 | 
 
 | 
  
249
  
 | 
  
1
  
 | 
317
 | 
     my ($self, $record) = @_;  | 
| 
113
 | 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
283
 | 
     my $result = undef;  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     TRY: {  | 
| 
116
 | 
249
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
262
 | 
         if (defined $self->pos) {  | 
| 
 
 | 
249
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
643
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
117
 | 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
234
 | 
             my $pos = $self->pos;  | 
| 
118
 | 
129
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
318
 | 
             my $array = $record->array or last TRY;  | 
| 
119
 | 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
294
 | 
             $result = "@$array[@$pos]";  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } elsif (defined $self->key) {  | 
| 
121
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
             my $key = $self->key;  | 
| 
122
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
9
 | 
             my $hash = $record->hash or last TRY;  | 
| 
123
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
             $result = "@$hash{@$key}";  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } elsif ($self->type eq 'date') {  | 
| 
125
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
             $result = $record->date;  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } elsif ($self->type eq 'number') {  | 
| 
127
 | 
8
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
26
 | 
             my $array = $record->array or last TRY;  | 
| 
128
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
             $result = $array->[0];  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
130
 | 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
242
 | 
             $result = $record->text;  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           | 
| 
133
 | 
248
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
557
 | 
         last TRY unless defined $result;  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           | 
| 
135
 | 
247
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
484
 | 
         if ($self->type eq 'date') {  | 
| 
136
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
50
 | 
             $result = looks_like_number($result) ? $result : str2time($result);  | 
| 
137
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
33
 | 
             last TRY unless defined $result;  | 
| 
138
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
             $result = POSIX::strftime($self->strftime, localtime $result);  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
142
 | 
249
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
517
 | 
     if ($self->convert) {  | 
| 
143
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         $result = $self->convert->($result);  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
146
 | 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
760
 | 
     return $result;  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 select_nodes  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Usage:  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $raw_node_list = [values %{$parent_node->children}];  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $sorted_node_list = $field->select_nodes($raw_node_list);  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Sorts and reduces a list of nodes (Data::Freq::Node) at the corresponding depth  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 in the L,  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 depending on the parameters passed to the L method.  | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is intended to be an internal method for L.  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub select_nodes {  | 
| 
165
 | 
48
 | 
 
 | 
 
 | 
  
48
  
 | 
  
1
  
 | 
259
 | 
     my ($self, $nodes, $subfield) = @_;  | 
| 
166
 | 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
115
 | 
     my $type  = $self->type;  | 
| 
167
 | 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
99
 | 
     my $sort  = $self->sort;  | 
| 
168
 | 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
     my $order = $self->order;  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
170
 | 
48
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
119
 | 
     if ($sort eq 'score') {  | 
| 
171
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
31
 | 
         if ($subfield) {  | 
| 
172
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
             $sort = $subfield->aggregate;  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
174
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
             $sort = 'count';  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
178
 | 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
98
 | 
     my @tuples = map {[$_, $_->$sort, $_->first]} @$nodes;  | 
| 
 
 | 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
467
 | 
    | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
180
 | 
48
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
222
 | 
     if ($type ne 'number' && $sort eq 'value') {  | 
| 
181
 | 
28
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
54
 | 
         if ($order eq 'asc') {  | 
| 
182
 | 
26
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
94
 | 
             @tuples = CORE::sort {$a->[1] cmp $b->[1] || $a->[2] <=> $b->[2]} @tuples;  | 
| 
 
 | 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
296
 | 
    | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
184
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
             @tuples = CORE::sort {$b->[1] cmp $a->[1] || $a->[2] <=> $b->[2]} @tuples;  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
187
 | 
20
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
50
 | 
         if ($order eq 'asc') {  | 
| 
188
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
36
 | 
             @tuples = CORE::sort {$a->[1] <=> $b->[1] || $a->[2] <=> $b->[2]} @tuples;  | 
| 
 
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
86
 | 
    | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
190
 | 
11
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
33
 | 
             @tuples = CORE::sort {$b->[1] <=> $a->[1] || $a->[2] <=> $b->[2]} @tuples;  | 
| 
 
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
101
 | 
    | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
194
 | 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
78
 | 
     my @result = map {$_->[0]} @tuples;  | 
| 
 
 | 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
292
 | 
    | 
| 
195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
196
 | 
48
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
110
 | 
     if (defined $self->offset || defined $self->limit) {  | 
| 
197
 | 
22
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
40
 | 
         my $offset = defined $self->offset ? $self->offset : 0;  | 
| 
198
 | 
22
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
45
 | 
         my $length = defined $self->limit ? $self->limit : scalar(@result);  | 
| 
199
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
         @result = splice(@result, $offset, $length);  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
202
 | 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
285
 | 
     return \@result;  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 type  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Retrieves the C parameter.  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 aggregate  | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Retrieves the C parameter.  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 sort  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Retrieves the C parameter.  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 order  | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Retrieves the C parameter.  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 pos  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Retrieves the C parameter as an array ref.  | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 key  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Retrieves the C parameter as an array ref.  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 limit  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Retrieves the C parameter.  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 offset  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Retrieves the C parameter.  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 strftime  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Retrieves the C parameter (L).  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 convert  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Retrieves the C parameter.  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
247
 | 
1150
 | 
 
 | 
 
 | 
  
1150
  
 | 
  
1
  
 | 
3515
 | 
 sub type      {$_[0]{type    }}  | 
| 
248
 | 
26
 | 
 
 | 
 
 | 
  
26
  
 | 
  
1
  
 | 
115
 | 
 sub aggregate {$_[0]{aggregate}}  | 
| 
249
 | 
94
 | 
 
 | 
 
 | 
  
94
  
 | 
  
1
  
 | 
319
 | 
 sub sort      {$_[0]{sort    }}  | 
| 
250
 | 
84
 | 
 
 | 
 
 | 
  
84
  
 | 
  
1
  
 | 
385
 | 
 sub order     {$_[0]{order   }}  | 
| 
251
 | 
394
 | 
 
 | 
 
 | 
  
394
  
 | 
  
1
  
 | 
1020
 | 
 sub pos       {$_[0]{pos     }}  | 
| 
252
 | 
126
 | 
 
 | 
 
 | 
  
126
  
 | 
  
1
  
 | 
410
 | 
 sub key       {$_[0]{key     }}  | 
| 
253
 | 
76
 | 
 
 | 
 
 | 
  
76
  
 | 
  
1
  
 | 
253
 | 
 sub limit     {$_[0]{limit   }}  | 
| 
254
 | 
89
 | 
 
 | 
 
 | 
  
89
  
 | 
  
1
  
 | 
300
 | 
 sub offset    {$_[0]{offset  }}  | 
| 
255
 | 
33
 | 
 
 | 
 
 | 
  
33
  
 | 
  
1
  
 | 
884
 | 
 sub strftime  {$_[0]{strftime}}  | 
| 
256
 | 
250
 | 
 
 | 
 
 | 
  
250
  
 | 
  
1
  
 | 
746
 | 
 sub convert   {$_[0]{convert }}  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _extract_any {  | 
| 
259
 | 
275
 | 
 
 | 
 
 | 
  
275
  
 | 
 
 | 
381
 | 
     my ($self, $input) = @_;  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
261
 | 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
484
 | 
     for my $target (qw(pos type aggregate sort order)) {  | 
| 
262
 | 
754
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1414
 | 
         my $method = "_extract_$target";  | 
| 
263
 | 
754
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1795
 | 
         return $self if $self->$method($input);  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
266
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return undef;  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _extract_type {  | 
| 
270
 | 
308
 | 
 
 | 
 
 | 
  
308
  
 | 
 
 | 
551
 | 
     my ($self, $input) = @_;  | 
| 
271
 | 
308
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
767
 | 
     return undef if ref($input);  | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
273
 | 
308
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
3749
 | 
     if (!defined $input || $input eq '' || $input =~ /^texts?$/i) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
274
 | 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
225
 | 
         $self->{type} = 'text';  | 
| 
275
 | 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
456
 | 
         return $self;  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^num(ber)?s?$/i) {  | 
| 
277
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
110
 | 
         $self->{type} = 'number';  | 
| 
278
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
201
 | 
         return $self;  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /\%/) {  | 
| 
280
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
         $self->{type} = 'date';  | 
| 
281
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         $self->{strftime} = $input;  | 
| 
282
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
         return $self;  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^years?$/i) {  | 
| 
284
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
         $self->{type} = 'date';  | 
| 
285
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
         $self->{strftime} = '%Y';  | 
| 
286
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
         return $self;  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^month?s?$/i) {  | 
| 
288
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
         $self->{type} = 'date';  | 
| 
289
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
         $self->{strftime} = '%Y-%m';  | 
| 
290
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
         return $self;  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^(date|day)s?$/i) {  | 
| 
292
 | 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
105
 | 
         $self->{type} = 'date';  | 
| 
293
 | 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
73
 | 
         $self->{strftime} = '%Y-%m-%d';  | 
| 
294
 | 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
371
 | 
         return $self;  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^hours?$/i) {  | 
| 
296
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
         $self->{type} = 'date';  | 
| 
297
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         $self->{strftime} = '%Y-%m-%d %H';  | 
| 
298
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
         return $self;  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^minutes?$/i) {  | 
| 
300
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
         $self->{type} = 'date';  | 
| 
301
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         $self->{strftime} = '%Y-%m-%d %H:%M';  | 
| 
302
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
         return $self;  | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^(seconds?|time)?$/i) {  | 
| 
304
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
89
 | 
         $self->{type} = 'date';  | 
| 
305
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         $self->{strftime} = '%Y-%m-%d %H:%M:%S';  | 
| 
306
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
         return $self;  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
309
 | 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
365
 | 
     return undef;  | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _extract_aggregate {  | 
| 
313
 | 
113
 | 
 
 | 
 
 | 
  
113
  
 | 
 
 | 
156
 | 
     my ($self, $input) = @_;  | 
| 
314
 | 
113
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
698
 | 
     return undef if !defined $input || ref($input) || $input eq '';  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
316
 | 
113
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
561
 | 
     if ($input =~ /^uniq(ue)?$/) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
317
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
         $self->{aggregate} = 'unique';  | 
| 
318
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
         return $self;  | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^max(imum)?$/) {  | 
| 
320
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
         $self->{aggregate} = 'max';  | 
| 
321
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
         return $self;  | 
| 
322
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^min(imum)?$/) {  | 
| 
323
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
         $self->{aggregate} = 'min';  | 
| 
324
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
         return $self;  | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^av(g|e(rage)?)?$/) {  | 
| 
326
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
         $self->{aggregate} = 'average';  | 
| 
327
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
         return $self;  | 
| 
328
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
330
 | 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
305
 | 
     return undef;  | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _extract_sort {  | 
| 
334
 | 
160
 | 
 
 | 
 
 | 
  
160
  
 | 
 
 | 
218
 | 
     my ($self, $input) = @_;  | 
| 
335
 | 
160
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
1049
 | 
     return undef if !defined $input || ref($input) || $input eq '';  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
337
 | 
160
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
835
 | 
     if ($input =~ /^values?$/i) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
338
 | 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
103
 | 
         $self->{sort} = 'value';  | 
| 
339
 | 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
224
 | 
         return $self;  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^counts?$/i) {  | 
| 
341
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
         $self->{sort} = 'count';  | 
| 
342
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
130
 | 
         return $self;  | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^scores?$/i) {  | 
| 
344
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
         $self->{sort} = 'score';  | 
| 
345
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
99
 | 
         return $self;  | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^(first|occur(rence)?s?)$/i) {  | 
| 
347
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
         $self->{sort} = 'first';  | 
| 
348
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
112
 | 
         return $self;  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^last$/i) {  | 
| 
350
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
         $self->{sort} = 'last';  | 
| 
351
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
89
 | 
         return $self;  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
354
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
106
 | 
     return undef;  | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _extract_order {  | 
| 
358
 | 
83
 | 
 
 | 
 
 | 
  
83
  
 | 
 
 | 
114
 | 
     my ($self, $input) = @_;  | 
| 
359
 | 
83
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
535
 | 
     return undef if !defined $input || ref($input) || $input eq '';  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
361
 | 
83
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
350
 | 
     if ($input =~ /^asc(end(ing)?)?$/i) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
362
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
126
 | 
         $self->{order} = 'asc';  | 
| 
363
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
259
 | 
         return $self;  | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^desc(end(ing)?)?$/i) {  | 
| 
365
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
         $self->{order} = 'desc';  | 
| 
366
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
154
 | 
         return $self;  | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
369
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return undef;  | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
372
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _extract_pos {  | 
| 
373
 | 
287
 | 
 
 | 
 
 | 
  
287
  
 | 
 
 | 
365
 | 
     my ($self, $input) = @_;  | 
| 
374
 | 
287
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
622
 | 
     return undef if !defined $input;  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
376
 | 
281
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1337
 | 
     if (ref $input eq 'ARRAY') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
377
 | 
11
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
45
 | 
         $self->{pos} ||= [];  | 
| 
378
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
         push @{$self->{pos}}, @$input;  | 
| 
 
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
    | 
| 
379
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
58
 | 
         return $self;  | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($input =~ /^-?\d+$/) {  | 
| 
381
 | 
30
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
153
 | 
         $self->{pos} ||= [];  | 
| 
382
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
         push @{$self->{pos}}, $input;  | 
| 
 
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
72
 | 
    | 
| 
383
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
157
 | 
         return $self;  | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
385
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
386
 | 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
845
 | 
     return undef;  | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _extract_key {  | 
| 
390
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
 
 | 
14
 | 
     my ($self, $input) = @_;  | 
| 
391
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
23
 | 
     return undef if !defined $input;  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
393
 | 
9
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
71
 | 
     $self->{key} ||= [];  | 
| 
394
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     push @{$self->{key}}, (ref($input) eq 'ARRAY' ? @$input : ($input));  | 
| 
 
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
    | 
| 
395
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
82
 | 
     return $self;  | 
| 
396
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
398
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHOR  | 
| 
399
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Mahiro Ando, C<<  >>  | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
402
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 LICENSE AND COPYRIGHT  | 
| 
403
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
404
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Copyright 2012 Mahiro Ando.  | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This program is free software; you can redistribute it and/or modify it  | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 under the terms of either: the GNU General Public License as published  | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 by the Free Software Foundation; or the Artistic License.  | 
| 
409
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See http://dev.perl.org/licenses/ for more information.  | 
| 
411
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
413
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  |