| line | stmt | bran | cond | sub | pod | time | code | 
| 1 | 2 |  |  | 2 |  | 44655 | use warnings; | 
|  | 2 |  |  |  |  | 4 |  | 
|  | 2 |  |  |  |  | 57 |  | 
| 2 | 2 |  |  | 2 |  | 10 | use strict; | 
|  | 2 |  |  |  |  | 5 |  | 
|  | 2 |  |  |  |  | 160 |  | 
| 3 |  |  |  |  |  |  | package Religion::Bible::Reference; | 
| 4 |  |  |  |  |  |  | # ABSTRACT: canonicalize shorthand bible references | 
| 5 |  |  |  |  |  |  | $Religion::Bible::Reference::VERSION = '0.016'; | 
| 6 | 2 |  |  |  |  | 17 | use Sub::Exporter -setup => { | 
| 7 |  |  |  |  |  |  | exports => [ qw(bibref) ], | 
| 8 |  |  |  |  |  |  | groups  => { default => [ qw(bibref) ] }, | 
| 9 | 2 |  |  | 2 |  | 1921 | }; | 
|  | 2 |  |  |  |  | 27011 |  | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | my %book_chapters; | 
| 12 |  |  |  |  |  |  | my %book_abbrev; | 
| 13 |  |  |  |  |  |  | my %book_short; | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | BEGIN { | 
| 16 | 2 |  |  | 2 |  | 7 | for my $attr (qw(book chapter ranges)) { | 
| 17 | 2 |  |  | 2 |  | 713 | no strict 'refs'; | 
|  | 2 |  |  |  |  | 3 |  | 
|  | 2 |  |  |  |  | 154 |  | 
| 18 |  |  |  |  |  |  | *$attr = sub { | 
| 19 | 9 | 50 |  | 9 |  | 48 | return $_[0]->{$attr} if @_ == 1; | 
| 20 | 0 |  |  |  |  | 0 | return $_[0]->{$attr} = $_[1]; | 
| 21 | 6 |  |  |  |  | 69 | }; | 
| 22 |  |  |  |  |  |  | } | 
| 23 |  |  |  |  |  |  | } | 
| 24 |  |  |  |  |  |  |  | 
| 25 | 2 |  |  | 2 |  | 1416 | use Religion::Bible::Reference::Standard; | 
|  | 2 |  |  |  |  | 5 |  | 
|  | 2 |  |  |  |  | 2558 |  | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | #pod =head1 SYNOPSIS | 
| 28 |  |  |  |  |  |  | #pod | 
| 29 |  |  |  |  |  |  | #pod  use Religion::Bible::Reference; | 
| 30 |  |  |  |  |  |  | #pod | 
| 31 |  |  |  |  |  |  | #pod  my $quote = bibref("jn8:32"); | 
| 32 |  |  |  |  |  |  | #pod | 
| 33 |  |  |  |  |  |  | #pod  print "($quote)";   # (John 8:32) | 
| 34 |  |  |  |  |  |  | #pod  print $quote->book; # John | 
| 35 |  |  |  |  |  |  | #pod | 
| 36 |  |  |  |  |  |  | #pod =head1 DESCRIPTION | 
| 37 |  |  |  |  |  |  | #pod | 
| 38 |  |  |  |  |  |  | #pod This module converts simple text descriptions of bible references and ranges | 
| 39 |  |  |  |  |  |  | #pod into objects that stringify into a canonical form. | 
| 40 |  |  |  |  |  |  | #pod | 
| 41 |  |  |  |  |  |  | #pod B  This module is mostly an idea and not so much a guaranteed | 
| 42 |  |  |  |  |  |  | #pod interface or well-tested implementation.  If you're interested in either of | 
| 43 |  |  |  |  |  |  | #pod those existing, you should let me know. | 
| 44 |  |  |  |  |  |  | #pod | 
| 45 |  |  |  |  |  |  | #pod =func bibref | 
| 46 |  |  |  |  |  |  | #pod | 
| 47 |  |  |  |  |  |  | #pod   my $ref = bibref($ref_string) | 
| 48 |  |  |  |  |  |  | #pod | 
| 49 |  |  |  |  |  |  | #pod This function is exported by default, and constructs a new | 
| 50 |  |  |  |  |  |  | #pod Religion::Bible::Reference | 
| 51 |  |  |  |  |  |  | #pod | 
| 52 |  |  |  |  |  |  | #pod Reference strings must be a book followed by a list of chapters, verses, or | 
| 53 |  |  |  |  |  |  | #pod ranges.  The following are all valid ranges: | 
| 54 |  |  |  |  |  |  | #pod | 
| 55 |  |  |  |  |  |  | #pod   Pro 23:12, 23:15-17 | 
| 56 |  |  |  |  |  |  | #pod   st.jn8:32 | 
| 57 |  |  |  |  |  |  | #pod   Song of Solomon 8:7-8 | 
| 58 |  |  |  |  |  |  | #pod   2 John 1 | 
| 59 |  |  |  |  |  |  | #pod | 
| 60 |  |  |  |  |  |  | #pod =cut | 
| 61 |  |  |  |  |  |  |  | 
| 62 | 9 |  |  | 9 | 1 | 2875 | sub bibref { __PACKAGE__->new(@_); } | 
| 63 |  |  |  |  |  |  |  | 
| 64 |  |  |  |  |  |  | #pod =method new | 
| 65 |  |  |  |  |  |  | #pod | 
| 66 |  |  |  |  |  |  | #pod   my $ref = Religion::Bible::Reference->new($ref_string) | 
| 67 |  |  |  |  |  |  | #pod | 
| 68 |  |  |  |  |  |  | #pod This method acts just like the exported C function. | 
| 69 |  |  |  |  |  |  | #pod | 
| 70 |  |  |  |  |  |  | #pod =cut | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | # ok: | 
| 73 |  |  |  |  |  |  | # jn8 | 
| 74 |  |  |  |  |  |  | # jn8:32 | 
| 75 |  |  |  |  |  |  | # jn8:30-32 | 
| 76 |  |  |  |  |  |  | # jn8:25-28,30-32 | 
| 77 |  |  |  |  |  |  | # jn8:1,3-4,6 | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | sub _parse_ref { | 
| 80 | 9 |  |  | 9 |  | 16 | my ($class, $ref_string) = @_; | 
| 81 | 9 |  |  |  |  | 39 | my $range_regex  = qr/\d+(?::(?:\d[-,]?)+)?/; | 
| 82 |  |  |  |  |  |  |  | 
| 83 | 9 |  |  |  |  | 182 | (my $book  = $ref_string) =~ s/\s*($range_regex)\z//; | 
| 84 | 9 |  |  |  |  | 30 | my $ranges = $1; | 
| 85 |  |  |  |  |  |  |  | 
| 86 | 9 |  |  |  |  | 57 | return (book => $book, ranges => $ranges); | 
| 87 |  |  |  |  |  |  | } | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | sub new { | 
| 90 | 9 |  |  | 9 | 1 | 17 | my ($class, $ref_string) = @_; | 
| 91 |  |  |  |  |  |  |  | 
| 92 | 9 |  |  |  |  | 27 | my %bibref = $class->_parse_ref($ref_string); | 
| 93 |  |  |  |  |  |  |  | 
| 94 | 9 |  |  |  |  | 15 | my $self; | 
| 95 |  |  |  |  |  |  |  | 
| 96 | 9 | 50 |  |  |  | 31 | return unless $self->{book}  = $class->canonicalize_book($bibref{book}); | 
| 97 |  |  |  |  |  |  |  | 
| 98 | 9 |  |  |  |  | 45 | bless $self => $class; | 
| 99 |  |  |  |  |  |  |  | 
| 100 | 9 | 50 |  |  |  | 29 | return unless my $range = $self->_parse_ranges($bibref{ranges}); | 
| 101 |  |  |  |  |  |  |  | 
| 102 | 9 |  |  |  |  | 31 | $self->{chapter} = $range->{chapter}; | 
| 103 | 9 |  |  |  |  | 17 | $self->{ranges}  = $range->{ranges}; | 
| 104 |  |  |  |  |  |  |  | 
| 105 | 9 | 100 |  |  |  | 34 | return unless $class->_validate_ranges( | 
| 106 |  |  |  |  |  |  | $self->{book}, | 
| 107 |  |  |  |  |  |  | $self->{chapter}, | 
| 108 |  |  |  |  |  |  | $self->{ranges}, | 
| 109 |  |  |  |  |  |  | ); | 
| 110 |  |  |  |  |  |  |  | 
| 111 | 7 |  |  |  |  | 32 | return $self; | 
| 112 |  |  |  |  |  |  | } | 
| 113 |  |  |  |  |  |  |  | 
| 114 |  |  |  |  |  |  | sub _validate_ranges { | 
| 115 | 9 |  |  | 9 |  | 14 | my ($class, $book, $chapter, $ranges) = @_; | 
| 116 |  |  |  |  |  |  |  | 
| 117 | 9 |  |  |  |  | 17 | foreach my $range (@$ranges) { | 
| 118 | 14 | 100 |  |  |  | 40 | return unless $class->validate_verse($book, $chapter, $range->[0]); | 
| 119 | 13 | 100 |  |  |  | 33 | return unless $class->validate_verse($book, $chapter, $range->[1]); | 
| 120 |  |  |  |  |  |  | } | 
| 121 | 7 |  |  |  |  | 21 | return 1; | 
| 122 |  |  |  |  |  |  | } | 
| 123 |  |  |  |  |  |  |  | 
| 124 |  |  |  |  |  |  | sub _parse_ranges { | 
| 125 | 9 |  |  | 9 |  | 17 | my ($self, $string) = @_; | 
| 126 |  |  |  |  |  |  |  | 
| 127 | 9 |  |  |  |  | 41 | my ($chapter, $rest) = $string =~ /\A(\d+)(?::(.+))?\z/; | 
| 128 |  |  |  |  |  |  |  | 
| 129 | 9 | 50 |  |  |  | 20 | return unless $chapter; | 
| 130 | 9 | 100 |  |  |  | 34 | return { chapter => $string, | 
| 131 |  |  |  |  |  |  | ranges => [[ 1, $book_chapters{$self->{book}}[$chapter - 1] ]] } | 
| 132 |  |  |  |  |  |  | unless $rest; | 
| 133 |  |  |  |  |  |  |  | 
| 134 | 8 |  |  |  |  | 31 | my @range_strings = split /,\s?/, $rest; | 
| 135 |  |  |  |  |  |  |  | 
| 136 | 8 |  |  |  |  | 11 | my @range; | 
| 137 |  |  |  |  |  |  |  | 
| 138 | 8 |  |  |  |  | 11 | for my $rs (@range_strings) { | 
| 139 | 13 |  |  |  |  | 46 | my ($start, $end) = $rs =~ /\A(\d+)(?:-(\d+))?\z/; | 
| 140 | 13 | 50 |  |  |  | 28 | return unless $start; | 
| 141 | 13 | 100 |  |  |  | 48 | push @range, [ $start, (defined $end ? $end : $start) ]; | 
| 142 |  |  |  |  |  |  | } | 
| 143 |  |  |  |  |  |  |  | 
| 144 | 8 |  |  |  |  | 50 | return { chapter => $chapter, ranges => \@range }; | 
| 145 |  |  |  |  |  |  | } | 
| 146 |  |  |  |  |  |  |  | 
| 147 |  |  |  |  |  |  | #pod =method stringify | 
| 148 |  |  |  |  |  |  | #pod | 
| 149 |  |  |  |  |  |  | #pod   $self->stringify | 
| 150 |  |  |  |  |  |  | #pod | 
| 151 |  |  |  |  |  |  | #pod This method returns a string representing the reference, using the canonical | 
| 152 |  |  |  |  |  |  | #pod book name. | 
| 153 |  |  |  |  |  |  | #pod | 
| 154 |  |  |  |  |  |  | #pod =cut | 
| 155 |  |  |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | sub stringify { | 
| 157 | 7 |  |  | 7 | 1 | 1337 | my ($self) = @_; | 
| 158 | 7 |  |  |  |  | 20 | my $string = $self->{book} | 
| 159 |  |  |  |  |  |  | . q{ } | 
| 160 |  |  |  |  |  |  | . $self->{chapter}; | 
| 161 |  |  |  |  |  |  |  | 
| 162 | 7 | 50 |  |  |  | 10 | return unless @{ $self->{ranges} }; | 
|  | 7 |  |  |  |  | 22 |  | 
| 163 |  |  |  |  |  |  |  | 
| 164 | 14 |  |  |  |  | 31 | $string .= | 
| 165 | 7 |  |  |  |  | 15 | ':' . join(', ', map { $self->_stringify_range($_) } @{ $self->{ranges} }) | 
|  | 7 |  |  |  |  | 14 |  | 
| 166 |  |  |  |  |  |  | ; | 
| 167 |  |  |  |  |  |  | } | 
| 168 |  |  |  |  |  |  |  | 
| 169 |  |  |  |  |  |  | sub _stringify_range { | 
| 170 | 15 |  |  | 15 |  | 22 | my ($self, $range) = @_; | 
| 171 |  |  |  |  |  |  |  | 
| 172 | 15 | 100 |  |  |  | 17 | map { $_->[0] == $_->[1] ? $_->[0] : "$_->[0]-$_->[1]" } $range | 
|  | 15 |  |  |  |  | 115 |  | 
| 173 |  |  |  |  |  |  | } | 
| 174 |  |  |  |  |  |  |  | 
| 175 |  |  |  |  |  |  | sub _register_book_set { | 
| 176 | 2 |  |  | 2 |  | 5 | my ($class, $package) = @_; | 
| 177 |  |  |  |  |  |  |  | 
| 178 | 2 |  |  |  |  | 10 | my @books = $package->_books; | 
| 179 | 2 |  |  |  |  | 10 | for my $book (@books) { | 
| 180 | 132 |  |  |  |  | 143 | my $full = $book->{full}; | 
| 181 | 132 |  |  |  |  | 261 | $book_chapters{ $full } = $book->{verses}; | 
| 182 | 132 |  |  |  |  | 163 | $book_abbrev  { $full } = $book->{abbreviations}; | 
| 183 | 132 |  |  |  |  | 306 | $book_short   { $full } = $book->{short}; | 
| 184 |  |  |  |  |  |  | } | 
| 185 |  |  |  |  |  |  | } | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | #pod =method stringify_short | 
| 188 |  |  |  |  |  |  | #pod | 
| 189 |  |  |  |  |  |  | #pod   my $str = $self->stringify_short | 
| 190 |  |  |  |  |  |  | #pod | 
| 191 |  |  |  |  |  |  | #pod This method returns a string representing the reference, using the short book | 
| 192 |  |  |  |  |  |  | #pod name. | 
| 193 |  |  |  |  |  |  | #pod | 
| 194 |  |  |  |  |  |  | #pod In other words, John 8:32 would be Jn 8:32.  All short forms should safely | 
| 195 |  |  |  |  |  |  | #pod round-trip back via parsing. | 
| 196 |  |  |  |  |  |  | #pod | 
| 197 |  |  |  |  |  |  | #pod =cut | 
| 198 |  |  |  |  |  |  |  | 
| 199 |  |  |  |  |  |  | sub stringify_short { | 
| 200 | 1 |  |  | 1 | 1 | 2 | my ($self) = @_; | 
| 201 |  |  |  |  |  |  |  | 
| 202 | 1 |  |  |  |  | 5 | my $string = $book_short{ $self->{book} } | 
| 203 |  |  |  |  |  |  | . q{ } | 
| 204 |  |  |  |  |  |  | . $self->{chapter}; | 
| 205 |  |  |  |  |  |  |  | 
| 206 | 1 | 50 |  |  |  | 2 | return unless @{ $self->{ranges} }; | 
|  | 1 |  |  |  |  | 7 |  | 
| 207 |  |  |  |  |  |  |  | 
| 208 | 1 |  |  |  |  | 3 | $string .= | 
| 209 | 1 |  |  |  |  | 2 | ':' . join(', ', map { $self->_stringify_range($_) } @{ $self->{ranges} }) | 
|  | 1 |  |  |  |  | 3 |  | 
| 210 |  |  |  |  |  |  | ; | 
| 211 |  |  |  |  |  |  | } | 
| 212 |  |  |  |  |  |  |  | 
| 213 |  |  |  |  |  |  | __PACKAGE__->_register_book_set("Religion::Bible::Reference::Standard"); | 
| 214 |  |  |  |  |  |  |  | 
| 215 |  |  |  |  |  |  | #pod =method canonicalize_book | 
| 216 |  |  |  |  |  |  | #pod | 
| 217 |  |  |  |  |  |  | #pod   my $book = $class->canonicalize_book($book_abbrev) | 
| 218 |  |  |  |  |  |  | #pod | 
| 219 |  |  |  |  |  |  | #pod If possible, this method returns the canonical name of the book whose | 
| 220 |  |  |  |  |  |  | #pod abbreviation was passed. | 
| 221 |  |  |  |  |  |  | #pod | 
| 222 |  |  |  |  |  |  | #pod =cut | 
| 223 |  |  |  |  |  |  |  | 
| 224 |  |  |  |  |  |  | # mdxi suggests that I could have a list of pre-limiting regex, something like | 
| 225 |  |  |  |  |  |  | # this: | 
| 226 |  |  |  |  |  |  | # [ qr/\A(?:1|First)/, [ '1 Kings', '1 Samuel' ... | 
| 227 |  |  |  |  |  |  | # so that if a passed string matches the regex, it's only checked against those | 
| 228 |  |  |  |  |  |  | # entries in the associated list; good idea, for future revision | 
| 229 |  |  |  |  |  |  |  | 
| 230 |  |  |  |  |  |  | sub canonicalize_book { | 
| 231 | 9 |  |  | 9 | 1 | 15 | my ($class, $book_abbrev) = @_; | 
| 232 | 9 | 50 |  |  |  | 32 | return $book_abbrev if $book_abbrev{$book_abbrev}; | 
| 233 | 9 |  |  |  |  | 85 | my $lc_abbrev = lc($book_abbrev); | 
| 234 | 9 |  |  |  |  | 121 | for my $book (keys %book_abbrev) { | 
| 235 | 207 | 50 |  |  |  | 398 | return $book if lc($book) eq $lc_abbrev; | 
| 236 | 207 |  |  |  |  | 217 | for (@{$book_abbrev{$book}}) { | 
|  | 207 |  |  |  |  | 369 |  | 
| 237 | 318 | 100 |  |  |  | 415 | if (ref $_) { return $book if $book_abbrev =~ m/$_/; } | 
|  | 75 | 100 |  |  |  | 493 |  | 
| 238 | 243 | 50 |  |  |  | 591 | else { return $book if $lc_abbrev eq lc($_);  } | 
| 239 |  |  |  |  |  |  | } | 
| 240 |  |  |  |  |  |  | } | 
| 241 | 0 |  |  |  |  | 0 | return; | 
| 242 |  |  |  |  |  |  | } | 
| 243 |  |  |  |  |  |  |  | 
| 244 |  |  |  |  |  |  | #pod =method validate_verse | 
| 245 |  |  |  |  |  |  | #pod | 
| 246 |  |  |  |  |  |  | #pod   $class->validate_verse($book, $chapter, $verse) | 
| 247 |  |  |  |  |  |  | #pod | 
| 248 |  |  |  |  |  |  | #pod This method returns true if the given book, chapter, and verse exists; | 
| 249 |  |  |  |  |  |  | #pod otherwise it returns false. | 
| 250 |  |  |  |  |  |  | #pod | 
| 251 |  |  |  |  |  |  | #pod =cut | 
| 252 |  |  |  |  |  |  |  | 
| 253 |  |  |  |  |  |  | sub validate_verse { | 
| 254 | 27 |  |  | 27 | 1 | 34 | my ($self, $book, $chapter, $verse) = @_; | 
| 255 | 27 | 50 |  |  |  | 57 | return unless exists $book_chapters{$book}; | 
| 256 | 27 | 100 |  |  |  | 94 | return unless defined $book_chapters{$book}[$chapter - 1]; | 
| 257 | 26 | 100 |  |  |  | 66 | return unless $book_chapters{$book}[$chapter - 1] >= $verse; | 
| 258 | 25 |  |  |  |  | 70 | return 1 | 
| 259 |  |  |  |  |  |  | } | 
| 260 |  |  |  |  |  |  |  | 
| 261 |  |  |  |  |  |  | #pod =method iterator | 
| 262 |  |  |  |  |  |  | #pod | 
| 263 |  |  |  |  |  |  | #pod   my $iterator = $bibref->iterator; | 
| 264 |  |  |  |  |  |  | #pod | 
| 265 |  |  |  |  |  |  | #pod   while (my $verse = $iterator->next) { | 
| 266 |  |  |  |  |  |  | #pod     my $text = retrieve($verse); | 
| 267 |  |  |  |  |  |  | #pod     print "$text\n"; | 
| 268 |  |  |  |  |  |  | #pod   } | 
| 269 |  |  |  |  |  |  | #pod | 
| 270 |  |  |  |  |  |  | #pod =cut | 
| 271 |  |  |  |  |  |  |  | 
| 272 |  |  |  |  |  |  | sub iterator { | 
| 273 | 3 |  |  | 3 | 1 | 21 | my ($self) = @_; | 
| 274 |  |  |  |  |  |  |  | 
| 275 | 3 |  |  |  |  | 6 | my $iterator = { | 
| 276 |  |  |  |  |  |  | book    => $self->book, | 
| 277 |  |  |  |  |  |  | chapter => $self->chapter, | 
| 278 | 3 |  |  |  |  | 10 | ranges  => [ @{ $self->ranges } ], | 
| 279 |  |  |  |  |  |  | }; | 
| 280 |  |  |  |  |  |  |  | 
| 281 | 3 |  |  |  |  | 16 | bless $iterator => 'Religion::Bible::Reference::Iterator'; | 
| 282 |  |  |  |  |  |  | } | 
| 283 |  |  |  |  |  |  |  | 
| 284 |  |  |  |  |  |  | package Religion::Bible::Reference::Iterator; | 
| 285 |  |  |  |  |  |  | $Religion::Bible::Reference::Iterator::VERSION = '0.016'; | 
| 286 |  |  |  |  |  |  | sub next { ## no critic # honestly, next is a great method for an iterator | 
| 287 | 64 |  |  | 64 |  | 7089 | my ($self) = @_; | 
| 288 | 64 | 100 |  |  |  | 57 | return unless @{ $self->{ranges} }; | 
|  | 64 |  |  |  |  | 151 |  | 
| 289 |  |  |  |  |  |  |  | 
| 290 | 61 |  | 66 |  |  | 136 | $self->{position} ||= $self->{ranges}[0][0]; | 
| 291 | 61 |  |  |  |  | 69 | my $position = $self->{position}; | 
| 292 |  |  |  |  |  |  |  | 
| 293 | 61 | 100 |  |  |  | 108 | if ($position == $self->{ranges}[0][1]) { | 
| 294 | 7 |  |  |  |  | 9 | shift @{ $self->{ranges} }; | 
|  | 7 |  |  |  |  | 10 |  | 
| 295 | 7 |  |  |  |  | 13 | undef $self->{position}; | 
| 296 |  |  |  |  |  |  | } else { | 
| 297 | 54 |  |  |  |  | 60 | $self->{position}++; | 
| 298 |  |  |  |  |  |  | } | 
| 299 | 61 | 100 |  |  |  | 150 | return wantarray ? (@$self{qw(book chapter)}, $position) : $position; | 
| 300 |  |  |  |  |  |  | } | 
| 301 |  |  |  |  |  |  |  | 
| 302 |  |  |  |  |  |  | #pod =head1 TODO | 
| 303 |  |  |  |  |  |  | #pod | 
| 304 |  |  |  |  |  |  | #pod =for :list | 
| 305 |  |  |  |  |  |  | #pod * allow L instead of registered abbrevs | 
| 306 |  |  |  |  |  |  | #pod * clean up regex/lists | 
| 307 |  |  |  |  |  |  | #pod * make public the interface to load modules of books and abbreviations | 
| 308 |  |  |  |  |  |  | #pod * make an interface to unload modules | 
| 309 |  |  |  |  |  |  | #pod | 
| 310 |  |  |  |  |  |  | #pod =cut | 
| 311 |  |  |  |  |  |  |  | 
| 312 |  |  |  |  |  |  | 1; | 
| 313 |  |  |  |  |  |  |  | 
| 314 |  |  |  |  |  |  | __END__ |