From 07b573df79601dab3bbb933258693f5afd55c55c Mon Sep 17 00:00:00 2001 From: Manuel Holtgrewe Date: Mon, 20 Feb 2023 17:47:38 +0100 Subject: [PATCH] feat: implement AlignmentMapper (#14) (#15) --- Cargo.toml | 1 + src/data/interface.rs | 39 +- src/data/mod.rs | 7 +- src/data/uta.rs | 123 ++- src/lib.rs | 2 + src/mapper/alignment.rs | 1028 ++++++++++++++++++++ src/mapper/cigar.rs | 565 +++++++++++ src/mapper/mod.rs | 3 + src/mapper/variant.rs | 85 ++ src/parser/display.rs | 92 +- src/parser/ds.rs | 143 ++- src/parser/impl_ops.rs | 16 + src/parser/impl_parse.rs | 38 +- src/parser/mod.rs | 80 +- src/parser/parse_funcs.rs | 116 +-- src/static_data/mod.rs | 5 + src/validator/mod.rs | 89 ++ tests/data/data/bootstrap.sh | 14 +- tests/data/data/uta_20210129-subset.pgd.gz | Bin 78023 -> 86584 bytes 19 files changed, 2240 insertions(+), 206 deletions(-) create mode 100644 src/mapper/alignment.rs create mode 100644 src/mapper/cigar.rs create mode 100644 src/mapper/mod.rs create mode 100644 src/mapper/variant.rs create mode 100644 src/parser/impl_ops.rs create mode 100644 src/validator/mod.rs diff --git a/Cargo.toml b/Cargo.toml index 1563b4c..3c158aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,5 +13,6 @@ linked-hash-map = "0.5.6" nom = "7.1.3" postgres = { version = "0.19.4", features = ["with-chrono-0_4"] } pretty_assertions = "1.3.0" +regex = "1.7.1" serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.93" diff --git a/src/data/interface.rs b/src/data/interface.rs index 10a0442..8073702 100644 --- a/src/data/interface.rs +++ b/src/data/interface.rs @@ -15,7 +15,7 @@ use crate::static_data::Assembly; /// aliases | AT1,ATA,ATC,ATD,ATE,ATDC,TEL1,TELO1 /// added | 2014-02-04 21:39:32.57125 /// ``` -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Default, Clone)] pub struct GeneInfoRecord { pub hgnc: String, pub maploc: String, @@ -44,7 +44,7 @@ pub struct GeneInfoRecord { /// structure means that the transcripts are defined on the same /// reference sequence and have the same exon spans on that /// sequence. -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Default, Clone)] pub struct TxSimilarityRecord { /// Accession of first transcript. pub tx_ac1: String, @@ -81,7 +81,7 @@ pub struct TxSimilarityRecord { /// alt_exon_id | 6063334 /// exon_aln_id | 3461425 ///``` -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Default, Clone)] pub struct TxExonsRecord { pub hgnc: String, pub tx_ac: String, @@ -111,7 +111,7 @@ pub struct TxExonsRecord { /// start_i | 95226307 /// end_i | 95248406 /// ``` -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Default, Clone)] pub struct TxForRegionRecord { pub tx_ac: String, pub alt_ac: String, @@ -130,7 +130,7 @@ pub struct TxForRegionRecord { /// lengths | {707,79,410} /// hgnc | VSX1 /// ``` -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Default, Clone)] pub struct TxIdentityInfo { pub tx_ac: String, pub alt_ac: String, @@ -149,7 +149,7 @@ pub struct TxIdentityInfo { /// alt_ac | AC_000143.1 /// alt_aln_method | splign /// ``` -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Default, Clone)] pub struct TxInfoRecord { pub hgnc: String, pub cds_start_i: Option, @@ -169,14 +169,15 @@ pub struct TxInfoRecord { /// alt_ac | NC_000012.11 /// alt_aln_method | genebuild /// ``` -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Default, Clone)] pub struct TxMappingOptionsRecord { pub tx_ac: String, pub alt_ac: String, pub alt_aln_method: String, } -pub trait Interface { +/// Interface for data providers. +pub trait Provider { /// Return the data version, e.g., `uta_20180821`. fn data_version(&self) -> &str; @@ -198,7 +199,7 @@ pub trait Interface { /// # Arguments /// /// * `hgnc` - HGNC gene name - fn get_gene_info(&mut self, hgnc: &str) -> Result; + fn get_gene_info(&self, hgnc: &str) -> Result; /// Return the (single) associated protein accession for a given transcript accession, /// or None if not found. @@ -206,14 +207,14 @@ pub trait Interface { /// # Arguments /// /// * `tx_ac` -- transcript accession with version (e.g., 'NM_000051.3') - fn get_pro_ac_for_tx_ac(&mut self, tx_ac: &str) -> Result, anyhow::Error>; + fn get_pro_ac_for_tx_ac(&self, tx_ac: &str) -> Result, anyhow::Error>; /// Return full sequence for the given accession. /// /// # Arguments /// /// * `ac` -- accession - fn get_seq(&mut self, ac: &str) -> Result; + fn get_seq(&self, ac: &str) -> Result; /// Return sequence part for the given accession. /// @@ -223,7 +224,7 @@ pub trait Interface { /// * `start` -- start position (0-based, start of sequence if missing) /// * `end` -- end position (0-based, end of sequence if missing) fn get_seq_part( - &mut self, + &self, ac: &str, begin: Option, end: Option, @@ -236,7 +237,7 @@ pub trait Interface { /// /// * `tx_ac` -- transcript accession with version (e.g., 'NM_000051.3') fn get_similar_transcripts( - &mut self, + &self, tx_ac: &str, ) -> Result, anyhow::Error>; @@ -249,7 +250,7 @@ pub trait Interface { /// * `alt_ac` -- specific genomic sequence (e.g., NC_000011.4) /// * `alt_aln_method` -- sequence alignment method (e.g., splign, blat) fn get_tx_exons( - &mut self, + &self, tx_ac: &str, alt_ac: &str, alt_aln_method: &str, @@ -260,7 +261,7 @@ pub trait Interface { /// # Arguments /// /// * `gene` - HGNC gene name - fn get_tx_for_gene(&mut self, gene: &str) -> Result, anyhow::Error>; + fn get_tx_for_gene(&self, gene: &str) -> Result, anyhow::Error>; /// Return transcripts that overlap given region. /// @@ -271,7 +272,7 @@ pub trait Interface { // * `start_i` -- 5' bound of region // * `end_i` -- 3' bound of region fn get_tx_for_region( - &mut self, + &self, alt_ac: &str, alt_aln_method: &str, start_i: i32, @@ -283,7 +284,7 @@ pub trait Interface { /// # Arguments /// /// * `tx_ac` -- transcript accession with version (e.g., 'NM_199425.2') - fn get_tx_identity_info(&mut self, tx_ac: &str) -> Result; + fn get_tx_identity_info(&self, tx_ac: &str) -> Result; /// Return a single transcript info for supplied accession (tx_ac, alt_ac, alt_aln_method), or None if not found. /// @@ -293,7 +294,7 @@ pub trait Interface { /// * `alt_ac -- specific genomic sequence (e.g., NC_000011.4) /// * `alt_aln_method` -- sequence alignment method (e.g., splign, blat) fn get_tx_info( - &mut self, + &self, tx_ac: &str, alt_ac: &str, alt_aln_method: &str, @@ -308,7 +309,7 @@ pub trait Interface { /// /// * `tx_ac` -- transcript accession with version (e.g., 'NM_000051.3') fn get_tx_mapping_options( - &mut self, + &self, tax_ac: &str, ) -> Result, anyhow::Error>; } diff --git a/src/data/mod.rs b/src/data/mod.rs index 4a1d104..da2d2ba 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -1,6 +1,3 @@ ///! Datatypes, interfaces, and data acess. -mod interface; -mod uta; - -pub use interface::*; -pub use uta::*; +pub mod interface; +pub mod uta; diff --git a/src/data/uta.rs b/src/data/uta.rs index c0ddf41..f6c0a9e 100644 --- a/src/data/uta.rs +++ b/src/data/uta.rs @@ -5,12 +5,14 @@ use linked_hash_map::LinkedHashMap; use postgres::{Client, NoTls, Row}; use std::fmt::Debug; +use std::sync::Mutex; use crate::static_data::{Assembly, ASSEMBLY_INFOS}; -use super::{ - GeneInfoRecord, Interface, TxExonsRecord, TxForRegionRecord, TxIdentityInfo, TxInfoRecord, - TxMappingOptionsRecord, TxSimilarityRecord, +use crate::data::{ + interface::GeneInfoRecord, interface::Provider as ProviderInterface, interface::TxExonsRecord, + interface::TxForRegionRecord, interface::TxIdentityInfo, interface::TxInfoRecord, + interface::TxMappingOptionsRecord, interface::TxSimilarityRecord, }; /// Configurationf or the `data::uta::Provider`. @@ -157,7 +159,7 @@ pub struct Provider { /// Configuration for the access. config: Config, /// Connection to the postgres database. - conn: Client, + conn: Mutex, /// The schema version, set on creation. schema_version: String, } @@ -174,8 +176,9 @@ impl Debug for Provider { impl Provider { pub fn with_config(config: &Config) -> Result { let config = config.clone(); - let mut conn = Client::connect(&config.db_url, NoTls)?; - let schema_version = Self::fetch_schema_version(&mut conn, &config.db_schema)?; + let conn = Mutex::new(Client::connect(&config.db_url, NoTls)?); + let schema_version = + Self::fetch_schema_version(&mut conn.lock().unwrap(), &config.db_schema)?; Ok(Self { config, conn, @@ -190,7 +193,7 @@ impl Provider { } } -impl Interface for Provider { +impl ProviderInterface for Provider { fn data_version(&self) -> &str { &self.config.db_schema } @@ -208,32 +211,39 @@ impl Interface for Provider { ) } - fn get_gene_info(&mut self, hgnc: &str) -> Result { + fn get_gene_info(&self, hgnc: &str) -> Result { let sql = format!( "SELECT * FROM {}.gene WHERE hgnc = $1", self.config.db_schema ); - self.conn.query_one(&sql, &[&hgnc])?.try_into() + self.conn + .lock() + .unwrap() + .query_one(&sql, &[&hgnc])? + .try_into() } - fn get_pro_ac_for_tx_ac(&mut self, tx_ac: &str) -> Result, anyhow::Error> { + fn get_pro_ac_for_tx_ac(&self, tx_ac: &str) -> Result, anyhow::Error> { let sql = format!( "SELECT pro_ac FROM {}.associated_accessions \ WHERE tx_ac = $1 ORDER BY pro_ac DESC", self.config.db_schema ); - if let Some(row) = (self.conn.query(&sql, &[&tx_ac])?).into_iter().next() { + if let Some(row) = (self.conn.lock().unwrap().query(&sql, &[&tx_ac])?) + .into_iter() + .next() + { return Ok(Some(row.try_get("pro_ac")?)); } Ok(None) } - fn get_seq(&mut self, ac: &str) -> Result { + fn get_seq(&self, ac: &str) -> Result { self.get_seq_part(ac, None, None) } fn get_seq_part( - &mut self, + &self, ac: &str, begin: Option, end: Option, @@ -242,13 +252,23 @@ impl Interface for Provider { "SELECT seq_id FROM {}.seq_anno WHERE ac = $1", self.config.db_schema ); - let seq_id: String = self.conn.query_one(&sql, &[&ac])?.try_get("seq_id")?; + let seq_id: String = self + .conn + .lock() + .unwrap() + .query_one(&sql, &[&ac])? + .try_get("seq_id")?; let sql = format!( "SELECT seq FROM {}.seq WHERE seq_id = $1", self.config.db_schema ); - let seq: String = self.conn.query_one(&sql, &[&seq_id])?.try_get("seq")?; + let seq: String = self + .conn + .lock() + .unwrap() + .query_one(&sql, &[&seq_id])? + .try_get("seq")?; let begin = begin.unwrap_or_default(); let end = end @@ -258,9 +278,9 @@ impl Interface for Provider { } fn get_similar_transcripts( - &mut self, + &self, tx_ac: &str, - ) -> Result, anyhow::Error> { + ) -> Result, anyhow::Error> { let sql = format!( "SELECT * FROM {}.tx_similarity_v \ WHERE tx_ac1 = $1 \ @@ -268,27 +288,31 @@ impl Interface for Provider { self.config.db_schema ); let mut result = Vec::new(); - for row in self.conn.query(&sql, &[&tx_ac])? { + for row in self.conn.lock().unwrap().query(&sql, &[&tx_ac])? { result.push(row.try_into()?); } Ok(result) } fn get_tx_exons( - &mut self, + &self, tx_ac: &str, alt_ac: &str, alt_aln_method: &str, - ) -> Result, anyhow::Error> { + ) -> Result, anyhow::Error> { let sql = format!( "SELECT * FROM {}.tx_exon_aln_v \ WHERE tx_ac = $1 AND alt_ac = $2 and alt_aln_method = $3 \ - ORDER BY tx_start_i, tx_end_i, alt_start_i, alt_end_i, \ - tx_exon_set_id, alt_exon_set_id", + ORDER BY alt_start_i", self.config.db_schema ); let mut result = Vec::new(); - for row in self.conn.query(&sql, &[&tx_ac, &alt_ac, &alt_aln_method])? { + for row in self + .conn + .lock() + .unwrap() + .query(&sql, &[&tx_ac, &alt_ac, &alt_aln_method])? + { result.push(row.try_into()?); } if result.is_empty() { @@ -303,7 +327,7 @@ impl Interface for Provider { } } - fn get_tx_for_gene(&mut self, gene: &str) -> Result, anyhow::Error> { + fn get_tx_for_gene(&self, gene: &str) -> Result, anyhow::Error> { let sql = format!( "SELECT hgnc, cds_start_i, cds_end_i, tx_ac, alt_ac, alt_aln_method \ FROM {}.transcript T \ @@ -313,14 +337,14 @@ impl Interface for Provider { self.config.db_schema, self.config.db_schema, ); let mut result = Vec::new(); - for row in self.conn.query(&sql, &[&gene])? { + for row in self.conn.lock().unwrap().query(&sql, &[&gene])? { result.push(row.try_into()?); } Ok(result) } fn get_tx_for_region( - &mut self, + &self, alt_ac: &str, alt_aln_method: &str, start_i: i32, @@ -338,7 +362,12 @@ impl Interface for Provider { self.config.db_schema, self.config.db_schema, ); let mut result = Vec::new(); - for row in self.conn.query(&sql, &[&alt_ac, &start_i, &end_i])? { + for row in self + .conn + .lock() + .unwrap() + .query(&sql, &[&alt_ac, &start_i, &end_i])? + { let record: TxForRegionRecord = row.try_into()?; // NB: The original Python code did not use alt_aln_method in the query either. if record.alt_aln_method == alt_aln_method { @@ -348,7 +377,7 @@ impl Interface for Provider { Ok(result) } - fn get_tx_identity_info(&mut self, tx_ac: &str) -> Result { + fn get_tx_identity_info(&self, tx_ac: &str) -> Result { let sql = format!( "SELECT DISTINCT(tx_ac), alt_ac, alt_aln_method, cds_start_i, \ cds_end_i, lengths, hgnc \ @@ -357,11 +386,15 @@ impl Interface for Provider { ORDER BY tx_ac, alt_ac, alt_aln_method, cds_start_i, cds_end_i, lengths, hgnc", self.config.db_schema ); - self.conn.query_one(&sql, &[&tx_ac])?.try_into() + self.conn + .lock() + .unwrap() + .query_one(&sql, &[&tx_ac])? + .try_into() } fn get_tx_info( - &mut self, + &self, tx_ac: &str, alt_ac: &str, alt_aln_method: &str, @@ -375,12 +408,14 @@ impl Interface for Provider { self.config.db_schema, self.config.db_schema, ); self.conn + .lock() + .unwrap() .query_one(&sql, &[&tx_ac, &alt_ac, &alt_aln_method])? .try_into() } fn get_tx_mapping_options( - &mut self, + &self, tx_ac: &str, ) -> Result, anyhow::Error> { let sql = format!( @@ -391,7 +426,7 @@ impl Interface for Provider { self.config.db_schema ); let mut result = Vec::new(); - for row in self.conn.query(&sql, &[&tx_ac])? { + for row in self.conn.lock().unwrap().query(&sql, &[&tx_ac])? { result.push(row.try_into()?); } Ok(result) @@ -400,7 +435,7 @@ impl Interface for Provider { #[cfg(test)] mod test { - use crate::{data::Interface, static_data::Assembly}; + use crate::{data::interface::Provider as ProviderInterface, static_data::Assembly}; use super::{Config, Provider}; @@ -441,7 +476,7 @@ mod test { #[test] fn get_gene_info() -> Result<(), anyhow::Error> { - let mut provider = Provider::with_config(&get_config())?; + let provider = Provider::with_config(&get_config())?; assert_eq!( format!("{:?}", provider.get_gene_info("OMA1")?), @@ -456,7 +491,7 @@ mod test { #[test] fn get_pro_ac_for_tx_ac() -> Result<(), anyhow::Error> { - let mut provider = Provider::with_config(&get_config())?; + let provider = Provider::with_config(&get_config())?; assert_eq!( provider.get_pro_ac_for_tx_ac("NM_130831.2")?, @@ -469,7 +504,7 @@ mod test { #[test] fn get_seq() -> Result<(), anyhow::Error> { - let mut provider = Provider::with_config(&get_config())?; + let provider = Provider::with_config(&get_config())?; assert_eq!(provider.get_seq("NM_001354664.1")?.len(), 6386); @@ -478,7 +513,7 @@ mod test { #[test] fn get_seq_part() -> Result<(), anyhow::Error> { - let mut provider = Provider::with_config(&get_config())?; + let provider = Provider::with_config(&get_config())?; assert_eq!( provider @@ -492,7 +527,7 @@ mod test { #[test] fn get_similar_transcripts() -> Result<(), anyhow::Error> { - let mut provider = Provider::with_config(&get_config())?; + let provider = Provider::with_config(&get_config())?; let records = provider.get_similar_transcripts("NM_001354664.1")?; @@ -509,7 +544,7 @@ mod test { #[test] fn get_tx_exons() -> Result<(), anyhow::Error> { - let mut provider = Provider::with_config(&get_config())?; + let provider = Provider::with_config(&get_config())?; let records = provider.get_tx_exons("NM_001354664.1", "NC_000003.11", "splign")?; @@ -529,7 +564,7 @@ mod test { #[test] fn get_tx_for_gene() -> Result<(), anyhow::Error> { - let mut provider = Provider::with_config(&get_config())?; + let provider = Provider::with_config(&get_config())?; let records = provider.get_tx_for_gene("OMA1")?; @@ -546,7 +581,7 @@ mod test { #[test] fn get_tx_for_region() -> Result<(), anyhow::Error> { - let mut provider = Provider::with_config(&get_config())?; + let provider = Provider::with_config(&get_config())?; let records = provider.get_tx_for_region("NC_000001.10", "splign", 58946391, 59012446)?; @@ -563,7 +598,7 @@ mod test { #[test] fn get_tx_identity_info() -> Result<(), anyhow::Error> { - let mut provider = Provider::with_config(&get_config())?; + let provider = Provider::with_config(&get_config())?; let record = provider.get_tx_identity_info("ENST00000421528")?; @@ -579,7 +614,7 @@ mod test { #[test] fn get_tx_info() -> Result<(), anyhow::Error> { - let mut provider = Provider::with_config(&get_config())?; + let provider = Provider::with_config(&get_config())?; let record = provider.get_tx_info("ENST00000421528", "NC_000001.10", "genebuild")?; @@ -595,7 +630,7 @@ mod test { #[test] fn get_tx_mapping_options() -> Result<(), anyhow::Error> { - let mut provider = Provider::with_config(&get_config())?; + let provider = Provider::with_config(&get_config())?; let records = provider.get_tx_mapping_options("ENST00000421528")?; diff --git a/src/lib.rs b/src/lib.rs index 1f47177..917d65c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,8 @@ pub mod data; +pub mod mapper; pub mod parser; pub mod static_data; +pub mod validator; pub fn add(left: usize, right: usize) -> usize { left + right diff --git a/src/mapper/alignment.rs b/src/mapper/alignment.rs new file mode 100644 index 0000000..23cc4a4 --- /dev/null +++ b/src/mapper/alignment.rs @@ -0,0 +1,1028 @@ +//! Mapping positions between pairs of sequence alignments. +//! +//! `AlignmentMapper` is at the heart of mapping between aligned sequences. + +// Implementation note re: "no-zero correction": HGVS doesn't have a +// 0. Counting is -3, -2, -1, 1, 2, 3 :-/ Coordinate calculations must +// take this discontinuity in c. positions into account. The +// implementation of imaginary transcript positions creates a second +// discontinuity. (By analogy with c., n.0 is declared to not exist.) +// The strategy used in this code is to use internal c0 and n0 +// coordinates, which include 0, for coordinate calculations and to +// translate these to c. and n. positions as needed. +// +// imag. imag. +// upstream 5' UTR CDS 3' UTR downstr +// |> +// - - - - - - ———————————— ||||||||||||||||| ——————————— - - - - - - +// a b C D E f g h i +// c. -4 -3 -2 -1 ! 1 2 3 ! *1 *2 *3 *4 +// c0 -4 -3 -2 -1 0 1 2 3 4 5 6 +// n0 -2 -1 0 1 2 3 4 5 6 7 8 +// n. -2 -1 ! 1 2 3 4 5 6 7 8 9 +// g. ... 123 124 125 126 127 128 129 130 131 132 133 ... + +use std::rc::Rc; + +use crate::{ + data::interface::{Provider, TxExonsRecord}, + parser::{CdsInterval, CdsPos, GenomeInterval, Mu, TxInterval, TxPos}, +}; + +use super::cigar::{ + parse_cigar_string, CigarElement, CigarMapper, CigarMapperResult, CigarOp, CigarString, +}; + +/// Convert zero-based coordinate to hgvs (1 based, missing zero) +fn zbc_to_hgvs(i: i32) -> i32 { + if i >= 0 { + i + 1 + } else { + i + } +} + +/// Convert hgvs (1 based, missing zero) +fn hgvs_to_zbc(i: i32) -> i32 { + if i >= 1 { + i - 1 + } else { + i + } +} + +/// Builds a single CIGAR string representing an alignment of the transcript sequence to a +/// reference sequence, including introns. +/// +/// The input exons are expected to be in transcript order, and the resulting CIGAR is also +/// in transcript order. +pub fn build_tx_cigar( + exons: &Vec, + strand: i16, +) -> Result { + if exons.is_empty() { + return Err(anyhow::anyhow!( + "Cannot build CIGAR string from empty exons" + )); + } + + // Parse CIGAR string and flip if on reverse strand. + let exon_cigars: Result, anyhow::Error> = exons + .iter() + .map(|record| { + let mut cigar = parse_cigar_string(&record.cigar)?; + if strand == -1 { + cigar.reverse(); + } + Ok(cigar) + }) + .collect(); + let exon_cigars = exon_cigars?; + + let mut result = exon_cigars[0].clone(); // exon 1 + for i in 1..exon_cigars.len() { + result.push(CigarElement { + count: exons[i].alt_start_i - exons[i - 1].alt_end_i, + op: CigarOp::Skip, + }); + result.append(&mut exon_cigars[i].clone()); + } + Ok(result) +} + +/// Helper function that wraps a value into `Option` but returns `None` for the default value. +pub fn none_if_default(value: T) -> Option +where + T: Default + PartialEq, +{ + if value == T::default() { + None + } else { + Some(value) + } +} + +/// Configuration for mapping. +pub struct Config { + /// Require transcript variants to be within transcript sequence bounds. + pub strict_bounds: bool, +} + +impl Default for Config { + fn default() -> Self { + Self { + strict_bounds: true, + } + } +} + +/// Map HGVS location objects between genomic (g), non-coding (n) and cds (c) +/// coordinates according to a CIGAR string. +pub struct AlignmentMapper { + /// Configuration for alignment mapping. + pub config: Config, + /// Data provider to use for the mapping. + pub provider: Rc, + + /// The transcript accession. + pub tx_ac: String, + /// The reference sequence asccession. + pub alt_ac: String, + /// The alignment method. + pub alt_aln_method: String, + pub strand: i16, + pub gc_offset: i32, + pub cds_start_i: Option, + pub cds_end_i: Option, + pub tgt_len: i32, + pub cigar_mapper: CigarMapper, +} + +impl AlignmentMapper { + pub fn new( + provider: Rc, + tx_ac: &str, + alt_ac: &str, + alt_aln_method: &str, + ) -> Result { + let (strand, gc_offset, cds_start_i, cds_end_i, tgt_len, cigar_mapper) = + if alt_aln_method != "transcript" { + let tx_info = provider.get_tx_info(tx_ac, alt_ac, alt_aln_method)?; + let tx_exons = { + let tx_exons = provider.get_tx_exons(tx_ac, alt_ac, alt_aln_method)?; + if tx_exons.is_empty() { + return Err(anyhow::anyhow!( + "Found no exons for tx_ac={}, alt_ac={}, alt_aln_method={}", + tx_ac, + alt_ac, + alt_aln_method + )); + } + + // Issue biocommons/hgvs#386: An assumption when building the CIGAR string is that + // exons are adjacent. Assert that here. + let mut sorted_exons = tx_exons.clone(); + sorted_exons.sort_by(|a, b| a.ord.partial_cmp(&b.ord).unwrap()); + let offenders = sorted_exons + .windows(2) + .filter(|pair| { + let lhs = &pair[0]; + let rhs = &pair[1]; + lhs.tx_end_i != rhs.tx_start_i + }) + .collect::>(); + if !offenders.is_empty() { + return Err(anyhow::anyhow!( + "Non-adjacent exons for tx_acc={}, alt_acc={}, alt_aln_method={}: {:?}", + tx_ac, + alt_ac, + alt_aln_method, + &offenders + )); + } + + tx_exons + }; + + let strand = tx_exons[0].alt_strand; + let gc_offset = tx_exons[0].alt_start_i; + let cds_start_i = tx_info.cds_start_i; + let cds_end_i = tx_info.cds_end_i; + + if cds_start_i.is_none() != cds_end_i.is_none() { + return Err(anyhow::anyhow!( + "CDS start and end must both be defined or undefined" + )); + } + + let cigar_mapper = CigarMapper::new(&build_tx_cigar(&tx_exons, strand)?); + let tgt_len = cigar_mapper.tgt_len; + + ( + strand, + gc_offset, + cds_start_i, + cds_end_i, + tgt_len, + cigar_mapper, + ) + } else { + // this covers the identity cases n <-> c + let tx_identity_info = provider.get_tx_identity_info(tx_ac)?; + + let cds_start_i = tx_identity_info.cds_start_i; + let cds_end_i = tx_identity_info.cds_end_i; + let tgt_len: i32 = tx_identity_info.lengths.iter().sum(); + + ( + 1, // strand + 0, // gc_offset + Some(cds_start_i), + Some(cds_end_i), + tgt_len, + Default::default(), + ) + }; + + if cds_start_i.is_none() != cds_end_i.is_none() { + return Err(anyhow::anyhow!( + "CDs start and end position but be both or neither defined." + )); + } + + Ok(AlignmentMapper { + config: Default::default(), + provider, + tx_ac: tx_ac.to_string(), + alt_ac: alt_ac.to_string(), + alt_aln_method: alt_aln_method.to_string(), + cds_start_i, + cds_end_i, + tgt_len, + cigar_mapper, + strand, + gc_offset, + }) + } + + /// Convert a genomic (g.) interval to a transcript (n.) interval. + pub fn g_to_n( + &self, + g_interval: &GenomeInterval, + _strict_bounds: bool, + ) -> Result, anyhow::Error> { + if let GenomeInterval { + start: Some(begin), + end: Some(end), + } = g_interval + { + let grs = begin - 1 - self.gc_offset; + let gre = end - 1 - self.gc_offset; + + // Compute start/end on forward strand with respect to the genome. + // + // frs, fre = (f)orward (r)na (s)tart & (e)nd + let frs = self + .cigar_mapper + .map_ref_to_tgt(grs, "start", self.config.strict_bounds)?; + let fre = self + .cigar_mapper + .map_ref_to_tgt(gre, "end", self.config.strict_bounds)?; + + // Project to reverse strand if necessary. + let (frs, fre) = if self.strand == -1 { + ( + CigarMapperResult { + pos: self.tgt_len - 1 - fre.pos, + offset: -fre.offset, + cigar_op: fre.cigar_op, + }, + CigarMapperResult { + pos: self.tgt_len - 1 - frs.pos, + offset: -frs.offset, + cigar_op: frs.cigar_op, + }, + ) + } else { + (frs, fre) + }; + + // The position is uncertain if the alignment ends in a gap. + let n_interval = TxInterval { + start: TxPos { + base: zbc_to_hgvs(frs.pos), + offset: none_if_default(frs.offset), + }, + end: TxPos { + base: zbc_to_hgvs(fre.pos), + offset: none_if_default(fre.offset), + }, + }; + let result = if frs.cigar_op != CigarOp::Del + && frs.cigar_op != CigarOp::Ins + && fre.cigar_op != CigarOp::Del + && fre.cigar_op != CigarOp::Ins + { + Mu::Certain(n_interval) + } else { + Mu::Uncertain(n_interval) + }; + Ok(result) + } else { + Err(anyhow::anyhow!( + "Cannot project genome interval with missing start or end position: {}", + g_interval + )) + } + } + + /// Convert a transcript (n.) interval to a genomic (g.) interval. + pub fn n_to_g( + &self, + n_interval: &TxInterval, + strict_bounds: bool, + ) -> Result, anyhow::Error> { + let frs = hgvs_to_zbc(n_interval.start.base); + let start_offset = n_interval.start.offset.unwrap_or(0); + let fre = hgvs_to_zbc(n_interval.end.base); + let end_offset = n_interval.end.offset.unwrap_or(0); + + let (fre, frs, start_offset, end_offset) = if self.strand == -1 { + ( + self.tgt_len - 1 - frs, + self.tgt_len - 1 - fre, + -end_offset, + -start_offset, + ) + } else { + (fre, frs, start_offset, end_offset) + }; + + // Obtain the genomic range start (grs) and end (gre). + let grs = self + .cigar_mapper + .map_tgt_to_ref(frs, "start", strict_bounds)?; + let gre = self + .cigar_mapper + .map_tgt_to_ref(fre, "start", strict_bounds)?; + let (grs_pos, gre_pos) = (grs.pos + self.gc_offset + 1, gre.pos + self.gc_offset + 1); + let (gs, ge) = (grs_pos + start_offset, gre_pos + end_offset); + + // The returned interval would be uncertain when locating at alignment gaps. + Ok(Mu::from( + GenomeInterval { + start: Some(gs), + end: Some(ge), + }, + grs.cigar_op != CigarOp::Del + && grs.cigar_op != CigarOp::Ins + && gre.cigar_op != CigarOp::Del + && gre.cigar_op != CigarOp::Ins, + )) + } + + fn pos_n_to_c(&self, pos: &TxPos) -> CdsPos { + let cds_start_i = self.cds_start_i.unwrap(); + let cds_end_i = self.cds_end_i.unwrap(); + if pos.base <= cds_start_i { + CdsPos { + base: pos.base - cds_start_i - (if pos.base > 0 { 1 } else { 0 }), + offset: pos.offset, + cds_from: crate::parser::CdsFrom::Start, + } + } else if pos.base > cds_start_i && pos.base <= cds_end_i { + CdsPos { + base: pos.base - cds_start_i, + offset: pos.offset, + cds_from: crate::parser::CdsFrom::Start, + } + } else { + CdsPos { + base: pos.base - cds_end_i, + offset: pos.offset, + cds_from: crate::parser::CdsFrom::End, + } + } + } + + /// Convert a transcript (n.) interval to a CDS (c.) interval. + pub fn n_to_c( + &self, + n_interval: &TxInterval, + strict_bounds: bool, + ) -> Result { + if self.cds_start_i.is_none() { + return Err(anyhow::anyhow!( + "CDS is undefined for {}; cannot map to c. coordinate (non-coding transcript?)", + self.tx_ac + )); + } + + if strict_bounds && (n_interval.start.base <= 0 || n_interval.end.base > self.tgt_len) { + return Err(anyhow::anyhow!( + "The given coordinate is outside the bounds of the reference sequence." + )); + } + + Ok(CdsInterval { + start: self.pos_n_to_c(&n_interval.start), + end: self.pos_n_to_c(&n_interval.end), + }) + } + + pub fn pos_c_to_n(&self, pos: &CdsPos, strict_bounds: bool) -> Result { + let cds_start_i = self.cds_start_i.unwrap(); + let cds_end_i = self.cds_end_i.unwrap(); + + let n = match pos.cds_from { + crate::parser::CdsFrom::Start => { + let n = pos.base + cds_start_i; + if pos.base < 0 { + // correct for lack of c.0 coordinate + n + 1 + } else { + n + } + } + crate::parser::CdsFrom::End => pos.base + cds_end_i, + }; + + let n = if n <= 0 { + // correct for lack of n.0 coordinate + n - 1 + } else { + n + }; + + if (n <= 0 || n > self.tgt_len) && strict_bounds { + Err(anyhow::anyhow!("c.{:?} coordinate is out of boounds", pos)) + } else { + Ok(TxPos { + base: n, + offset: pos.offset, + }) + } + } + + /// Convert a a CDS (c.) interval to a transcript (n.) interval. + pub fn c_to_n( + &self, + c_interval: &CdsInterval, + strict_bounds: bool, + ) -> Result { + if self.cds_start_i.is_none() { + return Err(anyhow::anyhow!( + "CDS is undefined for {}; cannot map to c. coordinate (non-coding transcript?)", + self.tx_ac + )); + } + + let n_start = self.pos_c_to_n(&c_interval.start, strict_bounds); + let n_end = self.pos_c_to_n(&c_interval.end, strict_bounds); + Ok(TxInterval { + start: n_start?, + end: n_end?, + }) + } + + /// Convert a genomic (g.) interval to a CDS (c.) interval. + pub fn g_to_c( + &self, + g_interval: &GenomeInterval, + strict_bounds: bool, + ) -> Result, anyhow::Error> { + let n_interval = self.g_to_n(g_interval, strict_bounds)?; + Ok(match &n_interval { + Mu::Certain(n_interval) => Mu::Certain(self.n_to_c(n_interval, strict_bounds)?), + Mu::Uncertain(n_interval) => Mu::Uncertain(self.n_to_c(n_interval, strict_bounds)?), + }) + } + + /// Convert a CDS (c.) interval to a genomic (g.) interval. + pub fn c_to_g( + &self, + c_interval: &CdsInterval, + strict_bounds: bool, + ) -> Result, anyhow::Error> { + let n_interval = self.c_to_n(c_interval, strict_bounds)?; + let g_interval = self.n_to_g(&n_interval, strict_bounds)?; + Ok(g_interval) + } + + /// Return the transcript is coding. + pub fn is_coding_transcript(&self) -> bool { + self.cds_start_i.is_some() + } + + /// Return whether the given genome interval is in bounds. + pub fn is_g_interval_in_bounds(&self, g_interval: GenomeInterval) -> bool { + let grs = g_interval.start.unwrap() - 1 - self.gc_offset; + let gre = g_interval.end.unwrap() - 1 - self.gc_offset; + grs >= 0 && gre <= self.cigar_mapper.ref_len + } +} + +#[cfg(test)] +mod test { + use std::{rc::Rc, str::FromStr}; + + use pretty_assertions::assert_eq; + + use crate::{ + data::{ + interface::{Provider as Interface, TxExonsRecord}, + uta::{Config, Provider}, + }, + parser::{CdsFrom, CdsInterval, CdsPos, GenomeInterval, Mu, TxInterval, TxPos}, + }; + + use super::{build_tx_cigar, none_if_default, AlignmentMapper}; + + #[test] + fn build_tx_cigar_empty() { + assert!(build_tx_cigar(&Vec::new(), 1).is_err()); + } + + #[test] + fn build_tx_cigar_forward() -> Result<(), anyhow::Error> { + let exons = vec![ + TxExonsRecord { + tx_start_i: 0, + tx_end_i: 10, + alt_start_i: 100, + alt_end_i: 110, + cigar: "5M1I4M".to_string(), + ..Default::default() + }, + TxExonsRecord { + tx_start_i: 10, + tx_end_i: 21, + alt_start_i: 120, + alt_end_i: 131, + cigar: "7M1I2M".to_string(), + ..Default::default() + }, + ]; + + assert_eq!(format!("{}", &build_tx_cigar(&exons, 1)?), "5MI4M10N7MI2M"); + + Ok(()) + } + + #[test] + fn build_tx_cigar_reverse() -> Result<(), anyhow::Error> { + let exons = vec![ + TxExonsRecord { + tx_start_i: 0, + tx_end_i: 10, + alt_start_i: 100, + alt_end_i: 110, + cigar: "5M1I4M".to_string(), + ..Default::default() + }, + TxExonsRecord { + tx_start_i: 10, + tx_end_i: 21, + alt_start_i: 120, + alt_end_i: 131, + cigar: "7M1I2M".to_string(), + ..Default::default() + }, + ]; + + assert_eq!(format!("{}", &build_tx_cigar(&exons, -1)?), "4MI5M10N2MI7M"); + + Ok(()) + } + + #[test] + fn run_none_if_default() { + assert_eq!(none_if_default(0u32), None); + assert_eq!(none_if_default(1u32), Some(1u32)); + assert_eq!(none_if_default(1i32), Some(1i32)); + assert_eq!(none_if_default(-1i32), Some(-1i32)); + } + + fn get_config() -> Config { + Config { + db_url: std::env::var("TEST_UTA_DATABASE_URL") + .expect("Environment variable TEST_UTA_DATABASE_URL undefined!"), + db_schema: std::env::var("TEST_UTA_DATABASE_SCHEMA") + .expect("Environment variable TEST_UTA_DATABASE_SCHEMA undefined!"), + } + } + + #[test] + fn construction() -> Result<(), anyhow::Error> { + let config = get_config(); + let provider = Provider::with_config(&config)?; + + assert_eq!(provider.data_version(), config.db_schema); + assert_eq!(provider.schema_version(), "1.1"); + + Ok(()) + } + + #[test] + fn failures() -> Result<(), anyhow::Error> { + let config = get_config(); + let provider = Rc::new(Provider::with_config(&config)?); + + // unknown sequences + + assert!(AlignmentMapper::new(provider.clone(), "bogus", "NM_033089.6", "splign").is_err()); + assert!( + AlignmentMapper::new(provider.clone(), "bogus", "NM_033089.6", "transcript").is_err() + ); + assert!(AlignmentMapper::new(provider.clone(), "NM_033089.6", "bogus", "splign").is_err()); + assert!( + AlignmentMapper::new(provider.clone(), "NM_000051.3", "NC_000011.9", "bogus").is_err() + ); + + // invalid intervals + + { + let am = + AlignmentMapper::new(provider.clone(), "NM_000348.3", "NC_000002.11", "splign")?; + assert!(am + .n_to_c( + &TxInterval { + start: TxPos { + base: -1, + offset: None + }, + end: TxPos { + base: -1, + offset: None + }, + }, + true + ) + .is_err()); + } + + { + let am = AlignmentMapper::new(provider, "NM_000348.3", "NC_000002.11", "splign")?; + assert!(am + .c_to_n( + &CdsInterval { + start: CdsPos { + base: 99999, + offset: None, + cds_from: CdsFrom::Start + }, + end: CdsPos { + base: 99999, + offset: None, + cds_from: CdsFrom::Start + }, + }, + true + ) + .is_err()); + } + + Ok(()) + } + + /// Helper for running multiple projection cases. + fn run_test_cases( + tx_ac: &str, + alt_ac: &str, + cases: &Vec<(GenomeInterval, TxInterval, CdsInterval)>, + ) -> Result<(), anyhow::Error> { + let config = get_config(); + let provider = Rc::new(Provider::with_config(&config)?); + let mapper = AlignmentMapper::new(provider, tx_ac, alt_ac, "splign")?; + + for (g_interval, n_interval, c_interval) in cases { + assert_eq!( + c_interval, + mapper.g_to_c(g_interval, true)?.inner(), + "{}~{} {} mapper.g_to_c", + tx_ac, + alt_ac, + &g_interval + ); + assert_eq!( + c_interval, + &mapper.n_to_c(n_interval, true)?, + "{}~{} {} mapper.n_to_c", + tx_ac, + alt_ac, + &n_interval + ); + + assert_eq!( + g_interval, + mapper.c_to_g(c_interval, true)?.inner(), + "{}~{} {} mapper.c_to_g", + tx_ac, + alt_ac, + &c_interval + ); + assert_eq!( + Mu::Certain(g_interval.clone()), + mapper.n_to_g(n_interval, true)?, + "{}~{} {} mapper.n_to_g", + tx_ac, + alt_ac, + &g_interval + ); + + assert_eq!( + n_interval, + &mapper.c_to_n(c_interval, true)?, + "{}~{} {} mapper.c_to_n", + tx_ac, + alt_ac, + &c_interval + ); + assert_eq!( + Mu::Certain(n_interval.clone()), + mapper.g_to_n(g_interval, true)?, + "{}~{} {} mapper.g_to_n", + tx_ac, + alt_ac, + &n_interval + ); + } + + Ok(()) + } + + /// Use NM_178434.2 tests to test mapping with uncertain positions + // #[test] // not yet supported (same as Python package) + fn _test_lce3c_uncertain() -> Result<(), anyhow::Error> { + let tx_ac = "NM_178434.2"; + let alt_ac = "NC_000001.10"; + let test_cases = vec![ + ( + GenomeInterval::from_str("?_152573139")?, + TxInterval::from_str("?_2")?, + CdsInterval::from_str("?_-69")?, + ), + ( + GenomeInterval::from_str("152573138_?")?, + TxInterval::from_str("1_?")?, + CdsInterval::from_str("-70_?")?, + ), + ]; + + run_test_cases(tx_ac, alt_ac, &test_cases)?; + + Ok(()) + } + + /// NM_178434.2: LCE3C single exon, strand = +1, all coordinate input/output are in HGVS + #[test] + fn test_lce3c() -> Result<(), anyhow::Error> { + let tx_ac = "NM_178434.2"; + let alt_ac = "NC_000001.10"; + let test_cases = vec![ + // 5' + ( + GenomeInterval::from_str("152573138")?, + TxInterval::from_str("1")?, + CdsInterval::from_str("-70")?, + ), + ( + GenomeInterval::from_str("152573140")?, + TxInterval::from_str("3")?, + CdsInterval::from_str("-68")?, + ), + // CDS + ( + GenomeInterval::from_str("152573207")?, + TxInterval::from_str("70")?, + CdsInterval::from_str("-1")?, + ), + ( + GenomeInterval::from_str("152573208")?, + TxInterval::from_str("71")?, + CdsInterval::from_str("1")?, + ), + // 3' + ( + GenomeInterval::from_str("152573492")?, + TxInterval::from_str("355")?, + CdsInterval::from_str("285")?, + ), + ( + GenomeInterval::from_str("152573493")?, + TxInterval::from_str("356")?, + CdsInterval::from_str("*1")?, + ), + ( + GenomeInterval::from_str("152573560")?, + TxInterval::from_str("423")?, + CdsInterval::from_str("*68")?, + ), + ( + GenomeInterval::from_str("152573562")?, + TxInterval::from_str("425")?, + CdsInterval::from_str("*70")?, + ), + ]; + + run_test_cases(tx_ac, alt_ac, &test_cases)?; + + Ok(()) + } + + /// NM_033445.2: H2AW single exon, strand = -1, all coordinate input/output are in HGVS + #[test] + fn test_h2a2() -> Result<(), anyhow::Error> { + let tx_ac = "NM_033445.2"; + let alt_ac = "NC_000001.10"; + let test_cases = vec![ + // 3' + ( + GenomeInterval::from_str("228645560")?, + TxInterval::from_str("1")?, + CdsInterval::from_str("-42")?, + ), + ( + GenomeInterval::from_str("228645558")?, + TxInterval::from_str("3")?, + CdsInterval::from_str("-40")?, + ), + // CDS + ( + GenomeInterval::from_str("228645519")?, + TxInterval::from_str("42")?, + CdsInterval::from_str("-1")?, + ), + ( + GenomeInterval::from_str("228645518")?, + TxInterval::from_str("43")?, + CdsInterval::from_str("1")?, + ), + // 5' + ( + GenomeInterval::from_str("228645126")?, + TxInterval::from_str("435")?, + CdsInterval::from_str("393")?, + ), + ( + GenomeInterval::from_str("228645125")?, + TxInterval::from_str("436")?, + CdsInterval::from_str("*1")?, + ), + ( + GenomeInterval::from_str("228645124")?, + TxInterval::from_str("437")?, + CdsInterval::from_str("*2")?, + ), + ( + GenomeInterval::from_str("228645065")?, + TxInterval::from_str("496")?, + CdsInterval::from_str("*61")?, + ), + ]; + + run_test_cases(tx_ac, alt_ac, &test_cases)?; + + Ok(()) + } + + /// NM_014357.4: LCE2B, two exons, strand = +1, all coordinate input/output are in HGVS + #[test] + fn test_lce2b() -> Result<(), anyhow::Error> { + let tx_ac = "NM_014357.4"; + let alt_ac = "NC_000001.10"; + let test_cases = vec![ + // 5' + ( + GenomeInterval::from_str("152658599")?, + TxInterval::from_str("1")?, + CdsInterval::from_str("-54")?, + ), + ( + GenomeInterval::from_str("152658601")?, + TxInterval::from_str("3")?, + CdsInterval::from_str("-52")?, + ), + // CDS + ( + GenomeInterval::from_str("152659319")?, + TxInterval::from_str("54")?, + CdsInterval::from_str("-1")?, + ), + ( + GenomeInterval::from_str("152659320")?, + TxInterval::from_str("55")?, + CdsInterval::from_str("1")?, + ), + // around end of exon 1 + ( + GenomeInterval::from_str("152658632")?, + TxInterval::from_str("34")?, + CdsInterval::from_str("-21")?, + ), + ( + GenomeInterval::from_str("152658633")?, + TxInterval::from_str("34+1")?, + CdsInterval::from_str("-21+1")?, + ), + // span + ( + GenomeInterval::from_str("152658633_152659299")?, + TxInterval::from_str("34+1_35-1")?, + CdsInterval::from_str("-21+1_-20-1")?, + ), + // around start of exon 2 + ( + GenomeInterval::from_str("152659300")?, + TxInterval::from_str("35")?, + CdsInterval::from_str("-20")?, + ), + ( + GenomeInterval::from_str("152659299")?, + TxInterval::from_str("35-1")?, + CdsInterval::from_str("-20-1")?, + ), + // around end of exon 2 + ( + GenomeInterval::from_str("152659652")?, + TxInterval::from_str("387")?, + CdsInterval::from_str("333")?, + ), + ( + GenomeInterval::from_str("152659653")?, + TxInterval::from_str("388")?, + CdsInterval::from_str("*1")?, + ), + // span + ( + GenomeInterval::from_str("152659651_152659654")?, + TxInterval::from_str("386_389")?, + CdsInterval::from_str("332_*2")?, + ), + // 3' + ( + GenomeInterval::from_str("152659877")?, + TxInterval::from_str("612")?, + CdsInterval::from_str("*225")?, + ), + ]; + + run_test_cases(tx_ac, alt_ac, &test_cases)?; + + Ok(()) + } + + /// NM_178449.3: PTH2, two exons, strand = -1, all coordinate input/output are in HGVS + #[test] + fn test_pth2() -> Result<(), anyhow::Error> { + let tx_ac = "NM_178449.3"; + let alt_ac = "NC_000019.9"; + let test_cases = vec![ + // 3' + ( + GenomeInterval::from_str("49926698")?, + TxInterval::from_str("1")?, + CdsInterval::from_str("-102")?, + ), + // CDS + ( + GenomeInterval::from_str("49926597")?, + TxInterval::from_str("102")?, + CdsInterval::from_str("-1")?, + ), + ( + GenomeInterval::from_str("49926596")?, + TxInterval::from_str("103")?, + CdsInterval::from_str("1")?, + ), + // around end of exon 1 + ( + GenomeInterval::from_str("49926469")?, + TxInterval::from_str("230")?, + CdsInterval::from_str("128")?, + ), + ( + GenomeInterval::from_str("49926468")?, + TxInterval::from_str("230+1")?, + CdsInterval::from_str("128+1")?, + ), + // span + ( + GenomeInterval::from_str("49925901_49926467")?, + TxInterval::from_str("230+2_231-2")?, + CdsInterval::from_str("128+2_129-2")?, + ), + // around start of exons 2 + ( + GenomeInterval::from_str("49925900")?, + TxInterval::from_str("231-1")?, + CdsInterval::from_str("129-1")?, + ), + ( + GenomeInterval::from_str("49925899")?, + TxInterval::from_str("231")?, + CdsInterval::from_str("129")?, + ), + // around end of exon2 + ( + GenomeInterval::from_str("49925725")?, + TxInterval::from_str("405")?, + CdsInterval::from_str("303")?, + ), + ( + GenomeInterval::from_str("49925724")?, + TxInterval::from_str("406")?, + CdsInterval::from_str("*1")?, + ), + ( + GenomeInterval::from_str("49925671")?, + TxInterval::from_str("459")?, + CdsInterval::from_str("*54")?, + ), + ]; + + run_test_cases(tx_ac, alt_ac, &test_cases)?; + + Ok(()) + } +} diff --git a/src/mapper/cigar.rs b/src/mapper/cigar.rs new file mode 100644 index 0000000..91b0534 --- /dev/null +++ b/src/mapper/cigar.rs @@ -0,0 +1,565 @@ +//! Code supporting the `CigarMapper` + +use std::fmt::Display; + +use nom::{combinator::all_consuming, multi::many0}; + +/// CIGAR operation as parsed from UTA. +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] +pub enum CigarOp { + /// = + Eq, + /// D + Del, + /// I + Ins, + /// M + Match, + /// S + Skip, + /// X + Mismatch, +} + +impl CigarOp { + pub fn is_advance_ref(&self) -> bool { + matches!( + self, + CigarOp::Eq | CigarOp::Match | CigarOp::Mismatch | CigarOp::Ins | CigarOp::Skip + ) + } + + pub fn is_advance_tgt(&self) -> bool { + matches!( + self, + CigarOp::Eq | CigarOp::Match | CigarOp::Mismatch | CigarOp::Del + ) + } +} + +impl TryFrom for CigarOp { + type Error = anyhow::Error; + + fn try_from(value: char) -> Result { + Ok(match value { + '=' => Self::Eq, + 'D' => Self::Del, + 'I' => Self::Ins, + 'M' => Self::Match, + 'N' => Self::Skip, + 'X' => Self::Mismatch, + _ => return Err(anyhow::anyhow!("Invalid CIGAR character {}", value)), + }) + } +} + +impl From for char { + fn from(val: CigarOp) -> Self { + match val { + CigarOp::Eq => '=', + CigarOp::Del => 'D', + CigarOp::Ins => 'I', + CigarOp::Match => 'M', + CigarOp::Skip => 'N', + CigarOp::Mismatch => 'X', + } + } +} + +impl Display for CigarOp { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", std::convert::Into::::into(*self)) + } +} + +/// CIGAR element consisting of count and CIGAR operation. +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] +pub struct CigarElement { + pub count: i32, + pub op: CigarOp, +} + +impl Display for CigarElement { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.count > 1 { + write!(f, "{}", self.count)?; + } + write!(f, "{}", self.op) + } +} + +impl CigarElement { + fn from_strs(count: &str, op: &str) -> CigarElement { + CigarElement { + count: if count.is_empty() { + 1 + } else { + str::parse(count).unwrap() + }, + op: op.chars().next().unwrap().try_into().unwrap(), + } + } +} + +#[derive(Debug, PartialEq, PartialOrd, Default, Clone)] +pub struct CigarString { + pub elems: Vec, +} + +impl CigarString { + fn from(elems: Vec) -> Self { + Self { elems } + } +} + +impl std::ops::Deref for CigarString { + type Target = Vec; + fn deref(&self) -> &Self::Target { + &self.elems + } +} +impl std::ops::DerefMut for CigarString { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.elems + } +} + +impl Display for CigarString { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for item in &self.elems { + write!(f, "{}", &item)? + } + Ok(()) + } +} + +pub mod parse { + use nom::{ + bytes::complete::take_while_m_n, + character::complete::digit0, + error::{context, VerboseError}, + sequence::pair, + IResult, + }; + + type Res = IResult>; + + use super::CigarElement; + + pub fn is_cigar_op_char(c: char) -> bool { + "=DIMNX".contains(c) + } + + pub fn cigar_element(input: &str) -> Res<&str, CigarElement> { + context( + "cigar_element", + pair(digit0, take_while_m_n(1, 1, is_cigar_op_char)), + )(input) + .map(|(rest, (count, op))| (rest, CigarElement::from_strs(count, op))) + } +} + +/// Parse a CIGAR `str` into a real one. +pub fn parse_cigar_string(input: &str) -> Result { + Ok(CigarString::from( + all_consuming(many0(parse::cigar_element))(input) + .map_err(|e| anyhow::anyhow!("Problem with parsing: {:?}", e))? + .1, + )) +} + +/// Provide coordinate mapping between two sequences whose alignment is given by a CIGAR string. +/// +/// CIGAR is about alignments between positions in two sequences. It is base-centric. +/// +/// Unfortunately, base-centric coordinate systems require additional complexity to refer to +/// zero-width positions. +/// +/// This code uses interbase intervals. Interbase positions are zero-width boundaries between +/// bases. They often look similar to zero-based, right open coordinates. (But don't call them +/// that. It upsets me deeply.) The most important difference is that zero width intervals +/// neatly represent insertions between bases (or before or after the sequence). +#[derive(Default, Debug)] +pub struct CigarMapper { + pub cigar_string: CigarString, + pub ref_pos: Vec, + pub tgt_pos: Vec, + pub cigar_op: Vec, + pub ref_len: i32, + pub tgt_len: i32, +} + +#[derive(Debug, PartialEq)] +pub struct CigarMapperResult { + pub pos: i32, + pub offset: i32, + pub cigar_op: CigarOp, +} + +impl CigarMapper { + pub fn new(cigar_string: &CigarString) -> Self { + let (ref_pos, tgt_pos, cigar_op) = Self::init(cigar_string); + + Self { + cigar_string: cigar_string.clone(), + ref_len: *ref_pos.last().unwrap(), + tgt_len: *tgt_pos.last().unwrap(), + ref_pos, + tgt_pos, + cigar_op, + } + } + + /// For a given CIGAR string, return the start positions of each aligned segment in ref + /// and tgt, and a list of CIGAR operators. + fn init(cigar_string: &CigarString) -> (Vec, Vec, Vec) { + let cigar_len = cigar_string.len(); + + let mut ref_pos = vec![-1; cigar_len]; + let mut tgt_pos = vec![-1; cigar_len]; + let mut cigar_op = vec![CigarOp::Mismatch; cigar_len]; + let mut ref_cur = 0; + let mut tgt_cur = 0; + for (i, CigarElement { count, op }) in cigar_string.iter().enumerate() { + ref_pos[i] = ref_cur; + tgt_pos[i] = tgt_cur; + cigar_op[i] = *op; + if op.is_advance_ref() { + ref_cur += *count; + } + if op.is_advance_tgt() { + tgt_cur += *count; + } + } + ref_pos.push(ref_cur); + tgt_pos.push(tgt_cur); + + (ref_pos, tgt_pos, cigar_op) + } + + pub fn map_ref_to_tgt( + &self, + pos: i32, + end: &str, + strict_bounds: bool, + ) -> Result { + self.map(&self.ref_pos, &self.tgt_pos, pos, end, strict_bounds) + } + + pub fn map_tgt_to_ref( + &self, + pos: i32, + end: &str, + strict_bounds: bool, + ) -> Result { + self.map(&self.tgt_pos, &self.ref_pos, pos, end, strict_bounds) + } + + /// Map position between aligned segments. + /// + /// Positions in this function are 0-based, base-counting. + fn map( + &self, + from_pos: &[i32], + to_pos: &[i32], + pos: i32, + end: &str, + strict_bounds: bool, + ) -> Result { + if strict_bounds && (pos < 0 || pos > *from_pos.last().unwrap()) { + return Err(anyhow::anyhow!( + "Position is beyond the bounds of transcript record (pos={}, from_pos={:?}, to_pos={:?}]", + pos, + from_pos, + to_pos, + )); + } + + // Find aligned segment to use as basis for mapping. It is okay for pos to be + // before first element or after last. + let pos_i = { + let mut pos_i = 0; + while pos_i < self.cigar_op.len() { + if pos < from_pos[pos_i + 1] { + break; + } + pos_i += 1; + } + std::cmp::min(pos_i, self.cigar_op.len().saturating_sub(1)) + }; + + let cigar_op = self.cigar_op[pos_i]; + + if cigar_op == CigarOp::Eq || cigar_op == CigarOp::Match || cigar_op == CigarOp::Mismatch { + Ok(CigarMapperResult { + pos: to_pos[pos_i] + (pos - from_pos[pos_i]), + offset: 0, + cigar_op, + }) + } else if cigar_op == CigarOp::Del || cigar_op == CigarOp::Ins { + Ok(CigarMapperResult { + pos: if end == "start" { + to_pos[pos_i] - 1 + } else { + to_pos[pos_i] + }, + offset: 0, + cigar_op, + }) + } else if cigar_op == CigarOp::Skip { + if pos - from_pos[pos_i] < from_pos[pos_i + 1] - pos { + Ok(CigarMapperResult { + pos: to_pos[pos_i] - 1, + offset: pos - from_pos[pos_i] + 1, + cigar_op, + }) + } else { + Ok(CigarMapperResult { + pos: to_pos[pos_i], + offset: -(from_pos[pos_i + 1] - pos), + cigar_op, + }) + } + } else { + Err(anyhow::anyhow!("Algorithm error in CIGAR mapper")) + } + } +} + +#[cfg(test)] +mod test { + use pretty_assertions::assert_eq; + + use super::{parse_cigar_string, CigarElement, CigarMapper, CigarMapperResult, CigarOp}; + + #[test] + fn parse_cigar_string_simple() -> Result<(), anyhow::Error> { + // assert_eq!(parse_cigar_string("")?, vec![]); + assert_eq!( + parse_cigar_string("M")?.elems, + vec![CigarElement { + count: 1, + op: CigarOp::Match + }] + ); + assert_eq!( + parse_cigar_string("MM")?.elems, + vec![ + CigarElement { + count: 1, + op: CigarOp::Match + }, + CigarElement { + count: 1, + op: CigarOp::Match + } + ] + ); + assert_eq!( + parse_cigar_string("1M")?.elems, + vec![CigarElement { + count: 1, + op: CigarOp::Match, + },] + ); + assert_eq!( + parse_cigar_string("1M2I3X")?.elems, + vec![ + CigarElement { + count: 1, + op: CigarOp::Match, + }, + CigarElement { + count: 2, + op: CigarOp::Ins, + }, + CigarElement { + count: 3, + op: CigarOp::Mismatch, + }, + ] + ); + assert_eq!( + parse_cigar_string("1MI3X")?.elems, + vec![ + CigarElement { + count: 1, + op: CigarOp::Match, + }, + CigarElement { + count: 1, + op: CigarOp::Ins, + }, + CigarElement { + count: 3, + op: CigarOp::Mismatch, + }, + ] + ); + + Ok(()) + } + + #[test] + fn cigar_mapper_simple() -> Result<(), anyhow::Error> { + // 0 1 2 3 4 5 6 7 8 9 tgt + // = = = N N = X = N N N = I = D = + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ref + let cigar = "3=2N=X=3N=I=D=".to_string(); + let cigar_str = parse_cigar_string(&cigar)?; + let cigar_mapper = CigarMapper::new(&cigar_str); + + assert_eq!(cigar_mapper.ref_len, 15); + assert_eq!(cigar_mapper.tgt_len, 10); + assert_eq!(cigar_mapper.ref_pos.len(), cigar_mapper.tgt_pos.len()); + assert_eq!( + cigar_mapper.ref_pos, + vec![0, 3, 5, 6, 7, 8, 11, 12, 13, 14, 14, 15] + ); + assert_eq!( + cigar_mapper.tgt_pos, + vec![0, 3, 3, 4, 5, 6, 6, 7, 7, 8, 9, 10] + ); + + // ref to tgt + { + let cases = vec![ + (0, "start", 0, 0, CigarOp::Eq), + (0, "end", 0, 0, CigarOp::Eq), + (1, "start", 1, 0, CigarOp::Eq), + (1, "end", 1, 0, CigarOp::Eq), + (2, "start", 2, 0, CigarOp::Eq), + (2, "end", 2, 0, CigarOp::Eq), + (3, "start", 2, 1, CigarOp::Skip), + (3, "end", 2, 1, CigarOp::Skip), + (4, "start", 3, -1, CigarOp::Skip), + (4, "end", 3, -1, CigarOp::Skip), + (5, "start", 3, 0, CigarOp::Eq), + (5, "end", 3, 0, CigarOp::Eq), + (6, "start", 4, 0, CigarOp::Mismatch), + (6, "end", 4, 0, CigarOp::Mismatch), + (7, "start", 5, 0, CigarOp::Eq), + (7, "end", 5, 0, CigarOp::Eq), + (8, "start", 5, 1, CigarOp::Skip), + (8, "end", 5, 1, CigarOp::Skip), + (9, "start", 5, 2, CigarOp::Skip), + (9, "end", 5, 2, CigarOp::Skip), + (10, "start", 6, -1, CigarOp::Skip), + (10, "end", 6, -1, CigarOp::Skip), + (11, "start", 6, 0, CigarOp::Eq), + (11, "end", 6, 0, CigarOp::Eq), + (12, "start", 6, 0, CigarOp::Ins), + (12, "end", 7, 0, CigarOp::Ins), + (13, "start", 7, 0, CigarOp::Eq), + (13, "end", 7, 0, CigarOp::Eq), + (14, "start", 9, 0, CigarOp::Eq), + (14, "end", 9, 0, CigarOp::Eq), + ]; + for (arg_pos, arg_end, pos, offset, cigar_op) in cases { + assert_eq!( + cigar_mapper.map_ref_to_tgt(arg_pos, arg_end, true)?, + CigarMapperResult { + pos, + offset, + cigar_op + }, + "case = {:?}", + (arg_pos, arg_end, pos, offset, cigar_op) + ); + } + } + + // tgt to ref + { + let cases = vec![ + (0, "start", 0, 0, CigarOp::Eq), + (0, "end", 0, 0, CigarOp::Eq), + (1, "start", 1, 0, CigarOp::Eq), + (1, "end", 1, 0, CigarOp::Eq), + (2, "start", 2, 0, CigarOp::Eq), + (2, "end", 2, 0, CigarOp::Eq), + (3, "start", 5, 0, CigarOp::Eq), + (3, "end", 5, 0, CigarOp::Eq), + (4, "start", 6, 0, CigarOp::Mismatch), + (4, "end", 6, 0, CigarOp::Mismatch), + (5, "start", 7, 0, CigarOp::Eq), + (5, "end", 7, 0, CigarOp::Eq), + (6, "start", 11, 0, CigarOp::Eq), + (6, "end", 11, 0, CigarOp::Eq), + (7, "start", 13, 0, CigarOp::Eq), + (7, "end", 13, 0, CigarOp::Eq), + (8, "start", 13, 0, CigarOp::Del), + (8, "end", 14, 0, CigarOp::Del), + (9, "start", 14, 0, CigarOp::Eq), + (9, "end", 14, 0, CigarOp::Eq), + ]; + for (arg_pos, arg_end, pos, offset, cigar_op) in cases { + assert_eq!( + cigar_mapper.map_tgt_to_ref(arg_pos, arg_end, true)?, + CigarMapperResult { + pos, + offset, + cigar_op + }, + "case = {:?}", + (arg_pos, arg_end, pos, offset, cigar_op) + ); + } + } + + Ok(()) + } + + #[test] + fn cigar_mapper_strict_bounds() -> Result<(), anyhow::Error> { + // 0 1 2 3 4 5 6 7 8 9 tgt + // = = = N N = X = N N N = I = D = + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ref + let cigar = "3=2N=X=3N=I=D=".to_string(); + let cigar_str = parse_cigar_string(&cigar)?; + let cigar_mapper = CigarMapper::new(&cigar_str); + + // error for out of bounds on left? + assert!(cigar_mapper.map_ref_to_tgt(-1, "start", true).is_err()); + // ... and right? + assert!(cigar_mapper + .map_ref_to_tgt(cigar_mapper.ref_len + 1, "start", true) + .is_err()); + + // test whether 1 base outside bounds results in correct position + assert_eq!( + cigar_mapper.map_ref_to_tgt(0, "start", true)?, + CigarMapperResult { + pos: 0, + offset: 0, + cigar_op: CigarOp::Eq, + } + ); + assert_eq!( + cigar_mapper.map_ref_to_tgt(-1, "start", false)?, + CigarMapperResult { + pos: -1, + offset: 0, + cigar_op: CigarOp::Eq, + } + ); + assert_eq!( + cigar_mapper.map_ref_to_tgt(cigar_mapper.ref_len, "start", true)?, + CigarMapperResult { + pos: cigar_mapper.tgt_len, + offset: 0, + cigar_op: CigarOp::Eq, + } + ); + assert_eq!( + cigar_mapper.map_ref_to_tgt(cigar_mapper.ref_len - 1, "start", false)?, + CigarMapperResult { + pos: cigar_mapper.tgt_len - 1, + offset: 0, + cigar_op: CigarOp::Eq, + } + ); + + Ok(()) + } +} diff --git a/src/mapper/mod.rs b/src/mapper/mod.rs new file mode 100644 index 0000000..87eca1b --- /dev/null +++ b/src/mapper/mod.rs @@ -0,0 +1,3 @@ +pub mod alignment; +pub mod cigar; +pub mod variant; diff --git a/src/mapper/variant.rs b/src/mapper/variant.rs new file mode 100644 index 0000000..cb1bc35 --- /dev/null +++ b/src/mapper/variant.rs @@ -0,0 +1,85 @@ +//! Code for variant mapping. + +use std::rc::Rc; + +use crate::{ + data::interface::Provider, + parser::HgvsVariant, + validator::{ValidationLevel, Validator}, +}; + +/// Configuration for Mapper. +/// +/// Defaults are taken from `hgvs` Python library. +#[derive(Debug, PartialEq, Clone)] +pub struct Config { + pub replace_reference: bool, + pub strict_validation: bool, + pub prevalidation_level: ValidationLevel, + pub add_gene_symbol: bool, +} + +impl Default for Config { + fn default() -> Self { + Self { + replace_reference: true, + strict_validation: false, + prevalidation_level: ValidationLevel::Extrinsic, + add_gene_symbol: false, + } + } +} + +pub struct Mapper { + config: Config, + provider: Rc, + validator: Box, +} + +impl Mapper { + fn new(config: &Config, provider: Rc) -> Mapper { + let validator = config + .prevalidation_level + .validator(config.strict_validation, provider.clone()); + Mapper { + config: config.clone(), + provider, + validator, + } + } + + fn config(&self) -> &Config { + &self.config + } + + /// Convert from genome to transcription. + /// + /// # Args + /// + /// * `var_g` -- `HgvsVariant::GenomeVariant` to project + /// * `tx_ac` -- accession of transcript to project to + /// * `alt_al_method` -- alignment method, e.g., `splign` + fn g_to_t( + &self, + var_g: HgvsVariant, + _tx_ac: &str, + _alt_aln_method: &str, + ) -> Result<(), anyhow::Error> { + if let HgvsVariant::GenomeVariant { + accession: _, + gene_symbol: _, + loc_edit: _, + } = &var_g + { + self.validator.validate(&var_g)?; + let _var_g = var_g.fill_ref(self.provider.as_ref())?; + + Ok(()) + } else { + Err(anyhow::anyhow!( + "Expected a GenomeVariant but received {}", + &var_g + )) + } + } +} diff --git a/src/parser/display.rs b/src/parser/display.rs index a0bff34..492f35a 100644 --- a/src/parser/display.rs +++ b/src/parser/display.rs @@ -144,8 +144,8 @@ impl Display for ProtPos { impl Display for ProtInterval { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.begin)?; - if self.begin != self.end { + write!(f, "{}", self.start)?; + if self.start != self.end { write!(f, "_{}", self.end)?; } Ok(()) @@ -172,8 +172,8 @@ impl Display for CdsLocEdit { impl Display for CdsInterval { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.begin)?; - if self.begin != self.end { + write!(f, "{}", self.start)?; + if self.start != self.end { write!(f, "_{}", self.end)?; } Ok(()) @@ -207,8 +207,8 @@ impl Display for TxLocEdit { impl Display for TxInterval { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.begin)?; - if self.begin != self.end { + write!(f, "{}", self.start)?; + if self.start != self.end { write!(f, "_{}", self.end)?; } Ok(()) @@ -238,8 +238,8 @@ impl Display for RnaLocEdit { impl Display for RnaInterval { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.begin)?; - if self.begin != self.end { + write!(f, "{}", self.start)?; + if self.start != self.end { write!(f, "_{}", self.end)?; } Ok(()) @@ -269,11 +269,11 @@ impl Display for GenomeLocEdit { impl Display for GenomeInterval { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self.begin { + match self.start { Some(begin) => write!(f, "{begin}")?, None => write!(f, "?")?, } - if self.begin != self.end { + if self.start != self.end { match self.end { Some(end) => write!(f, "_{end}")?, None => write!(f, "_?")?, @@ -291,11 +291,11 @@ impl Display for MtLocEdit { impl Display for MtInterval { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self.begin { + match self.start { Some(begin) => write!(f, "{begin}")?, None => write!(f, "?")?, } - if self.begin != self.end { + if self.start != self.end { match self.end { Some(end) => write!(f, "_{end}")?, None => write!(f, "_?")?, @@ -1025,7 +1025,7 @@ mod test { format!( "{}", CdsInterval { - begin: CdsPos { + start: CdsPos { base: 42, offset: Some(-10), cds_from: CdsFrom::Start, @@ -1044,7 +1044,7 @@ mod test { format!( "{}", CdsInterval { - begin: CdsPos { + start: CdsPos { base: 42, offset: Some(10), cds_from: CdsFrom::Start, @@ -1067,7 +1067,7 @@ mod test { "{}", CdsLocEdit { loc: Mu::Certain(CdsInterval { - begin: CdsPos { + start: CdsPos { base: 42, offset: Some(-10), cds_from: CdsFrom::Start, @@ -1130,7 +1130,7 @@ mod test { format!( "{}", TxInterval { - begin: TxPos { + start: TxPos { base: 42, offset: Some(-10), }, @@ -1147,7 +1147,7 @@ mod test { format!( "{}", TxInterval { - begin: TxPos { + start: TxPos { base: 42, offset: Some(10), }, @@ -1168,7 +1168,7 @@ mod test { "{}", TxLocEdit { loc: Mu::Certain(TxInterval { - begin: TxPos { + start: TxPos { base: 42, offset: Some(-10), }, @@ -1228,7 +1228,7 @@ mod test { format!( "{}", RnaInterval { - begin: RnaPos { + start: RnaPos { base: 42, offset: Some(-10), }, @@ -1245,7 +1245,7 @@ mod test { format!( "{}", RnaInterval { - begin: RnaPos { + start: RnaPos { base: 42, offset: Some(10), }, @@ -1266,7 +1266,7 @@ mod test { "{}", RnaLocEdit { loc: Mu::Certain(RnaInterval { - begin: RnaPos { + start: RnaPos { base: 42, offset: Some(-10), }, @@ -1291,7 +1291,7 @@ mod test { format!( "{}", GenomeInterval { - begin: None, + start: None, end: None } ), @@ -1302,7 +1302,7 @@ mod test { format!( "{}", GenomeInterval { - begin: Some(10), + start: Some(10), end: None } ), @@ -1313,7 +1313,7 @@ mod test { format!( "{}", GenomeInterval { - begin: None, + start: None, end: Some(10) } ), @@ -1324,7 +1324,7 @@ mod test { format!( "{}", GenomeInterval { - begin: Some(10), + start: Some(10), end: Some(20) } ), @@ -1335,7 +1335,7 @@ mod test { format!( "{}", GenomeInterval { - begin: Some(10), + start: Some(10), end: Some(10) } ), @@ -1350,7 +1350,7 @@ mod test { "{}", GenomeLocEdit { loc: Mu::Certain(GenomeInterval { - begin: Some(10), + start: Some(10), end: Some(20) }), edit: Mu::Certain(NaEdit::RefAlt { @@ -1369,7 +1369,7 @@ mod test { format!( "{}", MtInterval { - begin: None, + start: None, end: None } ), @@ -1380,7 +1380,7 @@ mod test { format!( "{}", MtInterval { - begin: Some(10), + start: Some(10), end: None } ), @@ -1391,7 +1391,7 @@ mod test { format!( "{}", MtInterval { - begin: None, + start: None, end: Some(10) } ), @@ -1402,7 +1402,7 @@ mod test { format!( "{}", MtInterval { - begin: Some(10), + start: Some(10), end: Some(20) } ), @@ -1413,7 +1413,7 @@ mod test { format!( "{}", MtInterval { - begin: Some(10), + start: Some(10), end: Some(10) } ), @@ -1428,7 +1428,7 @@ mod test { "{}", MtLocEdit { loc: Mu::Certain(MtInterval { - begin: Some(10), + start: Some(10), end: Some(20) }), edit: Mu::Certain(NaEdit::RefAlt { @@ -1461,7 +1461,7 @@ mod test { format!( "{}", ProtInterval { - begin: ProtPos { + start: ProtPos { aa: "Leu".to_string(), number: 42 }, @@ -1478,7 +1478,7 @@ mod test { format!( "{}", ProtInterval { - begin: ProtPos { + start: ProtPos { aa: "Leu".to_string(), number: 42 }, @@ -1499,7 +1499,7 @@ mod test { "{}", ProtLocEdit::Ordinary { loc: Mu::Certain(ProtInterval { - begin: ProtPos { + start: ProtPos { aa: "Leu".to_string(), number: 42 }, @@ -1543,7 +1543,7 @@ mod test { }), loc_edit: CdsLocEdit { loc: Mu::Certain(CdsInterval { - begin: CdsPos { + start: CdsPos { base: 100, offset: None, cds_from: CdsFrom::Start, @@ -1574,7 +1574,7 @@ mod test { gene_symbol: None, loc_edit: CdsLocEdit { loc: Mu::Certain(CdsInterval { - begin: CdsPos { + start: CdsPos { base: 100, offset: None, cds_from: CdsFrom::Start, @@ -1610,7 +1610,7 @@ mod test { }), loc_edit: GenomeLocEdit { loc: Mu::Certain(GenomeInterval { - begin: Some(100), + start: Some(100), end: Some(100) }), edit: Mu::Certain(NaEdit::RefAlt { @@ -1633,7 +1633,7 @@ mod test { gene_symbol: None, loc_edit: GenomeLocEdit { loc: Mu::Certain(GenomeInterval { - begin: Some(100), + start: Some(100), end: Some(100) }), edit: Mu::Certain(NaEdit::RefAlt { @@ -1661,7 +1661,7 @@ mod test { }), loc_edit: MtLocEdit { loc: Mu::Certain(MtInterval { - begin: Some(100), + start: Some(100), end: Some(100) }), edit: Mu::Certain(NaEdit::RefAlt { @@ -1684,7 +1684,7 @@ mod test { gene_symbol: None, loc_edit: MtLocEdit { loc: Mu::Certain(MtInterval { - begin: Some(100), + start: Some(100), end: Some(100) }), edit: Mu::Certain(NaEdit::RefAlt { @@ -1712,7 +1712,7 @@ mod test { }), loc_edit: TxLocEdit { loc: Mu::Certain(TxInterval { - begin: TxPos { + start: TxPos { base: 100, offset: None }, @@ -1741,7 +1741,7 @@ mod test { gene_symbol: None, loc_edit: TxLocEdit { loc: Mu::Certain(TxInterval { - begin: TxPos { + start: TxPos { base: 100, offset: None }, @@ -1775,7 +1775,7 @@ mod test { }), loc_edit: RnaLocEdit { loc: Mu::Certain(RnaInterval { - begin: RnaPos { + start: RnaPos { base: 100, offset: None }, @@ -1804,7 +1804,7 @@ mod test { gene_symbol: None, loc_edit: RnaLocEdit { loc: Mu::Certain(RnaInterval { - begin: RnaPos { + start: RnaPos { base: 100, offset: None }, diff --git a/src/parser/ds.rs b/src/parser/ds.rs index c131b0a..ba6a0df 100644 --- a/src/parser/ds.rs +++ b/src/parser/ds.rs @@ -9,6 +9,30 @@ pub enum Mu { Uncertain(T), } +impl Mu { + pub fn from(value: T, is_certain: bool) -> Self { + if is_certain { + Mu::Certain(value) + } else { + Mu::Uncertain(value) + } + } + + pub fn unwrap(self) -> T { + match self { + Mu::Certain(value) => value, + Mu::Uncertain(value) => value, + } + } + + pub fn inner(&self) -> &T { + match self { + Mu::Certain(value) => value, + Mu::Uncertain(value) => value, + } + } +} + /// Representation of gene symbol, e.g., `TTN` or `Ttn`. #[derive(Clone, Debug, PartialEq)] pub struct GeneSymbol { @@ -143,7 +167,7 @@ pub struct CdsLocEdit { #[derive(Clone, Debug, PartialEq)] pub struct CdsInterval { /// Start position - pub begin: CdsPos, + pub start: CdsPos, /// End position pub end: CdsPos, } @@ -180,7 +204,7 @@ pub struct GenomeLocEdit { #[derive(Clone, Debug, PartialEq)] pub struct GenomeInterval { /// Start position - pub begin: Option, + pub start: Option, /// End position pub end: Option, } @@ -198,7 +222,7 @@ pub struct MtLocEdit { #[derive(Clone, Debug, PartialEq)] pub struct MtInterval { /// Start position - pub begin: Option, + pub start: Option, /// End position pub end: Option, } @@ -216,7 +240,7 @@ pub struct TxLocEdit { #[derive(Clone, Debug, PartialEq)] pub struct TxInterval { /// Start position - pub begin: TxPos, + pub start: TxPos, /// End position pub end: TxPos, } @@ -243,7 +267,7 @@ pub struct RnaLocEdit { #[derive(Clone, Debug, PartialEq)] pub struct RnaInterval { /// Start position - pub begin: RnaPos, + pub start: RnaPos, /// End position pub end: RnaPos, } @@ -278,7 +302,7 @@ pub enum ProtLocEdit { #[derive(Clone, Debug, PartialEq)] pub struct ProtInterval { /// Start position - pub begin: ProtPos, + pub start: ProtPos, /// End position pub end: ProtPos, } @@ -291,3 +315,110 @@ pub struct ProtPos { /// Number of `aa`. pub number: i32, } + +#[cfg(test)] +mod test { + use pretty_assertions::assert_eq; + + use super::{TxInterval, TxPos}; + use crate::parser::Mu; + + #[test] + fn mu_construct() { + assert_eq!(format!("{:?}", Mu::Certain(1)), "Certain(1)"); + assert_eq!(format!("{:?}", Mu::Certain(Some(1))), "Certain(Some(1))"); + assert_eq!(format!("{:?}", Mu::Uncertain(1)), "Uncertain(1)"); + assert_eq!( + format!("{:?}", Mu::Uncertain(Some(1))), + "Uncertain(Some(1))" + ); + } + + #[test] + fn mu_unwrap() { + assert_eq!(Mu::Certain(1).unwrap(), 1); + assert_eq!(Mu::Uncertain(1).unwrap(), 1); + } + + #[test] + fn mu_inner() { + assert_eq!(Mu::Certain(1).inner(), &1); + assert_eq!(Mu::Uncertain(1).inner(), &1); + } + + #[test] + fn mu_from() { + assert_eq!(Mu::from(1, true), Mu::Certain(1)); + assert_eq!(Mu::from(1, false), Mu::Uncertain(1)); + assert_eq!(Mu::from(Some(1), true), Mu::Certain(Some(1))); + assert_eq!(Mu::from(Some(1), false), Mu::Uncertain(Some(1))); + } + + #[derive(Clone, Debug, PartialEq)] + pub struct TestInterval { + pub start: TestPos, + pub end: TestPos, + } + + #[derive(Clone, Debug, PartialEq)] + pub struct TestPos { + pub base: i32, + pub offset: Option, + } + + #[test] + fn mu_from_problematic() { + let test_itv = TestInterval { + start: TestPos { + base: 34, + offset: Some(1), + }, + end: TestPos { + base: 35, + offset: Some(-1), + }, + }; + + assert_eq!( + Mu::from(test_itv, true), + Mu::Certain(TestInterval { + start: TestPos { + base: 34, + offset: Some(1), + }, + end: TestPos { + base: 35, + offset: Some(-1), + } + }) + ); + } + + #[test] + fn mu_from_tx_interval() { + let test_itv = TxInterval { + start: TxPos { + base: 34, + offset: Some(1), + }, + end: TxPos { + base: 35, + offset: Some(-1), + }, + }; + + assert_eq!( + Mu::from(test_itv, true), + Mu::Certain(TxInterval { + start: TxPos { + base: 34, + offset: Some(1), + }, + end: TxPos { + base: 35, + offset: Some(-1), + } + }) + ); + } +} diff --git a/src/parser/impl_ops.rs b/src/parser/impl_ops.rs new file mode 100644 index 0000000..9e08450 --- /dev/null +++ b/src/parser/impl_ops.rs @@ -0,0 +1,16 @@ +//! Implementation of operations on the data structures. + +use crate::data::interface::Provider; + +use super::HgvsVariant; + +impl HgvsVariant { + /// Fill reference bases using the given data provider. + /// + /// # Args + /// + /// * `provider` -- The `Provider` to use for fetching reference bases. + pub fn fill_ref(&self, _provider: &dyn Provider) -> Result { + todo!() + } +} diff --git a/src/parser/impl_parse.rs b/src/parser/impl_parse.rs index 2d5dcdb..04bbb8a 100644 --- a/src/parser/impl_parse.rs +++ b/src/parser/impl_parse.rs @@ -14,7 +14,7 @@ use crate::parser::ds::*; use crate::parser::parse_funcs::*; impl HgvsVariant { - pub fn parse_cds_variant(input: &str) -> IResult<&str, Self> { + fn parse_cds_variant(input: &str) -> IResult<&str, Self> { map( tuple(( Accession::parse, @@ -362,7 +362,7 @@ mod test { }), loc_edit: CdsLocEdit { loc: Mu::Certain(CdsInterval { - begin: CdsPos { + start: CdsPos { base: 123, offset: None, cds_from: CdsFrom::Start @@ -394,7 +394,7 @@ mod test { }), loc_edit: GenomeLocEdit { loc: Mu::Certain(GenomeInterval { - begin: Some(123), + start: Some(123), end: Some(123), }), edit: Mu::Certain(NaEdit::RefAlt { @@ -418,7 +418,7 @@ mod test { }), loc_edit: MtLocEdit { loc: Mu::Certain(MtInterval { - begin: Some(123), + start: Some(123), end: Some(123), }), edit: Mu::Certain(NaEdit::RefAlt { @@ -442,7 +442,7 @@ mod test { }), loc_edit: TxLocEdit { loc: Mu::Certain(TxInterval { - begin: TxPos { + start: TxPos { base: 123, offset: None }, @@ -472,7 +472,7 @@ mod test { }), loc_edit: RnaLocEdit { loc: Mu::Certain(RnaInterval { - begin: RnaPos { + start: RnaPos { base: 123, offset: None }, @@ -502,7 +502,7 @@ mod test { }), loc_edit: ProtLocEdit::Ordinary { loc: Mu::Certain(ProtInterval { - begin: ProtPos { + start: ProtPos { aa: "Leu".to_string(), number: 3 }, @@ -528,7 +528,7 @@ mod test { "", CdsLocEdit { loc: Mu::Uncertain(CdsInterval { - begin: CdsPos { + start: CdsPos { base: 123, offset: None, cds_from: CdsFrom::Start @@ -556,7 +556,7 @@ mod test { "", GenomeLocEdit { loc: Mu::Uncertain(GenomeInterval { - begin: Some(123), + start: Some(123), end: Some(123), }), edit: Mu::Certain(NaEdit::RefAlt { @@ -576,7 +576,7 @@ mod test { "", MtLocEdit { loc: Mu::Uncertain(MtInterval { - begin: Some(123), + start: Some(123), end: Some(123), }), edit: Mu::Certain(NaEdit::RefAlt { @@ -596,7 +596,7 @@ mod test { "", TxLocEdit { loc: Mu::Uncertain(TxInterval { - begin: TxPos { + start: TxPos { base: 123, offset: None, }, @@ -622,7 +622,7 @@ mod test { "", RnaLocEdit { loc: Mu::Uncertain(RnaInterval { - begin: RnaPos { + start: RnaPos { base: 123, offset: None, }, @@ -648,7 +648,7 @@ mod test { "", ProtLocEdit::Ordinary { loc: Mu::Uncertain(ProtInterval { - begin: ProtPos { + start: ProtPos { aa: "Leu".to_string(), number: 123, }, @@ -682,7 +682,7 @@ mod test { Ok(( "", CdsInterval { - begin: CdsPos { + start: CdsPos { base: 123, offset: None, cds_from: CdsFrom::Start, @@ -704,7 +704,7 @@ mod test { Ok(( "", GenomeInterval { - begin: Some(123), + start: Some(123), end: Some(123), } )) @@ -718,7 +718,7 @@ mod test { Ok(( "", MtInterval { - begin: Some(123), + start: Some(123), end: Some(123), } )) @@ -732,7 +732,7 @@ mod test { Ok(( "", TxInterval { - begin: TxPos { + start: TxPos { base: 123, offset: None }, @@ -752,7 +752,7 @@ mod test { Ok(( "", RnaInterval { - begin: RnaPos { + start: RnaPos { base: 123, offset: None }, @@ -772,7 +772,7 @@ mod test { Ok(( "", ProtInterval { - begin: ProtPos { + start: ProtPos { aa: "Leu".to_string(), number: 123 }, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 2c3a784..5bba051 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -6,6 +6,7 @@ mod display; mod ds; +mod impl_ops; mod impl_parse; mod parse_funcs; @@ -25,6 +26,36 @@ impl FromStr for HgvsVariant { } } +impl FromStr for GenomeInterval { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + Self::parse(s) + .map_err(|e| anyhow::anyhow!("problem with parsing HGVS genome interval: {:?}", &e)) + .map(|(_rest, g_interval)| g_interval) + } +} + +impl FromStr for TxInterval { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + Self::parse(s) + .map_err(|e| anyhow::anyhow!("problem with parsing HGVS transcript interval: {:?}", &e)) + .map(|(_rest, g_interval)| g_interval) + } +} + +impl FromStr for CdsInterval { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + Self::parse(s) + .map_err(|e| anyhow::anyhow!("problem with parsing HGVS CDS interval: {:?}", &e)) + .map(|(_rest, g_interval)| g_interval) + } +} + #[cfg(test)] mod test { use std::{ @@ -33,7 +64,9 @@ mod test { str::FromStr, }; - use crate::parser::{Accession, CdsFrom, CdsInterval, CdsLocEdit, CdsPos, Mu, NaEdit}; + use crate::parser::{ + Accession, CdsFrom, CdsInterval, CdsLocEdit, CdsPos, GenomeInterval, Mu, NaEdit, + }; use super::HgvsVariant; @@ -48,7 +81,7 @@ mod test { gene_symbol: None, loc_edit: CdsLocEdit { loc: Mu::Certain(CdsInterval { - begin: CdsPos { + start: CdsPos { base: 22, offset: Some(1), cds_from: CdsFrom::Start @@ -109,4 +142,47 @@ mod test { Ok(()) } + + // Test genome interval parsing. + #[test] + fn genome_interval_from_str() -> Result<(), anyhow::Error> { + assert!(GenomeInterval::from_str("x").is_err()); + assert_eq!( + GenomeInterval::from_str("1")?, + GenomeInterval { + start: Some(1), + end: Some(1) + } + ); + assert_eq!( + GenomeInterval::from_str("1_1")?, + GenomeInterval { + start: Some(1), + end: Some(1) + } + ); + assert_eq!( + GenomeInterval::from_str("?_1")?, + GenomeInterval { + start: None, + end: Some(1) + } + ); + assert_eq!( + GenomeInterval::from_str("1_?")?, + GenomeInterval { + start: Some(1), + end: None + } + ); + assert_eq!( + GenomeInterval::from_str("?_?")?, + GenomeInterval { + start: None, + end: None + } + ); + + Ok(()) + } } diff --git a/src/parser/parse_funcs.rs b/src/parser/parse_funcs.rs index 9d1575d..d3b5bdd 100644 --- a/src/parser/parse_funcs.rs +++ b/src/parser/parse_funcs.rs @@ -467,14 +467,14 @@ pub mod cds_pos { pub fn int(input: &str) -> IResult<&str, CdsInterval> { let (rest, (begin, _, end)) = tuple((pos, tag("_"), pos))(input)?; - Ok((rest, CdsInterval { begin, end })) + Ok((rest, CdsInterval { start: begin, end })) } pub fn loc(input: &str) -> IResult<&str, CdsInterval> { alt(( int, map(pos, |pos| CdsInterval { - begin: pos.clone(), + start: pos.clone(), end: pos, }), ))(input) @@ -502,7 +502,7 @@ pub mod genome_pos { pub fn int(input: &str) -> IResult<&str, GenomeInterval> { map(tuple((pos, tag("_"), pos)), |(begin, _, end)| { - GenomeInterval { begin, end } + GenomeInterval { start: begin, end } })(input) } @@ -510,7 +510,7 @@ pub mod genome_pos { alt(( int, map(pos, |pos| GenomeInterval { - begin: pos, + start: pos, end: pos, }), ))(input) @@ -538,7 +538,7 @@ pub mod mt_pos { pub fn int(input: &str) -> IResult<&str, MtInterval> { map(tuple((pos, tag("_"), pos)), |(begin, _, end)| MtInterval { - begin, + start: begin, end, })(input) } @@ -547,7 +547,7 @@ pub mod mt_pos { alt(( int, map(pos, |pos| MtInterval { - begin: pos, + start: pos, end: pos, }), ))(input) @@ -581,14 +581,14 @@ pub mod tx_pos { pub fn int(input: &str) -> IResult<&str, TxInterval> { let (rest, (begin, _, end)) = tuple((pos, tag("_"), pos))(input)?; - Ok((rest, TxInterval { begin, end })) + Ok((rest, TxInterval { start: begin, end })) } pub fn loc(input: &str) -> IResult<&str, TxInterval> { alt(( int, map(pos, |pos| TxInterval { - begin: pos.clone(), + start: pos.clone(), end: pos, }), ))(input) @@ -622,14 +622,14 @@ pub mod rna_pos { pub fn int(input: &str) -> IResult<&str, RnaInterval> { let (rest, (begin, _, end)) = tuple((pos, tag("_"), pos))(input)?; - Ok((rest, RnaInterval { begin, end })) + Ok((rest, RnaInterval { start: begin, end })) } pub fn loc(input: &str) -> IResult<&str, RnaInterval> { alt(( int, map(pos, |pos| RnaInterval { - begin: pos.clone(), + start: pos.clone(), end: pos, }), ))(input) @@ -664,14 +664,14 @@ pub mod prot_pos { pub fn int(input: &str) -> IResult<&str, ProtInterval> { let (rest, (begin, _, end)) = tuple((pos, tag("_"), pos))(input)?; - Ok((rest, ProtInterval { begin, end })) + Ok((rest, ProtInterval { start: begin, end })) } pub fn loc(input: &str) -> IResult<&str, ProtInterval> { alt(( int, map(pos, |pos| ProtInterval { - begin: pos.clone(), + start: pos.clone(), end: pos, }), ))(input) @@ -1606,7 +1606,7 @@ mod test { Ok(( "", MtInterval { - begin: Some(42), + start: Some(42), end: Some(42), } )) @@ -1620,7 +1620,7 @@ mod test { Ok(( "", MtInterval { - begin: Some(42), + start: Some(42), end: Some(100), } )) @@ -1630,7 +1630,7 @@ mod test { Ok(( "", MtInterval { - begin: None, + start: None, end: Some(100), } )) @@ -1640,7 +1640,7 @@ mod test { Ok(( "", MtInterval { - begin: Some(42), + start: Some(42), end: None, } )) @@ -1650,7 +1650,7 @@ mod test { Ok(( "", MtInterval { - begin: None, + start: None, end: None, } )) @@ -1664,7 +1664,7 @@ mod test { Ok(( "", CdsInterval { - begin: CdsPos { + start: CdsPos { base: 123, offset: None, cds_from: CdsFrom::Start, @@ -1686,7 +1686,7 @@ mod test { Ok(( "", CdsInterval { - begin: CdsPos { + start: CdsPos { base: 123, offset: None, cds_from: CdsFrom::Start, @@ -1704,7 +1704,7 @@ mod test { Ok(( "", CdsInterval { - begin: CdsPos { + start: CdsPos { base: 123, offset: None, cds_from: CdsFrom::Start, @@ -1722,7 +1722,7 @@ mod test { Ok(( "", CdsInterval { - begin: CdsPos { + start: CdsPos { base: -123, offset: None, cds_from: CdsFrom::Start, @@ -1740,7 +1740,7 @@ mod test { Ok(( "", CdsInterval { - begin: CdsPos { + start: CdsPos { base: 123, offset: Some(42), cds_from: CdsFrom::Start, @@ -1758,7 +1758,7 @@ mod test { Ok(( "", CdsInterval { - begin: CdsPos { + start: CdsPos { base: 123, offset: Some(42), cds_from: CdsFrom::Start, @@ -1776,7 +1776,7 @@ mod test { Ok(( "", CdsInterval { - begin: CdsPos { + start: CdsPos { base: -123, offset: Some(42), cds_from: CdsFrom::Start, @@ -1794,7 +1794,7 @@ mod test { Ok(( "", CdsInterval { - begin: CdsPos { + start: CdsPos { base: 123, offset: Some(-42), cds_from: CdsFrom::Start, @@ -1812,7 +1812,7 @@ mod test { Ok(( "", CdsInterval { - begin: CdsPos { + start: CdsPos { base: 123, offset: Some(-42), cds_from: CdsFrom::Start, @@ -1830,7 +1830,7 @@ mod test { Ok(( "", CdsInterval { - begin: CdsPos { + start: CdsPos { base: -123, offset: Some(-42), cds_from: CdsFrom::Start, @@ -1988,7 +1988,7 @@ mod test { Ok(( "", GenomeInterval { - begin: Some(42), + start: Some(42), end: Some(42), } )) @@ -2002,7 +2002,7 @@ mod test { Ok(( "", GenomeInterval { - begin: Some(42), + start: Some(42), end: Some(100), } )) @@ -2012,7 +2012,7 @@ mod test { Ok(( "", GenomeInterval { - begin: None, + start: None, end: Some(100), } )) @@ -2022,7 +2022,7 @@ mod test { Ok(( "", GenomeInterval { - begin: Some(42), + start: Some(42), end: None, } )) @@ -2032,7 +2032,7 @@ mod test { Ok(( "", GenomeInterval { - begin: None, + start: None, end: None, } )) @@ -2046,7 +2046,7 @@ mod test { Ok(( "", TxInterval { - begin: TxPos { + start: TxPos { base: 123, offset: None, }, @@ -2066,7 +2066,7 @@ mod test { Ok(( "", TxInterval { - begin: TxPos { + start: TxPos { base: 123, offset: None, }, @@ -2082,7 +2082,7 @@ mod test { Ok(( "", TxInterval { - begin: TxPos { + start: TxPos { base: 123, offset: None, }, @@ -2098,7 +2098,7 @@ mod test { Ok(( "", TxInterval { - begin: TxPos { + start: TxPos { base: -123, offset: None, }, @@ -2114,7 +2114,7 @@ mod test { Ok(( "", TxInterval { - begin: TxPos { + start: TxPos { base: 123, offset: Some(42), }, @@ -2130,7 +2130,7 @@ mod test { Ok(( "", TxInterval { - begin: TxPos { + start: TxPos { base: 123, offset: Some(42), }, @@ -2146,7 +2146,7 @@ mod test { Ok(( "", TxInterval { - begin: TxPos { + start: TxPos { base: -123, offset: Some(42), }, @@ -2162,7 +2162,7 @@ mod test { Ok(( "", TxInterval { - begin: TxPos { + start: TxPos { base: 123, offset: Some(-42), }, @@ -2178,7 +2178,7 @@ mod test { Ok(( "", TxInterval { - begin: TxPos { + start: TxPos { base: 123, offset: Some(-42), }, @@ -2194,7 +2194,7 @@ mod test { Ok(( "", TxInterval { - begin: TxPos { + start: TxPos { base: -123, offset: Some(-42), }, @@ -2308,7 +2308,7 @@ mod test { Ok(( "", RnaInterval { - begin: RnaPos { + start: RnaPos { base: 123, offset: None, }, @@ -2328,7 +2328,7 @@ mod test { Ok(( "", RnaInterval { - begin: RnaPos { + start: RnaPos { base: 123, offset: None, }, @@ -2344,7 +2344,7 @@ mod test { Ok(( "", RnaInterval { - begin: RnaPos { + start: RnaPos { base: 123, offset: None, }, @@ -2360,7 +2360,7 @@ mod test { Ok(( "", RnaInterval { - begin: RnaPos { + start: RnaPos { base: -123, offset: None, }, @@ -2376,7 +2376,7 @@ mod test { Ok(( "", RnaInterval { - begin: RnaPos { + start: RnaPos { base: 123, offset: Some(42), }, @@ -2392,7 +2392,7 @@ mod test { Ok(( "", RnaInterval { - begin: RnaPos { + start: RnaPos { base: 123, offset: Some(42), }, @@ -2408,7 +2408,7 @@ mod test { Ok(( "", RnaInterval { - begin: RnaPos { + start: RnaPos { base: -123, offset: Some(42), }, @@ -2424,7 +2424,7 @@ mod test { Ok(( "", RnaInterval { - begin: RnaPos { + start: RnaPos { base: 123, offset: Some(-42), }, @@ -2440,7 +2440,7 @@ mod test { Ok(( "", RnaInterval { - begin: RnaPos { + start: RnaPos { base: 123, offset: Some(-42), }, @@ -2456,7 +2456,7 @@ mod test { Ok(( "", RnaInterval { - begin: RnaPos { + start: RnaPos { base: -123, offset: Some(-42), }, @@ -2624,7 +2624,7 @@ mod test { Ok(( "", ProtInterval { - begin: ProtPos { + start: ProtPos { aa: "Leu".to_string(), number: 10 }, @@ -2644,7 +2644,7 @@ mod test { Ok(( "", ProtInterval { - begin: ProtPos { + start: ProtPos { aa: "Leu".to_string(), number: 10 }, @@ -2660,7 +2660,7 @@ mod test { Ok(( "", ProtInterval { - begin: ProtPos { + start: ProtPos { aa: "L".to_string(), number: 10 }, @@ -2676,7 +2676,7 @@ mod test { Ok(( "", ProtInterval { - begin: ProtPos { + start: ProtPos { aa: "Leu".to_string(), number: 10 }, @@ -2692,7 +2692,7 @@ mod test { Ok(( "", ProtInterval { - begin: ProtPos { + start: ProtPos { aa: "L".to_string(), number: 10 }, @@ -2708,7 +2708,7 @@ mod test { Ok(( "", ProtInterval { - begin: ProtPos { + start: ProtPos { aa: "L".to_string(), number: 10 }, diff --git a/src/static_data/mod.rs b/src/static_data/mod.rs index 7ae2e63..fb9ae4c 100644 --- a/src/static_data/mod.rs +++ b/src/static_data/mod.rs @@ -7,11 +7,13 @@ use flate2::read::GzDecoder; use serde::Deserialize; const GRCH37_JSON_GZ: &[u8] = include_bytes!("_data/GRCh37.json.gz"); +const GRCH37_P10_JSON_GZ: &[u8] = include_bytes!("_data/GRCh37.p10.json.gz"); const GRCH38_JSON_GZ: &[u8] = include_bytes!("_data/GRCh38.json.gz"); #[derive(Debug, Deserialize, Enum)] pub enum Assembly { Grch37, + Grch37p10, Grch38, } @@ -20,6 +22,7 @@ impl Assembly { fn load_assembly_info(&self) -> AssemblyInfo { let payload = match self { Assembly::Grch37 => GRCH37_JSON_GZ, + Assembly::Grch37p10 => GRCH37_P10_JSON_GZ, Assembly::Grch38 => GRCH38_JSON_GZ, }; let mut d = GzDecoder::new(payload); @@ -56,6 +59,7 @@ lazy_static::lazy_static! { /// Provide information about the assemblies. pub static ref ASSEMBLY_INFOS: EnumMap = enum_map! { Assembly::Grch37 => Assembly::Grch37.load_assembly_info(), + Assembly::Grch37p10 => Assembly::Grch37p10.load_assembly_info(), Assembly::Grch38 => Assembly::Grch38.load_assembly_info(), }; } @@ -69,6 +73,7 @@ mod test { #[test] fn smoke() { assert_eq!(ASSEMBLY_INFOS[Assembly::Grch37].sequences.len(), 92); + assert_eq!(ASSEMBLY_INFOS[Assembly::Grch37p10].sequences.len(), 275); assert_eq!(ASSEMBLY_INFOS[Assembly::Grch38].sequences.len(), 455); } } diff --git a/src/validator/mod.rs b/src/validator/mod.rs new file mode 100644 index 0000000..895d52b --- /dev/null +++ b/src/validator/mod.rs @@ -0,0 +1,89 @@ +//! Implementation of validation. + +use std::rc::Rc; + +use crate::{data::interface::Provider, parser::HgvsVariant}; + +#[derive(Debug, PartialEq, Clone, Copy)] +pub enum ValidationLevel { + Null, + Intrinsic, + Extrinsic, +} + +impl ValidationLevel { + pub fn validator(&self, strict: bool, provider: Rc) -> Box { + match self { + ValidationLevel::Null => Box::new(NullValidator::new(strict)), + ValidationLevel::Intrinsic => Box::new(IntrinsicValidator::new(strict)), + ValidationLevel::Extrinsic => Box::new(ExtrinsicValidator::new(strict, provider)), + } + } +} + +pub trait Validator { + fn is_strict(&self) -> bool; + + fn validate(&self, var: &HgvsVariant) -> Result<(), anyhow::Error>; +} + +pub struct NullValidator { + strict: bool, +} + +impl NullValidator { + pub fn new(strict: bool) -> Self { + Self { strict } + } +} + +impl Validator for NullValidator { + fn is_strict(&self) -> bool { + self.strict + } + + fn validate(&self, _var: &HgvsVariant) -> Result<(), anyhow::Error> { + todo!() + } +} + +pub struct IntrinsicValidator { + strict: bool, +} + +impl IntrinsicValidator { + pub fn new(strict: bool) -> Self { + Self { strict } + } +} + +impl Validator for IntrinsicValidator { + fn is_strict(&self) -> bool { + self.strict + } + + fn validate(&self, _var: &HgvsVariant) -> Result<(), anyhow::Error> { + todo!() + } +} + +pub struct ExtrinsicValidator { + strict: bool, + provider: Rc, +} + +impl ExtrinsicValidator { + pub fn new(strict: bool, provider: Rc) -> Self { + Self { strict, provider } + } +} + +impl Validator for ExtrinsicValidator { + fn is_strict(&self) -> bool { + self.strict + } + + fn validate(&self, _var: &HgvsVariant) -> Result<(), anyhow::Error> { + todo!() + } +} diff --git a/tests/data/data/bootstrap.sh b/tests/data/data/bootstrap.sh index a231053..2bc0cab 100644 --- a/tests/data/data/bootstrap.sh +++ b/tests/data/data/bootstrap.sh @@ -64,7 +64,7 @@ VERSION=$2 DST=$SCRIPT_DIR # The HGNC symbols of the genes to fetc. -GENES="OMA1 OPA1" +GENES="OMA1 OPA1 LCE3C H2AW LCE2B PTH2 SRD5A2" # Transform gene list for postgres query. PG_GENES=$(pg-list $GENES) @@ -78,12 +78,12 @@ cd $DST # download database dumps -mkdir -p download -cd download -for f in $VERSION.pgd.gz{,.sha1}; do - test -e $f || wget $DL_URL/$f -done -cd .. +#mkdir -p download +#cd download +#for f in $VERSION.pgd.gz{,.sha1}; do +# test -e $f || wget $DL_URL/$f +#done +#cd .. # extract identifiers diff --git a/tests/data/data/uta_20210129-subset.pgd.gz b/tests/data/data/uta_20210129-subset.pgd.gz index cd14e732b48d460d5e776a00948684e6c33e5b4d..4f187c32c4e3549af33c5a4c841ebfa9aeff00c6 100644 GIT binary patch literal 86584 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

O7AvYmx9M)CVlpZO zWe_U2u^&}WgH)pwB-&*Gs_`Z=&A&x}Im6^@LBe2w^3ihEQylBbBy#hbBL87(mu%sw zk04@jZxX!Js8v#oI8ThkTHO%>yLo@Evk0EXc@e@om$A50eQ!A1f%LfAdzzESfK?D| znKgLY=`8fZlJ7gVs5zic%c2Fl0<1o6j)9B7yR!!Sf49C0pNVk~#*>LF>jSLAN;PQ2 z{PQ~Jcf#j2SOKacx%id>j!lHgU@3)d2UVAGk@*vIn}b{ty2(B55gm||tmCD~Ldh_w zM!I^Zai(Y4$1YJ(HCP)?yD|#PwHp#3T^s32N`ikuPGdU1;iBUgY%j%ucUWdt{eA&1 zXici0v7)DMM1H>(iU1c7f{1)rPYM^GN0zww@cX-t&9z@iIMlP(484xa$ zlh$e$yOGeM@3ye24ih!oZOu}eY-AXkvaPnb$Qg#ZcjdY?;E!g&g#2e>@m*k1?*%O0 z;Q6Nym9A%hdH-p`iYmqz(8T&`i-$@91}VJO zfR$4qk&aSnb8TRjf=#}GO6&aR=h8%%$?F7xgu8?(4%fn=AVe8Xmzy-zZQ;CWwrJFT zDeE#2sD=FmE^hUe*%@C>-Q`m`ey4h>e=J22DVHFBk^wrJdAK*RZ{4S@+9{W@xi&6r zAwGWQ>E8MLq+tkWCdSSVY72?Qgm0)Oo=9z2v;Q$16IetehLHz>E&BCZNaph~%sv2vG&YE4;$qFZEqAwqCUH|8*?FWpsigjqUK{@l zzo~W{2-epqfc1Dp?3kkH@@ZDML-S`V6EVM@#4RIt*-b*m zRh@BGu)XjQ7PD+orG-+=Z(YU*w`hHcooW6E5 zm)tUyw*I8LgW?rQN0{)RUi^q#5?nBN95OmHC27`O%}P0JB$VBLs)EfW==+EM?BZa- z-upZ3ovos`n=~dAMyW(Q2wKEh* z1uKzSp8hAQIC-QABz65$v>_3AKqI)2T3rg#6cJoL1r=oV)GBhF%;=D#)1piQ?QV)n zFJ%}T`5PeC)n8jy+=7WOeucmq#@#ilonl`p1n{pwzRL|F^vCD|m!DkcGkSm`+wj=? zmKyBsG^?HRqh3HbncOeb2Y8K?HAR3%OxTNV59$}8B`(px;JFTM(e*}U{iHrx!=&5Z zr@3pN4p>Fq7DZkH`K`zgj1pY)c85M#z0cmgc@CQNsi)S;+mnp7)|jr^P^<)4;#ak0 zqM#dD&n3enkhGgN`>;=YW_f6X{p!Rkqsf4Tc_lc->s9+UsP7<+5;d}j{V`u{wlQY? z;vj^0vnKZk)9=+ypLUA<(SoZFrdcNKne;54{S+^-ypom*d$I6t1HUSBmn^ zqH{_RGo>^0=%+vD@j3a>%beDCqeWeA0OBZ2tCNIeLrt_s+@#60i!qN1;osMoU!{GO zme={TOvBU&Ku#=%zHgu*3=~$1dQr7UZTR0Y1}gj{>!N?yh{hoEL`3bMI6mEt`F91Y z0YP_HPpQji{1s>BPzulOZX^hbNvQ1UwHF2C8X~er~ z9`BgXyEpeDAC;tWQ}HtBrt8Zl4%s>ZSzt6a$b=ol#4;fNEr?tb#>^LrH6va!j=|{f z`e}md3=e%O-O}>~1D>d2FSQ+pAT+*VXc#@YQpwfvUvVlPb|cy3kl?kqlbfxbt=)3d zO)Sfx*tdLA_6{=Q%~_o&$kBh4cvRiSE?7}-DyxlA5dT(}_P=>&)t;XQ(}niXKHK4u zmvUFUh6!On1cq89L_L0ZD_)Z`NqbXEefK?_r>S^uJ?SI`DDZK-yD&1@X><$LT=%2X z3}<`GGnsdvPwg@AlWUN>ug2`fk1#>UU2a~Pb?x+aYJ6(X^Hj}DiH!d$ygWt)t<#%D z4&yqvxdf2?yCPGT_2`{U!AL6WT2h=Fez(0B6U+q?lN^%E{cWZWP5F0ay?TB5pt)t6 zX(eSL^?Tt#V)^PM@%!|igauM-1KF0_3VI6keww)99!jqVlDb<69!s*k`hnUDqaAY} z^EJzs``D8W9V&Pjb^kUvz4&h1GN~JjZ^Lb%PhnbQy4L5eXN z;U{#2wuKhVy1kX!ZBD(MRq;6Bsj%hQ)*~wxo1#r_Y9jw_b4vV#8au7|JQXP;g){%+ z?WJ*nII{<-km#`{`JvULqT@^_L=3Y@XdR@Uu<&B6t#Y< z^!)v#aqfa@NyG%BgR*avy&C<#Eq3@r!ircrt`E&C*Z$Zeg%i8ZJ_+W@guK8>RvXpX zABe^#fgBGup3s~$+~jfNrrcl*i>#DL^lo+DO!KB*#P8Oc*eI4r>ff_my6TKiiL$te z#Z0hg);HE&KgS?l?^ejW)Z368#r8DM0Z3>is59@=s{EFQu!^%H(z-$XVOPJK=)nEAevzbR`)rZ(PHRr}UHPh7&1>j8g`1!`EX4j}8&eyf z)23S|ym`sLLL^iC5W%O{X+C4I<6l7&W|0CO94f)xY?OKm{rl-^C388;6XeY4v69Oi z3wgswA&^gr5%I$GxsDCn9?Q>k%oA2Ep$yT9vdrs%8K*CVNgAt4+%ChLv))1+R{otN z0p>(jk$DAZO#}e$-2i~^Q<=?4l($&eSp?_ylr82mMKo@kG-U{ouYTvd=!oL zEYrh{fWX=Y4xU~MT9YwKS~nqU2@Q8u#N>vpa?SS5cFg+D{k!A}CrJso)E0@z%a$Sw z+AV8wVl{AO3?8QJaI~h8B#7!eHYDW|y12>al7@1>U|CIoP0DbAHZbLymo zogvPDS^04zHC@DRmITYkSg5Cz&BAXg_2G(Bo7NA zg}Vbqq=5yA^2gm?>AauoOUj{T3AgfkMq#$Lrr}y-gpqv{X^{lr7Gm)e-;Z~aLdw^e ze$E-T-kAwN3u!)>?r_rMUO0HiPns%t)=w7$r?_DXNhR8W4Wf0boA<#Ry4s60q~X!T za%*`t9OXZcVaDS5Ht=2-FRH=xTz^>#^Ql=C2H3pvk&wlbrx3r05~Db{Xj{b`C)oD! zwRJZG2qLmV+xH_2 z+lwg0Nr76tW37V>>MO#S2g6E(iA5 zV_{7v2%4JeVqP4u`g&9EQ|cm!@EoPbr)1*ADU~B#|g7?ydY#6w&QgYtHHSQ zs_5-OJDlS50`C~95WPhIjk&PDZOC-Q%a%&OBD+k5wP49#O&8+AHY#t?Hc^I)amo(D zq}y+q0l-6yJNL@GZ;3MD5p$YniOc|WbMELGdwT|aBjMfF32#EB(I`yreY9>LTz38v z>P{HaA8=qiOA)(jP~f)B>C(_`4bmSK+Xf!mQZndS+)>D<|M$73>`DamFW}jOYUt(@ zstnk^UJTp8B`W={Rg`9g5wgT!qinMR2@imdLZx=XO6kQM6Y*0iB@yR|07;TS#{-tB8gf%Asq(x@DdbTRz7s=K`6@8%ALj$w7urR;+hb-m*Fjk0`B;8TOLi|9au*ei!^Mo&jx#2*&p z1hwbpq=M{LrNff7@8y-m6bQ0L8p7eXdY~b))Hm5ChxlbwrlEm?AUw6RavryX+fqX& zmSG<#oono`otgyK1FXe+Ii3XEAfN~r5n%&Cy& zGJgyKONj~_jGDWzMe$}p?u=pBk>>8VW zYj`KrQ}>AccYc08PJHM5xN%_AuJGvr_E;Ub{Au&{UFhwvFBAWkTW)W@ZI2%Qz9>M) zaD6;0lm8R+82aFV#_D}MHo78ec=|l+)Al3E=G(7lM>#sT2fO^)!KQyv8}9@L- zzx(hm=mrtm`*^)-s`Icv82H!q?&pNwv;1!6$Mc&FQ_tUe3WK8yR;zCxVUH6(|J}v? zozUAF-LUzF8>9F1-Bp|^g&^0`ZQmXE99Efn78iG05&$)Mp7K63nALhjL1Z(E!ry!= z=K3o+n_RlG0OwEhPu(WW_BKCk_&7^Annpix6HK|3)P_=MlXvI16oyN$W+sqk?g5&&I zADeAzPAQiDr5n-TMYf@bj^FtQfdkRusp!zkO%n;>Uz%qTc;dpIKLA~zJ-nWz&$s&v zFLLbvj@i#>04@PlI0NAf6UycNfu0E^p8TBE%O<^H3a*Lolq|~Iyb+4)UV!_<0xj

HAoeZKx?9^Jlw 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 ZId}YJ@vT(o+YJQf6QyKVVHNy`{}1eB6QBS9 literal 78023 zcmb4pbzBtOvp0=|bR!^0hYOMhElMLLNQ06}h#zh`+|>^xA2Xy*|RdPTD$(39g>e-5K~ zw}ST!O{2i|UjAY&4thFbgh5StAu%U2=?DxG4n17jI4;ASZFsp_1fW)`VJwv#xEHQn zNNLNa(>5 zFyShPSx+B8z>ZJTy~^O;@|nk|dTHcbt=BT72~Fy9v78QRy4WjmMax`)?Ner5bR9{{ zXAPj2dnXV9C=??Cx*zTe_q!`22RlaB?_y@J_PfGyOD$oiB?EJ3O-weYr&IFKz3o1~ zXPEUk4oqLYbQ%0?o z%SFy481(G08iu!CbI;`z+EC()+JS-_6_yl>l}wx?h$h>MOa_}Tge zym<=!mr|a1CfEkLf4Y^P)p)vpHjzcl*s%Wzb3SH|*(-dxbqqh%$wFU1VCePZg{9dh z^zV`^^!b=8W-VPBL4CXd>B9dOcfRhGh2HzFlWLAwdnkW81c6=rE`;Buw!AokpW8i> zJKJiS8Bpu9Y(lkd$irk4&QIa6i{%+Gt6d_GU1`R3`G7+-SnN>=Bs67|uMxHKi4L7G z07Y>?FV@gB7e913La)+e_}mai9GKOy6G|u)J(gV7#Pa84AsuOPv0M%2-Y0*4IwAkt zU=@$IYgHd{wPFmN4$=Bkjd*f=Zs&hqa_ovm$zGsJ5a{LOtc&er*m3&6Nx_#jc4n@*}y(rE`Y>QY4ShZ-r6XGvrEhUxL^sJJA<7c^)ARZox5MZ-rWCg7e`^W z8AriwX$-T!CGE<9A&$5vf1>j3#&*E&j1lZqkpPbD&ynxlo&v_aU_`mF$bmWOW6bG- z?k?32K=7Z^j;2f|BcQ1rY;tCU)nZ)iP2oS&2aa=BMBlrjkg#uvt&Ux;H%B?AtF_8g zNI49Leh{V$5pZe=woviz1@GQ=85DKK(Rd1h9sh>;{eCQ2`rNkUez%g|7!voOH#=Xv?HShCx zq$EfC3lA}@{)jU93m)h-HKUj3o^s?!9v}1q5_)#L(D-#0V}U@z&bAO2oq@I11Lq9f zJ7TZPEfqN0Z%V<>XZRR**v4C-gNXA@dz`EC?3jR`w3dyZ!q;LcbP{13=~u5_Y>yc2 zKxr7z+s9<~Ct9I{^qz?4=kq~Toqq!woa31s&*oVi&*IlT=KKBfwxSE6zPV9J9G2V1 z>xIX}7^c&1hoi%ESC_YoY=)*6T=ER&&eO{ezlVsRAC4Lt9|yP{Q(D5I82k{3EFN`= zCj@a+3RR((wYspB7r`giq@&6#b zd?#1$BKFma0*5x^keJ<>_1AXD)1lxH;@d?-@+RlNZ*0k*uS}7t^>I|9Ke1(=O++`M zXVNie`x6NN{Vhss!G6E*Dq=rM2p4XFZ>9V)(Dt~cNmPy>ED}{K@axy|GOLDHJgNw8fN~I)z zn7uVX_y>BiCEtkJUg(gc+KdKgb*KByPYze6knqiVk((s04}Y2Vm3Pmu1eFX^J&A*B z-ad68?;WD9D5ylyN{z~ z8?!5<-o+FTyZRm}4@WIWOUuI!SFi{T{kma$b-xTim6|zWf{^D7G zSwn4E^6`l^*Hn18LxSI{;96;xm07dE?LOSKS*AzF53FZS^h0K9t`Ba{qzg?q`sMDr zocHCfwaxFA*(yNg-rDR^g>$gL_Ghw)yc=P-@<#T|$KK>OGx4X&?4S9Oy^1NB;Gp{> zSG)sZ(W?l*7|bO_&=4_@=N`K@F)z%CCWzh%GbXCxtK7v6S=u^Hf^(Q-ykN(@mY5lg zy)g@HZLoG`F@M0Xgn0O3pAvtgnVa}e&=;aiMI-#7x-L(v%#(Hn*>{J{vZ4_|{yFPG z0rAP#R*CCaPP$k>K0MI4pi^438l^P7aD}0ML*Oe`{%5$kyKzr(&Z($5YakCp9`7yl zZ0{W%W;LN7cb1k3?IO|VM_a&HRS4~xg1t8=znR2A&U0!WJPf!{jv(9aoj--op7*Mm zU=|K1V9;C=h(Go0eg`CnFoa`1-CJOOfwHI1`1Ts)nf*CR$I^xlt+?>(WM-n`x0fYl z`RO^OD*~pf8HYH>w>?IkR&hw-x%vKq7azlXgW$36(5Dt~RH;{7miOz=J)Xgg$TOpU zFPdU)OSWTt1>UsO^8-#CEYF2Gaa2p~`b> z)@r%0gTZX`obzL2oAQ^0566sr9Iwe5e2!6l&jJEg`~v3v%AP(ggS32`2w$Cie&e1L z(X@6(nEWy+{g%TVd|8(6$rt;rWv<4>3!V%Xq};y7Y{`rDi8`Lf28UA^E2Sm>=idR3)rS|Qg(tg`HCHoy} zU)8^%v)Ho%c_xkC)%Y7YavkP_`7Mv+>?OjiSfWL*czDN>C}r(ricxRs-kd&;ddT)v zCtPMsZ1!*>N}bs{@9Z_JpNHUt`*a#{+q8RI#Yv!x`*6GEs6N_RS!6}}QNZenbH&pP zW&>AoZ*8_gEBb)pxpy-MkxO^*|9q(sH??$2Pap9A+{=2;kItCf$;#N3yECd~ujcE* z^zzvo=NP#|&fLGf(y)_Hoci)ghX>L~3NjCG!y~y9)59O0f9*^g>sf8QbyLHTH>-l#cn`nMaWd;8|H8KQni1^KGxCge z{n@BdGChLK(oOrQP3i=E!~BKad3W;5dhiPxMKcIC8( zaz1P|H}}UwmHVa{|9B2JLFas$M z?&;uEve@dD1}KIAv1OnlK5i57sz0R;%bgWUCa0FEDe5Fs9ws3PKQ`sUcUx!Dw{D$X zd-4On1k!Gp)%ux9$sD$u8GLv=t!out6WWcY`6(6)KT5+D4hH1gwSFCr< zsysVVt9Rx2amlg(v)#%JNTD3v?meoGpRue`{w+u#>e+X;j|tYK@m&Jx+yqBO`U(9H z)R-$k6EF`po) zhAvs>&W#wk7p(TPowqc-%gSqVCp46Dn7Y+2!3c5D^Eb~4&zKw=jOH9pDSk95Io7o;^*i=Q}372Cl{_mPGl#y zIZx!r(g8G!T9t^qV|mbKK80n*+`nWuJRhO!eBVf z1;v+&9s6hTk%jaL#E^jiibDJ!2YFxw_Q zp474UYJOyPjVk!42K7+KUh-7TP407m|IWkh+($hp$MB1=Qt2iNqgTBgD3vwMppyL1 zxYoR9U34`j4+o;6=Tq^F(lt2pRY*XUNOjy^PP-bjkzXW7qKX=j%(gsb6c8tY_*p*K zR}uO^lpLUn%58GcC-?r{CCUPMvM4}S$KKVxl`P|KdA}xeE{o^=Egq!_4JKs$8@+-@ ztG;Wt&}4)>_PyW(4h8Vgh%yNH6L z=1?vne};gJNto1p9(gJiVX2a|+U16vty1~u;_1(Q_EMI#eb4n_r-C@|OLP+N)thIc zl~r=DRf8SfeCGV-cJV3&t~6{u{rai_=i5y#GaY=fa~jnQyiXg<=qI;|^?5xSC8WE0 zuU82$)L9TKobaSd@hDHUtnX>aIFp8#9@8y*M4?0%8CBt%9bXU8N6Bwa6R0fWpb}&nN&#R`l4Ul<*&#e*oJ-cBUQ7a#J8nU} zi4Y?u#9}F5@2Buq)E*IUn2#s zP(Hs!sBTAU7AoBvt(Sslbmo0l!SAUzmrg{!Q;1hA2Fwi6crx1LaQ*d3xtybQ6fWe9 zX^MdOy7rU7LjsKO%QpfPb(y_*KoB{2h?nb4!lU_V@Q{?hW|5}AZ1v6w6*Q7pb7=68 z$i{e>#FP5(shcLB49?4L;?i(y98EWzc{(Z!O59}(&nFpRV#HTYNGKG{8VSn^ah!So6LvKAu3PKu_I$b*rd~o9}5-gYj+plU1?jDd3>6g5O6kJNdRK z14FSW34~HSo|s^GJ+H-0s$IeYipG0-SYC zUp2UwRR}iRHDzrSD#3wb57@eA%JuE$e2v9?jsA6#{EuO|;~A{ES`<7rvnO@z>I!R` zL&}biIvW(}uBm6NFywg`WQ)9CeuSrP1%7@XA&B}jQZqIwUY$HubQ?}Pod43(@Eh{oY8wn0i0M6kx%@AYYWA4n|H>UXv^;E90c$J17ADpbi zd&IQZlXaS+(t1r3SV!vyHJ*yKT9Gz5rA*BhW>{C`ElYH*Bifkpr5VK0xQ3cX;sra> zN{N2~T&#IF?s!TLztc<2dBCE_qCcvt431iC<&f)0Ud*f}9l8In_hEDcbS#bw^*vmK zynk&e8*^@&e3aO{kGol?q5-_`MYAxAqiSz7(ekS|w_VlRbQ}i{6G-DExV3`@56LmY zsV4%obriHAmNvWk!X9jzW^is=?5^NzK4~Sc75h0ph|Wp};C; zhd)*YGGX1ZPUb@vtbLujEibDo17os?W54=S1-n1CF)ZwkPsW&8Sya<~ z8s=a-JX*wQk|81K5;4xJ)u(%Z<3oX+K%R=UV+Ik~RrVZ|ijc#M4~y)5@(&Sj#Du-i zsU&X-Qia*v)>InhVc{mHb?twA-(rtbopgkiYmbIn*UG%lRiJ~1Cx=eDjpx2aFc&Fw zDap{Rf{QfeCp20}i1q{N~9^w)*2!r#ne2>Kc7bb)Nr~l;28EOV)}J5A?cgI)+7@Xy&LLYuikLp zh7?ohA2X|RRv@0GY##YPSmcpR8@hL2wtCckdQp*?$Y$=gvzvWPiekjThP4bo6Y0Yq zTPD0doj-tzXkJq7w6x}kB;L0+#{m?|*-L6SFivUF_k};G65Y6NJu_NYq`(xBwW2`a zWNL7oTw#O5`R^jnHSUwe8I}mb@f1d80g`8xp$6x?_=J|Wy~V<}sq+`>h`8P*7e(Mv z%fa&vlPV+dzL~=bA15_O;Keo|xP(lfDUi5yoJBS~3rm<2!>Q=ja8MfCqM%pLujBcsz2(2UTp{wK4%Ed$%DXk3 zRH;9(y-yzXuEXb^)GGnyNZhvK^oG2!gdo}sVjHFzQ3jk0Qqe@>D+J|nJH(SpF0X7` zmS|EAPI5!KzSl-AvPhZaa5x^6mDjG%I|bBaEZ7D1Roe(xCcGC=S%Mc$}-Y0&;$XmoLwxWKq3w zu(3kOT=j=kcc=?DI?(5_>JPG;6CkU^e>_%YkUnKrYM3Ip^DvNV5<9X?O6*)$%A=BZ zPEUVRT8~>#9cs$wkm-FEAuZi?eCpf9aiuO@NUih{anXDn#e>b|p7>rKZ@-iG=?P9k zQDiH8C)61UP9?#;^v3p`9Lh+g&tKI_uNdE#Pm6a#m?+Fq9C6n z$>6sLgcp{dN5z#h!4h{B9rryujNDFJEv^1QNR)T(@8qj~Q#>JzzGb`b(=pK^Hg9>` zS)gr&r0H6S(7BK=WYH{Vo^_IWZQ{h@SQp{1&hcVq9-_*-W6G%_kS8PYYR4#2JmG$f zium{~X4c6WQy!J#yhk2Pu$Ixk)!OPKF;AEOT6Pco!m-&*dnx-z87~WAQmigy8W8Jg7O2) zCG`{S!j4neFiuV7V~U`rEfaFE8no5&{Q_J1k#I;Ra`rX#vxI)QS5I7+gi4iKgsx-3 z)pE~sGGR=)@3IBQQRmQ}&aZUX+M-s;D-Q+Uy=Rr&%cALUGVf&9J(;W50yFHsV zPYE?%O+~3`Iq|-o{X=`vGpE)0m6_mRQAry;Q5NaygV{`BSSbf8I&4 zN*y`c&AMcNBdV#o4aGfk#TO-|4?DbYzkRLEq(cz4SIyTAcU^6(Qt};&VI-eoSyR6u zO+F>KrX_A6`eGx`tIxZoJU?MGLC=LLNji4|=m@3j7B7Wadx{G-PK$nVevqFc6y{vs ztL?ZPX6+&_*f%Zu%k@EiDr;D1Uy;PCw(=V0L^~IzD#?X^Wg&JAR+Hl~$!WDu|6$gX zMD?3b#1EO%{V?7X;@bmpD!8Y%I7U~14=8nrPKvlfT$MEBDjI#y(ie#>>1wEf6Q2RG}wCB^F z&h&V)+a4GO>DkE#U>U79(Tm?jzm$i|qlC$YHs`8CRqgjbm%|493w#VG8?*eA0IUCp z)!NIAGziK$%Jnt~S_rgDl|@0)hHjNbm0eP!JKy?B=IiY$f0fWAJbtnNnINBGszFe3 ztwX9z{ZSOCq)D*56f+J6!cIX(cL>pFq8{2Sd|lE&akeEWdlz5ZmdT@Jk{ z{wdP@yxS}2qsWV+om8Zgl=GACA@V3q2OCT#>V<>NF?26=uzmIdtC-=p{QZ-FN}s)w zz8|t}TSgm~u)w zb&}1$csrWM42k$|sF$ej67k(rFWRo*djDf}L-ktD{&96f6Tlv87&>7~8v4H2lBRxC zEmv${L4m|8<&R%e|0niXa)Iz=m0jBCFSdVYlf4{zJuZ*-)I)hcXN`WkHF#9>?WeWS z<`914e5;m9y8FmNju-Kf!Eu}5B#jM*ZOsAZQBz6S=HeF;zz}htqH4m`r@Wft;7`}+ z-Gs#Y=BuxViDgw(nboPsSKBA5RmvXKa~Y}%PS3nIchB~cewI;}eDWw`>Ojh@=S_Nr z^i6|mf-83sL1ku_G;#&>*Cv-18f_V zFVs$Xx`W1)hw(os(=OD2g4lRhMpu!3fy$vqeC`JdQ$LTbA6gMiN!(q;JSU9nYn!_! z7xB+JwvHBplNTyMgESnT@Q)4Gvc@246xUdgkH`Wy*^{w_=Qy8H64ORCJZs6^&%JQf zf1MbIMn1ZT&-0=tC2Ph!zm;1@RQ-fh8&!(0x+R=<=VHc#<;e3+?b^M~jRWTqpUH`} z;e!40vXKv3PR6dcb%>>kt?N7PU5w|2Z6)n_7=2)=GW|KCq2)B`!mP6*QLI}}c&++i zF?$9tMkCN^(1oP4hPgd^hAYNVJVLSFmMNKhEPF;N#ui)3XG*36C7T$H7@&E(ljq@W zhmLX`jd$*YQPx>W+@LOAQzIVKsTJ_3Njg+>kHqJ(RGP*+s_9+*Bhp>TT}-r<^vopQ zAmp{iEfF;fP_kW5SD`QwJ1FFfNYZ9Hjn0G}T6FAW#9rS$wDuUVoGWr3(vp8y%v0G4 z7Yz;ASLraaCZoN;GoB3oXmNf2$0Q1R^=Q!5N1N{*%9pF_ij+_O%`nsfZg<72wqdPv zvUP3eHEqUs`(4Ub;&d?wf?*d2IH|5oXZy)W8}lM<;&;V~(lm-0LEQG3c{&av(KW`c z;OQ7WPO)}6QcQ4y1TGnm!-ELsA;`2a+)yvaMl-PDfb2;6N(#T4_~|&x=+UgA$P@9> zhkQj7JXX2zmr2rSDbbMYQ*hdZ<9_Y}K*sr$xJgnJ%Rq~+3lewk{D82p?7YG-Xs>FgDn$fpQ zme+N0<$+v;Pfo=o_BX&a0?JU<3qh7x&`>ZVpjWJ~Ls+p`u#Y=X9!QzJHfZFH8&4mc9nm9$1brz*jDwx*C56S3s}_t z0W9`d!16W0f^LDnt?IEah^^#PPHXBS0Mz)dsY9g6O`{yO1(u_%SvS-4(`v0#rodXH z$@kL%0tmCVzQixWE|>Tv{~!F)aEV_YOXUv#y4tpGX8;-jz+#kEYXbm_RKWOYjJ0!J zDS$114y-oB!+xy&9JeQbK9cqI;fp`&sV>g4Si~|?|8;JiHwWN^o4CU}wBYOeYrqw!RjIoV zV*$*a?k8dvpB#mF82>>oU;aTZU;aTZU;clQ%m0LGMtU#t$sQK71e~MsB(xZ_P&Z2v z3`Yk5vkXeGouh+&Brndebmo#aUeXLK9m|u;{8h4i30Jb2ocBMg^f{y%iD2Q1lez$a zD?({Q5@l(6y#THxSOBL^1soP_F@?iGl7t0SrI@EJOaoRx(kV`=9*^QNn&^RR za&g;SO}waJA^vM8hAWB|?GyBtJKiju=cKxM2Ct8H7&#c+3N5vs8F;2oN!Qdl9gBK*%kpfr8m0SEMxMQq{f76_cOpi1udw-35$ntBoN}8@my11F zmv-hD3lM$0CW|Ymhy|H7IyW0#_Zc{G8p+&9Yn5UUhoXji@x$ozQ;5lhu;Jw~He3F}kBviy*f{hVn^uGT6SwU%Hmx?q zrqv~viurb#U`W&wn3Xov2TV53(gI9&J{dcc6Rem5dK)Cs-3Q2C>hvo00zb>x$x6vv zjc4v4dw#bzoqR*eIiT`0>gHf2{cxIHgTlzTsy<7t;>cq)ue4n}EmJ=8wMCE`3&=WP z^WLu>`H8F&&ObczlK^Y<$WI2W!vow~NRW_kfave=CvELNFq5=haG61*^%4sPvIW2m zM=Gnt5*7@E6jWfrz@UM2E=WJp{@6Y18?|@X8|f|^7+frjv&{O`t@H1pXhU2AwKg|l zzu%*SX_8Afg4P`${%+VCsV^H?PR!~L2#_jkfJ6;Qlr>zYp$)FsWVFFZ@LQh{$48Ki z3UMUpz1Z&w$GZF;Vr)vfcbSsd%9F53H#sLE&QyI!=j1?tNIRz;`- zTZzr^m%d{&d=yAhtt_yq>HcS6F)2nM+Jm$iSjV!VE;gn{jsE)JBiVQv+xcL4@q}6< zU6(O`_l(;8O?mxdeHw^DBQ2MA7vOGUPy)nxfCG?C*ei`%AlC0o8+cP-A_1~yL&rtj zG^ddmUJ1ke55x{m+Tv-0qY01Mvx^0OfS{xA3xW;^@;F*r*sM7Xn>9;fvt}nSAD{@b z=3;En(Ff5!umD_M;AokHOQ5u$y(>ZII9iK~1Guirv?vhG!+70y8M8>V7XOlE>%P13 zY=#Fx@19hIk2;P9xij`M6XgDNsNnf}1??$+-F?TOYv~ZjCbIdOz9KqzZzwelK{#LrLZ(VYjCY=f|4)`8!!u+Gc7mXLPRcl?vBV z@V%imdT$m^+ZtIyS~^1Vw|$IYV(rZi(_D(>3Md%({!>VK#eC4h#2Ke^iyaID zka{io9WlYakN-`9q0bwP9HS@x0Q8ZNCf1Wp*-4JFdFowf!0|~yxhZAtdp5}rZWOsg z&pQb3zp|59Vk>IP$Nq)*77O$)fj*!8U82+u!{LVDmZ>Yq-<8|T$NY=LK_2? z+Z=%^F^b}u6wO?nMa(*&b*^3y3RL|{+Xeb!fGl*K zdB{wP_8v16k-x=mh8X!tF!)6v>i)XB8T~$dO?fBUD-E=kN&ZG(gwo5vb>;Y2pAoRz zjX&Ui9vSRu%AvKk5akIK$`cBmZgzQ|=hx?rTmLn_)W99T{_6*J5YRTO^n5`IP(Ed{ zrY_Zaf@b`jeMa-&_bv{r~})uK&a2G<)(1o{X&UX_;=x0KWfEznN)4gW0R^N z^FP>3th^VSi4ncF#X8^SQkTxp%n&OO>4Cr9Jhe*zdTh>2fm(0f+D*w*>KsGZ_9VN# zi0&?KL?N%dZVo4!TfUoNs_bvE#}+rr)s%e_+r+)6((QG`^ByA5lnaUUf3nLKptdL! zkKEMYvK;e&Xi3AIs6-BEz1_Xj_-3XIEc;pHVRI7ylSyJ>DEa<_eEK#lWw@k_mz3#} zGXE)Rt)sO8HpWL>bwq2t5`BjCr~!m7aVqzk!$pGf*v8}OX#0X)#4Rn!I?E2PTi=~ znavzGB=pRHMJ&hYXNtsvm~Uvz6LEH+U6f#RzwF&Nr_QGbq|AvXF{|{q1RI%#gsfuJ z#U5Zqc9)_)AbMtyhHVbE9kc*JFT#Q|cQ^+0{verm~_CYP`NxChL>j}ZT{|4rX9}?ub5_h%a`#3ZmWR<8ggx)@PQ@uQ?Owd`g%1G zqIN0zf&wB@!BAsBANP5K3gEH7D-*}4^Cc-uGnI_Q*oRXvB|a9$Qj<$+aY=11soj51 zT|}kwnR`FsKPY1!0G+G%rTiN;?|7Cf7V8g{C=*=nxgv+3CRos;+9WPv_$%SPzrDlf z6#g5i{y_sVod-J^jKuE;gqptl5c(_bF)!0&=Pp$i2u=Z3q|TA#LkRvM1A*PjfaTjS zA*&Z@yDuzopH9Ts?>mV;$fxUVz{3u|OfM?#^xLnJkAilM&xmi#21t-G(0tNvJ(0X4u|OC9hr7k|p6k<*)4UeXxKdVH)`BuB zY7+LNntZLp=%}d%<>f`AoG=x_V2-)&cOj!SMG8B`?iczw1u9zP8{`mAW3I)InNcdpr{^IeUq5WiX)ve{FBQVZFb?W;?>d|!ZbRyGG9=UpwTR|Iwcri6@m+=>``zZw5KjD;@LMD#{j$hC zsAv4#9rmIcM`tj>(U&tchXKPo{B~|9)e86|JguUt77eO9A8@85N@yW8t=uh#1gP=UrM z&4g|-Qu^=-4KfXaZZV>(EN0>EhcAbif{4H`_UWTkpAL%|G3#AdlN5={M$TAMDKTv@ z#Eb7`>1p8iV4ohmK#?me5aP|-AVztv5&ilB3IC~~bYIPR-1@rv)U)ixdm9|IKHZW0 zt1d3Op*(^)bKlfWO{~?T`HhWz$%KW2d~V*B{SX$>pb}2?I||ZWeRqa~JWJ=Xd^meC~Yx zR%y%j%9O%02O+d574sC)mK+uH>?K7IT_v7htuR%JaSb7w7*hDXXB`-VevlNcVRQXf zD=yfB`CF!UV%)$UJVQkXrSufEK6vPMr(Ho4Y(vn6ip})`9`2lGZ9y@rk$75NbwhkH zh%R-0tMTvQ9u1TGxYLY45JXLAcTJ3HpMja37Pl#xDZ;0lT%deifY_!#o!k_PZ&&TI z2d0ikkln8EtKO26CnTsUKPh=M0`D)i7}YDpvup(saxto2u<#x4PLUrKc@OCB4B320 z9)0J|7GbOQmYC~B)s&tPcpoAlcKbFJna0%^E~X+=u6)g?u7?C-!|K?x`<(H{*Ggc< zDc65E3iEl#QkviUTBo+_?XNtX*%fH^c`~YSVZxzO2gAvAHw`x&1sO6=XouM zX*>rKNoo(sBqAvtUh2*HzPU13kPl`cppj8^&(TdbT(Bt{JWJcCy^kUkrdQb6T#T+% zQ^0v2|BQpfYqS+TAUqqA;s1qEY<9$Rmwj`wZJ64u%&>v@E=nO}V~9+xBAs%Et+b1a zyW2&sVYw#r`y02T1F{p?qoU`qYj;lxbul;ilfS`Z*#fc^ncs5d|B96}s0}nMGFzND z1jCYq_2&7!KCpfiyKy_ZY=3i=lEngI4a=~Xhf9zLyfEVNIojovNxd#r$2PF|yRWNx z$yo zXXJAvbvf1KwKifWK72rmVY&D@qM!pzz%9NbiF;~n>=Sp#*>^Sb-3kK9fn^Ed$K(O^ z{D>xP8Z%Wp*0OPPxs3X{Sz7AFPAu!k%sI$^OZ+ z&Let&c+6t@lb-JyU%d=#*P|m`J)|#PS$C4yX`kfl--4Q?W^pwJ-y((I`~NVJHEnwY zTXOp0D;4@OYrn(k@CEUNe>D)dhJ-yX*+GA>*YF;ktE;$_Ja}BE?)!8pzpKX9M`&ntcW_cf3M&`yC(JjN zn*^BTaFJ$8ROKgv*H*)i-xG0R4^yk>l+&S4G`WCr(9>RF*VMl+1st|rKP_P$O5CA} z)NPkr*-unejK9hup`i(jA)p@%@USc_5~d-7eONZi{pE4i#&)Gb@okclu@xT4oWaO~ z%U4wq_8KpW6L}=_?zeu?vd~jjZ`Y$Tb+QF-*r?ksOr3aK_Oj`|Bm=j?`%1 zf_&Xu{i^Wiw_^Y$zS>os<~qqw3Ea+)s|SQeEb{lSv1&|J8yie4ko#XSi%B7 zi)!9WZ~sAs%a~ccI>}EYSgNYL-j!r#o}(Dtb?1huoM(49zm-^|u1Ru4M7()IZskn@ zYQit>V(J?-bh=KO?g`^OLOBYHhB3oc?J9I;-==7uLqCYASQ~n9?Ikg@_bfymhy<7_ zDXZ@oXV_ug1kE7-AHC=GMw~o~0ktAOs=xy?v#4wN&fvwFZK52f`;<8Y{|`09a5Z)> zbZergf%6GoA$BhIgm)XiZ}z;ceunj}49Guv8!tZ$(Z3lx6p@rFecpIgS?Vh%6_hpX zg&F0a0H%tUSA+JZJi0q2f7w^B#lPJ!L5|p3E%<`v=k+FN?MFX$t3=6?fp8D zTUBYj1p$om^%D?YSh!wglKdl-O4QRE?%z)!ua&a?kem>KS90pdL{v?nLU%7w z)OjzSUKgk4NR%8J8O?tc`Mn$Z;V%dOpKsyTJEnHtyo}p1zm@i}Pw(XH#K=P|!LJy| zmH^tr{pj_s?>bPn&0$?@<|cbs3$O;l*Z5o3O#av%NKvcEUj}tbeAWjrDT7X?l;Hi$iO=MU^|2J4DGx%v>j|nF@Z)ZnueQK5v`}w@w-N&9zR! zR++eZv$gJ;s*V`DdYku!S*LAWE%P&`p4>}4^1TsE40DgR|Fik_3VVBPzWCdt2LzP$ zj@54SG!!)VhytqK*vvk==2F}n#FYFl0tMKYjQqFT{~LKa`8u z#su$%y5$dwNDyFG=37ZYY;gp!1$QK_YEWnm+h)Mz2>>ilux@8RiiVz~XRDZv@#^8Rh z?q=Sf=*5c8r)9xH^v(N+?IL6S6_j7PYNBwZQ0+Hs`h5?wNxD5pZ@8g4Y}cr3g69Qm zXAV}sk+`cs9gQ72ELI;w2uitY`k%7a?9EqnO1aT@NRIlmPBnK_=u8|(X*U_snpGLp zFIMEO&&&r;1ksjI>KzLEJ-+qE%6pV|*Fx^f&HYCI1hZwo{Ekqhip)ztNK!!UPoXL< zM9Gz#lZ5Ff4@>qMKQDf!N^Rk=9#C!`<4#6D*tIZse|t=N#_9zj7e4EOY%SYM6mQKD zCTrAqzfN|t`duwlYWF)=na->rOex+hDNM=2jB-JYuEVp{aPD*bMnnndXM)-&sD!Lk zyp*DJmB488cD`)kkB$y;a-_oTZD&sKS3<0x>AN`l)E~J^<<+4l4fA)mfH?a^+s`xt zqTaMH%PF?ZK(lUu(>QaE?*YxK;hkxP~XSnDk^X-=Hp6+&F}wn z;puoxVWSB4=4cc2UCjIxs8!gpAFWVZCWGf~KAAsw!SlMzm9O3Q)+sBg&-b1%E&FT> zt^|0Q^4;@G+;6J?N|OoaML2GV?$UR7{kfy*Z@9-+O+jlp;$Qf+4cuzE&)$iN8FK6# z8MnS%iDwE^qISP&c%+!qr3~Eaxw7$sTfKdt0B-dz3n`a{w0{bzpzsW&mMhr)Bwo$l z(ZpU`{Ch!7JhO^|Hg`1U8|XXVPC`PF?!|N7Z+0~JG#MtZ!V5;Z!9SM8Lf{X}3VnYX zcRMbI-EWVVO>2kakjWv7WO9|Aa2vt-3-<*72_zLVnGUgZxBbi(+}KXeFuLpdliEZF z_WwHN-xp$DcR@^XXMK&Erq3#lo2SdVZAe#kqMhg-0pV}b&%ZVw9j}wxAr@7fQ!e+| ze8Z&u*rhh%%gIed{gPhPe7%3!I}Jns!Zh3V32ub9Qx@DNM(^gAxF>9Rd&d^=+&dli zP~z|)zAO~mwJVwag?DD#8R@eeN!>(i?io;XHVLC%=m+Are$Yw7)2+fl8RXcBsN z^|pf9%4*Of&bZv|P&1kPW;0~&f3J(}%l^z4lrz1lwX0U!F1Vz0S_E~Jk38E#T1i89 z&7Bxsjf|Z*YrOEqQB#i`rT;PsgQDAmyP6^lRIpK#nQKk zL(M)f*BghVmkBgQi}5cG(<7<~$-Y2EY6)J?Z`>k$HE)@JrIGOHZ;3UD3pgjGVROsT zQAiu&sAG*NowOkBRgrRx#YiRI#BEwD!YCv^s3V9%7DXYQ@Lie;P?aS7O}Ro%TCLymTov8-Q8Ux-QC?KAT1~&-5}i{E!|zx4T7|QbR!BVq3G|f zjrZR7#&h4#^WJ|}%$l{&*=MgaGi&BMYx{qcj58a5(|z^R?F{LhaLoRbbkM7-7cJN= z63e!=_P;DnLQJp5>{q0NOaYblo_cV}J-&|~{Z)rI@1}59bTRhcp~}A#rGB(y!kY(q zvq1+qv9zart#nv~mtq;Azcv3(BDcttZv}~ZtP<-%*7+cCG?v?makF&iJRQadzPWa& zGj-nqzU+V5p@qD|;CjGO=Luc>z5_X!!3SzOK@H#!MmyngeX$Z-l^KB-GN@1g7Srdn z>2WHIuBYaP?SQIo?vIXD!cEsM?~(|-=odNW{%TR5PjOnI#@?q*k4hf4?k_tED&e{g z*_L3xtft+qAgOMSPe_$J1tmaBE{aIGXU!U&Jd|Y~GCO$)5KB+1X$eY*04qTW@qG!q zFG>DosZ#>c|JQQ94Eg|#5<3cT=~M`u^FY*R_wBR>T@TBxGlsSNpCb&}?Gq3(TV75S zoHklhvXuWU^wj+%l-zHpYN#5|XE&~qs8z0%_B9rtbC`6FqCdx7~_ZMM5Kh%Zb9xJqHWWGn6F zdJ9{p6x)~4AJ9I^`JAl^FSqLUPygO+TzpC^dY$~is5b6&jrVQ4*`rsp{);bMzAI5* zff8VtPnu@|ZnJu6IN!^vc4>H%zo^;lQOL*WZcu8)K;_5#QY-ep{jW>l5(T4wOY50f z@Bv_fV4pN|D^0Bxpz>=YW9c#tpcr3&5$5IR*Or>9<9!qG8-V~uH!P6%+dAIvz_K_Ib6W#0xEj;PNc6o!2cjk_z z&+tKj9f6fa_6a&U-m##$zJI&Mn%`YTs(xl7cEdH2`40kG*!yqaMyC!4&37!3srX{L zaLg0@69vlVYWw9_K_n?Xx%Q3~h2!{%zv8*B`g#KuPF+eO=hL3NTm6tMN#kkh!(dKK zd+PJrG~WZRbKR*W)=Swk=Dk*_BrOH_&~0-K+K>r}5?LH~QV$J>i4 zdRb%Q&9|)SB(^fcg?!rZZ$Yq)LIRn1hrZBoG~D}m2_$-9qmYM9n5v`th;QLQNw|TV zl>nqH`tINq&;^7ZAGe>X0n9GrGl|+8js$H1^BI3qkK_HAqPBy1H zL5~l@*2)-)P?sw(DImGxhjG67y@RR?zp3Xu;R&1yJ&oLF?(rk=V%a* zUM2+L;W0-E^sJ*Bt;fTuZzM zIET&;A7E*vKo(cd60`uJ1`_H?+D`S{Y{DhP zj|P&S-;aTZjiGD?$^PAcuL&R-!*zV!cNejijv}{vBm*D6pHJ|HmjIZHy(k;NT8LR2 zWMKvP0jA%-Af}G%d#1AqfXB%F1q^M2l%Kx+budU#X#xbpfYnE!sD`QlFee7!6k$Y_ zK%=p-G())07eEE=LX3(K-X;mc+t5RJn|s{n|B}X{1?j3{NTb~|LJ0!ls+{k8AT&tr zJsRZX9t{#@LImI-ueC7Ec~nu}Q`EZxVCeOaNN)fP?XH!tS|!Z{M~Dc;c|*WZsQ;76 z?9#CcA7Fr_TrFDpwF>RJ0@w8vHCft&))y7W04B%Bn7IUiah6@G2>=*p*`+z96vTB~ ze`uwcff*2r4w|UlZ8vYh$W;Y}enG_ezgz*>9W;*_iZnOa4ga1kJKfZl@^L74{d0(Z z99W536Zs;XQha*--QWVfeo*xLn<9qCmac9E?CoveoYC%Z56-Oy_vn|tiD!~yTdbNq z@epRZ3w=zb$@#2?sZ9#gtBY}-z>I;^jlPfHH4Mf04Q1U?t7}bHd$>qh>>iF_ijAar zT)fdH#uD<$A?-eil#&g+^Q`LS&i*fTuVf zV>){g#4D`Hw-rOA85l7?EM%gTmTS3p`>?qwIEKg)7%&>heYQ z@AMZ*BwFy(rp68u&OBtB+jEmORQG;#w%Q1Ge#qPNal9C!XnN$fcga95K*LU)NR#L3 zNJ?Mu1*1R;CV|knsB`%(>$i^3aW)EFqsCi$^GXGmZdB%MDeHYdKPy zQ4iJt>Br)=aB8|=yk7(`3XE{(TnBLWO-r}9RIFfFWN-P}KHKA>6+-UiZV_&bB4fVM z!SG9rR=2{pGIYL7zZz}v2MXc)q~kvkshR+HUxY3NH^xp9wr1~Rf&nfLTwMB2x(G`X zEgB_vMXZ4~MA;P5MzV1Cv1q0TCRVUvdX7TL;d)s3m7H%64R`l=$Zf+ujccyq|87WlJ0|OEoshi07Ul3Z8HBbl z%Au75o*B>qv47ARE+tWq@f-wbEwdcy;bZW-xyM7E8Hn~B&}fIjmJI6fd4diEuK-iQ z9*_6{0$y|p$wTgpAz^4E$2m=HtqoPcq@47FE@O9pnZGj^C#91J&Tady11+ne3`8R+ z1F;$C?igQV=4!B9w#hEM8Nq((#0(@PE{1G_M<721^hr9TPx2uArYWRPKyCy>_zwu^ zc>?|H^ap(4IgBwkgA~e~k1=tUV*nU$Y2cy63&!5@SzG@snbXScgOW0Fz6 zq?a`5^fZN%O0gSSEXqnUV~#`|^cTSIuVku5nv`A@2@hxZen>a1E%IYOJUks|6fTm+ z=VzIz?7aDiOr2+~GfL~f;nk&vmE5w|1W44KR4->dXug_-5lBwgmFPVmky7%3D8ScC z-`f5z4g9-<;5A?^^T$9=eiA88g|hOG+=Z1DfEO4|jnGoL8U$16`*9`ywn}>cNN{7Y zDp#+ETYgFQpbVd4|KtJ_cx!hm8#pUb)YXPyt?ma3HhXwI&YKo>Ipfvith58jR z2J{#J6e8HfSfJXKMdp3};CCWbV@L}A-nN3ZfZGqkVhXo3r=dZk8;Y`A2A=<C{s#4&Hm!?2bd+FjK#R2h*MEo6a zHUVZ)KUGLalpnxAY-Lonl-p{GpVj5ar{Q}?A)`{Dh5uxKJ0n2C6j&M%!^8%3L+uM9 z5C;cq!uR_v!!Olg&xuRYa0Rml8YT9p0y2<-Bz4 zx@EcaRu-Y^%oL-T4D<&ySALy%D4!%TL>ZF07SN{GRn4Il3b8&AIN4TaT2P-}{ z%NtgM#r-s4PS+(_&s{m1%(j`+sK~#FJ$Ro1^D-_crzQ(5hO>g2jXyt$phd4XxK6pT zUFwsQngz3WfgUdlb(H(!1%u$^o%WorF?990IBQzt1#=$g7%)0T7Ex`IQ z(OcU-RyL7wbnCrMGcd=aMXS1sbYEi zk-o849_<8DP&{S~%StL486QCgxz)`-13YY@DEEos5fJ*tW~GaPqJ0|MeQ9sZFTg`z zSslPxbYLW5E|=%V$ga)CNLed_g->xl!9{Z30hcxh2abIIAdX?|28Q%S!P&`a+Igu!)Ai^L_?%K9+y-9u-R0qGR{@t4P%A}rCtO^>xl0{H}f1tm5hY3jh; zXW(6NIfH|fnW`CufdxjY`QoVuFtEU#8!!<8Qw#{bpWc&b;Pj0IEh;+R2x^(6^UjxY z2kcXt3e+cHhR+63}P97%?t9& z;7Cs99&Iz6bKuk%ccJT{xs7j+gD|?xoRJW)avup7_@Lf(QSCmW_UKVggUV4f$Zra3F0CJ{@TD z9AX(rn|Dz`+WY_sQsctVW$d7t08$BEv&1g8i^^saV35Jg20K01q999QNS}iU1W3Rr z1}6$k0A#4gqbPvN)pn&l*B!IBHgHY)FkA-$4^fsw%pes$`r`;fcxpb-;jBuuAO{0@ z5xA>t{%5j=*8iTYp$jEz{LR6Dk_N#x3v3?$RkFqcWEE6u@v6fXi|yDj9ufIbNb;u` zm5(O{S&jm)()kQ*Go(|wXRd&I@Bo0HXJF6+h!%Fd1W?lXF0FA)_ZGdbk5FaQ z1(IdlTgue%3ZGE~6I!s&f$B7HZ$)R=WW5R$CT8CduEF)AW?xsEz30nrr#Lv#yBbRPNc~ z)*aO6+c?T#vC=^krqq@N*wVcCavI2~KcWKw+amWwvwNakN$MrwF9W#S(r5^G3oZrW zZlTElcMB$iH3F^+;cit3q1E%ITxz%qK)NAzJBS_lX`xRBhPM!)mDrulH1Q`J^6nuy zjLTlE%%oIq^A<1*f*U|ex#G@@|bcPZeE4{wlj z0@KUY0v786bN4dTjD?z0Q1j!zYIfgKSs{j3GthN7`GH4dL3t_zCQuwEO})43Uf@m( zbJOkf7U4)~%i0woBUUnb<(~Tn9f{-kPxeWG36r}YNRt4A!G8xqcsw4R9t5-1M#5Ue zdf{S=Pq)6q5`R8P5n*Qe5#r$TQRf(C_GfYVJa%zVyEI?w&nJBE9on$tdFvvH7%+M3 zc!>3Bf&JTdW||eijW-U|1ZX+j=Ap{?n29$q~f;^ zXb=?`z0gDeQ`tF9kzJ(4LBYG(qW5#xps8}Aq zT4#(t|AudTg{ve8?N_a@4C|tHfo+rYQ7khIGG)gs&%$USA3*Ogwz1PIAny~bh+F0% zg_y6WxqPn?SHSl&)7qKGp8RJ6Y?g~LHds|NCin&DP?)Hzhen*al^e2;%Ru&Y=mr6G=t4ye77Qv?2_U*P1a zq|o0)>E_!sN&{dVjLP*R;*CyTO$eyu>xNPWZ3cN z52R(81AhmWOB^p11acw!RCf<;fj=s>RGxx>9*q06!ffU4RsrVR)^re-vZG;J05bZO zg8ZD`@N)f1AgkHIU@7L>6PV6tLYs5l!8p$6Qr-K4U(JyJN*hUQR@0*r+AkE0Gd}x(x(oqXwdJYsju?I{TzF6tOSF2?y zoiZ93^JOlpH%U0!==pGC#ANf0GhKOfum%A8z5AIJEUgZ}a{Fw#F(&XZ@x;imS;8$1 zfqfIs(GochPE*ULYlVfEIP++DRCvJB=$Q(8X@X$kw!pVjXDx*>&@c#$+M|}i<0P1- z2m}4Ii!{TLbvs4X=lrJuVAo%%=v=-49&@ZP=cuItI804xe$LbsJYyd-tO0Oh7=c^a z5LXrW1(?^zEDcr}o~xW*d%zYU-%lOkKplHIwJhBgJ~(3x|CcA&GJ!rl@>*ddv?T~q zqBg1R!t9(2(O^9rts4j)O{d!sW{ZSUOh8AUV1pZUbniPLc;UA|c-yfnTH66nc_{OZ zT;CLe=kHXoULcJ#*VuOS*0pxuXG3Q(b38V8`nNZ!nZg7g9kh@u8jfQ|taC01lUIBN|j?tDNu19Z6( z7(y1LRRS5HEDnflcTXnyKgb|EM+%<{U{lZmJCuG$^K_qifbzC*7aWtrFa(atnT-CL zQ5g;n8zZk~fWCBBMzp``IXSU*Vy$w|r4`FJdJr>;DIWy}i#s>rZHh$fkd93(_=PjT z??^jr#li!;IwmTzz@hdAuz~y&wo)4Fx!4iFrsKp-q#eY~+6{w72&};f^g}~4d7+s= z<3R&_|Br!X{vGg&6okJrW_Lrc`-Co z1COA7)hY`!ICQ5Dq+W>tyQVcK^~Ojn#itvb(h#d>=ZaI6CkG!bG6Kr8Uvv)*IWIFjG?S&{f;yyvmJht zZFn3x4E?FTTYR`R4nM@GOvZ@S@VBD%W)S)bs|!#d_ zu&?EO?}C7}R;>Q!r>v;k ze&4?8>Z~$d&w=XdYy-|5;s89f0NsnYp9 zPhqjH*AV-A@06x^*S6;WylVc-@_$#dA}pI6JK~}Qfz9sdBt-qp*(TF7AX_-ybOfy5b2$lB#MBFe!%2$RzwL9zlE(kE!^k?1mNVvO zHxuG?X!4%>7>Q5WW#Ubs3m{g`VC02Sf<&wCze)2D}kN7l6R zFj_9)r0gmA`i#SWxjJI%C@;E*m7Db&b12gEdcteuKwvr_Yw%A-z?1IPHt4R5G)FTC zcUGdMAi<+Yz@rBqR$)TDDNG%7e1?2m3Ik_5(RXH}rPQiP2co5*)eq*7aOTLfq6s(q zV1V*6?9xG&`rYCiOHk@1fYQFxjiQ=qcb0b7w`Kaxm27mK*ZLoP1U=QVerhi#FuVY9ow+1{cwb!i?*gY;Lf+_{U|Su_EgsT&q^M8^jq6I33BwH}w`p zUi4O1fwgaJ2-bdU16cd6wqWhAjf1t{mI~Is8|zbuF;B#ab5rju=^U;#8hHF&32RB- zXtLU15X-q_xD=$9k-TyDvjNhDEL|Q_Mxeu%bq)ia7nWi}dx=2dL{HG#zjve9x#%@) zc8zTl^Z1E=z|HX{XRF^Yc7pbu-W%L>`Dw2$vEjW$ZPw99Kw3L)|)&_D3~)i_eG;kNV;3*HC1u?BLHu!n*} z3)CMj{R*3tYTIpcbq-aYHWy+KRpu~(O0~)nxwc*KLqmhXU{LMpC?FjFCB#F76Nu0Z zHO>C5CLb+oioG4JNmdXdB;}@r`fZwUIHtHj<=n`HS`B%md ztQ~$l+@2jZ~X5h7e&)(nO z{aD(#`}=mn^K1L}ci^p7-xoH(+Xv0TTM@p#zZnsHX8zCV!rP7afBbuSY|yXXzW@2< z@vF;y(T zh{4Okemvj#ly2Tb-Lmxc^WDZE!ux=`o=SN{Z);*6l zg*wQ|>OQ@OOU0d2H@zvpt~I&MM1PFFmwZgSEBvQ*Bao{mXP{A9CJpolsaeGLa!>EB^rF_~CHKOTMvJ`<#@)It_u-$ic+J=es&;7-qPHAL6^~=i z?Arr)!ddAae-)&7t&@RX&n`Q6a^8NMjQG;|GQhS>E%ZZJ!RGntsMAB?4h+$N=W~+- z4hnC=anr8&NU<3o%bj;?WIQc^gIdpLO!)U=Ph^!@q^p}4#^}xnsC6_j-4K@`#isZ3Wk@jSnM8t(>Pb^C1Z^&$tgHI#N~OgAI+-U#gk)7?zv_8=9fS>f8;nv(-VOyd z!uT4=PLKa~a*P>sx@3{paQ20!XwRjFtLMtZSMqLRWX*#oh-#^VTt!%k0`&G}Ico(? zj1oS}C3@x*v}Dsp#^eKi@unHLZJgN5<{KFzawPbgaFu%gY(Y6stEe9Qu=BPpYiHz7 zDPw;V?5q};U!b-3@B(H4Bd6t&>7P9t4xJ%8U0R`K(i|y^g?YtybB7|634|TRhl-u@ zxFtud*iWxmhX%zp$%dKXIooo^9@jlul59UWGgFbVq3M@oLQKS|{Wg5v{{RzypUNGz zAoC^fji$XXc@c5<+&Z=RE6%jxN2>K#H4D_Q!UM0)bPvA))!~qmEqd8cM?|J>W%njjv1;rV`&gvVha9`WVoKT~(OW@!IZd;$ zz}RnII)C4}AlC2UvDEm{XWfPh9%J1va1~C@W-LpcsK=3$1HT*D8iZzs`Kg&Rd?dB_ zLVG(Ydz$H)u`A8CJ<+LcEGC$;iN+;=@nhs0$DW6Bn)ng1T))X(FT_Tu3SD2c-o)() zE8++vWPQE$&(oR%KaBAr`}3i=f=qdM#4`3|=kKu$S^Y0Bx|Fqjdc5~tWU%DbG5nWJ zPy***nGwoh|BQ>d5SYz*0@LLX0MU9594#$NRl(8-v+nHBB zVf%>aurpm~&o!0NWPAKB@*wjc_&KPA`zx+MOE_Q03W4WQ2MMq1u*gh5gOQb#%t(@7 znrez?TK*br6HTct?pplBZZgYy_)xQgU&CH$E%Q!(Z<$uIx*BOAlXQh4$_3vZ!{|^2 zfhfy43so2YN9ifWX?Y)&D)+;3EBVkD`8bWLL|OWWgBsE@lZct$s=0e?JEbvC;|i-I zax|PL8XwLN2vB6V)W=}86g|=Ro6$Wf*fj5~!$Ct{;Y(qCg2X^YR-N^8jH|d}-kGL| z0Y}B=Ay=NboMbDSH(ppQN#TRZ*{L5bF*%P^ocq`59N6NzU)Zb9hoQkv54JyvNz$T{ zOgNj9zvus+b7E-OP!ylI5*7XY#LDu*!DNW<4M}Nkv}bIK!Q65ZufLXNvc65SgTH&| zMZ&G+6^mw;c7gy0Ssh}V<A9S+q%%t@BhBdjWS)XmxNUL&v=k8jiYfji}#M#0Dq zQ)WZln-B3D#N83C*u4g7VN#g=D38c}ku{c)L%n66O)gnmxxkx>hta?Z7<{Z_^9^{) zMWvb3>CRSc72WfIBV#t5`VCchUC17>0FT1QFJq&a| z4$ARl6b^arinPDYWfGPsX|JzgOs0TySN}=MOgqKrB@(_bkVMp zOPs$9W|Gz?;ld{(g$rOuplB~v&q=@TuA%$3F+iqFELOP0$Csg)Tl zJJpLdgA0H6813ozJ*|}bxRQ=1vTNMP4|2^P!K1NHkW_LvZ+Vu6QlXW5|R?o1e{5GesgKtAkH!7eP5{`#hz6^ zgy(4@A{BOvI;hWKdxsz1{gr1J=~d9WC;aGz%?y35^(w)4%O#4_@QCHBna^0iyp~^{ zNs!j&tVynml?7y|I13%T?YNrLFl)bRoR|Bh&h@P=TgpYwS;RF`wNKw7u)8VF`ulYS zTe##Ra*jcexryp~&sdr=MV6Goc>8^K9m=1(unDWb9&81+2Kp3^(1Etye{6!Hl-(jv1 zF>eaFy0z^-M7-Zl?1%~V=5g;9)p>FVX{7{l66N-IwwwNZYlj<;S4I%RZJU#NQ0kH~ zE8|8OOrTp-zbPV5!#>}O)2#3FocS`hUYcSF?rQBsJ7u40xz6JGC5q@v46K)K->W#l zaS7J5X}hTuVzGzJMDR$&^m;GMh^;HJ{%I;r-PLuY)@t2l_6@8dOr>n`Or}CVBloG2 zQnmD`mvZLMzouiLJDZ6T_3{rCHKj-i|@mz96=+Nj+&&>dyy|4(>$US(Ev0S{lJeKKJOI!3a3sa{I7`4<- zn?=jRhiv^e{lgiZCJ98AuEp!)pIor*1gn$|*zFFwqUEpc`!f()Jh$^cx9u_GCW| z=^<+lTNv<7!>9O7Mf}y;AdOJCJI$8=o0XWLV%1g|vbxpIYn6WnvDKf1tDk$x`da%8 zjaw4FdWps#^(I%jgjXgm^VbN{5gc*->5y}R`#VDJ50@JCR3viM`pU#XO{Kn}r47Nl;5;wyD#JjIsSo60JJ#AQHpExW z%G2M~Jc29sulacF9WcyOUQIH=);5Z7Gjhmg9ZxL(l;J`C zm@cwr@ViV4BY_N;rv}!pv4oC4q#Si}0@2hZ?GiAw474;8C)N5MHAr-haM%`y2r*&O z5Qih!W4IZMbq>MW;2JRKYdV@26)*kktf{T@bu(wTE+(t2V`f@J#sCyTFxD23>zWajH2Vg&dP83|%9v0h^>U}02RareqEsvmX{k-HN8X-FQq z(L_gWyF|B$UhQWY6t=XGoa!YNN7*AeEG$`fLhcYFd%zI#BCoELtN%$D`@jM@EpK^o zS<+y%bwt_af~0w-!~mY+$I3%97=QJ!bk*}$&MJyX!@n?e5>fQNNG@o+o$$zeo};Gg zdsLLkAxpk)Rw^hN(Oa6Boh6J`r?9(~QzafVxR6GKoAX7p80#Hlj6R3uFd|dlCMG(^ zK$c=c1(M(c`k|v(>_2vgZEZaV959!Z&yt?{FO;5@(K8WeZUv{4Z_zRF$`;tQTdlmv z`bqs{CCb2BYm!9>*^rO`y_ovjX3T>udtp~$+@yNfK3`dI??RPx!ovZYaHHlUP$fu8aXW*?EamevFG%|4&yn?8tyyGM}h?#b> zrqgut-B0W!toRr>XIxHI>5mCk*jZq8!`tRz5_AkyVuA_qjNj*-`<=)_Dr1Ply*Sn0 zl(e(1C%ChJh;KJwd_Cn{HoT&7^@*~o2(v6PDSC~Y<$ylO+jjQ}7F8IgxfMsGl}lMj z)0FdE3YyK>X-gtF>h?1BrTO=_s?@(%)Mq#t#e4<--?kKwG*;i*ryQ>z;qPy|!KV<8^}e%aDMDuIR<4fVNHgoh3-i?=mZ|^&M)poId|JcQAq>vgVF}&LMyy~- zkPje2&Q_Akif!LGdNxu{dgq75e!OEWjgk@*mJyjOGspcNvFNCdJe;cgJJRpi6#6p~pOotBPgyyOJTH54BvFz>k(4t=SQ!S{ z;4szac#KNtTfW4(d;8F?_>n&s`JjTMr_N#?RTu~>9KN1MuQ;Dg(!7C)lFR?|o98MTswNQdh;TEyclGM+oM~&g_R#BUGzyr1D&&7YNHO%(BO; zHf^4dA~xIFB0i)^pwUEVDa$<&sY`WAU>2%rY2FCMP@b3yqI!;ckxI>LP_?t8`Au&m zI4r43M2|4HVe9Cbov{#$dX{4xL+7wHvD?b0Z~P*9*G`uNoMv|6qpsKE)H(Ti6HEuf zEFZrH-FE+W+$@VNnbg{0W@Xksh{eX}qMNjxt zc!i0iF@1)cF)YepuP^o(?z%KmBlpwzyu0v_QZgC7q2^}aY~^61W>Y?1aMsWS0d8H; ztown6H2<6wH4k&6kGMVCIUlm{wO((B=8g4gELq3)@0fODTq%W<&{S?_aDrV*xhQ3e zq>FIhAD1Ixjm25A;Axc-k_|M*4`Vv$Tz3{sh-z$pqi@JwH7I_-dI3B5qVV zS!y4uv5My7uD96Zn7I*~4x%>n-I@wwa-sVL8(6rr;=ioYprd((Gt%IdRejJz2IYz^ zk%+P)krt$<@2=1XrgLR4n)%4%N>e>|+`cIqV|`&HkhF5KRfwIwP3) z$;AM?{&BtHJ035_7VPIY!SaJ7H7~U-Puh(plxwV&8XH8&9dusAbXg|1s_9Lpwe+$` zGKaYc4+O~NAU}$z%jbjlrJ7ahanV4R+3rlP3|=pht{Bb>9s0<6bu5%CXA~Z#_W^N- z1KF{m%9r}(v!kBIXW3s=_a0!{M#;v7M=|U1JXM#?{LuB3x6vj2%sA*;ODRf~!OzX& zox2*kvsOb3`tBB~BQ5JxGe|SKo)05uMAcOd%cGnS&}xjc$WYroCi|p7#fT+s@r9mM zz-X2eXKPI)o!-HyjKQsU8a1;6{hea|@5$BL=**x9lIiO5CZ5Na_KxIp<8Q;7c-WZ? zn25_;yH9Vt>AJo6^=eIhI{6!1Q@;xYfTktJ4lgawYD025&3Bp-{3ibRES~jw zP&KVWP1DC2besC<4{-!c+qGfd5)*gi2Fts5sO7{tKO|ju2TDuTo=92BBICL}t2-E$ z5?a!^dYW-Gg)xSue;G&3_p?Fe#OS5*ik#y07mY{y$&)65p@KQTeJQP)TeV~qmJ?yR z!t;5kiI(U+nVfLLEr)8J%3Axe-43=e=|NQef-uoN*^km-uA!~y?NqtAz3_DIUTEAo z^(+3p{RQU<^xC`-uElZqj08S+MX9jrNjpv?J*u)w) z)pRWF^`?@GzTj=~Rb%pr0shk^QWPPNMt|3g@|+o7w}O?mMD#~`TwhfE-S7$$X4`Xw ziG>VkQw#Jz%#IE}b?zfWahyCF7jd`b_@Mb#q?qsPU}sj5$y~W-5%bH=P2@k7#N(vJ z+DuF?+LQ$E+OG@9Ge`p&uV>xO?$%;LR^k?iPj@T6w^?wGyRM3>A`g2;xR)f=2WQjc z9;SYk%_c(oWnh!`lvS-d`N_&7(G9A>io1#CDizOl=`0Ne4a9%}EhE1<#6Nu*mIXKl zUp^V+Tu~s%yq9-qtv2xSdPuAvJc-X@klkxyd~Wuol-ZStstD)J-YW|VeZ7Thrz{F? zG?F*uFD@dfUCbCRUw($)5JDg=RkN;P(;!uKF&*vKe{?4Kav3>cUZ7fm!)43ntL1ra z5X^sqA}LnkL#~%tq=n(U+1CkbMQn;-Ss}b-)br=~PQR#BU9r!5s%-H-oqyk@mTN~L zLQ5*gfElbeU2py{LHP#_tB>3oPZ&X7KQW zf(}90`FN58pKQW@di%Vlpt)+GLkso14J%hSLSpaxr;i+gW{~#a7x##_C+l&7g9bga zQVP0=hDHCRsjTSWTr~TPbW;|3)xmf zY&qbKWVbP$rzKls7}fYPs+0J;D=?MWY}lgUecD^IhiBouwp;MCbHj_zlF#Hu>yq)g z$uplzAgaBHUJQMp8JMDDY-Z@*Xjj0G{bZ^?!6p^USC%_n(x`!OH&i1*X={@X&J2cx zvTDLz+g$z`R{4+xGvu~lTrFfC=J?8I`X45-fU1g+ga;xb!93@`oRu_Vocl2*4HQ#X zGSV>9GaF*oEuz!MA4GMzk=tRtYwv%k7@RS{K)^Rw+qV6TPgy}yujdU50a4aN2XB3tiEt8oh&9eSOvoIx`(*7%SXluHlcYb&<}U zvb=*vM^vtms}rJ?Sbg{vWxjI#nQS6_^SM#-JA?LckR6iu)(z#6#`7y-;e1^zexjwN zG^6AusyUOw1M-lw@;fccj2a@HZs)agE+p1dZj(c*ljun{axCv*X^FYdUfkcbX>`>a z1JSF?IwG=sn8%KlgV0aEeYA1aLo(K=IfKPt^AlqUBfnHu@!}Uvbr~LmBO{E|dqGC^ z0+Z(z(YU|W^HVafH=L(wlmRU!SU++WH&#BMU6*Uq@s^jc8WirnD&xx(i}W*q84lAL zWg}4?mY>%qXlE6ciNv&cl(C2KQT&Nw_@616rl89-H8 zXheZ?$~vZ7%l$G@c-DPrY%(V>1XrhNJtjH`Gbxt6_LDXVmSy61!@Iz&j(5>PHA+t+ zxL9koy?Di(F|S07@syT5dXTF>ubudx5va0Fa=@o3rd@|&axVtBr~ksr*eN^Wbq~%v zrcC@U^g3=dlfi}K& z>RA$F-HyF_fuDk`jg)baL^W}1IiN{OF6~_*p*EmUa!XC;^#dCVLDk&V`r1boMVVXb zzQ&OXqP9o17#E9wUew<7bn?2sCOF9tAR1x(@iRipr-Xs<;JLSJ(uf9G3VDbjb?=(h zS0(fcDupsrI;Ym{FKzatHDx;WjtCy1G1L6@7Xtn|-UNljzX~5!8L#?D()-%x4mu(x z4LItV!d({Iq#|zFjqH|0*yOHq-90t8*5d8XZpIpuXh%t38bPl5O*`2pBB+vB;zIlb zCT@^*T}Rd4YP4l1Ga*f(V7P1NCx}A*&OzGevoL?D|Hr439(t(kilO0sE{{IBe`juY zNnk~pp5%$N{8PzZ$YZC%|0|S6pGjmfo?j))#JgZBTNbmm7#!|p^C;owWt zZR+)B@>rWp{Ifs$ohNSvXKPZ0!@Uw>@auv{&LyIkp8whnOp311oEJtF^B_8!qeicn zza4j96x@ax2v!>Pc7-9?`;6>)s5!bWvbLDwQJ?6PxXZU6bmm3xyR2GyJ@&>@#a&P% z9gJYJAOQ)7-xr$CL%GW{M$RO6^X>Oc8@5KHJcW%@oqK~PG#6a*R!LVhPt@Q2j=eQs zN~^U(QDD98dG7V~E(FuML4C^W+K+2+j>uH#x161@y@uOhfWuqjewC9a5q4tjpScd|+8YK3bzb5U;eJ=;$ z4R$7+zP51Ax!G`*86@Jt9{QeT*7fNf=__rv%PXa!BEQtMH7QHav{TsmFdZ|v(?=&+ zD%QBcH2Wv-oa$po@VNb!5;hrkC_J5B-Rz!0@Fx_)u$83(qT>1pw3x?ogd%Rbv1?nD zj~7yo#-8p>eNf>uy6I+gbl#~xmN6D%w*T_UWhL`R9(7zb`feL*}`9&nZJB;l~6C=sU?>le5pfRl#Y6tV8Z%t$Lgz zuO_Wr>a1r`c_a8HZXW3c9K<=n8X{c6u9z81CUV|$ZG|VBSojU|Xs`A@;uK7>|6}x7 z12Kj{?@aDTb(zbGD@TSqi?n}PAA%;m;SC}3sTs?&O@S92NOdw=(FzY2RGQ>%sU9Q*S3_~Ub~d%xX4FwoGinK;^4QRm~C=`{ueMigX00(`p8*RI>ErJFjuaus=OY z5-&YT$Olj#Bhmmxa$I+`D3V_`K%uJZ&mZGv5<#cRDnXbpmuDhfVR`n9`dwGHuCLU1 zK_!~4Y);F<)-v({XHZFHRrC!CN5%;HX$FA}%_Ucm4IJtRVUD$y;L&QEd=UoqOpD10 zNdpV~oVk~C;t@k^At-hBq}kI7C*20a7p2muJbkn8{OS^A54X-U1z5aJb6abOayM=Bra z56S(S=b7MxOKBT4A{11+TD7YoWXV}JK<=jf(@4rGLBO&0w-mV$3E34dN|dS4r2%Zs zxM*6R`GSkI4*8k-dS4R3-nd!@zs|DCHBoO+rkRum@QSg;u*W*pC=wlN>#9BB)^(rO zi_ix76R1oN1@RuPm-=;}@rzd#)wGCT6^>W1o2OqGQYOjv`&#QVHmahB5bjQ2tar$VRrt2l^Jz9Wcr#%!m>RWpCt=Npsc;W}h+hd5Bi|D5dwnsPc6$G9JfevE zTSCLEaS9`qT#ea4d6k5Oig|rh*{5&E_D1%0RduvFI|Z5xU(M`OzS)ph7h>S}9_h-J z8soQbA_zM_9zOWgq2hmlP-_=;;1q^O)wK8HYM%>#V~nw_cJS;_$J6PPr)~xj`EmRz zzY5AsWzlQvY}-u-tok>1;ikBXetVW_4|W=!a~-YviE&BoUXKsRi#qo~o zXFmzTwh^KW`O4R&V}q*mc3+8&(=Q?-lsUbyBCq{A&B?%Dp?qG?8Ks|g_co^-FE*Q07*c$zr31V-LknT zJ>J^+4YONo*9wsS;mLDe^5oF z2}xmCN9=rplC;O2PkR}^cpWkfGulYS7aq#q4_{i9#o{VLTr&;4T&r)y5WQSth6MY) zPzMnhd!Y{Y%*j)=;J8n&mPw}9y#(YAy@3`bGR>_fftOOPGhqRlLUU43smv^FdaSi8 z4w5lrRArJQpLNQcfr`0p5zNe9g;6a%v|03aIdWCSPvQMfcWa(GVTKMMSE6^dX~QQ8rVy2QSX?Yn=R}nnUx~>y zfFF)V9^Olni&t?b2Jk0$Yw&}G>%A&UT9Q~}z+>&swkG&YK4-NNs845r-1uzU*0RU=~^%uAWK~b~BxUM#Gb!;mCLC$MdoZZ!&{D9M&5BFp`~& z8bU2N(G)9N8FA?0B&MPg^qZ*U(|tXl#*Pk^A}b!pJS&E>uUD+Sd=RFA8gH^&6;TSa zK{B_!$1^nvR!}Hnm%?mtT8W)D=!$b{nSIqyCdjc$$-**wO{z9jNwUby=)>D;Hnssfa_$u%4}zNK;)@VduFOn@f{H!4~uQ zIbW3-#1S(N?n7kLTyTW~461F)bHRu_HnT80;Am^AltHhv9s%tdy4Q*pd2C%DW6VQyPfiD8B;=-Cw!9`Q3SZgD*DiUrnSe5OR^~wmch6d_b>Ol| z|0T-eaUC|8+EtKY$jA}D3S5)1c&|IR$3RzysG{Y;>G1@FmNfzXOGs+L$nkdQ$nN+- zxqFvX(sh@4gD~fs*F!9I2hRMZDrgo(1@LpMrY+zhN+RaAQo?8y*h~0h5>=-Jz$w1s z)YsAv8SdNu$xUS}q?Kbq6Xd;4`!-O6I`0e0o{LKQxja=?3ZW^us9~PSL34-&Z;)<_ z1-eAHC}MG}!6s{S01dZUCS-;cI%e~yKOD9fQj}{pD?@P}1yY`B|HHbQ4A1wuxsi`X zgTyRrVGU+hdHzrI?8b9Yw3r2|VaJr0`*9q^>3GQp(Z)aIIgPQ><>rUL2Q={tvvcML zLjt%c_JtEklba79JY}U-4)-#uL*jFieosz^>eM^XqBe1d=vR23^55*5%dQq}I=L=p zp^lrJ%{szxESt&%jbbBc$GT0{5p=~RxsC|uLWmQ{@mSxR7r)m6CB^|9^I6{HF+J=J zfy3x!>JC8ou0q-Y?Txl@rgqP&V$z(i+5YopUxt0y&CAe`pXb^ahV(grO5!< zyyj>a1h0;Z=8B4QOKZ2P5QE8$C#;JprHOsRgLL;2){FwnIx@Y)MX`IZfvaw&mxM8u zsc1`^ho*B?#Bgu`cfab=W`Hw7=L!pD(OEl#VD&a+RW8O$w=>m;Y-})JWo-dp=jsga z;O!4XVMwDWH*QveVFoHq*nv%ZN_RNj(aiVc2Mgz{lPP zU%Wh?-t+OzR3ac^#Q-yAl5$i#8@kBf>%JTU=_`8J`_4VWz;YDv&IZ|%cDxfR2dnYx z=E^>e{rIrdQ7)C*k~nsx!CJe$$1+7#Z4=5Db6c8$ABueD2vw>@e|CNOfuvr$dSI+$ z;*b~{-7M%$D?5kK@V2jHFdIiNo!CjMZ^g=Zf&*!yDoYBZb?>ujki24_5+8Lb%efsr zv&oQcr#Ge$^s$b8<`WQBJ)BkqA)~Gq_M?R6oXvGCSYAm^C7Sdg@(CK`F_>GOL83Cj zvPS9kLaCF7I=R8AVkYe4^C^~a;(?W<0$zpM1V4+v@}8t@TXisWRmQKM+hDo&t2@+a z+ZswmjlRfxWip>s6zqaPa6)rY^*X|8OFhG0IET@fr2(AkOy8p-i)IiVhJ6asl!T*b zb}@+#%SC3|VCh9}rEqQb49COI+`|D|bP!L4LC7gR3^(p!|HlAVuewHV!U1h~wu5Ei z_~CoW{YGKhaK!YWaZR; zUe5=LGgjqd5274HRBy~HQL{EryXOe(OpaL9`S#w;b51A_bEu25ADfCiY79c6J6pel z+)Up!Lkf~i3iWb>L5HB|xo{1b>m@`9H+k-FW$V>WeTM>zF{mW;X>xOLyjg)KfVuHM za`C#PS%!#GpY9cq!~%(2yBNUiL@l94=ZagIZKXB6?Y_%$qYXA1*lSor&RH!Z)R{L$ zpL;mnY} zJYo<|Qh&(1cTrX+f~ff}od!3vPjiE_-({C!8H>fN2hGHHf`AFzvx-dc z0fVzXNxkPv@4e!sd5M#=Xm6M~v1a%eqndhoInKshK(|>R48D5J>S&9WW|<(8)uG(N z-uhB>pl~qEw})<>utmK8Eb_ZkE@k+aAq0l&bqZ~bio_@ zCNp~-pI^oCDjW>|`r|a>D!2N8p4Py^fayejM>6nnxO?}w;-B44=gd)&_AaIVxL4>MlMmD8hL zpJY5XdzC_>DjJtVA*H=WQ@k$rp$_MQluIjL84k>7Dj|KY02NpjerPXt642rgt^OsV({5s zPfo+zQISW_@646Gpbn}v5a8@6Cqpi7WkZpnYQ^HfD5(0>gt=_M3B2K{T1Qn6Eqxwh zPvOqTnqVmu71oOL>Qfucka?jh;@}U;x zjz5&Fwvup4VBrjfU{!(uL3OoGiM1-IbTh@4?)gDG+7g=1i^#M7GWO$UK@AvPqWB(W z%s9F1o{AalgpzH3$9D0J)slTV?Y!U7u&Q^o29EymAvoc1?BQNIFI}xBm6ah)Z4Wyf zcB*pI5!yIo=sXOvUD|j|Urrs~8}oc;nl}$s_4h(@YO=KPDjdU+;dt1hu+>|uN~T)p z<2AN`%)`AP+zH9b@}+}V-|P@ZwX)r?{+2qdxQU82!ydN|XaRqE%&w|xh71sO*!gK@ zS64XbOfK1Rc?7PD3^@*#+Y=xMN%oAii&as4=uq8wnqZ+00g#9AiuewKx#YHE0Xixt6a65k~0~YZZ!vd}4nGSn7$|@9bZQbY9GjlU8^ePuc#L{&>{JQa4 zVLog=-cF*IRxft#xuXh)LUIo~svH#Ckro+;0B3#zxH4w>i_+y$)DH68(a_)>9kAAK zp0olvwX19NF`79Yi%VyK^T)BJ{8QI{8p@|=iT))vrPTj!G4 z{DN)EN28}D$l=P6`R?oogHhx4gR88r2iwtjPC2ygd3TS|7J~Qi;2|7*Fw8hSd0!ew z@J_^O$JjV?5T3>O5d)wsF zPMbp=Cvo0UgTjW>|2!x;*3i|1)kNCzo=6W*_Feao;rZexLnsYCx$cutJ;o$acR?sD0)7}gXv8V{3ahhMO<|7c9B6?QVj z3fXk)@bW|B>a*5#AbC5IHz9AE(qPa(X$i1I0PK}{l&TQKBJM^c7AWi?>&0#eMECx5Rz;>OeT8m&aXXY z<$51k)EYL>DP{TDPa^k|VTawjH#d%|lX$&Og$HUFEt6N{87k^f{|el{ppRQ^V=Jm_ z`$UaBckTYrwa2JPQOVk8{@~0X+#a-?@aPEHntNE}9yZ`KTbjx~=`rc6Ivy4lP|f$w zseAq2+`n*Oz*oB?5OM1oitZ%T!`k>-Y(3zi+^0!y+>`FwfziOT$i@Ik1{$Cdr5kex z^PU?I?PY6Vlp?%>PBSx#EV0P^L*oiZ#j3^;Mn;3-L_pLZ1YTveC~Td0TvZ-dPM!OB zzr(Owo9g9(yISx(tkXkRYcV>d@G!xQ#|R|Wn&TRBShe6bn9;XCKD&DjNP#t=M>Vm*2o0zqMTq|OG82ldqc@Y%50$g9@e+Y*n@@St+ApqlD1 zG4L4c+*gAMX=A#MUB5VETHrYomLHAxPH>8-Zp@e#dG>&^0%qfqo&M;|{XCJbhb?T5 zk_1+WYRuh?4ML1Fn2(0~GHP^>_odMtSYqQQLfcxVw2CWe}aU zBp*Z9(|(%Wt?>}G5q&UyI|sIJgWA0icBoqlibW{!~oci|rVE^1!=W!lc%(GpKzuq(xs zS&b6OZ}cE$C^t%$bwn6qczhZ8f)7wy5zm(|Bl( zabnsF!=t{K#f5uW;$9XWtc?V=iW*&IdIOAuVDwqTqcv?7^I0FWCKgNrvL@F329VOK zP#BK6hdXq>LwV@rJtsZ&!lrPZdI?slJ@sbDcuPf70>?a zE}eOAJe>4PW45v!Lur42(i}t6lR(XC0|>@rjBc7^7J2X3xKLxyjoZ_c@pL%Zcy<(a z!0Lm~n$xi5b?e5h*>h|Uo?{;Ky>=v^3L%FV$dP!k4*M_84m4J9q5z6c3C3O*yEsJ6Wl}wPd{_G;Z2oid_~vZWt~+ zM(;f>O6j(|*N@K$Y-ao&8q3;6*f`Ep?P%S=TCae%byq>5wj8`?ClA+othcT$R^2$y z6)jp=GBr9HH{YFZOe;&CUAy3RuJxgHDoqQl%43b;?6(8zaoZ}27-8E+PcCGN1yMx! z(7M-)n!8G@f*OR~l2{)OyzIuw%@V|k2SG7bJD_peyPc@9=fHp9z(3f&$K?)aU286? z_1p``izRzY=&doJiyHdLMY-Y%RZ{&S{LYPoieaQ#g_6fbX~yy+G|fSElEl?#IDY^V zyi83&I%n0wF7i0pUg`-csV!}Imu;)ehiQ<$eqOtT#>qv!?n#3x@R}A@i#Hcd!#<*% zo-9uYYIp{RH7we&6us^uU8Lf)jx`<(^lPCP6+TGb$x}bTIgQ_^9C8N zRRUT5=Bq=Byly;eG!`BjdymVZbxo>|d0xPDiHAn9Rsx}MZz|}LxVQu7S%T62{Ndo# zD4lsO>%?eOoehKoFoS+L;~>wfL2URuG_ECSomE+#5<-vWpw3QrG~Z;(J9t0mrD|w8 z6s>yrTqEa29(j`Ep>bgidrpz< zlAbw{V%KZA&l{KzC>yIIB^v|_jYmV{oV2tPn--OvF$gZ2xhG(%Y5YtE+VN4TXX&huK~ggVC9d%2~!#Z6B)2vbfTWqFsNd5LO~V2xT4L)UbHZM4zjVYMXR>W$7~YJGH)wN9Zm z#p#ph$P^?vj3HpP#$^=Q+KV&e8WdGD&7xGQ9$J~9J9W0Hyn$lS7>i-c#=LQ)u^E{x z^K~@NzUUs7ldLO_aT@EvIeD$;xjT#pW!bs2hsKu$YS>*Pwy{GQsei4{8(`N()?k?# z;T=!q&9ct}6j9j6+f(Bvw=VUZZP4*G=xHf)Pwb32ux&3`>03dCDN|vD=eDqFYG!_c zfvq#v%G}SxbBjyH`~Z!ig=);{SG*1lc_UVT2s!C~IIBL-07HCwaB)t_i;q5-`?zbi zJ8>A(fLhOl@>B%ytmSNLIY17-mi8OhUqdI7kTn8Hm>rJ$(E~S)GgM$KsT6UD-zE^gh4$ zM;{tzSM+yvLB@GVUoz05_-?8@sWE&emoVn{W=TyB;50NQXE7Kq(Qs z?f60+b?j{2b9P18hxHs97g3f58?&+*jzX|!j##ncxNJP(h>w%#4?+LfoKEOWa}Pk{ zepVjz1*b9TkLDSVeKG%lgu_VI3jt{cr#UY%xM(9vY*{Zn!@;H`Z*C2zV@9hroN%RI zyvbv5TX~E|!3~1fMtYwc82IsGBjBNREJ-KiGbnL(2Gq2*26r4tt1@x2Tc?(gLuExx z1En>p<)s;*=3*ob4s3e<@E)puI!CE_kff)r1j7Zcs%>8Tf@pNQzk;=$VRcYTcg}Mh z?Q7nYP{!gCvTdD3hN)v%drP2c*6FI*$(>rQK{-rAta;doUcWPM_Ge=z+YV3;&Z(i0 zxkwBb+Oq(E&$x|)zfOm$oBM+fcOeZ-c~&KbVau4#0g89k8 z*UL-uuw)#=<6=!|hjanp8I0ytvHTFND8n06nLRnpYzlV1As4M%kB;H0EAC;1x4b5M zmv4!fvLPEcxosWR6Rlx29I~o%YBNWpq23)Wsd*d7%J5Az3}!b=gpyPA&^=>MDxRD( zCo?sUAeL;ucJejo#xs|KXLxU$Qw0{MRWHf&Ku|W4`#Kiq(70SC_{{k_Y!ms1P~7m^ zbtD^7Kg1bam`rP#L2BO|zbNH2gB!PLOyI5+IDMUlZq4D-<*^X3E=hE+42 z)>6z+T%=PaR8MI$XPLj+*In-A_UsO!5B1qCh%>($^doED>QFvdX-gHwZ+O_cWro5b zk7}}=2PSZ0LOE^>AcUK8bdOT*6Ey+8RUZn^3XVF*eJ7*53dsCY#1>SkCRdkdzqzS*ys#qZaOp` z-dItMSB*x(Ix9aB+SbvUtbRtiItI9Tw|x`w1%v$?{d5HC*ZI<&r6hsDjP0^63Z8;;j#45fs$ zYx-cTd#r^^`t;yudy4y0%qF~qa9Kfz1r~9tZo^Vv)_4i+>Kq1n zzyXv2F$X#1_$!rqeRNwfQ?Ey3EF!8JtLpi%2itaO-bomHAmX`P#E%hj|`W z_Z$X{3bU7}Ds8uB=cPnQHS0w`dY%W)VArfIP7zbhbPt=yckuEmE?L?O8*qoD)8xwB z_QNaZG1Lc7rCe;eGFKQlLk~7~+EOpIX&{_+8Z+ByFLaRZWKZ!Sy@N%Iu zcXmNztZphBbEQ~roNN~$K>h#av&QE40o^vxmkdsMuJU>kEuwAy}Ixp>Zvj#vD7~T_jit!J6Ws ze>wfpJWaEK0EI)$IcuOu*N<-M6v1Nmu;F}M%)s2mkzfsW@mV!n#~XJQUxG6dFzmqV zlr@_`FrLu$sF-njcAB6Pgf(43%t~#{DrL@f{KehbKE?3ZQ`V2>qf6O1&*nyVXq^0| z@x&nRBk5sjBL=7zuUfN3#hYV8G*_XZb!``UvrEEZ$o5d?Hin+mB59dXdM@M!r?8mX zih2`W;Y@VLp)E+HKX3hmwjrw6Ygs{h4ywW778d3YJ5aBMmzjw^3lH^U8BuPWbp}01 zN}d*5`@_hHI`y+ubx3WGPtR>SQ=`m8bgoN@Su*Bm9#gpX9yvtsIY}6h*#hneg=O`l zXRZbZK;bata|{z&$D*HH<~6i#I^Vp^Om|L<3*n(FLm?2gI9Ip|3(tzZSUHRlYcF2f&KMuNZ|9*EMdG)mFJ#$%L?}<4o2k_`o>F1#z zTxq#mTMeLbDazNcoH$=+{O+%@-~d$#^ceKCBFXbF3w*Y|I`m+wt{rcTB{xcU5<&S+j-5u+O$dK0dpscy#3~3_kG@aNHV4xq6-JQ|I}K zY*a&mAWN+fEibz9tl7eO#Qs>$k{e^}K{lQxTXv3Yww`%HJf~;dM9j_Ut^buvws0+^TI@CR+@e>39f$u+5 z_2tH;H{Ez1{>|Eo4}s`BOl4(#Ro;}~*zJQYM-MN4skjAcw&-OuidNfkEAFbV&I@Ba zwe_dAA*%>boyR)z98n&6H+WuZi(us6D)v-)$zbjh0syq$Ii#%T_gNo@V+!FRrclCVuQcr0 zK>XwAWPOly!1AK9EguHXxlZ6^nX^raKIl;~R}45u3t-ejz%j9F%+H*&T^Rw3jesTU zBL`}p$tgTLJ2T@C8h2Gf3AP8*P-btv+rgg#0b?z%A`f?kgVimAq$DhcE!)mQ09@O< zoBPP1b3L<<$l*;{p<~VuU5Tru$c!<(GJg1P&du9Ojaf zyR@G8#VG}_HP(D|33_@ivnmPiZ5k+I&CexYc5~IaD}d9dz(+HYQ|IMFQCSoh=XHi; zPg27ZiA^`2n-#f}_y>=9coSV)aAnp2Wfv|y%@!qVam^xK93y}|z{MI=r8+&D3zzX^ zqac}^4WV(<#x}1OcrFhHeb>g3f+zUM*0h12lQrRHR%oLPhf70eouLhePS_)9#odQz z$)IP+D5hTQ{I<(Y(%EJE4TRX;QSL z77XfKFkss+g6(Gx%9bwxI2R1Kj3(qt+EYfWYNJhUvq%IhI@%eo1v3_9+Zm$eZw~1J z4Z72F6=&pgb}Wn&GZs|3@7kDYlz72GR;V>%8YCS~0#t2jp5vkxt(zs}BA%|T7H2B2 z7BGUr3}E)otHa;sf+x>%Sd-im^*~OQ(+icNDHVWQmxsBgcU|eM_8I!(bu=GrMOEjb zS|YA<4WM$!FWVu%3cDlJdw1IW#<>%C1fucUcIAfZCjF5}!`2E&1|X&K2a` z%I3_CSa4)5^as_NfrLL9HriP8>p<;`FV<)ME0$Nc7sBcgSJaKUE)ZWibsjRR_O zH*PZs&zqs()D-)phufuk3FI`Qhrr@Sd)XL~75w(58qc|kA3eOuVnNt=N{sr^ku52X z%{qIBW&ETKb*cQyHqX4}heKT49MjFiVUwygO;?T=O_Eh(2ijI$N4UAU^vE5h+5uK5 z*st6wsC174XH(2u^)5!+;B?jeHWRh^!7!Iu5ZFS{NlB2wgq@7@*7`%XG!|o*ZMgtV z=U$SnS{KkXXVtlzpR0*HQw4i+Z=v+AA3QfWa>B@X^5KX_Zrrp<(q{b`j@5!)V~(p9 za8Xvarh4Xc$4xa0AixRMK3|T%p7}X!Kc(qT1`*DdOUH3bJQ=}tBy#SEd|u4oRe z^_I{UrWee;tUsijv~)R=8BUPEH7W++W|r54#$8*@7#fDs4eVz`J7_R0>Y%&mOfly@ z3}C0&jV}W_aFB&FbfCghv(Pi^!*|*&?#=6%xDVIr+^~G3x(FBdo<+qWrNQdjSH$4g+X9PH}-4Z zIMK|#<7jLXRYO7K zl4ZOR0FsBF7GGNpDl4MR;x&%f%G$$v_i$0Fo+xLan9CT1{sbmt0IJpUHj~Rau>nkJ z%Z`LNva$qQV#|aJ=0^8~zr!O^>nN~DjcYJG(dLKYF*=n>OoA?pA${)Q)wUv`UP{pd zn`dCKb$~~32II9mB>ZcM%|(8mboxUIT8DGX^o!FfKL^*rzc(e;6QA zPC9IrP$SV$E&UuVEW9*nVM$S}y97XSkTh zhJRSi?K$cys*q`nTgdpEomu1v8fRUC2KT~(gT>BSG;6s)Rs2VPW&4+(L@hfiwFs;vq( z+`GerWzw&8d%)DkggBl&%0s?jFQse$Y!*uA3QKs3s3q{y^dZXN)!~z8X(zL)$!I*h zX+5H6z7e};kfmwu-00UL*ti!H;g`2awuhK;uTk%>Y_p6E@6UmQicRaekIt-hy%N;f zuY@!!b9lh+3;o$VWpe!ls4-#>uG(})Tr1qq=DBA6Vb>p=F{2{ZtwBDzq87{L1R3)jT%Fd3n(mr7S6Cg>+s+pEI=K+VB7jC_@BA(v)ll_{jvw4 zZOmbonZvee)up<%#RRXc+Qv0cW8<`FU-5Xc*CuHL?Ph+D8XZwq*-)XAQ7LF#H=K$ar*EMb28W-3)q#DOGH=p54yJCKE z83t3)ZTBvAdT_NHN59XI!^U%p?(|?lmTa_z(|>|&o81ftQr~K(qze>Zt*Wh`nPS)$ zByK*pIIp@#O*3vw?;K1)LkeAy?+n#c`M4)+3wfT#JCAqk>T{!;v1V-Q_f&IG5~ifd z#$_#+Ve7b;%MMx+N0Z_g!)Ee%`aF~s6NiglTGvk^RA^B{0!~AnhoM93oj`qP+!cI8 zKTpr30pZP23^f^BQ*Gy&b)G-j#t(p7g*};FLhhF!jyW?Q8kfGJ^VB#^2L~Sv8@SHW zg2uJTucfh*(ts4`}ORQeV7|KVjfX_JcbF2clB(K5dvf zNLa@nopij90-*u5jw+=ARhEZv7*S=H+oi^3ZjUDD>gGt!aI%H!*Co%RDNtVdVMxJp zP1oO?_6g?r&1s!re*fm~ng)?lW`LYJSYK1};n96((~_>zbmwqbj4@+<^H5b+P!D+= z>&SO}?YxeBKd7qg^&9$Vw~o`M)@~hAd}xglmaX$T-I(v`#zTLLIHmcpPdhW^-^2jX0;_*U#c`ga~^j=78OM4;L8) zZkBwcsVY5m(o*!`D0Qv?5tualxv+K-v>D{*5v>Hi$();E6QyhlTRVBhzm(=-i@7x+v|k!%Bz7U7LO|zB$2yRFxhK zW#_Vz7l))^o`JTp8xuRW-KDgsZJxmfnycc2tV?iN!4M}e^3;yI|4j=$G(A_PnK{IE zL5L4;9m_?@ZJswrN`A2Jp}4SW+UG&G)US5}&Y^7%x@YD(_k^RQv$Lm2*i7KmlXIJ? zo+K^XV1-O?r~R2ePu!&G^`T$Z*fes@_{N02U_)l2t--RfpDE|`#mSuGAki@^s4iii zh)wf)ei#t71Z8JOj&4NHlWUm^Rfo3KDSI_y$tEhmPhb3C`azzL9!{mrO)}Vcj29cc za&S$%yrs`GkZ7KWcK^y_>eKUTUDditVz%*@L)b@CQ(M2vk7DEYFw5j1f{xUBCJnK{ zn|7xAp>+ybdCZju70cV@C)2SvZH}~crZ#ChJxFXA588HYe(t#;qt%(XIYwO4nA^gv zV^0t6wzOji+U#u8PUk_D9y&M7LQYK;EzM#tG^&CLoWqORC9|k)o|~M=cYW$$aDuq% zV6Dup(IhTArUJb$>6fmvh&_RBG68$c=vBEy&>6X6BYm)ccy7%_i@MJvk_k8M-~^nx zqDCW}96q;7)1Y{A*N1PZ04(ulv^hoPY=<_yyO>^W7Lg-CKX|UNDc};0Y4b=_l2&_o z=@gR|H6Mc(=Zqen;H%-Gyt1`lK}xcKn(YzgcJ&K-n59Pu2a^5OxuqD?Q0{RqGSSTZ zG@@GGC8wz|um7?Ql={mw(KPd5+YdXnD<8_ulj*sGlpXs&w8ny-vNbQs zO#q5^h%@)>n;I4_%-V|7vy*Mw=U#RR0BRiPo&plK9rDY=wO1At^keKFJWlikH z=`YUnY*!k~@nJmmt}UqKI9|x{2@LXD6YFpbk}}VetFvZ40d{$CccDPMLQdCbHU`Nn ztYwx%8&wjBU`6g;{h9Y+np&8gi?y~eXitD|0;IJE?(3e!Ny@OU$Q}vo?hFhUDAFZ@Uhcr)sq+wNUE2uy( z*6*EX$vf&{cCfPeUi92NE0#t^q53o=gR9E7fORM?)KA9SLlmh5-;!=T)5&;hFAr|b z=-XBK%qjGF-ZDMfo^48q+6#npf%qI7cYIhH&n^|+c!mpkVh;~y=Ws7$(Ccj!H=Aj@(4B^Z=a$2ZDmm8fNhUa!ekK^wGI=o=c6hj3Z4J4{^%T zZ?zeN<`x|*NOQ$Q_Zr`(f&_3YK4*o*Wk(vJ>XM$6Yne&IWQb(b;f9UQ+7798ZkZ!t zJ&a>0d9Jn8W{n)0W*+iuir9otZTs9IL-X5{4LM4vrdhXQCJs{VZS2buhKMy;h zFMbNZ*D=IZxG>G_uk)kh!^B*@*fLD5IjOSpiwFCwE5z-znaqX^caie6>{+wVdUBnC zU7jk6jX+QoOwSap%nfg3x%meJ9jXC|1qYCpD-zP{|%3hKcQOZaRyg$GQKXF(MJtx=Ukm%eoPv-fYll#M44~J(b>(Y~XMxpc>Cy3=ZkuK? zMuHG$2Nxjj;`JBjRZyQ`;OWURXf?ZaZUW^m)CV>D6!e4ZJoe=o6 zc?8(DtqOaLwYc`41L`0TD@$-xdeS|c7ioCK0aL-PE&{PHoy|QLwfLi(jeKyJp2||m z-p?WpgkBGE-7zGRnxdeX3Gb96X*=6fheKGSl9-S4902;}V2_I6oC+dAT_ZllkAO2j z4d#JkgE!#XAbVp%_ZHA`SnmPJuKCA zBnXWwd!4$&d0(oJaCRbZ5uq$evu&;VrKdl|1G?F9l@9A2>aBUVEQhmWvLURG>9;CT zXFrcNCHS)^sveyVkwTswmnx+W((UI)?J`4BB3GyOAm8?P40HLj7_gR=EAi`8F9mtsE4C<*-SI{TuwjE zj(cR&~z*ZFPk#f^0H$p_E3WCQ-#wU-kec; zC~#nzZBWT?J8|?76Yy#yb#w zXdU`?d9iii)`?s1EY3sgD9q_}(i5nMgykiW9)_K>Zq1KsN z2m0(Te40b+(wc5v_}MHp5$HU$uB~X1S8g4-^_p1^jhhHVVdKV)8#i7ny@$rV>euev zmbJAvmE7B6flkr3P$z>;-PpG7Edz(fzHj>pTYGNJ%7VyvwHgNz8^Olh$%1EHt$oag z#<2w@uflx{4z9<>A~EvT9CpO-?0sy`z07kL73+Y9)}`nUUNV0+3mht5HLGzI8}qR7 z>|{Kw_x{U6;~t_GIQKCCFnsTo<$P~E-n;9@vyXA(J+mJg`(1gR8qZD^xbcpqA6kdJ z4M%8QCzf$X*&6^3jR6x>>yIUG`*)()LfSeQ8=`bGqcOh71Qw-Z2#2zgyd53mdnGu@&Pku}!VT zgo&-QIbnJz*{AwgcN++?aeM$m*jKAwyidD~9}NkImSqJ+qq>q=pJ2v)bPQAzMkDTc zkd3EV#>y@a@E_Y{RQEYyvaTUxz_KTO>|zZVThD$Lxt}H5%J9kU6P6MmIj{^XeDP!& zRvxP0>c#@g@WrEzWhqn*!oBT@9^X6L6MY&zSgTq<88$8tP?oZ*Qs88RvK@>cU2Qwq zL&g54TKjFuVry?(vOZz?2-$j~8IP{q>`%FJOOM?tM;H)D~(bZwd$kbv)1>$a^~MAG8{zJVa>R*^;(x9GI;YoRMz|jWaiXn63ll?5e)v8O{=W z0KxWfM-NS1$;?j=Ao8OhJeTnQZ|~iEaj z7Bs^hSN8+}N(nVVv!oerTixU1z*LX!QA+4+Hv{*4d3h;tabyW*LDLMD%YmX&M!5pZ zVy1b}ayc+pDkZbVU=}jN4Xb-xN~N5(g@~#wWroMR95N~8l`ooBEMYj9j8r^nC zU=}jXLME5vEv2HGben}tb3ROcbyQr<4=CCBNxVvp}*W$jo6?b

yt4BgMX*=bMh@T9Y1* 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