diff --git a/.gitignore b/.gitignore index 920a4a7..0332f84 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +/dist +/quickdna/*.pyd /target /.hypothesis /.vscode diff --git a/README.md b/README.md index 6f14353..30b62d2 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ Quickdna is a simple, fast library for working with DNA sequences. It is up to 1 translation tasks, in part because it uses a native Rust module (via PyO3) for the translation. However, it exposes an easy-to-use, type-annotated API that should still feel familiar for Biopython users. +⚠ *Quickdna is "pre-1.0" software. Its API is still evolving. For now, if you're interested in using quickdna, we suggest you depend on an [exact version](https://python-poetry.org/docs/dependency-specification/#exact-requirements) or [git `rev`](https://python-poetry.org/docs/dependency-specification/#git-dependencies), so that new releases don't break your code.* + ```python # These are the two main library types. Unlike Biopython, DnaSequence and # ProteinSequence are distinct, though they share a common BaseSequence base class @@ -55,12 +57,20 @@ ProteinSequence(seq='WLNSLD'), ProteinSequence(seq='G*IVLI')) # There is a similar method, `translate_self_frames`, that only returns the # (up to 3) translated frames for this direction, without the reverse complement -# The IUPAC ambiguity code 'N' is supported as well. +# The IUPAC ambiguity codes are supported as well. # Codons with N will translate to a specific amino acid if it is unambiguous, # such as GGN -> G, or the ambiguous amino acid code 'X' if there are multiple # possible translations. >>> DnaSequence("GGNATN").translate() ProteinSequence(seq='GX') + +# The fine-grained ambiguity codes like "R = A or G" are accepted too, and +# translation results are the same as Biopython. In the output, amino acid +# ambiguity code 'B' means "either asparagine or aspartic acid" (N or D). +>>> DnaSequence("RAT").translate() +ProteinSequence(seq='B') + +# To disallow ambiguity codes in translation, try: `.translate(strict=True)` ``` ## Benchmarks @@ -91,10 +101,6 @@ reverse_complement_biopython(covid_genome) | 0.02928ms / iter | 121.55% * It's not yet 1.0 -- the API is liable to change in the future. * It doesn't support reading FASTA files or many of the other tasks Biopython can do, so you'll probably end up still using Biopython or something else to do those tasks. - * It doesn't support the (rarer) IUPAC ambiguity codes like B for non-A nucleotides, - instead only supporting the general N ambiguity code. - * If support for these codes is important to you, please make an issue! It may be possible - to support them, it just isn't a priority right now. ## Installation diff --git a/quickdna/__init__.py b/quickdna/__init__.py index 7313d35..000d08d 100644 --- a/quickdna/__init__.py +++ b/quickdna/__init__.py @@ -1,6 +1,6 @@ import typing as ty -from .quickdna import _translate, _reverse_complement # type: ignore +from .quickdna import _translate, _translate_strict, _reverse_complement, _reverse_complement_strict # type: ignore T = ty.TypeVar("T", bound="BaseSequence") @@ -102,22 +102,31 @@ class ProteinSequence(BaseSequence): class DnaSequence(BaseSequence): """ - A DNA sequence is a sequence of A, T, C, G, or N (ambiguous) nucleotide ASCII bytes. + A DNA sequence is a sequence of A, T, C, G, or IUPAC nucleotide ambiguity code ASCII bytes. """ - def translate(self, table: int = 1) -> ProteinSequence: + def translate(self, table: int = 1, strict: bool = False) -> ProteinSequence: """ Translate a DNA sequence into a protein sequence, using the specified NCBI table ID. Raises ValueError if the table argument is invalid or any characters in this sequence are invalid nucleotides. + + If `strict` is true, then the input must be all `ATCG`, with no + ambiguous nucleotides. Otherwise, a ValueError is raised. """ - seq = _translate(table, self._seq) + if strict: + seq = _translate_strict(table, self._seq) + else: + seq = _translate(table, self._seq) + return ProteinSequence(seq) - def translate_self_frames(self, table: int = 1) -> ty.List[ProteinSequence]: + def translate_self_frames( + self, table: int = 1, strict: bool = False + ) -> ty.List[ProteinSequence]: """ Translate this DNA sequence into up to 3 protein sequences, one for each possible reading frame on this sense. @@ -127,27 +136,32 @@ def translate_self_frames(self, table: int = 1) -> ty.List[ProteinSequence]: and a sequence of length 2 has none. Can raise ValueError, see `self.translate()` + + If `strict` is true, then the input must be all `ATCG`, with no + ambiguous nucleotides. Otherwise, a ValueError is raised. """ if len(self) >= 5: return [ - self.translate(table), - self[1:].translate(table), - self[2:].translate(table), + self.translate(table, strict), + self[1:].translate(table, strict), + self[2:].translate(table, strict), ] elif len(self) == 4: return [ - self.translate(table), - self[1:].translate(table), + self.translate(table, strict), + self[1:].translate(table, strict), ] elif len(self) == 3: return [ - self.translate(table), + self.translate(table, strict), ] else: return [] - def translate_all_frames(self, table: int = 1) -> ty.List[ProteinSequence]: + def translate_all_frames( + self, table: int = 1, strict: bool = False + ) -> ty.List[ProteinSequence]: """ Translate this DNA sequence into at most 6 protein sequences, one for each possible reading frame on this sense and the reverse complement. @@ -157,21 +171,32 @@ def translate_all_frames(self, table: int = 1) -> ty.List[ProteinSequence]: and a sequence of length 2 has none. Can raise ValueError, see `self.translate()` + + If `strict` is true, then the input must be all `ATCG`, with no + ambiguous nucleotides. Otherwise, a ValueError is raised. """ return [ - *self.translate_self_frames(table=table), - *self.reverse_complement().translate_self_frames(table=table), + *self.translate_self_frames(table=table, strict=strict), + *self.reverse_complement().translate_self_frames( + table=table, strict=strict + ), ] - def reverse_complement(self) -> "DnaSequence": + def reverse_complement(self, strict: bool = False) -> "DnaSequence": """ Takes the reverse complement of a DNA sequence. Raises ValueError if any character in this sequence is an invalid nucleotide. + + If `strict` is true, then the input must be all `ATCG`, with no + ambiguous nucleotides. Otherwise, a ValueError is raised. """ - seq = _reverse_complement(self._seq) + if strict: + seq = _reverse_complement_strict(self._seq) + else: + seq = _reverse_complement(self._seq) return DnaSequence(seq) diff --git a/src/bin/gen_table.rs b/src/bin/gen_table.rs index 49123d5..4eb6c8c 100644 --- a/src/bin/gen_table.rs +++ b/src/bin/gen_table.rs @@ -2,11 +2,11 @@ //! Should be run from the repository root. //! Translation table via Wikipedia. -use std::fs; +use std::{collections::HashSet, fs}; use quickdna::{ trans_table::{CodonIdx, TranslationTable}, - Codon, Nucleotide, + CodonAmbiguous, Nucleotide, NucleotideAmbiguous, NucleotideLike, }; // via https://en.wikipedia.org/wiki/List_of_genetic_codes @@ -77,45 +77,36 @@ GGA || G || G || G || G || G || G || G || G || G || G || G || G || G || G || G | GGG || G || G || G || G || G || G || G || G || G || G || G || G || G || G || G || G || G || G || G || G || G || G || G || G || G || G || G "; -fn codon_first_n_index(codon: Codon) -> Option { - let codon: [Nucleotide; 3] = codon.into(); - codon - .iter() - .enumerate() - .find_map(|(idx, &n)| if n == Nucleotide::N { Some(idx) } else { None }) -} - fn ambiguous_codon_protein( - codon: Codon, + codon: CodonAmbiguous, table_idx: usize, - translation_tables: [u8; TranslationTable::LOOKUP_SIZE], + translation_tables: &[u8; TranslationTable::LOOKUP_SIZE], ) -> u8 { - match codon.count(Nucleotide::N) { - 0 => panic!("not an ambigious codon: {}", codon), - 1 => { - // try and see if all possible permutations of this codon map to the same protein - let mut seen_protein = None; - let n_index = codon_first_n_index(codon).unwrap(); - - for possible in [Nucleotide::A, Nucleotide::T, Nucleotide::C, Nucleotide::G] { - let mut candidate: [Nucleotide; 3] = codon.into(); - candidate[n_index] = possible; - let codon_idx: usize = CodonIdx::from(candidate).into(); + let mut seen_proteins: HashSet = HashSet::new(); + + for &n1 in codon.0[0].possibilities() { + for &n2 in codon.0[1].possibilities() { + for &n3 in codon.0[2].possibilities() { + let codon_idx: usize = CodonIdx::from([n1, n2, n3]).into(); let candidate_protein = translation_tables[table_idx * TranslationTable::CODONS_PER_TABLE + codon_idx]; - match seen_protein { - None => { - seen_protein = Some(candidate_protein); - } - Some(p) if p == candidate_protein => {} - _ => return b'X', + seen_proteins.insert(candidate_protein); + if seen_proteins.len() >= 3 { + return b'X'; } } - - seen_protein.unwrap() } - // all codons with 2 or more Ns always map to X + } + + let mut seen_vec: Vec = seen_proteins.into_iter().collect(); + seen_vec.sort(); + + match seen_vec.as_slice() { + [single] => *single, + [b'D', b'N'] => b'B', // B = Asx = Asparagine or Aspartic acid + [b'E', b'Q'] => b'Z', // Z = Glx = Glutamine or Glutamic acid + [b'I', b'L'] => b'J', // J = Xle = Leucine or Isoleucine _ => b'X', } } @@ -141,15 +132,16 @@ fn gen_translation_tables() -> [u8; TranslationTable::LOOKUP_SIZE] { } // setup ambiguous codons - for &a in Nucleotide::NUCLEOTIDES.iter() { - for &b in Nucleotide::NUCLEOTIDES.iter() { - for &c in Nucleotide::NUCLEOTIDES.iter() { - if a == Nucleotide::N || b == Nucleotide::N || c == Nucleotide::N { - let codon = Codon([a, b, c]); + for a in NucleotideAmbiguous::ALL { + for b in NucleotideAmbiguous::ALL { + for c in NucleotideAmbiguous::ALL { + if a.is_ambiguous() || b.is_ambiguous() || c.is_ambiguous() { + let codon = CodonAmbiguous([a, b, c]); let codon_idx: usize = CodonIdx::from(codon).into(); for table_idx in 0..TranslationTable::N_TRANS_TABLES { - let protein = ambiguous_codon_protein(codon, table_idx, translation_tables); + let protein = + ambiguous_codon_protein(codon, table_idx, &translation_tables); translation_tables [table_idx * TranslationTable::CODONS_PER_TABLE + codon_idx] = protein; } @@ -164,4 +156,5 @@ fn gen_translation_tables() -> [u8; TranslationTable::LOOKUP_SIZE] { fn main() { let tables = gen_translation_tables(); fs::write("src/tables.dat", tables).expect("failed to write tables.dat"); + println!("Wrote codon translation table data to src/tables.dat."); } diff --git a/src/errors.rs b/src/errors.rs index 86a946f..04dc18e 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -8,6 +8,8 @@ pub enum TranslationError { NonAsciiChar(char), #[error("bad nucleotide: {:?}", .0)] BadNucleotide(char), + #[error("unexpected ambiguous nucleotide: {:?}", .0)] + UnexpectedAmbiguousNucleotide(char), #[error("not a ncbi translation table: {}", .0)] BadTranslationTable(u8), } diff --git a/src/fasta.rs b/src/fasta.rs index bebf047..afc7cee 100644 --- a/src/fasta.rs +++ b/src/fasta.rs @@ -57,7 +57,7 @@ pub struct FastaParseSettings { /// FastaRecord { /// header: "b".to_string(), /// contents: "...".to_string(), - /// line_range: (2, 4), + /// line_range: (2, 4), /// } /// ], /// ); @@ -72,7 +72,7 @@ pub struct FastaParseSettings { /// header: "a\nb".to_string(), /// contents: "...".to_string(), /// line_range: (1, 4), - /// } + /// } /// ], /// ); /// ``` @@ -93,7 +93,7 @@ pub struct FastaParseSettings { /// FastaRecord { /// header: "a".to_string(), /// contents: "sequence".to_string(), - /// line_range: (2, 4), + /// line_range: (2, 4), /// } /// ] /// ); @@ -112,7 +112,7 @@ pub struct FastaParseSettings { /// FastaRecord { /// header: "a".to_string(), /// contents: "sequence".to_string(), - /// line_range: (2, 4), + /// line_range: (2, 4), /// } /// ] /// ); @@ -459,7 +459,7 @@ fn try_parse_header(line: &str) -> Option<&str> { mod tests { use super::*; - use crate::{DnaSequence, ProteinSequence, TranslationError}; + use crate::{DnaSequence, Nucleotide, NucleotideAmbiguous, ProteinSequence, TranslationError}; use std::time::Duration; macro_rules! assert_parse { @@ -1123,7 +1123,7 @@ mod tests { fn test_dna_fasta() { assert_parse!( ">Virus1\nAAAA", - FastaParser::::strict(), + FastaParser::>::strict(), vec![FastaRecord { header: "Virus1".to_string(), contents: "AAAA".parse().unwrap(), @@ -1132,11 +1132,35 @@ mod tests { ); } + #[test] + fn test_dna_fasta_ambiguous() { + assert_parse!( + ">Virus1\nABCD", + FastaParser::>::strict(), + vec![FastaRecord { + header: "Virus1".to_string(), + contents: "ABCD".parse().unwrap(), + line_range: (1, 3), + }] + ); + } + + #[test] + fn test_dna_fasta_strict() { + // Strict as in "when parsing Nucleotide, disallow ambiguity codes". + // No relation to the FastaParser `strict()` call. + assert_parse_err!( + ">Virus1\nABCD", + FastaParser::>::strict(), + FastaParseError::ParseError(TranslationError::UnexpectedAmbiguousNucleotide('B')) + ); + } + #[test] fn test_dna_fasta_multiple() { assert_parse!( ">Virus1\nAAAA\nAAAA\n>Virus2\nCCCC\nCCCC\n", - FastaParser::::strict(), + FastaParser::>::strict(), vec![ FastaRecord { header: "Virus1".to_string(), @@ -1150,13 +1174,29 @@ mod tests { }, ] ); + assert_parse!( + ">Virus1\nAAAA\nAAAA\n>Virus2\nCCCC\nRRRR\n", + FastaParser::>::strict(), + vec![ + FastaRecord { + header: "Virus1".to_string(), + contents: "AAAAAAAA".parse().unwrap(), + line_range: (1, 4), + }, + FastaRecord { + header: "Virus2".to_string(), + contents: "CCCCRRRR".parse().unwrap(), + line_range: (4, 7), + }, + ] + ); } #[test] fn test_dna_dna_whitespace() { assert_parse!( ">Virus1\nAAAA \n", - FastaParser::::strict(), + FastaParser::>::strict(), vec![FastaRecord { header: "Virus1".to_string(), contents: "AAAA".parse().unwrap(), @@ -1165,11 +1205,11 @@ mod tests { ); assert_parse!( - ">Virus1\n AAAA\t\t\n", - FastaParser::::strict(), + ">Virus1\n AAAA\tBCD \t\n", + FastaParser::>::strict(), vec![FastaRecord { header: "Virus1".to_string(), - contents: "AAAA".parse().unwrap(), + contents: "AAAABCD".parse().unwrap(), line_range: (1, 3), }] ); @@ -1179,7 +1219,12 @@ mod tests { fn test_dna_invalid_dna() { assert_parse_err!( ">Virus1\nAAAelephant", - FastaParser::::strict(), + FastaParser::>::strict(), + FastaParseError::ParseError(TranslationError::BadNucleotide('e')) + ); + assert_parse_err!( + ">Virus1\nAAAelephant", + FastaParser::>::strict(), FastaParseError::ParseError(TranslationError::BadNucleotide('e')) ); } @@ -1188,7 +1233,12 @@ mod tests { fn test_dna_invalid_dna_multiple() { assert_parse_err!( ">Virus1\nAAAA\n>Virus2\nAAAAelephant", - FastaParser::::strict(), + FastaParser::>::strict(), + FastaParseError::ParseError(TranslationError::BadNucleotide('e')) + ); + assert_parse_err!( + ">Virus1\nAAAA\n>Virus2\nAAAAelephant", + FastaParser::>::strict(), FastaParseError::ParseError(TranslationError::BadNucleotide('e')) ); } @@ -1197,7 +1247,12 @@ mod tests { fn test_dna_invalid_dna_unicode() { assert_parse_err!( ">Virus1\nAAčCCG\n", - FastaParser::::strict(), + FastaParser::>::strict(), + FastaParseError::ParseError(TranslationError::NonAsciiByte(196)) + ); + assert_parse_err!( + ">Virus1\nAAčCCG\n", + FastaParser::>::strict(), FastaParseError::ParseError(TranslationError::NonAsciiByte(196)) ); } @@ -1239,7 +1294,7 @@ mod tests { fn test_duplicate_header_lines() { assert_parse!( ">Virus1\nAAAA\nAAAA\n>Virus1\nCCCC\nCCCC\n", - FastaParser::::strict(), + FastaParser::>::strict(), vec![ FastaRecord { header: "Virus1".to_string(), diff --git a/src/nucleotide.rs b/src/nucleotide.rs index 89e633e..168f6dc 100644 --- a/src/nucleotide.rs +++ b/src/nucleotide.rs @@ -2,23 +2,90 @@ use std::fmt::{self, Write}; use crate::errors::TranslationError; -/// A DNA nucleotide, or the IUPAC ambiguity code 'N'. +/// A DNA nucleotide. /// -/// Sorts in ATCGN order, not alphabetical. +/// Sorts in ATCG order, not alphabetical. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, std::hash::Hash)] #[repr(u8)] pub enum Nucleotide { - A = 0, - T = 1, - C = 2, - G = 3, - /// IUPAC ambiguity code - N = 4, + A = 0b0001, + T = 0b0010, + C = 0b0100, + G = 0b1000, } +/// A DNA nucleotide, or an IUPAC ambiguity code representing a set of possible nucleotides. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, std::hash::Hash)] +#[repr(u8)] +pub enum NucleotideAmbiguous { + A = Nucleotide::A as u8, + T = Nucleotide::T as u8, + C = Nucleotide::C as u8, + G = Nucleotide::G as u8, + + W = Nucleotide::A as u8 | Nucleotide::T as u8, + M = Nucleotide::A as u8 | Nucleotide::C as u8, + R = Nucleotide::A as u8 | Nucleotide::G as u8, // purines + Y = Nucleotide::T as u8 | Nucleotide::C as u8, // pyrimidines + S = Nucleotide::C as u8 | Nucleotide::G as u8, + K = Nucleotide::T as u8 | Nucleotide::G as u8, + + B = Nucleotide::T as u8 | Nucleotide::C as u8 | Nucleotide::G as u8, // not A + V = Nucleotide::A as u8 | Nucleotide::C as u8 | Nucleotide::G as u8, // not T + D = Nucleotide::A as u8 | Nucleotide::T as u8 | Nucleotide::G as u8, // not C + H = Nucleotide::A as u8 | Nucleotide::T as u8 | Nucleotide::C as u8, // not G + + N = Nucleotide::A as u8 | Nucleotide::T as u8 | Nucleotide::C as u8 | Nucleotide::G as u8, +} + +pub trait NucleotideLike: + Copy + Eq + Into + Into + TryFrom +{ + fn complement(self) -> Self; + fn bits(self) -> u8; + fn to_ascii(self) -> u8; + fn is_ambiguous(self) -> bool; +} + +const fn ascii_to_nucleotide_table() -> [Option; 256] { + // PERF: This was previously a 128-byte array, with "high" bytes eliminated + // by a separate check. But extending it to 256 elements makes Rust realize + // it's safe to index with any u8-cast-to-usize and eliminate a bounds check + // from the generated code. + let mut pack_table = [None; 256]; + + macro_rules! insert { + ($chr:literal, $variant:expr) => { + pack_table[$chr.to_ascii_uppercase() as usize] = Some($variant); + pack_table[$chr.to_ascii_lowercase() as usize] = Some($variant); + }; + } + + insert!(b'a', NucleotideAmbiguous::A); + insert!(b't', NucleotideAmbiguous::T); + insert!(b'c', NucleotideAmbiguous::C); + insert!(b'g', NucleotideAmbiguous::G); + + // ambiguity codes + insert!(b'n', NucleotideAmbiguous::N); // A, T, C, or G (complement N) + insert!(b'm', NucleotideAmbiguous::M); // A or C (complement K) + insert!(b'r', NucleotideAmbiguous::R); // A or G (complement Y) + insert!(b'w', NucleotideAmbiguous::W); // A or T (complement W, itself) + insert!(b's', NucleotideAmbiguous::S); // C or G (complement S, itself) + insert!(b'y', NucleotideAmbiguous::Y); // C or T (complement R) + insert!(b'k', NucleotideAmbiguous::K); // G or T (complement M) + insert!(b'v', NucleotideAmbiguous::V); // A, C or G (complement B) + insert!(b'h', NucleotideAmbiguous::H); // A, C or T (complement D) + insert!(b'd', NucleotideAmbiguous::D); // A, G or T (complement H) + insert!(b'b', NucleotideAmbiguous::B); // C, G or T (complement V) + + pack_table +} + +const ASCII_TO_NUCLEOTIDE: [Option; 256] = ascii_to_nucleotide_table(); + impl Nucleotide { - pub const NUCLEOTIDES: [Self; 5] = [Self::A, Self::T, Self::C, Self::G, Self::N]; - const N_NUCLEOTIDES: u8 = Self::NUCLEOTIDES.len() as u8; + pub const ALL: [Self; 4] = [Self::A, Self::T, Self::C, Self::G]; pub const PURINES: [Self; 2] = [Self::A, Self::G]; pub const PYRIMIDINES: [Self; 2] = [Self::C, Self::T]; @@ -26,59 +93,160 @@ impl Nucleotide { pub const M_AMBIGUITY: [Self; 2] = [Self::A, Self::C]; pub const R_AMBIGUITY: [Self; 2] = Self::PURINES; pub const W_AMBIGUITY: [Self; 2] = [Self::A, Self::T]; - pub const S_AMBIGUITY: [Self; 2] = [Self::C, Self::G]; pub const Y_AMBIGUITY: [Self; 2] = Self::PYRIMIDINES; - pub const K_AMBIGUITY: [Self; 2] = [Self::G, Self::T]; pub const V_AMBIGUITY: [Self; 3] = [Self::A, Self::C, Self::G]; pub const H_AMBIGUITY: [Self; 3] = [Self::A, Self::C, Self::T]; pub const D_AMBIGUITY: [Self; 3] = [Self::A, Self::G, Self::T]; pub const B_AMBIGUITY: [Self; 3] = [Self::C, Self::G, Self::T]; +} + +impl NucleotideLike for Nucleotide { + fn complement(self) -> Self { + match self { + Self::A => Self::T, + Self::T => Self::A, + Self::C => Self::G, + Self::G => Self::C, + } + } + + fn bits(self) -> u8 { + self as u8 + } + + fn to_ascii(self) -> u8 { + match self { + Self::A => b'A', + Self::T => b'T', + Self::C => b'C', + Self::G => b'G', + } + } - const fn ascii_pack_table() -> [u8; 128] { - let mut pack_table = [255u8; 128]; + fn is_ambiguous(self) -> bool { + false + } +} - macro_rules! insert { - ($chr:literal, $variant:expr) => { - pack_table[$chr.to_ascii_uppercase() as usize] = $variant as u8; - pack_table[$chr.to_ascii_lowercase() as usize] = $variant as u8; - }; +impl NucleotideAmbiguous { + pub const ALL: [Self; 15] = [ + Self::A, + Self::T, + Self::W, + Self::C, + Self::M, + Self::Y, + Self::H, + Self::G, + Self::R, + Self::K, + Self::D, + Self::S, + Self::V, + Self::B, + Self::N, + ]; + + pub const fn possibilities(self) -> &'static [Nucleotide] { + match self { + Self::A => &[Nucleotide::A], + Self::T => &[Nucleotide::T], + Self::C => &[Nucleotide::C], + Self::G => &[Nucleotide::G], + Self::W => &[Nucleotide::A, Nucleotide::T], + Self::M => &[Nucleotide::A, Nucleotide::C], + Self::R => &[Nucleotide::A, Nucleotide::G], + Self::Y => &[Nucleotide::T, Nucleotide::C], + Self::S => &[Nucleotide::C, Nucleotide::G], + Self::K => &[Nucleotide::T, Nucleotide::G], + Self::B => &[Nucleotide::T, Nucleotide::C, Nucleotide::G], + Self::V => &[Nucleotide::A, Nucleotide::C, Nucleotide::G], + Self::D => &[Nucleotide::A, Nucleotide::T, Nucleotide::G], + Self::H => &[Nucleotide::A, Nucleotide::T, Nucleotide::C], + Self::N => &[Nucleotide::A, Nucleotide::T, Nucleotide::C, Nucleotide::G], } + } +} - insert!(b'a', Self::A); - insert!(b't', Self::T); - insert!(b'c', Self::C); - insert!(b'g', Self::G); +impl NucleotideLike for NucleotideAmbiguous { + fn complement(self) -> Self { + match self { + Self::A => Self::T, + Self::T => Self::A, + Self::W => Self::W, + Self::C => Self::G, + Self::M => Self::K, + Self::Y => Self::R, + Self::H => Self::D, + Self::G => Self::C, + Self::R => Self::Y, + Self::K => Self::M, + Self::D => Self::H, + Self::S => Self::S, + Self::V => Self::B, + Self::B => Self::V, + Self::N => Self::N, + } + } - // ambiguity codes (all mapped to N for now) - insert!(b'n', Self::N); // A, T, C, or G (complement N) - insert!(b'm', Self::N); // A or C (complement K) - insert!(b'r', Self::N); // A or G (complement Y) - insert!(b'w', Self::N); // A or T (complement W (self)) - insert!(b's', Self::N); // C or G (complement S (self)) - insert!(b'y', Self::N); // C or T (complement R) - insert!(b'k', Self::N); // G or T (complement M) - insert!(b'v', Self::N); // A, C or G (complement B) - insert!(b'h', Self::N); // A, C or T (complement D) - insert!(b'd', Self::N); // A, G or T (complement H) - insert!(b'b', Self::N); // C, G or T (complement V) + fn bits(self) -> u8 { + self as u8 + } - pack_table + fn to_ascii(self) -> u8 { + match self { + Self::A => b'A', + Self::T => b'T', + Self::W => b'W', + Self::C => b'C', + Self::M => b'M', + Self::Y => b'Y', + Self::H => b'H', + Self::G => b'G', + Self::R => b'R', + Self::K => b'K', + Self::D => b'D', + Self::S => b'S', + Self::V => b'V', + Self::B => b'B', + Self::N => b'N', + } } - const ASCII_PACK_TABLE: [u8; 128] = Self::ascii_pack_table(); + fn is_ambiguous(self) -> bool { + (self as usize).count_ones() > 1 + } +} - const COMPLEMENT_TABLE: [Self; Self::N_NUCLEOTIDES as usize] = - [Self::T, Self::A, Self::G, Self::C, Self::N]; - pub const fn complement(self) -> Self { - Self::COMPLEMENT_TABLE[self as u8 as usize] +impl From for NucleotideAmbiguous { + #[inline(always)] + fn from(value: Nucleotide) -> Self { + match value { + Nucleotide::A => Self::A, + Nucleotide::T => Self::T, + Nucleotide::C => Self::C, + Nucleotide::G => Self::G, + } } +} - const ASCII_MAP: [u8; Self::N_NUCLEOTIDES as usize] = [b'A', b'T', b'C', b'G', b'N']; - pub const fn to_ascii(self) -> u8 { - Self::ASCII_MAP[self as usize] +impl TryFrom for Nucleotide { + type Error = TranslationError; + + #[inline(always)] + fn try_from(value: NucleotideAmbiguous) -> Result { + match value { + NucleotideAmbiguous::A => Ok(Self::A), + NucleotideAmbiguous::T => Ok(Self::T), + NucleotideAmbiguous::C => Ok(Self::C), + NucleotideAmbiguous::G => Ok(Self::G), + other => Err(TranslationError::UnexpectedAmbiguousNucleotide( + other.into(), + )), + } } } @@ -87,17 +255,29 @@ impl TryFrom for Nucleotide { #[inline(always)] fn try_from(u: u8) -> Result { - if u < 128 { - let v = Self::ASCII_PACK_TABLE[u as usize]; - if v < Self::N_NUCLEOTIDES { - // SAFETY: there are only X variants, with assigned numbers, so 0..=(X - 1) - // are valid reprs of this type - Ok(unsafe { std::mem::transmute(v) }) - } else { - Err(TranslationError::BadNucleotide(u.into())) - } - } else { - Err(TranslationError::NonAsciiByte(u)) + if u >= 128 { + return Err(TranslationError::NonAsciiByte(u)); + } + + match ASCII_TO_NUCLEOTIDE[u as usize] { + Some(na) => Nucleotide::try_from(na), + None => Err(TranslationError::BadNucleotide(u.into())), + } + } +} + +impl TryFrom for NucleotideAmbiguous { + type Error = TranslationError; + + #[inline(always)] + fn try_from(u: u8) -> Result { + if u >= 128 { + return Err(TranslationError::NonAsciiByte(u)); + } + + match ASCII_TO_NUCLEOTIDE[u as usize] { + Some(na) => Ok(na), + None => Err(TranslationError::BadNucleotide(u.into())), } } } @@ -114,46 +294,33 @@ impl From for char { } } -impl fmt::Display for Nucleotide { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_char((*self).into()) +impl From for u8 { + fn from(n: NucleotideAmbiguous) -> Self { + n.to_ascii() } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, std::hash::Hash)] -pub struct Codon(pub [Nucleotide; 3]); - -impl Codon { - /// How many of the specified nucleotide this codon includes - pub fn count(&self, n: Nucleotide) -> usize { - let mut count = 0; - if self.0[0] == n { - count += 1 - } - if self.0[1] == n { - count += 1 - } - if self.0[2] == n { - count += 1 - } - count +impl From for char { + fn from(n: NucleotideAmbiguous) -> Self { + n.to_ascii() as char } +} - /// Whether the codon includes `N` - pub fn is_ambiguous(&self) -> bool { - self.count(Nucleotide::N) > 0 +impl fmt::Display for Nucleotide { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_char((*self).into()) } +} - /// Returns an iterator of all codons, including ambiguous codons with `N` - pub fn all_codons() -> impl Iterator { - const N: [Nucleotide; 5] = Nucleotide::NUCLEOTIDES; - N.iter().flat_map(move |&a| { - N.iter() - .flat_map(move |&b| N.iter().map(move |&c| Codon([a, b, c]))) - }) +impl fmt::Display for NucleotideAmbiguous { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_char((*self).into()) } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, std::hash::Hash)] +pub struct Codon(pub [Nucleotide; 3]); + impl TryFrom<[u8; 3]> for Codon { type Error = TranslationError; @@ -177,3 +344,43 @@ impl fmt::Display for Codon { write!(f, "{}{}{}", self.0[0], self.0[1], self.0[2]) } } + +#[derive(Debug, Clone, Copy, PartialEq, Eq, std::hash::Hash)] +pub struct CodonAmbiguous(pub [NucleotideAmbiguous; 3]); + +impl TryFrom<[u8; 3]> for CodonAmbiguous { + type Error = TranslationError; + + fn try_from(value: [u8; 3]) -> Result { + Ok(Self([ + NucleotideAmbiguous::try_from(value[0])?, + NucleotideAmbiguous::try_from(value[1])?, + NucleotideAmbiguous::try_from(value[2])?, + ])) + } +} + +impl From for [NucleotideAmbiguous; 3] { + fn from(c: CodonAmbiguous) -> Self { + c.0 + } +} + +impl fmt::Display for CodonAmbiguous { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}{}{}", self.0[0], self.0[1], self.0[2]) + } +} + +impl CodonAmbiguous { + pub fn possibilities(&self) -> impl Iterator + '_ { + self.0[0].possibilities().iter().flat_map(move |&a| { + self.0[1].possibilities().iter().flat_map(move |&b| { + self.0[2] + .possibilities() + .iter() + .map(move |&c| Codon([a, b, c])) + }) + }) + } +} diff --git a/src/python_api.rs b/src/python_api.rs index 774744e..12b876e 100644 --- a/src/python_api.rs +++ b/src/python_api.rs @@ -5,6 +5,7 @@ use pyo3::{exceptions::PyValueError, prelude::*, types::PyBytes}; use crate::{ errors::TranslationError, trans_table::{reverse_complement_bytes, TranslationTable}, + Nucleotide, NucleotideAmbiguous, }; impl From for PyErr { @@ -19,16 +20,52 @@ fn _check_table(table: u8) -> PyResult<()> { Ok(()) } +/// Translate a bytestring of DNA nucleotides into a bytestring of amino acids. +/// +/// The input string is allowed to contain IUPAC ambiguity codes; ambiguous +/// codons are represented by `X` in the output. +/// +/// * `translate(b"CCNTACACK CATNCNAAT")` returns `b"PYTHXN"` #[pyfunction] fn _translate(py: Python, table: u8, dna: &PyBytes) -> PyResult { let table = TranslationTable::try_from(table)?; - let bytes = table.translate_dna_bytes(dna.as_bytes())?; + let bytes = table.translate_dna_bytes::(dna.as_bytes())?; Ok(PyBytes::new(py, &bytes).into()) } +/// Translate a bytestring of DNA nucleotides into a bytestring of amino acids. +/// +/// The input string is validated to consist of unambiguous nucleotides (no IUPAC ambiguity codes). +/// +/// * `translate_strict(b"AAACCCTTTGGG")` returns `b"KPFG"` +/// * `translate_strict(b"AAACCCTTTGGN")` is an error. +#[pyfunction] +fn _translate_strict(py: Python, table: u8, dna: &PyBytes) -> PyResult { + let table = TranslationTable::try_from(table)?; + let bytes = table.translate_dna_bytes::(dna.as_bytes())?; + Ok(PyBytes::new(py, &bytes).into()) +} + +/// Get the reverse complement of a bytestring of DNA nucleotides. +/// +/// The input string is allowed to contain IUPAC ambiguity codes. +/// +/// * `reverse_complement(b"AAAAABCCC")` returns `b"GGGVTTTTT"` #[pyfunction] fn _reverse_complement(py: Python, dna: &PyBytes) -> PyResult { - let bytes = reverse_complement_bytes(dna.as_bytes())?; + let bytes = reverse_complement_bytes::(dna.as_bytes())?; + Ok(PyBytes::new(py, &bytes).into()) +} + +/// Get the reverse complement of a bytestring of DNA nucleotides. +/// +/// The input string is validated to consist of unambiguous nucleotides (no IUPAC ambiguity codes). +/// +/// * `reverse_complement_strict(b"AAAAAACCC")` returns `b"GGGTTTTTT"` +/// * `reverse_complement_strict(b"AAAAAACCN")` is an error. +#[pyfunction] +fn _reverse_complement_strict(py: Python, dna: &PyBytes) -> PyResult { + let bytes = reverse_complement_bytes::(dna.as_bytes())?; Ok(PyBytes::new(py, &bytes).into()) } @@ -36,7 +73,9 @@ fn _reverse_complement(py: Python, dna: &PyBytes) -> PyResult { fn quickdna(_py: Python, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(_check_table, m)?)?; m.add_function(wrap_pyfunction!(_translate, m)?)?; + m.add_function(wrap_pyfunction!(_translate_strict, m)?)?; m.add_function(wrap_pyfunction!(_reverse_complement, m)?)?; + m.add_function(wrap_pyfunction!(_reverse_complement_strict, m)?)?; Ok(()) } diff --git a/src/rust_api.rs b/src/rust_api.rs index baaed7f..c419f53 100644 --- a/src/rust_api.rs +++ b/src/rust_api.rs @@ -5,7 +5,9 @@ use std::str::FromStr; use smallvec::SmallVec; pub use crate::errors::TranslationError; -pub use crate::nucleotide::{Codon, Nucleotide}; +pub use crate::nucleotide::{ + Codon, CodonAmbiguous, Nucleotide, NucleotideAmbiguous, NucleotideLike, +}; pub use crate::trans_table::TranslationTable; use crate::trans_table::reverse_complement; @@ -134,13 +136,13 @@ impl FromStr for ProteinSequence { } #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, std::hash::Hash)] -pub struct DnaSequence { - dna: Vec, +pub struct DnaSequence { + dna: Vec, } -impl DnaSequence { +impl DnaSequence { /// Construct a new DnaSequence from a Vec of nucleotides - pub fn new(dna: Vec) -> Self { + pub fn new(dna: Vec) -> Self { Self { dna } } @@ -211,13 +213,13 @@ impl DnaSequence { self.dna.windows(length).map(|w| Self::new(w.to_vec())) } - pub fn push(&mut self, n: Nucleotide) { + pub fn push(&mut self, n: T) { self.dna.push(n); } } -impl BaseSequence for DnaSequence { - type Item = Nucleotide; +impl BaseSequence for DnaSequence { + type Item = T; fn as_slice(&self) -> &[Self::Item] { &self.dna @@ -228,9 +230,10 @@ impl BaseSequence for DnaSequence { } } -impls!(DnaSequence); +impls!(DnaSequence); +impls!(DnaSequence); -impl fmt::Display for DnaSequence { +impl fmt::Display for DnaSequence { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { for &n in &self.dna { f.write_char(n.into())?; @@ -239,7 +242,7 @@ impl fmt::Display for DnaSequence { } } -impl TryFrom<&[u8]> for DnaSequence { +impl TryFrom<&[u8]> for DnaSequence { type Error = TranslationError; fn try_from(value: &[u8]) -> Result { @@ -248,14 +251,14 @@ impl TryFrom<&[u8]> for DnaSequence { for &b in value { if b != b' ' && b != b'\t' { - vec.push(Nucleotide::try_from(b)?); + vec.push(T::try_from(b)?); } } Ok(Self::new(vec)) } } -impl TryFrom> for DnaSequence { +impl TryFrom> for DnaSequence { type Error = TranslationError; fn try_from(value: Vec) -> Result { @@ -263,7 +266,7 @@ impl TryFrom> for DnaSequence { } } -impl FromStr for DnaSequence { +impl FromStr for DnaSequence { type Err = TranslationError; fn from_str(s: &str) -> Result { @@ -284,7 +287,11 @@ mod tests { }; } - fn dna(dna: &str) -> DnaSequence { + fn dna(dna: &str) -> DnaSequence { + DnaSequence::from_str(dna).unwrap() + } + + fn dna_strict(dna: &str) -> DnaSequence { DnaSequence::from_str(dna).unwrap() } @@ -302,7 +309,7 @@ mod tests { fn test_dna_parses() { for c in 0_u8..128 { let c = char::from(c); - let r = DnaSequence::from_str(&String::from(c)); + let r = DnaSequence::::from_str(&String::from(c)); if "aAtTcCgGmMrRwWsSyYkKvVhHdDbBnN \t".chars().any(|x| x == c) { assert!( r.is_ok(), @@ -317,12 +324,48 @@ mod tests { } } + #[test] + fn test_dna_parses_strict() { + for c in 0_u8..128 { + let c = char::from(c); + let r = DnaSequence::::from_str(&String::from(c)); + if "aAtTcCgG \t".chars().any(|x| x == c) { + assert!( + r.is_ok(), + "{c:?} should be a valid nucleotide, or allowed whitespace" + ); + } else { + assert!( + r.is_err(), + "{c:?} should *not* be a valid nucleotide, or allowed whitespace" + ); + } + } + } + #[test] fn test_translate() { assert_eq!( dna("AAAGGGAAA").translate(TranslationTable::Ncbi1), protein("KGK") ); + assert_eq!( + dna_strict("AAAGGGAAA").translate(TranslationTable::Ncbi1), + protein("KGK") + ); + } + + #[test] + fn test_translate_ambiguous() { + // R means "A or G" and both {TTA,TTG} map to L (Leucine). + // Thus, "TTR" should map to L. + // + // But V means "A or G or C", and TTC maps to F (Phenylalanine). + // Thus, "TTV" is truly ambiguous and maps to X. + assert_eq!( + dna("TTR TTV").translate(TranslationTable::Ncbi1), + protein("LX") + ); } #[test] @@ -332,6 +375,11 @@ mod tests { dna("AAAGGGAAA").translate_self_frames(TranslationTable::Ncbi1), smallvec![protein("KGK"), protein("KG"), protein("RE"),] ); + assert_eq_smallvec!( + 3, + dna_strict("AAAGGGAAA").translate_self_frames(TranslationTable::Ncbi1), + smallvec![protein("KGK"), protein("KG"), protein("RE"),] + ); } #[test] @@ -361,6 +409,33 @@ mod tests { .is_empty()); } + #[test] + fn test_short_translate_self_strict() { + assert_eq_smallvec!( + 3, + dna_strict("GGGG").translate_self_frames(TranslationTable::Ncbi1), + smallvec![protein("G"), protein("G"),] + ); + + assert_eq_smallvec!( + 3, + dna_strict("GGG").translate_self_frames(TranslationTable::Ncbi1), + smallvec![protein("G"),] + ); + + assert!(dna_strict("GG") + .translate_self_frames(TranslationTable::Ncbi1) + .is_empty()); + + assert!(dna_strict("G") + .translate_self_frames(TranslationTable::Ncbi1) + .is_empty()); + + assert!(dna_strict("") + .translate_self_frames(TranslationTable::Ncbi1) + .is_empty()); + } + #[test] fn test_translate_all() { assert_eq_smallvec!( @@ -375,6 +450,18 @@ mod tests { protein("SL"), ] ); + assert_eq_smallvec!( + 6, + dna_strict("AAAGGGAAA").translate_all_frames(TranslationTable::Ncbi1), + smallvec![ + protein("KGK"), + protein("KG"), + protein("RE"), + protein("FPF"), + protein("FP"), + protein("SL"), + ] + ); } #[test] @@ -404,6 +491,33 @@ mod tests { .is_empty()); } + #[test] + fn test_short_translate_all_strict() { + assert_eq_smallvec!( + 6, + dna_strict("GGGG").translate_all_frames(TranslationTable::Ncbi1), + smallvec![protein("G"), protein("G"), protein("P"), protein("P"),] + ); + + assert_eq_smallvec!( + 6, + dna_strict("GGG").translate_all_frames(TranslationTable::Ncbi1), + smallvec![protein("G"), protein("P"),] + ); + + assert!(dna_strict("GG") + .translate_all_frames(TranslationTable::Ncbi1) + .is_empty()); + + assert!(dna_strict("G") + .translate_all_frames(TranslationTable::Ncbi1) + .is_empty()); + + assert!(dna_strict("") + .translate_all_frames(TranslationTable::Ncbi1) + .is_empty()); + } + #[test] fn test_dna_equality() { let d1 = dna("aaa"); @@ -414,6 +528,16 @@ mod tests { assert_eq!(d1, d3); } + #[test] + fn test_dna_equality_strict() { + let d1 = dna_strict("aaa"); + let d2 = dna_strict("aaa"); + let d3 = dna_strict("aAa"); + + assert_eq!(d1, d2); + assert_eq!(d1, d3); + } + #[test] fn test_protein_equality() { let p1 = protein("aaa"); @@ -428,6 +552,14 @@ mod tests { fn test_protein_case() { assert_eq!(dna("GGG").translate(TranslationTable::Ncbi1), protein("g")); assert_eq!(dna("GGG").translate(TranslationTable::Ncbi1), protein("G")); + assert_eq!( + dna_strict("GGG").translate(TranslationTable::Ncbi1), + protein("g") + ); + assert_eq!( + dna_strict("GGG").translate(TranslationTable::Ncbi1), + protein("G") + ); } #[test] @@ -442,6 +574,18 @@ mod tests { assert_eq!(hash(&p1), hash(&p2)); } + #[test] + fn test_hash_strict() { + let d1 = dna_strict("aaa"); + let d2 = dna_strict("aaa"); + let p1 = protein("aaa"); + let p2 = protein("aaa"); + + assert_eq!(hash(&d1), hash(&d2)); + assert!(hash(&d1) != hash(&p1)); + assert_eq!(hash(&p1), hash(&p2)); + } + #[test] fn test_dna_windows() { let d = dna("gcantacctaangtnattag"); @@ -465,6 +609,29 @@ mod tests { assert_eq!(dna("antg").windows(10).next(), None); } + #[test] + fn test_dna_windows_strict() { + let d = dna_strict("gcactacctaacgtcattag"); + assert_eq!( + d.windows(10).collect::>(), + vec![ + dna_strict("gcactaccta"), + dna_strict("cactacctaa"), + dna_strict("actacctaac"), + dna_strict("ctacctaacg"), + dna_strict("tacctaacgt"), + dna_strict("acctaacgtc"), + dna_strict("cctaacgtca"), + dna_strict("ctaacgtcat"), + dna_strict("taacgtcatt"), + dna_strict("aacgtcatta"), + dna_strict("acgtcattag"), + ] + ); + + assert_eq!(dna_strict("actg").windows(10).next(), None); + } + #[test] fn test_protein_windows() { let p = protein("gcantacctaangtnattag"); @@ -495,6 +662,10 @@ mod tests { dna(" gcantac\tctaangtnattag "); dna(" gca ntac ctaangtnattag \t"); + dna_strict("gcactacctaacgtcattag "); + dna_strict(" gcactac\tctaacgtcattag "); + dna_strict(" gca ctac ctaacgtcattag \t"); + protein("angtnattag "); protein(" angtnattag "); protein(" an gtnattag \t"); diff --git a/src/tables.dat b/src/tables.dat index 369ac5e..b107575 100644 --- a/src/tables.dat +++ b/src/tables.dat @@ -1 +1 @@ -KNNKX***IIIMX***TTTTT***RSSRX***XXXXX****************************YY*X***LFFLX***SSSSS****CCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***MIIMX***TTTTT****SS*X***XXXXX****************************YY*X***LFFLX***SSSSS***WCCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***MIIMX***TTTTT***RSSRX***XXXXX****************************YY*X***LFFLX***SSSSS***WCCWX***XXXXX***************************QHHQX***TTTTT***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX****************************YY*X***LFFLX***SSSSS***WCCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***MIIMX***TTTTT***SSSSS***XXXXX****************************YY*X***LFFLX***SSSSS***WCCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX***************************QYYQX***LFFLX***SSSSS****CCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXNNNKX***IIIMX***TTTTT***SSSSS***XXXXX****************************YY*X***LFFLX***SSSSS***WCCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX****************************YY*X***LFFLX***SSSSS***CCCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX****************************YY*X***LFFLX***SSSSS****CCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX****************************YY*X***LFFLX***SSSSS****CCWX***XXXXX***************************QHHQX***LLLSX***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***MIIMX***TTTTT***GSSGX***XXXXX****************************YY*X***LFFLX***SSSSS***WCCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXNNNKX***IIIMX***TTTTT***SSSSS***XXXXX***************************YYY*X***LFFLX***SSSSS***WCCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX****************************YYQX***LFFLX***SSSSS****CCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX****************************YYLX***LFFLX***SSSSS****CCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXNNNKX***MIIMX***TTTTT***SSSSS***XXXXX****************************YY*X***LFFLX***SSSSS***WCCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX****************************YYLX***LFFLX****SSSX****CCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX****************************YY*X****FFLX***SSSSS****CCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***SSSKX***XXXXX****************************YY*X***LFFLX***SSSSS***WCCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX****************************YY*X***LFFLX***SSSSS***GCCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX****************************YY*X***LFFLX***SSSSS****CCWX***XXXXX***************************QHHQX***LLLAX***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX***************************QYYQX***LFFLX***SSSSS***WCCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX***************************QYYQX***LFFLX***SSSSS***WCCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX***************************YYYYY***LFFLX***SSSSS****CCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX***************************EYYEX***LFFLX***SSSSS****CCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX***************************EYYEX***LFFLX***SSSSS***WCCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***RSSRX***XXXXX****************************YYWX***LFFLX***SSSSS****CCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXXKNNKX***IIIMX***TTTTT***SSSKX***XXXXX***************************YYY*X***LFFLX***SSSSS***WCCWX***XXXXX***************************QHHQX***LLLLL***PPPPP***RRRRR***XXXXX***************************EDDEX***VVVVV***AAAAA***GGGGG***XXXXX***************************XXXXX***XXXXX***XXXXX***XXXXX***XXXXX \ No newline at end of file +*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX**CXCXCXWXXXXXXX**XXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*MIXIXIXMMXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX**SXSXSX**XXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*WCXCXCXWWXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XJXJXJXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*MIXIXIXMMXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*WCXCXCXWWXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*WCXCXCXWWXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*MIXIXIXMMXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*WCXCXCXWWXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XJXJXJXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QYXYXYXQQXXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX**CXCXCXWXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QXXXXXXQQXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************NNNNNNNKXXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*WCXCXCXWWXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*CCCCCCCWXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX**CXCXCXWXXXXXXX**XXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX**CXCXCXWXXXXXXX**XXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLSXXXXXXX*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*MIXIXIXMMXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GSXSXSXGGXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*WCXCXCXWWXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XJXJXJXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GXXXXXXGGXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************NNNNNNNKXXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************YYYYYYY*XXXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*WCXCXCXWWXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYXQXXXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX**CXCXCXWXXXXXXX**XXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXQXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXZXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXZXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYXLXXXXXXX*LFXFXFXLLXXXXXX*XXXXXXXLXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX**CXCXCXWXXXXXXX**XXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************NNNNNNNKXXXXXXX*MIXIXIXMMXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*WCXCXCXWWXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XJXJXJXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYXLXXXXXXX*LFXFXFXLLXXXXXX*XXXXXXXLXXXXXXX**SXSXSXSXSXSXSX**XXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX**CXCXCXWXXXXXXX**XXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX**XXXXXXXXXXXXXX**XXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX**FXFXFXLXXXXXXX**XXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX**CXCXCXWXXXXXXX**XXXXXXXXXXXXXX**XXXXXXXXXXXXXX**XXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXLXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSKXXXXXXX*XXXXXXXKXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*WCXCXCXWWXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GCXCXCXWXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYX**XXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX**CXCXCXWXXXXXXX**XXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLAXXXXXXX*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QYXYXYXQQXXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*WCXCXCXWWXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QXXXXXXQQXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QYXYXYXQQXXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*WCXCXCXWWXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QXXXXXXQQXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************YYYYYYYYYYYYYYY*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX**CXCXCXWXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EYXYXYXEEXXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX**CXCXCXWXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EXXXXXXEEXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EYXYXYXEEXXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*WCXCXCXWWXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EXXXXXXEEXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RSXSXSXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX******************YXYXYXWXXXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX**CXCXCXWXXXXXXX**XXXXXXWXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RXXXXXXRRXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*********************************************************************************************************************************************************************************************************************************************************************************KNXNXNXKKXXXXXX*IIIIIIIMXXXXXXX*XXXXXXXXXXXXXXX*TTTTTTTTTTTTTTT*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSKXXXXXXX*XXXXXXXKXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************YYYYYYY*XXXXXXX*LFXFXFXLLXXXXXX*XXXXXXXXXXXXXXX*SSSSSSSSSSSSSSS*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*WCXCXCXWWXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************QHXHXHXQQXXXXXX*LLLLLLLLLLLLLLL*XXXXXXXXXXXXXXX*PPPPPPPPPPPPPPP*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*RRRRRRRRRRRRRRR*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JJJJJJJXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*LXXXXXXLLXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*JXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************EDXDXDXEEXXXXXX*VVVVVVVVVVVVVVV*XXXXXXXXXXXXXXX*AAAAAAAAAAAAAAA*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*GGGGGGGGGGGGGGG*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XBXBXBXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************ZXXXXXXZZXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*****************XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX*XXXXXXXXXXXXXXX \ No newline at end of file diff --git a/src/trans_table.rs b/src/trans_table.rs index b88373a..c5517fb 100644 --- a/src/trans_table.rs +++ b/src/trans_table.rs @@ -1,48 +1,83 @@ use crate::{ errors::TranslationError, - nucleotide::{Codon, Nucleotide}, + nucleotide::{Codon, CodonAmbiguous, NucleotideLike}, }; +/// Identifies a translation table for turning codons into amino acids. +/// See: https://en.wikipedia.org/wiki/List_of_genetic_codes #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum TranslationTable { + /// The standard code Ncbi1, + /// The vertebrate mitochondrial code Ncbi2, + /// The yeast mitochondrial code Ncbi3, + /// The mold, protozoan, and coelenterate mitochondrial code and the mycoplasma/spiroplasma code Ncbi4, + /// The invertebrate mitochondrial code Ncbi5, + /// The ciliate, dasycladacean and hexamita nuclear code Ncbi6, + /// The kinetoplast code; cf. table 4. Ncbi7, + /// Same as table 1. Ncbi8, + /// The echinoderm and flatworm mitochondrial code Ncbi9, + /// The euplotid nuclear code Ncbi10, + /// The bacterial, archaeal and plant plastid code Ncbi11, + /// The alternative yeast nuclear code Ncbi12, + /// The ascidian mitochondrial code Ncbi13, + /// The alternative flatworm mitochondrial code Ncbi14, + /// The Blepharisma nuclear code Ncbi15, + /// The chlorophycean mitochondrial code Ncbi16, + // tables 17-20 are not assigned + /// The trematode mitochondrial code Ncbi21, + /// The Scenedesmus obliquus mitochondrial code Ncbi22, + /// The Thraustochytrium mitochondrial code Ncbi23, + /// The Pterobranchia mitochondrial code Ncbi24, + /// The candidate division SR1 and gracilibacteria code Ncbi25, + /// The Pachysolen tannophilus nuclear code Ncbi26, + /// The karyorelict nuclear code Ncbi27, + /// The Condylostoma nuclear code Ncbi28, + /// The Mesodinium nuclear code Ncbi29, + /// The Peritrich nuclear code Ncbi30, + /// The Blastocrithidia nuclear code Ncbi31, + /// The Balanophoraceae plastid code Ncbi32, + /// The Cephalodiscidae mitochondrial code Ncbi33, } #[repr(transparent)] pub struct CodonIdx(usize); -impl From<[Nucleotide; 3]> for CodonIdx { - fn from(value: [Nucleotide; 3]) -> Self { - Self((value[0] as usize) << 6 | (value[1] as usize) << 3 | (value[2] as usize)) +impl From<[T; 3]> for CodonIdx { + fn from(value: [T; 3]) -> Self { + let v0 = value[0].bits() as usize; + let v1 = value[1].bits() as usize; + let v2 = value[2].bits() as usize; + Self((v0 << 8) | (v1 << 4) | v2) } } @@ -52,6 +87,12 @@ impl From for CodonIdx { } } +impl From for CodonIdx { + fn from(c: CodonAmbiguous) -> Self { + c.0.into() + } +} + impl From for usize { fn from(c: CodonIdx) -> Self { c.0 @@ -59,9 +100,8 @@ impl From for usize { } impl TranslationTable { - /// There are really only 125 possible codons (len(ATCGN)^3), but since codons take up - /// 3 bits, the maximum codon value is 0b100100100, so we need some holes in the table. - pub const CODONS_PER_TABLE: usize = 293; + /// Each ambiguity code is represented by 4 bits, so there are (2^4)^3 codons per table. + pub const CODONS_PER_TABLE: usize = 1 << 12; // Number of NCBI translation tables (they go up to 33, but there's gaps in the numbering) pub const N_TRANS_TABLES: usize = 27; pub const LOOKUP_SIZE: usize = Self::CODONS_PER_TABLE * Self::N_TRANS_TABLES; @@ -102,7 +142,10 @@ impl TranslationTable { } } - pub fn translate_dna_bytes(self, dna: &[u8]) -> Result, TranslationError> { + pub fn translate_dna_bytes( + self, + dna: &[u8], + ) -> Result, TranslationError> { if dna.is_empty() { return Ok(Vec::new()); } @@ -115,9 +158,9 @@ impl TranslationTable { // biopython also truncates, but warns -- generally I don't think we care, // so I just made it silently truncate for chunk in dna.chunks_exact(3) { - let a = chunk[0].try_into()?; - let b = chunk[1].try_into()?; - let c = chunk[2].try_into()?; + let a: T = chunk[0].try_into()?; + let b: T = chunk[1].try_into()?; + let c: T = chunk[2].try_into()?; let codon_idx = CodonIdx::from([a, b, c]); result.push( Self::TRANSLATION_TABLES @@ -128,7 +171,7 @@ impl TranslationTable { Ok(result) } - pub fn translate_dna(self, dna: &[Nucleotide]) -> Vec { + pub fn translate_dna(self, dna: &[T]) -> Vec { if dna.is_empty() { return Vec::new(); } @@ -141,7 +184,7 @@ impl TranslationTable { // biopython also truncates, but warns -- generally I don't think we care, // so I just made it silently truncate for chunk in dna.chunks_exact(3) { - let sized_chunk: [Nucleotide; 3] = [chunk[0], chunk[1], chunk[2]]; + let sized_chunk: [T; 3] = [chunk[0], chunk[1], chunk[2]]; let codon_idx = CodonIdx::from(sized_chunk); result.push( Self::TRANSLATION_TABLES @@ -192,19 +235,21 @@ impl TryFrom for TranslationTable { } } -pub fn reverse_complement_bytes(dna: &[u8]) -> Result, TranslationError> { +pub fn reverse_complement_bytes( + dna: &[u8], +) -> Result, TranslationError> { let mut v = vec![0u8; dna.len()]; for (i, &b) in dna.iter().enumerate() { - let n = Nucleotide::try_from(b)?; + let n = T::try_from(b)?; v[dna.len() - 1 - i] = n.complement().to_ascii(); } Ok(v) } -pub fn reverse_complement(dna: &[Nucleotide]) -> Vec { - let mut v = vec![Nucleotide::N; dna.len()]; - for (i, &n) in dna.iter().enumerate() { - v[dna.len() - 1 - i] = n.complement(); - } - v +// Perf: it looks like .collect() gets great codegen here, but not when dealing +// with Result as it would in `reverse_complement_bytes` above. Here, it beats +// writing something like `let mut v = vec![T::default(), dna.len()];` which +// wastes time doing a memset before filling the Vec. +pub fn reverse_complement(dna: &[T]) -> Vec { + dna.iter().rev().map(|n| n.complement()).collect() } diff --git a/tests/test_exhaustive.py b/tests/test_exhaustive.py index 8c2f9d4..c31decd 100644 --- a/tests/test_exhaustive.py +++ b/tests/test_exhaustive.py @@ -7,7 +7,7 @@ from quickdna import DnaSequence from .utils import valid_tables -NUCLEOTIDES = "ATCGN" +NUCLEOTIDES = "ATCGWMRYSKBVDHN" def test_exhaustive(): @@ -19,4 +19,4 @@ def test_exhaustive(): qd_trans = chr(DnaSequence(dna).translate(table=table)[0]) bp_trans = str(Seq(dna).translate(table=table))[0] - assert qd_trans == bp_trans, dna + assert qd_trans == bp_trans, f"Testing {dna} in table {table}" diff --git a/tests/test_wrapper.py b/tests/test_wrapper.py index 8b1790d..edcb312 100644 --- a/tests/test_wrapper.py +++ b/tests/test_wrapper.py @@ -135,3 +135,20 @@ def test_iter(): p_src = "kgkg" * 20 assert list(ProteinSequence(p_src)) == list(p_src) + + +def test_reverse_complement(): + rc = DnaSequence("AAAGGGGGG").reverse_complement() + assert rc == DnaSequence("CCCCCCTTT") + rc = DnaSequence("AAABBBGGG").reverse_complement() + assert rc == DnaSequence("CCCVVVTTT") + with pytest.raises(ValueError): + DnaSequence("AAABBBGGG").reverse_complement(strict=True) + + +def test_strict(): + assert DnaSequence("AAAGGGAAA").translate(table=1, strict=True) == ProteinSequence( + "KGK" + ) + with pytest.raises(ValueError): + DnaSequence("AAABBBAAA").translate(table=1, strict=True)