line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Data::Petitcom::BMP; |
2
|
|
|
|
|
|
|
|
3
|
6
|
|
|
6
|
|
33
|
use strict; |
|
6
|
|
|
|
|
9
|
|
|
6
|
|
|
|
|
206
|
|
4
|
6
|
|
|
6
|
|
31
|
use warnings; |
|
6
|
|
|
|
|
10
|
|
|
6
|
|
|
|
|
178
|
|
5
|
|
|
|
|
|
|
|
6
|
6
|
|
|
6
|
|
911
|
use parent qw{Exporter}; |
|
6
|
|
|
|
|
346
|
|
|
6
|
|
|
|
|
35
|
|
7
|
|
|
|
|
|
|
our @EXPORT_OK = qw{ DATA2BMP BMP2DATA Load Dump RGB555toRGB888 RGB888toRGB555 }; |
8
|
|
|
|
|
|
|
|
9
|
6
|
|
|
6
|
|
1568
|
use bytes (); |
|
6
|
|
|
|
|
18
|
|
|
6
|
|
|
|
|
89
|
|
10
|
6
|
|
|
6
|
|
30
|
use Carp (); |
|
6
|
|
|
|
|
28
|
|
|
6
|
|
|
|
|
150
|
|
11
|
|
|
|
|
|
|
|
12
|
6
|
|
|
6
|
|
28
|
use constant CHR_WIDTH => 8; |
|
6
|
|
|
|
|
15
|
|
|
6
|
|
|
|
|
601
|
|
13
|
6
|
|
|
6
|
|
34
|
use constant CHR_SIZE => CHR_WIDTH * CHR_WIDTH; |
|
6
|
|
|
|
|
9
|
|
|
6
|
|
|
|
|
1242
|
|
14
|
|
|
|
|
|
|
|
15
|
6
|
|
|
|
|
610
|
use constant DEFAULT_COLORMAP => [ |
16
|
|
|
|
|
|
|
0x000000,0x383838,0xf81800,0xf858c0,0x0038f0,0x7838f8,0x00b8f8,0x905828,0xf8a000,0xf8c8a0,0x007800,0x00f018,0xf8e000,0xb8b8b8,0x000000,0xf8f8f8, |
17
|
|
|
|
|
|
|
0x000000,0x282828,0x883028,0x985880,0x203880,0x604890,0x287088,0x584030,0x886028,0xa09080,0x104010,0x208030,0x887828,0x808080,0xf8f8f8,0x000000, |
18
|
|
|
|
|
|
|
0xf8f8f8,0xf8f8c8,0xf8f898,0xf8f860,0xf8f830,0xf8f800,0xf8c8f8,0xf8c8c8,0xf8c898,0xf8c860,0xf8c830,0xf8c800,0xf898f8,0xf898c8,0xf89898,0xf89860, |
19
|
|
|
|
|
|
|
0xf89830,0xf89800,0xf860f8,0xf860c8,0xf86098,0xf86060,0xf86030,0xf86000,0xf830f8,0xf830c8,0xf83098,0xf83060,0xf83030,0xf83000,0xf800f8,0xf800c8, |
20
|
|
|
|
|
|
|
0xf80098,0xf80060,0xf80030,0xf80000,0xc8f8f8,0xc8f8c8,0xc8f898,0xc8f860,0xc8f830,0xc8f800,0xc8c8f8,0xc8c8c8,0xc8c898,0xc8c860,0xc8c830,0xc8c800, |
21
|
|
|
|
|
|
|
0xc898f8,0xc898c8,0xc89898,0xc89860,0xc89830,0xc89800,0xc860f8,0xc860c8,0xc86098,0xc86060,0xc86030,0xc86000,0xc830f8,0xc830c8,0xc83098,0xc83060, |
22
|
|
|
|
|
|
|
0xc83030,0xc83000,0xc800f8,0xc800c8,0xc80098,0xc80060,0xc80030,0xc80000,0x98f8f8,0x98f8c8,0x98f898,0x98f860,0x98f830,0x98f800,0x98c8f8,0x98c8c8, |
23
|
|
|
|
|
|
|
0x98c898,0x98c860,0x98c830,0x98c800,0x9898f8,0x9898c8,0x989898,0x989860,0x989830,0x989800,0x9860f8,0x9860c8,0x986098,0x986060,0x986030,0x986000, |
24
|
|
|
|
|
|
|
0x9830f8,0x9830c8,0x983098,0x983060,0x983030,0x983000,0x9800f8,0x9800c8,0x980098,0x980060,0x980030,0x980000,0x60f8f8,0x60f8c8,0x60f898,0x60f860, |
25
|
|
|
|
|
|
|
0x60f830,0x60f800,0x60c8f8,0x60c8c8,0x60c898,0x60c860,0x60c830,0x60c800,0x6098f8,0x6098c8,0x609898,0x609860,0x609830,0x609800,0x6060f8,0x6060c8, |
26
|
|
|
|
|
|
|
0x606098,0x606060,0x606030,0x606000,0x6030f8,0x6030c8,0x603098,0x603060,0x603030,0x603000,0x6000f8,0x6000c8,0x600098,0x600060,0x600030,0x600000, |
27
|
|
|
|
|
|
|
0x30f8f8,0x30f8c8,0x30f898,0x30f860,0x30f830,0x30f800,0x30c8f8,0x30c8c8,0x30c898,0x30c860,0x30c830,0x30c800,0x3098f8,0x3098c8,0x309898,0x309860, |
28
|
|
|
|
|
|
|
0x309830,0x309800,0x3060f8,0x3060c8,0x306098,0x306060,0x306030,0x306000,0x3030f8,0x3030c8,0x303098,0x303060,0x303030,0x303000,0x3000f8,0x3000c8, |
29
|
|
|
|
|
|
|
0x300098,0x300060,0x300030,0x300000,0x00f8f8,0x00f8c8,0x00f898,0x00f860,0x00f830,0x00f800,0x00c8f8,0x00c8c8,0x00c898,0x00c860,0x00c830,0x00c800, |
30
|
|
|
|
|
|
|
0x0098f8,0x0098c8,0x009898,0x009860,0x009830,0x009800,0x0060f8,0x0060c8,0x006098,0x006060,0x006030,0x006000,0x0030f8,0x0030c8,0x003098,0x003060, |
31
|
|
|
|
|
|
|
0x003030,0x003000,0x0000f8,0x0000c8,0x000098,0x000060,0x000030,0xe8e8e8,0xd8d8d8,0xb8b8b8,0xa8a8a8,0x888888,0x707070,0x505050,0x404040,0x202020, |
32
|
6
|
|
|
6
|
|
36
|
]; |
|
6
|
|
|
|
|
16
|
|
33
|
6
|
|
|
|
|
12401
|
use constant SPRITE_SIZE => { |
34
|
|
|
|
|
|
|
8 => [ 8, 16, 32 ], |
35
|
|
|
|
|
|
|
16 => [ 8, 16, 32 ], |
36
|
|
|
|
|
|
|
32 => [ 8, 16, 32, 64 ], |
37
|
|
|
|
|
|
|
64 => [ 32, 64 ], |
38
|
6
|
|
|
6
|
|
43
|
}; |
|
6
|
|
|
|
|
13
|
|
39
|
|
|
|
|
|
|
|
40
|
27
|
50
|
33
|
27
|
0
|
359
|
sub is_valid_width { $_[0] && $_[0] <= 256 && $_[0] % CHR_WIDTH == 0 } |
41
|
27
|
50
|
33
|
27
|
0
|
253
|
sub is_valid_height { $_[0] && $_[0] <= 192 && $_[0] % CHR_WIDTH == 0 } |
42
|
|
|
|
|
|
|
sub is_valid_spsize { |
43
|
14
|
|
|
14
|
0
|
1084
|
my ($width, $height) = @_; |
44
|
14
|
100
|
66
|
|
|
98
|
return unless ($width && $height); |
45
|
13
|
100
|
|
|
|
23
|
for ( @{ SPRITE_SIZE->{$width} } ) { return 1 if ( $height == $_ ) } |
|
13
|
|
|
|
|
63
|
|
|
23
|
|
|
|
|
93
|
|
46
|
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
sub _xy(&;%) { |
49
|
10
|
|
|
10
|
|
918
|
my $code = shift; |
50
|
|
|
|
|
|
|
|
51
|
10
|
|
|
|
|
66
|
my %opts = @_; |
52
|
10
|
|
50
|
|
|
255
|
my $width = delete $opts{width} || 256; |
53
|
10
|
|
50
|
|
|
39
|
my $height = delete $opts{height} || 64; |
54
|
10
|
|
50
|
|
|
207
|
my $sp_width = delete $opts{sp_width} || 16; |
55
|
10
|
|
50
|
|
|
243
|
my $sp_height = delete $opts{sp_height} || 16; |
56
|
10
|
|
|
|
|
24
|
my $vflip = delete $opts{vflip}; |
57
|
10
|
|
|
|
|
23
|
my $debug = delete $opts{debug}; |
58
|
10
|
50
|
33
|
|
|
92
|
Carp::croak "invalid sp_width: $sp_width" |
59
|
|
|
|
|
|
|
if ( $sp_width > $width || $width % $sp_width ); |
60
|
10
|
50
|
33
|
|
|
70
|
Carp::croak "invalid sp_height: $sp_height" |
61
|
|
|
|
|
|
|
if ( $sp_height > $height || $height % $sp_height ); |
62
|
|
|
|
|
|
|
|
63
|
10
|
|
|
|
|
31
|
my $sp_cols = $width / $sp_width; |
64
|
10
|
|
|
|
|
21
|
my $sp_rows = $height / $sp_height; |
65
|
10
|
|
|
|
|
26
|
my $sp_nums = $sp_cols * $sp_rows; |
66
|
10
|
|
|
|
|
19
|
my $sp_size = $sp_width * $sp_height; |
67
|
|
|
|
|
|
|
|
68
|
10
|
|
|
|
|
20
|
my $chr_cols = $sp_width / CHR_WIDTH; |
69
|
10
|
|
|
|
|
21
|
my $chr_rows = $sp_height / CHR_WIDTH; |
70
|
10
|
|
|
|
|
17
|
my $chr_nums = $chr_cols * $chr_rows; |
71
|
|
|
|
|
|
|
|
72
|
10
|
100
|
|
|
|
40
|
my $flip_y = ($vflip) ? ($height - 1) : 0; |
73
|
10
|
|
|
|
|
32
|
for my $i ( 0 .. ( $sp_nums - 1 ) ) { |
74
|
100
|
|
|
|
|
497
|
my $sp_x = $i % $sp_cols * $sp_width; |
75
|
100
|
|
|
|
|
191
|
my $sp_y = int( $i / $sp_cols ) * $sp_height; |
76
|
|
|
|
|
|
|
|
77
|
100
|
|
|
|
|
220
|
for my $j ( 0 .. ( $chr_nums - 1 ) ) { |
78
|
3088
|
|
|
|
|
13346
|
my $chr_x = $sp_x + ( $j % $chr_cols * CHR_WIDTH ); |
79
|
3088
|
|
|
|
|
4600
|
my $chr_y = $sp_y + ( int( $j / $chr_cols ) * CHR_WIDTH ); |
80
|
|
|
|
|
|
|
|
81
|
3088
|
|
|
|
|
5907
|
for my $k ( 0 .. ( CHR_SIZE - 1 ) ) { |
82
|
197632
|
|
|
|
|
700780
|
my $x = $chr_x + ( $k % CHR_WIDTH ); |
83
|
197632
|
|
|
|
|
319659
|
my $y = abs( $flip_y - ( $chr_y + ( int( $k / CHR_WIDTH ) ) ) ); |
84
|
|
|
|
|
|
|
|
85
|
197632
|
50
|
|
|
|
374191
|
print STDERR sprintf("(% 3d, % 3d)\n", $x, $y) if ($debug); |
86
|
|
|
|
|
|
|
|
87
|
197632
|
|
|
|
|
904125
|
my $pixel = $code->( $x, $y, { |
88
|
|
|
|
|
|
|
width => $width, |
89
|
|
|
|
|
|
|
height => $height, |
90
|
|
|
|
|
|
|
sp_width => $sp_width, |
91
|
|
|
|
|
|
|
sp_height => $sp_height, |
92
|
|
|
|
|
|
|
count => ( $sp_size * $i ) + ( CHR_SIZE * $j ) + $k, |
93
|
|
|
|
|
|
|
} ); |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
sub DATA2BMP { |
102
|
3
|
|
|
3
|
0
|
657
|
my ($data, %opts) = @_; |
103
|
3
|
|
50
|
|
|
14
|
my $width = delete $opts{width} || 256; |
104
|
3
|
50
|
|
|
|
12
|
Carp::croak "invalid width: $width" |
105
|
|
|
|
|
|
|
unless ( is_valid_width($width) ); |
106
|
3
|
|
50
|
|
|
15
|
my $height = delete $opts{height} || 64; |
107
|
3
|
50
|
|
|
|
10
|
Carp::croak "invalid height: $height" |
108
|
|
|
|
|
|
|
unless ( is_valid_height($height) ); |
109
|
3
|
|
50
|
|
|
16
|
my $sp_width = delete $opts{sp_width} || 16; |
110
|
3
|
|
50
|
|
|
14
|
my $sp_height = delete $opts{sp_height} || 16; |
111
|
3
|
50
|
|
|
|
13
|
Carp::croak "invalid sprite size: $sp_width x $sp_height " |
112
|
|
|
|
|
|
|
unless( is_valid_spsize($sp_width, $sp_height ) ); |
113
|
|
|
|
|
|
|
|
114
|
3
|
|
|
|
|
5
|
my @pixels; |
115
|
|
|
|
|
|
|
_xy { |
116
|
65792
|
|
|
65792
|
|
92236
|
my ( $x, $y, $info ) = @_; |
117
|
65792
|
|
|
|
|
82836
|
my $index = $width * $y + $x; |
118
|
65792
|
|
|
|
|
210774
|
$pixels[$index] = bytes::substr $data, $info->{count}, 1; |
119
|
|
|
|
|
|
|
} |
120
|
3
|
|
|
|
|
33
|
width => $width, |
121
|
|
|
|
|
|
|
height => $height, |
122
|
|
|
|
|
|
|
sp_width => $sp_width, |
123
|
|
|
|
|
|
|
sp_height => $sp_height, |
124
|
|
|
|
|
|
|
vflip => 1, |
125
|
|
|
|
|
|
|
debug => 0; |
126
|
|
|
|
|
|
|
|
127
|
65792
|
|
|
|
|
103807
|
return Dump( |
128
|
|
|
|
|
|
|
width => $width, |
129
|
|
|
|
|
|
|
height => $height, |
130
|
3
|
|
|
|
|
343
|
pixels => [ map { unpack 'C', $_ } @pixels ], |
131
|
|
|
|
|
|
|
); |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
sub BMP2DATA { |
135
|
5
|
|
|
5
|
0
|
677
|
my ($raw_bmp, %opts) = @_; |
136
|
5
|
|
50
|
|
|
31
|
my $sp_width = delete $opts{sp_width} || 16; |
137
|
5
|
|
50
|
|
|
23
|
my $sp_height = delete $opts{sp_height} || 16; |
138
|
5
|
50
|
|
|
|
28
|
Carp::croak "invalid sprite size: $sp_width x $sp_height " |
139
|
|
|
|
|
|
|
unless( is_valid_spsize($sp_width, $sp_height ) ); |
140
|
|
|
|
|
|
|
|
141
|
5
|
|
|
|
|
21
|
my $bmp = Load($raw_bmp); |
142
|
5
|
|
|
|
|
15
|
my $data; |
143
|
|
|
|
|
|
|
_xy { |
144
|
131328
|
|
|
131328
|
|
165883
|
my ( $x, $y ) = @_; |
145
|
131328
|
|
|
|
|
235318
|
my $offset = $bmp->{width} * ( ( $bmp->{height} - 1 ) - $y ) + $x; |
146
|
131328
|
|
|
|
|
1004343
|
$data .= pack( 'C', $bmp->{pixels}->[$offset] ); |
147
|
|
|
|
|
|
|
} |
148
|
5
|
|
|
|
|
404
|
width => $bmp->{width}, |
149
|
|
|
|
|
|
|
height => $bmp->{height}, |
150
|
|
|
|
|
|
|
sp_width => $sp_width, |
151
|
|
|
|
|
|
|
sp_height => $sp_height, |
152
|
|
|
|
|
|
|
debug => 0; |
153
|
|
|
|
|
|
|
|
154
|
5
|
|
|
|
|
2537
|
return $data; |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
sub Load { |
158
|
19
|
|
|
19
|
0
|
568
|
my $raw_bmp = shift; |
159
|
|
|
|
|
|
|
|
160
|
19
|
|
|
|
|
118
|
my @file_header = unpack 'a2VvvV', bytes::substr( $raw_bmp, 0, 14 ); |
161
|
19
|
|
|
|
|
3483
|
my $type = $file_header[0]; |
162
|
19
|
50
|
|
|
|
78
|
Carp::croak "invalid type: $type" |
163
|
|
|
|
|
|
|
if ( $type ne 'BM' ); |
164
|
|
|
|
|
|
|
|
165
|
19
|
|
|
|
|
63
|
my @info_header = unpack 'VVVvvVVVVVV', bytes::substr( $raw_bmp, 0x0E, 40 ); |
166
|
19
|
|
|
|
|
242
|
my $width = $info_header[1]; |
167
|
19
|
50
|
|
|
|
62
|
Carp::croak "invalid width: $width" |
168
|
|
|
|
|
|
|
unless ( is_valid_width($width) ); |
169
|
19
|
|
|
|
|
40
|
my $height = $info_header[2]; |
170
|
19
|
50
|
|
|
|
67
|
Carp::croak "invalid height: $height" |
171
|
|
|
|
|
|
|
unless ( is_valid_height($height) ); |
172
|
19
|
|
|
|
|
40
|
my $bit = $info_header[4]; |
173
|
19
|
50
|
|
|
|
61
|
Carp::croak "invalid bit: $bit" |
174
|
|
|
|
|
|
|
if ( $bit != 8 ); |
175
|
|
|
|
|
|
|
|
176
|
19
|
|
|
|
|
68
|
my @colormap = unpack 'V*', bytes::substr( $raw_bmp, 0x36, 256 * 4 ); |
177
|
19
|
|
|
|
|
847
|
my @pixels = unpack 'C*', bytes::substr( $raw_bmp, 0x0436, $width * $height ); |
178
|
19
|
100
|
|
|
|
71363
|
if ( my $lack = ( $width * $height ) - @pixels ) { |
179
|
6
|
|
|
|
|
707
|
push @pixels, 0x00 for ( 1 .. $lack ); |
180
|
|
|
|
|
|
|
} |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
return +{ |
183
|
19
|
|
|
|
|
991
|
width => $width, |
184
|
|
|
|
|
|
|
height => $height, |
185
|
|
|
|
|
|
|
colormap => \@colormap, |
186
|
|
|
|
|
|
|
pixels => \@pixels, |
187
|
|
|
|
|
|
|
}; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
sub Dump { |
191
|
5
|
50
|
|
5
|
0
|
687
|
my $bmp = ( ref $_[0] eq 'HASH' ) ? shift : {@_}; |
192
|
|
|
|
|
|
|
|
193
|
5
|
|
|
|
|
24
|
my $width = delete $bmp->{width}; |
194
|
5
|
50
|
|
|
|
25
|
Carp::croak "invalid width: $width" |
195
|
|
|
|
|
|
|
unless ( is_valid_width($width) ); |
196
|
5
|
|
|
|
|
18
|
my $height = delete $bmp->{height}; |
197
|
5
|
50
|
|
|
|
21
|
Carp::croak "invalid height: $height" |
198
|
|
|
|
|
|
|
unless ( is_valid_height($height) ); |
199
|
5
|
|
100
|
|
|
38
|
my $colormap = delete $bmp->{colormap} || DEFAULT_COLORMAP; |
200
|
5
|
50
|
|
|
|
19
|
Carp::croak "invalid colormap: " . scalar @$colormap |
201
|
|
|
|
|
|
|
if ( scalar @$colormap != 256 ); |
202
|
5
|
|
|
|
|
15
|
my $pixels = delete $bmp->{pixels}; |
203
|
5
|
50
|
|
|
|
24
|
Carp::croak "pixels mismatch: " . scalar @$pixels |
204
|
|
|
|
|
|
|
if ( scalar @$pixels != $width * $height ); |
205
|
|
|
|
|
|
|
|
206
|
5
|
|
|
|
|
12
|
my $size = 14 + 40 + 256 * 4 + $width * $height; |
207
|
5
|
|
|
|
|
48
|
my $raw_bmp = pack 'a2VvvV', "BM", $size, 0, 0, 14 + 40; |
208
|
5
|
|
|
|
|
34
|
$raw_bmp .= pack "VVVvvVVVVVV", 40, $width, $height, 1, 8, 0, 0, 0, 0, 0, 0; |
209
|
5
|
|
|
|
|
57
|
$raw_bmp .= pack 'V*', @$colormap; |
210
|
5
|
|
|
|
|
999
|
$raw_bmp .= pack 'C*', @$pixels; |
211
|
|
|
|
|
|
|
|
212
|
5
|
|
|
|
|
7713
|
return $raw_bmp; |
213
|
|
|
|
|
|
|
} |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
sub RGB888toRGB555 { |
216
|
6
|
100
|
|
6
|
0
|
2609
|
my $rgb888 = (ref $_[0] eq 'ARRAY') ? shift : [ @_ ]; |
217
|
261
|
|
|
|
|
270
|
my @rgb555 = map { |
218
|
6
|
|
|
|
|
14
|
my $rgb = $_; |
219
|
261
|
|
|
|
|
456
|
my ( $r, $g, $b ) = map { $_ >> 3 } ( |
|
783
|
|
|
|
|
1260
|
|
220
|
|
|
|
|
|
|
($rgb >> 16 ) & 0xFF, |
221
|
|
|
|
|
|
|
($rgb >> 8 ) & 0xFF, |
222
|
|
|
|
|
|
|
$rgb & 0xFF, |
223
|
|
|
|
|
|
|
); |
224
|
|
|
|
|
|
|
# Unused(1), Blue(5), Green(5), Red(5) |
225
|
261
|
|
|
|
|
525
|
( $b << 10 ) | ( $g << 5 ) | $r; |
226
|
|
|
|
|
|
|
} @$rgb888; |
227
|
6
|
|
|
|
|
47
|
return \@rgb555; |
228
|
|
|
|
|
|
|
} |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
sub RGB555toRGB888 { |
231
|
6
|
50
|
|
6
|
0
|
2408
|
my $rgb555 = (ref $_[0] eq 'ARRAY') ? shift : [ @_ ]; |
232
|
261
|
|
|
|
|
248
|
my @rgb888 = map { |
233
|
6
|
|
|
|
|
15
|
my $rgb = $_; |
234
|
261
|
|
|
|
|
368
|
my ($r, $g, $b) = map { $_ << 3 | $_ >> 2 } ( |
|
783
|
|
|
|
|
1291
|
|
235
|
|
|
|
|
|
|
$rgb & 0x1F, |
236
|
|
|
|
|
|
|
($rgb >> 5) & 0x1F, |
237
|
|
|
|
|
|
|
($rgb >> 10) & 0x1F, |
238
|
|
|
|
|
|
|
); |
239
|
|
|
|
|
|
|
# Reserved(8), Red(8), Green(8), Blue(8) |
240
|
261
|
|
|
|
|
458
|
($r << 16) | ($g << 8) | $b; |
241
|
|
|
|
|
|
|
} @$rgb555; |
242
|
6
|
|
|
|
|
44
|
return \@rgb888; |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
1; |