line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Kephra::App::StatusBar;
|
2
|
|
|
|
|
|
|
our $VERSION = '0.09';
|
3
|
1
|
|
|
1
|
|
1056
|
use strict;
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
34
|
|
4
|
1
|
|
|
1
|
|
5
|
use warnings;
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
3234
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
my (@fields, @abs_border_x, %index, %width);
|
7
|
|
|
|
|
|
|
my $bar;
|
8
|
0
|
0
|
|
0
|
|
|
sub _ref { $bar = ref $_[0] eq 'Wx::StatusBar' ? $_[0] : $bar }
|
9
|
0
|
|
|
0
|
|
|
sub _config { Kephra::API::settings()->{app}{statusbar} }
|
10
|
0
|
|
|
0
|
|
|
sub _item { $fields[$_[0]] }
|
11
|
0
|
|
|
0
|
|
|
sub _l18n { Kephra::Config::Localisation::strings()->{app}{status} }
|
12
|
|
|
|
|
|
|
sub _none_string {
|
13
|
0
|
|
|
0
|
|
|
Kephra::Config::Localisation::strings()->{dialog}{general}{none};
|
14
|
|
|
|
|
|
|
}
|
15
|
|
|
|
|
|
|
sub _set_text {
|
16
|
0
|
|
|
0
|
|
|
my ($msg, $nr) = @_;
|
17
|
0
|
|
|
|
|
|
my $win = Kephra::App::Window::_ref();
|
18
|
0
|
0
|
0
|
|
|
|
return if not defined $nr or $nr < 0 or $nr > @fields or not $win or not defined $msg;
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
19
|
0
|
|
|
|
|
|
$win->SetStatusText($msg, $nr);
|
20
|
|
|
|
|
|
|
}
|
21
|
|
|
|
|
|
|
sub _index_from_mouse_pos {
|
22
|
0
|
|
|
0
|
|
|
my $x_pos = shift;
|
23
|
0
|
|
|
|
|
|
for (0 .. $#abs_border_x) {
|
24
|
0
|
0
|
|
|
|
|
return $_ if $width{ $fields[$_] } == -1;
|
25
|
0
|
0
|
|
|
|
|
return $_ if $x_pos <= $abs_border_x[$_];
|
26
|
|
|
|
|
|
|
}
|
27
|
|
|
|
|
|
|
}
|
28
|
|
|
|
|
|
|
#
|
29
|
|
|
|
|
|
|
# external API
|
30
|
|
|
|
|
|
|
#
|
31
|
|
|
|
|
|
|
sub create {
|
32
|
0
|
|
|
0
|
0
|
|
my $win = Kephra::App::Window::_ref();
|
33
|
0
|
|
|
|
|
|
$win->CreateStatusBar(1);
|
34
|
0
|
|
|
|
|
|
my $bar = $win->GetStatusBar;
|
35
|
|
|
|
|
|
|
|
36
|
0
|
|
|
|
|
|
my $statusbar_def = Kephra::Config::File::load_from_node_data( _config() );
|
37
|
0
|
0
|
|
|
|
|
unless ($statusbar_def) {
|
38
|
0
|
|
|
|
|
|
$statusbar_def = Kephra::Config::Default::toolbars()->{statusbar};
|
39
|
|
|
|
|
|
|
}
|
40
|
|
|
|
|
|
|
|
41
|
0
|
|
|
|
|
|
for my $nr (0 .. $#$statusbar_def) {
|
42
|
0
|
|
|
|
|
|
my @item = split / /, $statusbar_def->[$nr];
|
43
|
0
|
0
|
0
|
|
|
|
if ($item[0] eq 'textpanel' and defined $item[1]) {
|
44
|
0
|
|
|
|
|
|
$index{$item[1]} = $nr;
|
45
|
0
|
0
|
|
|
|
|
$width{$item[1]} = defined $item[2] ? $item[2] : 50;
|
46
|
|
|
|
|
|
|
}
|
47
|
|
|
|
|
|
|
}
|
48
|
0
|
|
|
|
|
|
$fields[ $index{$_} ] = $_ for keys %index;
|
49
|
0
|
|
|
|
|
|
$abs_border_x[0] = $width{ $fields[0] };
|
50
|
|
|
|
|
|
|
$abs_border_x[$_] = $abs_border_x[$_-1] + $width{ $fields[$_] } + 2
|
51
|
0
|
|
|
|
|
|
for 1 .. $#fields;
|
52
|
|
|
|
|
|
|
|
53
|
0
|
|
|
|
|
|
my $length = scalar keys %index;
|
54
|
0
|
|
|
|
|
|
$bar->SetFieldsCount( $length );
|
55
|
0
|
|
|
|
|
|
my @field_width;
|
56
|
0
|
|
|
|
|
|
$field_width[$_] = $width{ $fields[$_] } for 0 .. $length - 1;
|
57
|
0
|
|
|
|
|
|
$bar->SetStatusWidths( @field_width );
|
58
|
0
|
|
|
|
|
|
$win->SetStatusBarPane( $index{message} );
|
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
Wx::Event::EVT_LEFT_DOWN ( $bar, sub {
|
61
|
0
|
0
|
|
0
|
|
|
return unless get_interactive();
|
62
|
0
|
|
|
|
|
|
my ( $bar, $event ) = @_;
|
63
|
0
|
|
|
|
|
|
my $field = _item( _index_from_mouse_pos( $event->GetX ) );
|
64
|
0
|
0
|
|
|
|
|
if ($field eq 'syntaxmode') {Kephra::Document::SyntaxMode::switch_auto()}
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
65
|
|
|
|
|
|
|
#elsif ($field eq 'codepage') {Kephra::Document::Property::switch_codepage()}
|
66
|
0
|
|
|
|
|
|
elsif ($field eq 'tab') {Kephra::Document::Property::switch_tab_mode()}
|
67
|
0
|
|
|
|
|
|
elsif ($field eq 'EOL') {Kephra::App::EditPanel::Indicator::switch_EOL_visibility()}
|
68
|
|
|
|
|
|
|
elsif ($field eq 'message') {next_file_info(); }
|
69
|
0
|
|
|
|
|
|
} );
|
70
|
|
|
|
|
|
|
Wx::Event::EVT_RIGHT_DOWN ( $bar, sub {
|
71
|
0
|
0
|
|
0
|
|
|
return unless get_contextmenu_visibility();
|
72
|
0
|
|
|
|
|
|
my ( $bar, $event ) = @_;
|
73
|
0
|
|
|
|
|
|
my $x = $event->GetX;
|
74
|
0
|
|
|
|
|
|
my $index = _index_from_mouse_pos( $x );
|
75
|
0
|
|
|
|
|
|
my $cell_start = $bar->GetFieldRect($index)->GetTopLeft;
|
76
|
0
|
0
|
|
|
|
|
$x = $cell_start->x unless $width{ _item($index) } == -1;
|
77
|
0
|
|
|
|
|
|
my $y = $cell_start->y;
|
78
|
0
|
|
|
|
|
|
my $field = _item( $index );
|
79
|
0
|
|
|
|
|
|
my $menu = \&Kephra::App::ContextMenu::get;
|
80
|
0
|
0
|
|
|
|
|
if ($field eq 'syntaxmode'){$bar->PopupMenu( &$menu('status_syntaxmode'),$x,$y)}
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
81
|
0
|
|
|
|
|
|
elsif ($field eq 'codepage') {$bar->PopupMenu( &$menu('status_encoding'), $x,$y)}
|
82
|
0
|
|
|
|
|
|
elsif ($field eq 'tab') {$bar->PopupMenu( &$menu('status_tab'), $x,$y)}
|
83
|
0
|
|
|
|
|
|
elsif ($field eq 'EOL') {$bar->PopupMenu( &$menu('status_eol'), $x,$y)}
|
84
|
|
|
|
|
|
|
elsif ($field eq 'message') {$bar->PopupMenu( &$menu('status_info'), $x,$y)}
|
85
|
0
|
|
|
|
|
|
});
|
86
|
0
|
|
|
|
|
|
my $help_index = -1;
|
87
|
|
|
|
|
|
|
Wx::Event::EVT_MOTION ( $bar, sub {
|
88
|
0
|
|
|
0
|
|
|
my $index = _index_from_mouse_pos( $_[1]->GetX );
|
89
|
0
|
0
|
|
|
|
|
return if $index == $help_index;
|
90
|
0
|
|
|
|
|
|
$help_index = $index;
|
91
|
0
|
|
|
|
|
|
info_msg( _l18n()->{help}{ _item( $index ) } );
|
92
|
0
|
|
|
|
|
|
});
|
93
|
0
|
|
|
0
|
|
|
Wx::Event::EVT_LEAVE_WINDOW( $bar, sub { info_msg(''); $help_index = -1 });
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
|
96
|
0
|
|
|
|
|
|
Kephra::EventTable::add_call
|
97
|
|
|
|
|
|
|
('caret.move', 'caret_status', \&caret_pos_info, __PACKAGE__);
|
98
|
0
|
|
|
|
|
|
Kephra::EventTable::add_call
|
99
|
|
|
|
|
|
|
('document.text.change', 'info_msg', \&refresh_info_msg, __PACKAGE__);
|
100
|
0
|
|
|
|
|
|
Kephra::EventTable::add_call
|
101
|
|
|
|
|
|
|
('editpanel.focus', 'info_msg', \&refresh_info_msg, __PACKAGE__);
|
102
|
|
|
|
|
|
|
|
103
|
0
|
|
|
|
|
|
show();
|
104
|
|
|
|
|
|
|
}
|
105
|
0
|
|
|
0
|
0
|
|
sub get_visibility { _config()->{'visible'} }
|
106
|
|
|
|
|
|
|
sub switch_visibility {
|
107
|
0
|
|
|
0
|
0
|
|
_config()->{'visible'} ^= 1;
|
108
|
0
|
|
|
|
|
|
show();
|
109
|
0
|
|
|
|
|
|
Kephra::App::Window::_ref()->Layout();
|
110
|
|
|
|
|
|
|
}
|
111
|
0
|
|
|
0
|
0
|
|
sub show { Kephra::App::Window::_ref()->GetStatusBar->Show( get_visibility() ) }
|
112
|
0
|
|
|
0
|
0
|
|
sub get_interactive { _config()->{interactive} }
|
113
|
0
|
|
|
0
|
0
|
|
sub get_contextmenu_visibility { _config()->{contextmenu_visible} }
|
114
|
0
|
|
|
0
|
0
|
|
sub switch_contextmenu_visibility { _config()->{contextmenu_visible} ^= 1 }
|
115
|
|
|
|
|
|
|
#
|
116
|
|
|
|
|
|
|
# update cell content
|
117
|
|
|
|
|
|
|
#
|
118
|
|
|
|
|
|
|
sub refresh_cursor {
|
119
|
0
|
|
|
0
|
0
|
|
caret_pos_info();
|
120
|
0
|
|
|
|
|
|
refresh_info_msg();
|
121
|
|
|
|
|
|
|
}
|
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub refresh_all_cells {
|
124
|
0
|
|
|
0
|
0
|
|
refresh_cursor();
|
125
|
0
|
|
|
|
|
|
style_info();
|
126
|
0
|
|
|
|
|
|
codepage_info();
|
127
|
0
|
|
|
|
|
|
tab_info();
|
128
|
0
|
|
|
|
|
|
EOL_info();
|
129
|
0
|
|
|
|
|
|
info_msg();
|
130
|
|
|
|
|
|
|
}
|
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
sub caret_pos_info {
|
133
|
0
|
|
|
0
|
0
|
|
my $ep = Kephra::App::EditPanel::_ref();
|
134
|
0
|
|
|
|
|
|
my $pos = $ep->GetCurrentPos;
|
135
|
0
|
|
|
|
|
|
my $line = $ep->LineFromPosition($pos) + 1;
|
136
|
0
|
|
|
|
|
|
my $lpos = $ep->GetColumn($pos) + 1;
|
137
|
0
|
|
|
|
|
|
my $value;
|
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
# caret pos display
|
140
|
0
|
0
|
0
|
|
|
|
if ( $line > 9999 or $lpos > 9999 )
|
141
|
0
|
|
|
|
|
|
{ _set_text(" $line : $lpos", $index{cursor} ) }
|
142
|
0
|
|
|
|
|
|
else { _set_text(" $line : $lpos", $index{cursor} ) }
|
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
# selection or pos % display
|
145
|
0
|
|
|
|
|
|
my ( $sel_beg, $sel_end ) = $ep->GetSelection;
|
146
|
0
|
0
|
|
|
|
|
unless ( Kephra::Document::Data::attr('text_selected') ) {
|
147
|
0
|
|
|
|
|
|
my $chars = $ep->GetLength;
|
148
|
0
|
0
|
|
|
|
|
if ($chars) {
|
149
|
0
|
|
|
|
|
|
my $value = int 100 * $pos / $chars + .5;
|
150
|
0
|
0
|
|
|
|
|
$value = ' ' . $value if $value < 10;
|
151
|
0
|
0
|
|
|
|
|
$value = ' ' . $value . ' ' if $value < 100;
|
152
|
0
|
|
|
|
|
|
_set_text( " $value%", $index{selection} );
|
153
|
0
|
|
|
|
|
|
} else { _set_text( " 100%", $index{selection} ) }
|
154
|
|
|
|
|
|
|
} else {
|
155
|
0
|
0
|
|
|
|
|
if ( $ep->SelectionIsRectangle ) {
|
156
|
0
|
|
|
|
|
|
my $x = abs int $ep->GetColumn($sel_beg) - $ep->GetColumn($sel_end);
|
157
|
0
|
|
|
|
|
|
my $lines = 1 + abs int $ep->LineFromPosition($sel_beg)
|
158
|
|
|
|
|
|
|
- $ep->LineFromPosition($sel_end);
|
159
|
0
|
|
|
|
|
|
my $chars = $x * $lines;
|
160
|
0
|
0
|
|
|
|
|
$lines = ' ' . $lines if $lines < 100;
|
161
|
0
|
0
|
|
|
|
|
if ($lines < 10000) { $value = "$lines : $chars" }
|
|
0
|
|
|
|
|
|
|
162
|
0
|
|
|
|
|
|
else { $value = "$lines:$chars" }
|
163
|
0
|
|
|
|
|
|
_set_text( $value, $index{selection} );
|
164
|
|
|
|
|
|
|
} else {
|
165
|
0
|
|
|
|
|
|
my $lines = 1 + $ep->LineFromPosition($sel_end)
|
166
|
|
|
|
|
|
|
- $ep->LineFromPosition($sel_beg);
|
167
|
0
|
|
|
|
|
|
my $chars = $sel_end - $sel_beg -
|
168
|
|
|
|
|
|
|
($lines - 1) * Kephra::Document::Data::get_attribute('EOL_length');
|
169
|
0
|
0
|
|
|
|
|
$lines = ' ' . $lines if $lines < 100;
|
170
|
0
|
0
|
|
|
|
|
if ($lines < 10000) { $value = "$lines : $chars" }
|
|
0
|
|
|
|
|
|
|
171
|
0
|
|
|
|
|
|
else { $value = "$lines:$chars" }
|
172
|
0
|
|
|
|
|
|
_set_text( $value, $index{selection});
|
173
|
|
|
|
|
|
|
}
|
174
|
|
|
|
|
|
|
}
|
175
|
|
|
|
|
|
|
}
|
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
sub style_info {
|
178
|
0
|
|
0
|
0
|
0
|
|
my $style = shift
|
179
|
|
|
|
|
|
|
|| Kephra::Document::Data::attr('syntaxmode')
|
180
|
|
|
|
|
|
|
|| _none_string();
|
181
|
0
|
|
|
|
|
|
_set_text( '' . $style, $index{syntaxmode} );
|
182
|
|
|
|
|
|
|
}
|
183
|
|
|
|
|
|
|
sub codepage_info {
|
184
|
0
|
|
0
|
0
|
0
|
|
my $codepage = shift || Kephra::Document::Data::attr('codepage');
|
185
|
0
|
0
|
|
|
|
|
my $msg = defined $codepage
|
186
|
|
|
|
|
|
|
? Kephra::CommandList::get_cmd_property
|
187
|
|
|
|
|
|
|
( 'document-encoding-'.$codepage, 'label' )
|
188
|
|
|
|
|
|
|
: _none_string();
|
189
|
0
|
|
|
|
|
|
_set_text( '' . $codepage, $index{codepage} );
|
190
|
|
|
|
|
|
|
}
|
191
|
|
|
|
|
|
|
sub tab_info {
|
192
|
0
|
|
0
|
0
|
0
|
|
my $mode = Kephra::App::EditPanel::_ref()->GetUseTabs || 0;
|
193
|
0
|
0
|
|
|
|
|
my $msg = $mode ? ' HT' : ' ST';
|
194
|
0
|
|
|
|
|
|
_set_text( $msg, $index{'tab'} );
|
195
|
|
|
|
|
|
|
}
|
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
sub EOL_info {
|
198
|
0
|
|
0
|
0
|
0
|
|
my $mode = shift || Kephra::Document::Data::get_attribute('EOL') || _none_string() || 'no';
|
199
|
0
|
|
|
|
|
|
my $msg;
|
200
|
0
|
0
|
0
|
|
|
|
if ( $mode eq 'none' or $mode eq 'no' ) { $msg = _none_string() || 'no' }
|
|
0
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
201
|
0
|
|
|
|
|
|
elsif ( $mode eq 'cr' or $mode eq 'mac' ) { $msg = " Mac" }
|
202
|
0
|
|
|
|
|
|
elsif ( $mode eq 'lf' or $mode eq 'lin' ) { $msg = "Linux" }
|
203
|
0
|
|
|
|
|
|
elsif ( $mode eq 'cr+lf' or $mode eq 'win' ) { $msg = " Win" }
|
204
|
0
|
|
|
|
|
|
_set_text( $msg, $index{EOL} );
|
205
|
|
|
|
|
|
|
}
|
206
|
|
|
|
|
|
|
#
|
207
|
|
|
|
|
|
|
# info messages, last cell
|
208
|
|
|
|
|
|
|
#
|
209
|
0
|
|
|
0
|
0
|
|
sub status_msg { info_msg(@_) }
|
210
|
|
|
|
|
|
|
sub info_msg {
|
211
|
0
|
|
|
0
|
0
|
|
my $msg;
|
212
|
0
|
|
|
|
|
|
$msg .= $_ for @_;
|
213
|
0
|
|
|
|
|
|
_set_text( $msg, $index{message} );
|
214
|
|
|
|
|
|
|
}
|
215
|
0
|
|
|
0
|
0
|
|
sub refresh_info_msg { refresh_file_info() }
|
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
sub info_msg_nr {
|
218
|
0
|
|
|
0
|
0
|
|
my $nr = shift;
|
219
|
0
|
0
|
|
|
|
|
if (defined $nr) { _config()->{msg_nr} = $nr}
|
|
0
|
|
|
|
|
|
|
220
|
0
|
|
|
|
|
|
else { _config()->{msg_nr} }
|
221
|
|
|
|
|
|
|
}
|
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
sub next_file_info {
|
224
|
0
|
|
|
0
|
0
|
|
my $info_nr = _config()->{msg_nr};
|
225
|
0
|
0
|
|
|
|
|
$info_nr = $info_nr >= 2 ? 0 : $info_nr + 1;
|
226
|
0
|
|
|
|
|
|
set_info_msg_nr($info_nr);
|
227
|
|
|
|
|
|
|
}
|
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
sub set_info_msg_nr {
|
230
|
0
|
|
0
|
0
|
0
|
|
my $info_nr = shift || 0;
|
231
|
0
|
|
|
|
|
|
info_msg_nr($info_nr);
|
232
|
0
|
|
|
|
|
|
refresh_file_info();
|
233
|
|
|
|
|
|
|
}
|
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
sub refresh_file_info {
|
236
|
0
|
0
|
|
0
|
0
|
|
my $msg = info_msg_nr() ? _get_file_info( _config()->{msg_nr} ) : '';
|
237
|
0
|
|
|
|
|
|
_set_text( $msg, $index{message} );
|
238
|
|
|
|
|
|
|
}
|
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
sub _get_file_info {
|
241
|
0
|
|
|
0
|
|
|
my $selector = shift;
|
242
|
0
|
0
|
|
|
|
|
return '' unless $selector;
|
243
|
0
|
|
|
|
|
|
my $l18n = _l18n()->{label};
|
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
# show how big file is
|
246
|
0
|
0
|
|
|
|
|
if ( $selector == 1 ) {
|
|
|
0
|
|
|
|
|
|
247
|
0
|
|
|
|
|
|
my $ep = Kephra::App::EditPanel::_ref();
|
248
|
|
|
|
|
|
|
|
249
|
0
|
|
|
|
|
|
return sprintf ' %s: %s %s: %s',
|
250
|
|
|
|
|
|
|
$l18n->{chars}, _dotted_number( $ep->GetLength ),
|
251
|
|
|
|
|
|
|
$l18n->{lines}, _dotted_number( $ep->GetLineCount );
|
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
# show how old file is
|
254
|
|
|
|
|
|
|
} elsif ( $selector == 2 ) {
|
255
|
0
|
|
|
|
|
|
my $file = Kephra::Document::Data::get_file_path();
|
256
|
0
|
0
|
|
|
|
|
if ($file) {
|
257
|
0
|
|
|
|
|
|
my @time = localtime( $^T - ( -M $file ) * 86300 );
|
258
|
0
|
|
|
|
|
|
return sprintf ' %s: %02d:%02d - %02d.%02d.%d', $l18n->{last_change},
|
259
|
|
|
|
|
|
|
$time[2], $time[1], $time[3], $time[4] + 1, $time[5] + 1900;
|
260
|
|
|
|
|
|
|
} else {
|
261
|
0
|
|
|
|
|
|
my @time = localtime;
|
262
|
0
|
|
|
|
|
|
return sprintf ' %s: %02d:%02d - %02d.%02d.%d', $l18n->{now_is},
|
263
|
|
|
|
|
|
|
$time[2], $time[1], $time[3], $time[4] + 1, $time[5] + 1900;
|
264
|
|
|
|
|
|
|
}
|
265
|
|
|
|
|
|
|
}
|
266
|
|
|
|
|
|
|
}
|
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
sub _dotted_number {
|
269
|
0
|
|
|
0
|
|
|
local $_ = shift;
|
270
|
0
|
|
|
|
|
|
1 while s/^(\d+)(\d{3})/$1.$2/;
|
271
|
0
|
|
|
|
|
|
return $_;
|
272
|
|
|
|
|
|
|
}
|
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
1;
|
275
|
|
|
|
|
|
|
|