|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
8
 | 
 use strict;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
    | 
| 
2
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
6
 | 
 use warnings;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
    | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Locale::Simple::Scraper::Parser;  | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 BEGIN {  | 
| 
6
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
45
 | 
   $Locale::Simple::Scraper::Parser::AUTHORITY = 'cpan:GETTY';  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $Locale::Simple::Scraper::Parser::VERSION = '0.019';  | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ABSTRACT: parser to finds translation tokens in a code file  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
11
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
7
 | 
 use base qw( Parser::MGC );  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1255
 | 
    | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
13
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
14627
 | 
 use Moo;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18116
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
    | 
| 
14
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
1119
 | 
 use Try::Tiny;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1635
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
    | 
| 
15
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
850
 | 
 use curry;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
206
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1690
 | 
    | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has func_qr => ( is => 'ro', default => sub { qr/\bl(|n|p|np|d|dn|dnp)\b/ } );  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has found   => ( is => 'ro', default => sub { [] } );  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has type => ( is => 'ro', required => 1 );  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 with "Locale::Simple::Scraper::ParserShortcuts";  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub parse {  | 
| 
24
 | 
21
 | 
 
 | 
 
 | 
  
21
  
 | 
  
0
  
 | 
4046
 | 
     my ( $self ) = @_;  | 
| 
25
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
139
 | 
     $self->sequence_of( $self->c_any_of( $self->curry::noise, $self->curry::call ) );  | 
| 
26
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
898
 | 
     return $self->found;  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub noise {  | 
| 
30
 | 
317
 | 
 
 | 
 
 | 
  
317
  
 | 
  
0
  
 | 
4347
 | 
     my ( $self ) = @_;  | 
| 
31
 | 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1015
 | 
     my $noise = $self->substring_before( $self->func_qr );  | 
| 
32
 | 
317
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
12671
 | 
     $self->fail( "no noise found" ) if !length $noise;  | 
| 
33
 | 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
549
 | 
     $self->debug( "discarded %d characters of noise", length $noise );  | 
| 
34
 | 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3895
 | 
     return $noise;  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub call {  | 
| 
38
 | 
188
 | 
 
 | 
 
 | 
  
188
  
 | 
  
0
  
 | 
9149
 | 
     my ( $self ) = @_;  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
40
 | 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
593
 | 
     my $func = $self->expect( $self->func_qr );  | 
| 
41
 | 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8694
 | 
     my $line = ( $self->where )[0];  | 
| 
42
 | 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20401
 | 
     $self->debug( "found func $func at line %d", $line );  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     try {  | 
| 
45
 | 
152
 | 
 
 | 
 
 | 
  
152
  
 | 
 
 | 
4629
 | 
         my $arguments = $self->arguments( $func );  | 
| 
46
 | 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
88
 | 
         push @{ $self->found }, { func => $func, args => $arguments, line => $line };  | 
| 
 
 | 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
387
 | 
    | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     catch {  | 
| 
49
 | 
94
 | 
  
 50
  
 | 
 
 | 
  
94
  
 | 
 
 | 
4198
 | 
         die $_ if !eval { $_->isa( "Parser::MGC::Failure" ) };  | 
| 
 
 | 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
397
 | 
    | 
| 
50
 | 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
305
 | 
         $self->warn_failure( $_ );  | 
| 
51
 | 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4268
 | 
     };  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
53
 | 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1719
 | 
     return;  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub arguments {  | 
| 
57
 | 
152
 | 
 
 | 
 
 | 
  
152
  
 | 
  
0
  
 | 
369
 | 
     my ( $self, $func ) = @_;  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
59
 | 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
310
 | 
     my @arguments = ( $self->op( "(" ), $self->required_args( $func ), $self->extra_arguments, $self->op( ")" ) );  | 
| 
60
 | 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3481
 | 
     $self->debug( "found %d arguments", scalar @arguments );  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
62
 | 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1490
 | 
     return \@arguments;  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub op {  | 
| 
66
 | 
255
 | 
 
 | 
 
 | 
  
255
  
 | 
  
0
  
 | 
1484
 | 
     my ( $self, $op ) = @_;  | 
| 
67
 | 
255
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
3352
 | 
     return if $self->with_ws( maybe_expect => qr/\s*\Q$op\E/ );  | 
| 
68
 | 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3049
 | 
     $self->fail( "Expected \"$op\"" );  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub extra_arguments {  | 
| 
72
 | 
58
 | 
 
 | 
 
 | 
  
58
  
 | 
  
0
  
 | 
90
 | 
     my ( $self ) = @_;  | 
| 
73
 | 
58
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
284
 | 
     return if !$self->maybe_expect( "," );  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
75
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
720
 | 
     my @types = ( $self->curry::call, $self->curry::dynamic_string, $self->curry::token_int, $self->curry::variable );  | 
| 
76
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
705
 | 
     my $extra_args = $self->list_of( ",", $self->c_any_of( @types ) );  | 
| 
77
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
689
 | 
     return @{$extra_args};  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
203
 | 
    | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub required_args {  | 
| 
81
 | 
97
 | 
 
 | 
 
 | 
  
97
  
 | 
  
0
  
 | 
5739
 | 
     my ( $self, $func ) = @_;  | 
| 
82
 | 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1032
 | 
     my %arg_lists = (  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         l    => [qw( tr_token )],  | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ln   => [qw( tr_token    comma  plural_token  comma  plural_count )],  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         lp   => [qw( context_id  comma  tr_token )],  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         lnp  => [qw( context_id  comma  tr_token      comma  plural_token  comma  plural_count )],  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ld   => [qw( domain_id   comma  tr_token )],  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ldn  => [qw( domain_id   comma  tr_token      comma  plural_token  comma  plural_count )],  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ldnp => [qw( domain_id   comma  context_id    comma  tr_token      comma  plural_token  comma  plural_count )],  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
91
 | 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
397
 | 
     return $self->collect_from( $arg_lists{$func} );  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
94
 | 
68
 | 
 
 | 
 
 | 
  
68
  
 | 
  
0
  
 | 
209
 | 
 sub tr_token     { shift->named_token( "translation token" ) }  | 
| 
95
 | 
21
 | 
 
 | 
 
 | 
  
21
  
 | 
  
0
  
 | 
63
 | 
 sub plural_token { shift->named_token( "plural translation token" ) }  | 
| 
96
 | 
20
 | 
 
 | 
 
 | 
  
20
  
 | 
  
0
  
 | 
66
 | 
 sub plural_count { shift->named_token( "count of plural entity", "token_int" ) }  | 
| 
97
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
0
  
 | 
34
 | 
 sub context_id   { shift->named_token( "context id" ) }  | 
| 
98
 | 
23
 | 
 
 | 
 
 | 
  
23
  
 | 
  
0
  
 | 
68
 | 
 sub domain_id    { shift->named_token( "domain id" ) }  | 
| 
99
 | 
45
 | 
 
 | 
 
 | 
  
45
  
 | 
  
0
  
 | 
97
 | 
 sub comma        { shift->op( "," ) }  | 
| 
100
 | 
11
 | 
 
 | 
 
 | 
  
11
  
 | 
  
0
  
 | 
888
 | 
 sub variable     { shift->expect( qr/[\w\.]+/ ) }  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub constant_string {  | 
| 
103
 | 
146
 | 
 
 | 
 
 | 
  
146
  
 | 
  
0
  
 | 
647
 | 
     my ( $self, @components ) = @_;  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
105
 | 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
217
 | 
     my $p = $self->{patterns};  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
107
 | 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
414
 | 
     unshift @components,  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       $self->curry::scope_of( q["], $self->c_with_ws( "double_quote_string_contents" ), q["] ),  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       $self->curry::scope_of( q['], $self->c_with_ws( "single_quote_string_contents" ), q['] );  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
111
 | 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1957
 | 
     my $string = $self->list_of( $self->concat_op, $self->c_any_of( @components ) );  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
113
 | 
146
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
22280
 | 
     return join "", map { $_ ? $_ : "" } @{$string} if @{$string};  | 
| 
 
 | 
116
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1177
 | 
    | 
| 
 
 | 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
204
 | 
    | 
| 
 
 | 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
397
 | 
    | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
115
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
103
 | 
     $self->fail;  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub concat_op {  | 
| 
119
 | 
146
 | 
 
 | 
 
 | 
  
146
  
 | 
  
0
  
 | 
908
 | 
     my %ops = ( js => "+", pl => ".", tx => qr/(_|~)/, py => "+" );  | 
| 
120
 | 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1088
 | 
     return $ops{ shift->type };  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub dynamic_string {  | 
| 
124
 | 
25
 | 
 
 | 
 
 | 
  
25
  
 | 
  
0
  
 | 
2138
 | 
     my ( $self ) = @_;  | 
| 
125
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
114
 | 
     return $self->constant_string( $self->curry::call, $self->curry::variable );  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub double_quote_string_contents {  | 
| 
129
 | 
55
 | 
 
 | 
 
 | 
  
55
  
 | 
  
0
  
 | 
77
 | 
     my ( $self ) = @_;  | 
| 
130
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
247
 | 
     return $self->string_contents( $self->c_expect( qr/[^\\"]+/ ), $self->c_expect_escaped( q["] ) );  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub single_quote_string_contents {  | 
| 
134
 | 
56
 | 
 
 | 
 
 | 
  
56
  
 | 
  
0
  
 | 
93
 | 
     my ( $self ) = @_;  | 
| 
135
 | 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
236
 | 
     return $self->string_contents(  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->c_expect( qr/[^\\']+/ ),  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->c_expect_escaped( q['] ),  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->c_expect_escaped( q[\\] ),  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->c_expect( qr/\\/ ),  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub string_contents {  | 
| 
144
 | 
111
 | 
 
 | 
 
 | 
  
111
  
 | 
  
0
  
 | 
219
 | 
     my ( $self, @contents ) = @_;  | 
| 
145
 | 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
296
 | 
     my $elements = $self->sequence_of( $self->c_any_of( @contents ) );  | 
| 
146
 | 
111
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
9648
 | 
     return join "", @{$elements} if @{$elements};  | 
| 
 
 | 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
546
 | 
    | 
| 
 
 | 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
322
 | 
    | 
| 
147
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     $self->fail( "no string contents found" );  | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |