From 6e10c7fa8b727c25463c2b2543af49b3ce7c5d24 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 19 Oct 2024 13:33:59 -0400 Subject: [PATCH 001/131] Initial lint fixes --- src/extractors/androidsparse.rs | 4 ++-- src/extractors/arcadyan.rs | 4 ++-- src/extractors/bzip2.rs | 4 ++-- src/extractors/cab.rs | 4 ++-- src/extractors/dmg.rs | 4 ++-- src/extractors/dtb.rs | 4 ++-- src/extractors/dumpifs.rs | 4 ++-- src/extractors/gif.rs | 4 ++-- src/extractors/gzip.rs | 4 ++-- src/extractors/jboot.rs | 4 ++-- src/extractors/jffs2.rs | 4 ++-- src/extractors/jpeg.rs | 4 ++-- src/extractors/linux.rs | 4 ++-- src/extractors/lz4.rs | 4 ++-- src/extractors/lzfse.rs | 4 ++-- src/extractors/lzma.rs | 4 ++-- src/extractors/lzop.rs | 4 ++-- src/extractors/mbr.rs | 4 ++-- src/extractors/pcap.rs | 4 ++-- src/extractors/pem.rs | 8 ++++---- src/extractors/png.rs | 4 ++-- src/extractors/rar.rs | 4 ++-- src/extractors/riff.rs | 4 ++-- src/extractors/romfs.rs | 4 ++-- src/extractors/sevenzip.rs | 4 ++-- src/extractors/squashfs.rs | 8 ++++---- src/extractors/srec.rs | 4 ++-- src/extractors/svg.rs | 4 ++-- src/extractors/tarball.rs | 4 ++-- src/extractors/trx.rs | 4 ++-- src/extractors/tsk.rs | 4 ++-- src/extractors/ubi.rs | 8 ++++---- src/extractors/uefi.rs | 4 ++-- src/extractors/uimage.rs | 4 ++-- src/extractors/vxworks.rs | 4 ++-- src/extractors/yaffs2.rs | 4 ++-- src/extractors/zip.rs | 4 ++-- src/extractors/zlib.rs | 4 ++-- src/extractors/zstd.rs | 4 ++-- src/signatures/aes.rs | 2 +- src/signatures/androidsparse.rs | 2 +- src/signatures/arcadyan.rs | 2 +- src/signatures/bzip2.rs | 3 ++- src/signatures/cab.rs | 2 +- src/signatures/cfe.rs | 2 +- src/signatures/chk.rs | 2 +- src/signatures/compressd.rs | 2 +- src/signatures/copyright.rs | 2 +- src/signatures/cpio.rs | 2 +- src/signatures/cramfs.rs | 2 +- src/signatures/deb.rs | 2 +- src/signatures/dlob.rs | 2 +- src/signatures/dmg.rs | 2 +- src/signatures/dtb.rs | 2 +- src/signatures/efigpt.rs | 2 +- src/signatures/elf.rs | 2 +- src/signatures/ext.rs | 2 +- src/signatures/fat.rs | 2 +- src/signatures/gif.rs | 2 +- src/signatures/gpg.rs | 2 +- src/signatures/gzip.rs | 2 +- src/signatures/iso9660.rs | 2 +- src/signatures/jboot.rs | 6 +++--- src/signatures/jffs2.rs | 2 +- src/signatures/jpeg.rs | 2 +- src/signatures/linux.rs | 6 +++--- src/signatures/luks.rs | 2 +- src/signatures/lz4.rs | 4 ++-- src/signatures/lzfse.rs | 2 +- src/signatures/lzma.rs | 2 +- src/signatures/lzop.rs | 4 ++-- src/signatures/mbr.rs | 2 +- src/signatures/openssl.rs | 2 +- src/signatures/packimg.rs | 2 +- src/signatures/pcap.rs | 2 +- src/signatures/pchrom.rs | 2 +- src/signatures/pdf.rs | 2 +- src/signatures/pe.rs | 2 +- src/signatures/pem.rs | 4 ++-- src/signatures/pjl.rs | 2 +- src/signatures/png.rs | 2 +- src/signatures/qnx.rs | 2 +- src/signatures/rar.rs | 4 ++-- src/signatures/riff.rs | 2 +- src/signatures/romfs.rs | 2 +- src/signatures/rsa.rs | 4 ++-- src/signatures/rtk.rs | 2 +- src/signatures/seama.rs | 2 +- src/signatures/sevenzip.rs | 2 +- src/signatures/squashfs.rs | 2 +- src/signatures/srec.rs | 4 ++-- src/signatures/svg.rs | 2 +- src/signatures/tarball.rs | 4 ++-- src/signatures/tplink.rs | 2 +- src/signatures/trx.rs | 2 +- src/signatures/ubi.rs | 6 +++--- src/signatures/uefi.rs | 4 ++-- src/signatures/uimage.rs | 2 +- src/signatures/vxworks.rs | 4 ++-- src/signatures/xz.rs | 4 ++-- src/signatures/yaffs.rs | 10 +++++----- src/signatures/zip.rs | 4 ++-- src/signatures/zlib.rs | 2 +- src/signatures/zstd.rs | 2 +- src/structures/androidsparse.rs | 6 +++--- src/structures/cab.rs | 6 +++--- src/structures/chk.rs | 4 ++-- src/structures/cpio.rs | 2 +- src/structures/cramfs.rs | 4 ++-- src/structures/deb.rs | 2 +- src/structures/dlob.rs | 2 +- src/structures/dmg.rs | 4 ++-- src/structures/dtb.rs | 4 ++-- src/structures/efigpt.rs | 2 +- src/structures/elf.rs | 4 ++-- src/structures/ext.rs | 2 +- src/structures/fat.rs | 2 +- src/structures/gif.rs | 8 ++++---- src/structures/gzip.rs | 2 +- src/structures/iso9660.rs | 2 +- src/structures/jboot.rs | 6 +++--- src/structures/jffs2.rs | 6 +++--- src/structures/linux.rs | 2 +- src/structures/luks.rs | 4 ++-- src/structures/lz4.rs | 8 ++++---- src/structures/lzfse.rs | 10 +++++----- src/structures/lzma.rs | 4 ++-- src/structures/lzop.rs | 12 ++++++------ src/structures/mbr.rs | 4 ++-- src/structures/openssl.rs | 4 ++-- src/structures/packimg.rs | 4 ++-- src/structures/pcap.rs | 6 +++--- src/structures/pchrom.rs | 8 ++++---- src/structures/pe.rs | 2 +- src/structures/png.rs | 4 ++-- src/structures/qnx.rs | 2 +- src/structures/rar.rs | 2 +- src/structures/riff.rs | 4 ++-- src/structures/romfs.rs | 12 ++++++------ src/structures/rtk.rs | 2 +- src/structures/seama.rs | 6 +++--- src/structures/sevenzip.rs | 2 +- src/structures/squashfs.rs | 12 ++++++------ src/structures/svg.rs | 10 +++++----- src/structures/tplink.rs | 2 +- src/structures/trx.rs | 2 +- src/structures/ubi.rs | 10 +++++----- src/structures/uefi.rs | 4 ++-- src/structures/uimage.rs | 8 ++++---- src/structures/vxworks.rs | 8 ++++---- src/structures/xz.rs | 4 ++-- src/structures/yaffs.rs | 4 ++-- src/structures/zip.rs | 4 ++-- src/structures/zstd.rs | 4 ++-- 154 files changed, 292 insertions(+), 291 deletions(-) diff --git a/src/extractors/androidsparse.rs b/src/extractors/androidsparse.rs index 444cccdca..b05006b8a 100644 --- a/src/extractors/androidsparse.rs +++ b/src/extractors/androidsparse.rs @@ -4,10 +4,10 @@ use crate::structures::androidsparse; /// Defines the internal extractor function for decompressing zlib data pub fn android_sparse_extractor() -> Extractor { - return Extractor { + Extractor { utility: ExtractorType::Internal(extract_android_sparse), ..Default::default() - }; + } } /// Android sparse internal extractor diff --git a/src/extractors/arcadyan.rs b/src/extractors/arcadyan.rs index 67670394b..72b6ede9f 100644 --- a/src/extractors/arcadyan.rs +++ b/src/extractors/arcadyan.rs @@ -3,10 +3,10 @@ use crate::extractors::lzma::lzma_decompress; /// Defines the internal extractor for Arcadyn Obfuscated LZMA pub fn obfuscated_lzma_extractor() -> Extractor { - return Extractor { + Extractor { utility: ExtractorType::Internal(extract_obfuscated_lzma), ..Default::default() - }; + } } /// Internal extractor for Arcadyn Obfuscated LZMA diff --git a/src/extractors/bzip2.rs b/src/extractors/bzip2.rs index 1942c6b77..074d7310c 100644 --- a/src/extractors/bzip2.rs +++ b/src/extractors/bzip2.rs @@ -3,10 +3,10 @@ use bzip2::{Decompress, Status}; /// Defines the internal extractor function for decompressing BZIP2 files pub fn bzip2_extractor() -> Extractor { - return Extractor { + Extractor { utility: ExtractorType::Internal(bzip2_decompressor), ..Default::default() - }; + } } /// Internal extractor for decompressing BZIP2 data diff --git a/src/extractors/cab.rs b/src/extractors/cab.rs index e20359411..4e800dcf2 100644 --- a/src/extractors/cab.rs +++ b/src/extractors/cab.rs @@ -2,11 +2,11 @@ use crate::extractors; /// Describes how to run the cabextract utility to extract MS CAB archives pub fn cab_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("cabextract".to_string()), extension: "cab".to_string(), arguments: vec![extractors::common::SOURCE_FILE_PLACEHOLDER.to_string()], exit_codes: vec![0], ..Default::default() - }; + } } diff --git a/src/extractors/dmg.rs b/src/extractors/dmg.rs index d0fefd343..d75e091c0 100644 --- a/src/extractors/dmg.rs +++ b/src/extractors/dmg.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the dmg2img utility to convert DMG images to MBR pub fn dmg_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("dmg2img".to_string()), extension: "dmg".to_string(), arguments: vec![ @@ -13,5 +13,5 @@ pub fn dmg_extractor() -> extractors::common::Extractor { ], exit_codes: vec![0, 1], ..Default::default() - }; + } } diff --git a/src/extractors/dtb.rs b/src/extractors/dtb.rs index bd79bbe4b..364ff5287 100644 --- a/src/extractors/dtb.rs +++ b/src/extractors/dtb.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the dtc utility to extract DTB files pub fn dtb_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("dtc".to_string()), extension: "dtb".to_string(), arguments: vec![ @@ -16,5 +16,5 @@ pub fn dtb_extractor() -> extractors::common::Extractor { ], exit_codes: vec![0], ..Default::default() - }; + } } diff --git a/src/extractors/dumpifs.rs b/src/extractors/dumpifs.rs index abf74259b..9f6de0c19 100644 --- a/src/extractors/dumpifs.rs +++ b/src/extractors/dumpifs.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the dumpifs utility to extract QNX IFS images pub fn dumpifs_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("dumpifs".to_string()), extension: "ifs".to_string(), arguments: vec![ @@ -11,5 +11,5 @@ pub fn dumpifs_extractor() -> extractors::common::Extractor { ], exit_codes: vec![0], ..Default::default() - }; + } } diff --git a/src/extractors/gif.rs b/src/extractors/gif.rs index 6e7e4ff4e..43f64e8f0 100644 --- a/src/extractors/gif.rs +++ b/src/extractors/gif.rs @@ -5,11 +5,11 @@ use crate::structures::gif::{parse_gif_extension, parse_gif_header, parse_gif_im /// Defines the internal extractor function for carving out JPEG images pub fn gif_extractor() -> Extractor { - return Extractor { + Extractor { do_not_recurse: true, utility: ExtractorType::Internal(extract_gif_image), ..Default::default() - }; + } } /// Parses and carves a GIF image from a file diff --git a/src/extractors/gzip.rs b/src/extractors/gzip.rs index 9a937b4cb..1b2b9377e 100644 --- a/src/extractors/gzip.rs +++ b/src/extractors/gzip.rs @@ -4,10 +4,10 @@ use crate::structures::gzip::parse_gzip_header; /// Defines the internal extractor function for decompressing gzip data pub fn gzip_extractor() -> Extractor { - return Extractor { + Extractor { utility: ExtractorType::Internal(gzip_decompress), ..Default::default() - }; + } } /// Internal extractor for gzip compressed data diff --git a/src/extractors/jboot.rs b/src/extractors/jboot.rs index 77ffae30d..858d89e05 100644 --- a/src/extractors/jboot.rs +++ b/src/extractors/jboot.rs @@ -4,10 +4,10 @@ use crate::structures::jboot::parse_jboot_sch2_header; /// Defines the internal extractor function for carving out JBOOT SCH2 kernels pub fn sch2_extractor() -> Extractor { - return Extractor { + Extractor { utility: ExtractorType::Internal(extract_jboot_sch2_kernel), ..Default::default() - }; + } } /// Extract the kernel described by a JBOOT SCH2 header diff --git a/src/extractors/jffs2.rs b/src/extractors/jffs2.rs index 3c5e83881..9c8185e97 100644 --- a/src/extractors/jffs2.rs +++ b/src/extractors/jffs2.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the jefferson utility to extract JFFS file systems pub fn jffs2_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("jefferson".to_string()), extension: "img".to_string(), arguments: vec![ @@ -13,5 +13,5 @@ pub fn jffs2_extractor() -> extractors::common::Extractor { ], exit_codes: vec![0, 1, 2], ..Default::default() - }; + } } diff --git a/src/extractors/jpeg.rs b/src/extractors/jpeg.rs index f3bc65a82..982564215 100644 --- a/src/extractors/jpeg.rs +++ b/src/extractors/jpeg.rs @@ -3,11 +3,11 @@ use aho_corasick::AhoCorasick; /// Defines the internal extractor function for carving out JPEG images pub fn jpeg_extractor() -> Extractor { - return Extractor { + Extractor { do_not_recurse: true, utility: ExtractorType::Internal(extract_jpeg_image), ..Default::default() - }; + } } /// Internal extractor for carving JPEG images to disk diff --git a/src/extractors/linux.rs b/src/extractors/linux.rs index 7220f8ab2..603406220 100644 --- a/src/extractors/linux.rs +++ b/src/extractors/linux.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the vmlinux-to-elf utility to convert raw kernel images to ELF files pub fn linux_kernel_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { do_not_recurse: true, utility: extractors::common::ExtractorType::External("vmlinux-to-elf".to_string()), extension: "bin".to_string(), @@ -14,5 +14,5 @@ pub fn linux_kernel_extractor() -> extractors::common::Extractor { ], exit_codes: vec![0], ..Default::default() - }; + } } diff --git a/src/extractors/lz4.rs b/src/extractors/lz4.rs index 446ca3746..8d6992982 100644 --- a/src/extractors/lz4.rs +++ b/src/extractors/lz4.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the lz4 utility to extract LZ4 compressed files pub fn lz4_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("lz4".to_string()), extension: "lz4".to_string(), arguments: vec![ @@ -13,5 +13,5 @@ pub fn lz4_extractor() -> extractors::common::Extractor { ], exit_codes: vec![0], ..Default::default() - }; + } } diff --git a/src/extractors/lzfse.rs b/src/extractors/lzfse.rs index 3284432db..ca553aba0 100644 --- a/src/extractors/lzfse.rs +++ b/src/extractors/lzfse.rs @@ -4,7 +4,7 @@ use crate::extractors::common::{Extractor, ExtractorType, SOURCE_FILE_PLACEHOLDE pub fn lzfse_extractor() -> Extractor { const OUTPUT_FILE_NAME: &str = "decompressed.bin"; - return Extractor { + Extractor { utility: ExtractorType::External("lzfse".to_string()), extension: "bin".to_string(), arguments: vec![ @@ -16,5 +16,5 @@ pub fn lzfse_extractor() -> Extractor { ], exit_codes: vec![0], ..Default::default() - }; + } } diff --git a/src/extractors/lzma.rs b/src/extractors/lzma.rs index 40012744f..ed58382f3 100644 --- a/src/extractors/lzma.rs +++ b/src/extractors/lzma.rs @@ -3,10 +3,10 @@ use xz2::stream::{Action, Status, Stream}; /// Defines the internal extractor function for decompressing LZMA/XZ data pub fn lzma_extractor() -> Extractor { - return Extractor { + Extractor { utility: ExtractorType::Internal(lzma_decompress), ..Default::default() - }; + } } /// Internal extractor for decompressing LZMA/XZ data streams diff --git a/src/extractors/lzop.rs b/src/extractors/lzop.rs index fb37a9b66..6fd0487e5 100644 --- a/src/extractors/lzop.rs +++ b/src/extractors/lzop.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the lzop utility to extract LZO compressed files pub fn lzop_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("lzop".to_string()), extension: "lzo".to_string(), arguments: vec![ @@ -13,5 +13,5 @@ pub fn lzop_extractor() -> extractors::common::Extractor { ], exit_codes: vec![0], ..Default::default() - }; + } } diff --git a/src/extractors/mbr.rs b/src/extractors/mbr.rs index 54390b5b4..f2dc6b927 100644 --- a/src/extractors/mbr.rs +++ b/src/extractors/mbr.rs @@ -3,10 +3,10 @@ use crate::structures::mbr::parse_mbr_image; /// Defines the internal extractor function for MBR partitions pub fn mbr_extractor() -> Extractor { - return Extractor { + Extractor { utility: ExtractorType::Internal(extract_mbr_partitions), ..Default::default() - }; + } } /// Validate and extract partitions from an MBR diff --git a/src/extractors/pcap.rs b/src/extractors/pcap.rs index 7d39477be..483aa9f97 100644 --- a/src/extractors/pcap.rs +++ b/src/extractors/pcap.rs @@ -4,11 +4,11 @@ use crate::structures::pcap::{parse_pcapng_block, parse_pcapng_section_block}; /// Defines the internal extractor function for extracting pcap-ng files pub fn pcapng_extractor() -> Extractor { - return Extractor { + Extractor { do_not_recurse: true, utility: ExtractorType::Internal(pcapng_carver), ..Default::default() - }; + } } /// Carves a pcap-ng file to disk diff --git a/src/extractors/pem.rs b/src/extractors/pem.rs index 446b77f0c..58f5bf0fc 100644 --- a/src/extractors/pem.rs +++ b/src/extractors/pem.rs @@ -3,20 +3,20 @@ use aho_corasick::AhoCorasick; /// Defines the internal extractor function for carving out PEM keys pub fn pem_key_extractor() -> Extractor { - return Extractor { + Extractor { do_not_recurse: true, utility: ExtractorType::Internal(pem_key_carver), ..Default::default() - }; + } } /// Internal extractor function for carving out PEM certs pub fn pem_certificate_extractor() -> Extractor { - return Extractor { + Extractor { do_not_recurse: true, utility: ExtractorType::Internal(pem_certificate_carver), ..Default::default() - }; + } } pub fn pem_certificate_carver( diff --git a/src/extractors/png.rs b/src/extractors/png.rs index e7e1daa1e..4797803cd 100644 --- a/src/extractors/png.rs +++ b/src/extractors/png.rs @@ -4,10 +4,10 @@ use crate::structures::png::parse_png_chunk_header; /// Defines the internal extractor function for carving out PNG images pub fn png_extractor() -> Extractor { - return Extractor { + Extractor { utility: ExtractorType::Internal(extract_png_image), ..Default::default() - }; + } } /// Internal extractor for carving PNG files to disk diff --git a/src/extractors/rar.rs b/src/extractors/rar.rs index b13d1d7cd..8441807c7 100644 --- a/src/extractors/rar.rs +++ b/src/extractors/rar.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the unrar utility to extract RAR archives pub fn rar_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("unrar".to_string()), extension: "rar".to_string(), arguments: vec![ @@ -12,5 +12,5 @@ pub fn rar_extractor() -> extractors::common::Extractor { ], exit_codes: vec![0], ..Default::default() - }; + } } diff --git a/src/extractors/riff.rs b/src/extractors/riff.rs index 68d207f82..53a95681f 100644 --- a/src/extractors/riff.rs +++ b/src/extractors/riff.rs @@ -3,11 +3,11 @@ use crate::structures::riff::parse_riff_header; /// Describes the internal RIFF image extactor pub fn riff_extractor() -> Extractor { - return Extractor { + Extractor { utility: ExtractorType::Internal(extract_riff_image), do_not_recurse: true, ..Default::default() - }; + } } /// Internal extractor for carving RIFF files to disk diff --git a/src/extractors/romfs.rs b/src/extractors/romfs.rs index 3c139594a..3911b03dd 100644 --- a/src/extractors/romfs.rs +++ b/src/extractors/romfs.rs @@ -28,10 +28,10 @@ struct RomFSEntry { /// Defines the internal extractor function for extracting RomFS file systems */ pub fn romfs_extractor() -> Extractor { - return Extractor { + Extractor { utility: ExtractorType::Internal(extract_romfs), ..Default::default() - }; + } } /// Internal RomFS extractor diff --git a/src/extractors/sevenzip.rs b/src/extractors/sevenzip.rs index a2d32437a..3de64dccd 100644 --- a/src/extractors/sevenzip.rs +++ b/src/extractors/sevenzip.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the 7z utility, supports multiple file formats pub fn sevenzip_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("7z".to_string()), extension: "bin".to_string(), arguments: vec![ @@ -14,5 +14,5 @@ pub fn sevenzip_extractor() -> extractors::common::Extractor { // If there is trailing data after the compressed data, extraction will happen but exit code will be 2 exit_codes: vec![0, 2], ..Default::default() - }; + } } diff --git a/src/extractors/squashfs.rs b/src/extractors/squashfs.rs index e1d8aa031..4f8c871a6 100644 --- a/src/extractors/squashfs.rs +++ b/src/extractors/squashfs.rs @@ -2,24 +2,24 @@ use crate::extractors; /// Describes how to run the sasquatch utility to extract SquashFS images pub fn squashfs_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("sasquatch".to_string()), extension: "sqsh".to_string(), arguments: vec![extractors::common::SOURCE_FILE_PLACEHOLDER.to_string()], // Exit code may be 0 or 2; 2 indicates running as not root, but otherwise extraction is ok exit_codes: vec![0, 2], ..Default::default() - }; + } } /// Describes how to run the sasquatch-v4be utility to extract big endian SquashFSv4 images pub fn squashfs_v4_be_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("sasquatch-v4be".to_string()), extension: "sqsh".to_string(), arguments: vec![extractors::common::SOURCE_FILE_PLACEHOLDER.to_string()], // Exit code may be 0 or 2; 2 indicates running as not root, but otherwise extraction is ok exit_codes: vec![0, 2], ..Default::default() - }; + } } diff --git a/src/extractors/srec.rs b/src/extractors/srec.rs index 2215b13b9..0bc049d30 100644 --- a/src/extractors/srec.rs +++ b/src/extractors/srec.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the srec2bin utility to convert Motorola S-records to binary pub fn srec_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("srec2bin".to_string()), extension: "hex".to_string(), arguments: vec![ @@ -11,5 +11,5 @@ pub fn srec_extractor() -> extractors::common::Extractor { ], exit_codes: vec![0], ..Default::default() - }; + } } diff --git a/src/extractors/svg.rs b/src/extractors/svg.rs index a5ebb2a55..74b3cfc84 100644 --- a/src/extractors/svg.rs +++ b/src/extractors/svg.rs @@ -3,11 +3,11 @@ use crate::structures::svg::parse_svg_image; /// Defines the internal extractor function for carving out SVG images pub fn svg_extractor() -> Extractor { - return Extractor { + Extractor { do_not_recurse: true, utility: ExtractorType::Internal(extract_svg_image), ..Default::default() - }; + } } /// Internal extractor for carving SVG images to disk diff --git a/src/extractors/tarball.rs b/src/extractors/tarball.rs index 4c963bb45..96ae07fba 100644 --- a/src/extractors/tarball.rs +++ b/src/extractors/tarball.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the tar utility to extract tarball archives pub fn tarball_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("tar".to_string()), extension: "tar".to_string(), arguments: vec![ @@ -13,5 +13,5 @@ pub fn tarball_extractor() -> extractors::common::Extractor { // Exit code may be 2 if attempting to create special device files fails exit_codes: vec![0, 2], ..Default::default() - }; + } } diff --git a/src/extractors/trx.rs b/src/extractors/trx.rs index f4349a7dc..97fb38719 100644 --- a/src/extractors/trx.rs +++ b/src/extractors/trx.rs @@ -4,10 +4,10 @@ use crate::structures::trx::parse_trx_header; /// Defines the internal TRX extractor pub fn trx_extractor() -> Extractor { - return Extractor { + Extractor { utility: ExtractorType::Internal(extract_trx_partitions), ..Default::default() - }; + } } /// Internal extractor for TRX partitions diff --git a/src/extractors/tsk.rs b/src/extractors/tsk.rs index 71d8a0b46..9363fe7a8 100644 --- a/src/extractors/tsk.rs +++ b/src/extractors/tsk.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the tsk_recover utility to extract various file systems pub fn tsk_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("tsk_recover".to_string()), extension: "img".to_string(), arguments: vec![ @@ -14,5 +14,5 @@ pub fn tsk_extractor() -> extractors::common::Extractor { ], exit_codes: vec![0], ..Default::default() - }; + } } diff --git a/src/extractors/ubi.rs b/src/extractors/ubi.rs index 60ef851a7..7aa7893f1 100644 --- a/src/extractors/ubi.rs +++ b/src/extractors/ubi.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the ubireader_extract_images utility to extract UBI images pub fn ubi_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External( "ubireader_extract_images".to_string(), ), @@ -10,16 +10,16 @@ pub fn ubi_extractor() -> extractors::common::Extractor { arguments: vec![extractors::common::SOURCE_FILE_PLACEHOLDER.to_string()], exit_codes: vec![0], ..Default::default() - }; + } } /// Describes how to run the ubireader_extract_files utility to extract UBIFS images pub fn ubifs_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("ubireader_extract_files".to_string()), extension: "ubifs".to_string(), arguments: vec![extractors::common::SOURCE_FILE_PLACEHOLDER.to_string()], exit_codes: vec![0], ..Default::default() - }; + } } diff --git a/src/extractors/uefi.rs b/src/extractors/uefi.rs index dcf7141ce..3d124c669 100644 --- a/src/extractors/uefi.rs +++ b/src/extractors/uefi.rs @@ -2,7 +2,7 @@ use crate::extractors; /* Describes how to run the uefi-firmware-parser utility to extract UEFI images */ pub fn uefi_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("uefi-firmware-parser".to_string()), extension: "img".to_string(), arguments: vec![ @@ -18,5 +18,5 @@ pub fn uefi_extractor() -> extractors::common::Extractor { */ do_not_recurse: true, ..Default::default() - }; + } } diff --git a/src/extractors/uimage.rs b/src/extractors/uimage.rs index 213fabc0e..91933385c 100644 --- a/src/extractors/uimage.rs +++ b/src/extractors/uimage.rs @@ -3,10 +3,10 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use crate::structures::uimage::parse_uimage_header; pub fn uimage_extractor() -> Extractor { - return Extractor { + Extractor { utility: ExtractorType::Internal(extract_uimage), ..Default::default() - }; + } } pub fn extract_uimage( diff --git a/src/extractors/vxworks.rs b/src/extractors/vxworks.rs index 228df60c0..f2337352d 100644 --- a/src/extractors/vxworks.rs +++ b/src/extractors/vxworks.rs @@ -7,11 +7,11 @@ use serde_json; /// Describes the VxWorks symbol table extractor pub fn vxworks_symtab_extractor() -> Extractor { - return Extractor { + Extractor { do_not_recurse: true, utility: ExtractorType::Internal(extract_symbol_table), ..Default::default() - }; + } } /// Internal extractor for writing VxWorks symbol tables to JSON diff --git a/src/extractors/yaffs2.rs b/src/extractors/yaffs2.rs index b3d856bb9..4e514fbae 100644 --- a/src/extractors/yaffs2.rs +++ b/src/extractors/yaffs2.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the unyaffs utility to extract YAFFS2 file systems pub fn yaffs2_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("unyaffs".to_string()), extension: "img".to_string(), arguments: vec![ @@ -11,5 +11,5 @@ pub fn yaffs2_extractor() -> extractors::common::Extractor { ], exit_codes: vec![0], ..Default::default() - }; + } } diff --git a/src/extractors/zip.rs b/src/extractors/zip.rs index 2be2a515a..5ba90ccfc 100644 --- a/src/extractors/zip.rs +++ b/src/extractors/zip.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the unzip utility to extract ZIP archives pub fn zip_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("unzip".to_string()), extension: "zip".to_string(), arguments: vec![ @@ -14,5 +14,5 @@ pub fn zip_extractor() -> extractors::common::Extractor { // Exit code 2 occurs when a CRC fails; files are still extracted though exit_codes: vec![0, 2], ..Default::default() - }; + } } diff --git a/src/extractors/zlib.rs b/src/extractors/zlib.rs index 9d2ae11b6..57b5d4c05 100644 --- a/src/extractors/zlib.rs +++ b/src/extractors/zlib.rs @@ -3,10 +3,10 @@ use crate::extractors::inflate; /// Defines the internal extractor function for decompressing zlib data pub fn zlib_extractor() -> Extractor { - return Extractor { + Extractor { utility: ExtractorType::Internal(zlib_decompress), ..Default::default() - }; + } } /// Internal extractor for decompressing ZLIB data diff --git a/src/extractors/zstd.rs b/src/extractors/zstd.rs index cc2abde60..c7632a617 100644 --- a/src/extractors/zstd.rs +++ b/src/extractors/zstd.rs @@ -2,7 +2,7 @@ use crate::extractors; /// Describes how to run the zstd utility to extract ZSTD compressed files pub fn zstd_extractor() -> extractors::common::Extractor { - return extractors::common::Extractor { + extractors::common::Extractor { utility: extractors::common::ExtractorType::External("zstd".to_string()), extension: "zst".to_string(), arguments: vec![ @@ -13,5 +13,5 @@ pub fn zstd_extractor() -> extractors::common::Extractor { ], exit_codes: vec![0], ..Default::default() - }; + } } diff --git a/src/signatures/aes.rs b/src/signatures/aes.rs index 8b56ea0b4..0a711e88e 100644 --- a/src/signatures/aes.rs +++ b/src/signatures/aes.rs @@ -25,5 +25,5 @@ pub fn aes_sbox_parser( }; // Nothing to do, just return success - return Ok(result); + Ok(result) } diff --git a/src/signatures/androidsparse.rs b/src/signatures/androidsparse.rs index 0c4a456c1..d4eeda239 100644 --- a/src/signatures/androidsparse.rs +++ b/src/signatures/androidsparse.rs @@ -44,5 +44,5 @@ pub fn android_sparse_parser( } } - return Err(SignatureError); + Err(SignatureError) } diff --git a/src/signatures/arcadyan.rs b/src/signatures/arcadyan.rs index eaab7ab8c..20268ec74 100644 --- a/src/signatures/arcadyan.rs +++ b/src/signatures/arcadyan.rs @@ -40,5 +40,5 @@ pub fn obfuscated_lzma_parser( } } - return Err(SignatureError); + Err(SignatureError) } diff --git a/src/signatures/bzip2.rs b/src/signatures/bzip2.rs index fbf3d8601..5c6c92207 100644 --- a/src/signatures/bzip2.rs +++ b/src/signatures/bzip2.rs @@ -36,8 +36,9 @@ pub fn bzip2_parser(file_data: &Vec, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result Option { diff --git a/src/signatures/dtb.rs b/src/signatures/dtb.rs index ab5c82f10..f487c8e55 100644 --- a/src/signatures/dtb.rs +++ b/src/signatures/dtb.rs @@ -36,5 +36,5 @@ pub fn dtb_parser(file_data: &Vec, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result Result { } } - return Err(SignatureError); + Err(SignatureError) } diff --git a/src/signatures/pjl.rs b/src/signatures/pjl.rs index 2d606a87c..f986c7197 100644 --- a/src/signatures/pjl.rs +++ b/src/signatures/pjl.rs @@ -36,5 +36,5 @@ pub fn pjl_parser(file_data: &Vec, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result Result { return Ok(block_count * leb_size); } - return Err(SignatureError); + Err(SignatureError) } diff --git a/src/signatures/uefi.rs b/src/signatures/uefi.rs index 87d389251..985baa10d 100644 --- a/src/signatures/uefi.rs +++ b/src/signatures/uefi.rs @@ -57,7 +57,7 @@ pub fn uefi_volume_parser( } } - return Err(SignatureError); + Err(SignatureError) } /// Validates UEFI capsule signatures @@ -88,5 +88,5 @@ pub fn uefi_capsule_parser( } } - return Err(SignatureError); + Err(SignatureError) } diff --git a/src/signatures/uimage.rs b/src/signatures/uimage.rs index 97eca2bef..a80ec11de 100644 --- a/src/signatures/uimage.rs +++ b/src/signatures/uimage.rs @@ -51,5 +51,5 @@ pub fn uimage_parser( } } - return Err(SignatureError); + Err(SignatureError) } diff --git a/src/signatures/vxworks.rs b/src/signatures/vxworks.rs index 9c4fa2cd1..f8da708ab 100644 --- a/src/signatures/vxworks.rs +++ b/src/signatures/vxworks.rs @@ -55,7 +55,7 @@ pub fn wind_kernel_parser( } } - return Err(SignatureError); + Err(SignatureError) } /// Validates VxWorks symbol table signatures @@ -94,5 +94,5 @@ pub fn symbol_table_parser( } } - return Err(SignatureError); + Err(SignatureError) } diff --git a/src/signatures/xz.rs b/src/signatures/xz.rs index 95ffa361b..34ccf6b49 100644 --- a/src/signatures/xz.rs +++ b/src/signatures/xz.rs @@ -34,7 +34,7 @@ pub fn xz_parser(file_data: &Vec, offset: usize) -> Result Result { } } - return Err(SignatureError); + Err(SignatureError) } diff --git a/src/signatures/yaffs.rs b/src/signatures/yaffs.rs index e670386a5..7c3446920 100644 --- a/src/signatures/yaffs.rs +++ b/src/signatures/yaffs.rs @@ -62,7 +62,7 @@ pub fn yaffs_parser(file_data: &Vec, offset: usize) -> Result Result { } // Nothing valid found - return Err(SignatureError); + Err(SignatureError) } /// Returns the detected spare size of the YAFFS image @@ -123,7 +123,7 @@ fn get_spare_size( } // Nothing valid found - return Err(SignatureError); + Err(SignatureError) } /// Returns the total size of the image, in bytes @@ -187,7 +187,7 @@ fn get_image_size( return Ok(image_size); } - return Err(SignatureError); + Err(SignatureError) } /// Returns the number of data blocks used to store file data; this size is only valid for file type objects @@ -209,5 +209,5 @@ fn get_file_block_count( } } - return Err(SignatureError); + Err(SignatureError) } diff --git a/src/signatures/zip.rs b/src/signatures/zip.rs index 99b27c647..752b98597 100644 --- a/src/signatures/zip.rs +++ b/src/signatures/zip.rs @@ -33,7 +33,7 @@ pub fn zip_parser(file_data: &Vec, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result Result Result Result Result let struct_size: usize = common::size(&chk_header_structure); // Parse the CHK header - if let Ok(chk_header) = common::parse(&header_data, &chk_header_structure, "big") { + if let Ok(chk_header) = common::parse(header_data, &chk_header_structure, "big") { // Validate the reported header size if chk_header["header_size"] > struct_size && chk_header["header_size"] <= MAX_EXPECTED_HEADER_SIZE @@ -57,5 +57,5 @@ pub fn parse_chk_header(header_data: &[u8]) -> Result } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/cpio.rs b/src/structures/cpio.rs index daf6d5eb9..8077d7c35 100644 --- a/src/structures/cpio.rs +++ b/src/structures/cpio.rs @@ -69,7 +69,7 @@ pub fn parse_cpio_entry_header(cpio_data: &[u8]) -> Result Result Result Result { } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/dlob.rs b/src/structures/dlob.rs index 75bf66fe8..6d0ce9aeb 100644 --- a/src/structures/dlob.rs +++ b/src/structures/dlob.rs @@ -54,5 +54,5 @@ pub fn parse_dlob_header(dlob_data: &[u8]) -> Result } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/dmg.rs b/src/structures/dmg.rs index ccbb92e67..e58409462 100644 --- a/src/structures/dmg.rs +++ b/src/structures/dmg.rs @@ -120,7 +120,7 @@ pub fn parse_dmg_footer(dmg_data: &[u8]) -> Result { let structure_size: usize = common::size(&dmg_footer_structure); // Parse the DMG footer - if let Ok(dmg_footer) = common::parse(&dmg_data, &dmg_footer_structure, "big") { + if let Ok(dmg_footer) = common::parse(dmg_data, &dmg_footer_structure, "big") { // Sanity check, make sure the reported header size is the size of this structure if dmg_footer["header_size"] == structure_size { return Ok(DMGFooter { @@ -131,5 +131,5 @@ pub fn parse_dmg_footer(dmg_data: &[u8]) -> Result { } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/dtb.rs b/src/structures/dtb.rs index e25f0293e..141139cb0 100644 --- a/src/structures/dtb.rs +++ b/src/structures/dtb.rs @@ -37,7 +37,7 @@ pub fn parse_dtb_header(dtb_data: &[u8]) -> Result { let dtb_structure_size = common::size(&dtb_structure); // Parse the header - if let Ok(dtb_header) = common::parse(&dtb_data, &dtb_structure, "big") { + if let Ok(dtb_header) = common::parse(dtb_data, &dtb_structure, "big") { // Check the reported versioning if dtb_header["version"] == EXPECTED_VERSION && dtb_header["min_compatible_version"] == EXPECTED_COMPAT_VERSION @@ -65,5 +65,5 @@ pub fn parse_dtb_header(dtb_data: &[u8]) -> Result { } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/efigpt.rs b/src/structures/efigpt.rs index 266808804..76ea006bb 100644 --- a/src/structures/efigpt.rs +++ b/src/structures/efigpt.rs @@ -94,7 +94,7 @@ pub fn parse_efigpt_header(efi_data: &[u8]) -> Result Result { }; // Endianness doesn't matter here, and we don't know what the ELF's endianness is yet - if let Ok(e_ident) = common::parse(&elf_data, &elf_ident_structure, "little") { + if let Ok(e_ident) = common::parse(elf_data, &elf_ident_structure, "little") { // Sanity check the e_ident fields if e_ident["padding_1"] == 0 && e_ident["padding_2"] == 0 { if e_ident["version"] == EXPECTED_VERSION { @@ -189,5 +189,5 @@ pub fn parse_elf_header(elf_data: &[u8]) -> Result { } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/ext.rs b/src/structures/ext.rs index a236a3ff6..e60461d3d 100644 --- a/src/structures/ext.rs +++ b/src/structures/ext.rs @@ -103,5 +103,5 @@ pub fn parse_ext_header(ext_data: &[u8]) -> Result { } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/fat.rs b/src/structures/fat.rs index 92bd14550..0ce67e3ec 100644 --- a/src/structures/fat.rs +++ b/src/structures/fat.rs @@ -88,5 +88,5 @@ pub fn parse_fat_header(fat_data: &[u8]) -> Result { } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/gif.rs b/src/structures/gif.rs index 9bed971b8..2b49eac3c 100644 --- a/src/structures/gif.rs +++ b/src/structures/gif.rs @@ -33,7 +33,7 @@ pub fn parse_gif_header(gif_data: &[u8]) -> Result { }); } - return Err(StructureError); + Err(StructureError) } /// Struct to store GIF flags info @@ -92,7 +92,7 @@ pub fn parse_gif_image_descriptor(gif_data: &[u8]) -> Result Result } } - return Err(StructureError); + Err(StructureError) } /// Parses a GIF extension block, returns the size of the extension block, in bytes. @@ -154,5 +154,5 @@ pub fn parse_gif_extension(extension_data: &[u8]) -> Result Result Result { } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/jboot.rs b/src/structures/jboot.rs index 066231765..22c87e5d9 100644 --- a/src/structures/jboot.rs +++ b/src/structures/jboot.rs @@ -86,7 +86,7 @@ pub fn parse_jboot_arm_header(jboot_data: &[u8]) -> Result Result Result Result { return Err(StructureError); } @@ -64,7 +64,7 @@ pub fn parse_jffs2_node_header(node_data: &[u8]) -> Result Result ..Default::default() }; - if let Ok(luks_base) = common::parse(&luks_data, &luks_base_structure, "big") { + if let Ok(luks_base) = common::parse(luks_data, &luks_base_structure, "big") { luks_hdr_info.version = luks_base["version"]; // Both v1 and v2 include the hash function string at the same offset @@ -87,5 +87,5 @@ pub fn parse_luks_header(luks_data: &[u8]) -> Result } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/lz4.rs b/src/structures/lz4.rs index 4c4b04d16..a7bc69862 100644 --- a/src/structures/lz4.rs +++ b/src/structures/lz4.rs @@ -34,7 +34,7 @@ pub fn parse_lz4_file_header(lz4_data: &[u8]) -> Result Result Result Result Result Result Result Result }; // Parse the lzma header - if let Ok(lzma_header) = common::parse(&lzma_data, &lzma_structure, "little") { + if let Ok(lzma_header) = common::parse(lzma_data, &lzma_structure, "little") { // Sanity check expected values for LZMA header fields if lzma_header["null_byte"] == 0 { if lzma_header["decompressed_size"] >= MIN_SUPPORTED_DECOMPRESSED_SIZE { @@ -46,5 +46,5 @@ pub fn parse_lzma_header(lzma_data: &[u8]) -> Result } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/lzop.rs b/src/structures/lzop.rs index 3c80fa955..d9c3d79cd 100644 --- a/src/structures/lzop.rs +++ b/src/structures/lzop.rs @@ -51,7 +51,7 @@ pub fn parse_lzop_file_header(lzop_data: &[u8]) -> Result Result Result { * It is unclear, but observed, that LZOP files end with 0x00000000; this is assumed to be an EOF marker, * as other similar compression file formats use that. This assumption could be incorrect. */ - if let Ok(eof_marker) = common::parse(&eof_data, &eof_structure, "big") { + if let Ok(eof_marker) = common::parse(eof_data, &eof_structure, "big") { // Sanity check the EOF marker if eof_marker["marker"] == EOF_MARKER { // Return the size of the EOF marker @@ -166,5 +166,5 @@ pub fn parse_lzop_eof_marker(eof_data: &[u8]) -> Result { } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/mbr.rs b/src/structures/mbr.rs index a93fac743..4bdf50c01 100644 --- a/src/structures/mbr.rs +++ b/src/structures/mbr.rs @@ -122,7 +122,7 @@ pub fn parse_mbr_image(mbr_data: &[u8]) -> Result { } // There should be at least one valid partition - if mbr_header.partitions.len() > 0 { + if !mbr_header.partitions.is_empty() { // Total size should be greater than minimum size if mbr_header.image_size > MIN_IMAGE_SIZE { return Ok(mbr_header); @@ -130,5 +130,5 @@ pub fn parse_mbr_image(mbr_data: &[u8]) -> Result { } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/openssl.rs b/src/structures/openssl.rs index 66901ff0d..1b5c28de3 100644 --- a/src/structures/openssl.rs +++ b/src/structures/openssl.rs @@ -9,11 +9,11 @@ pub struct OpenSSLCryptHeader { pub fn parse_openssl_crypt_header(ssl_data: &[u8]) -> Result { let ssl_structure = vec![("magic", "u32"), ("salt", "u64")]; - if let Ok(ssl_header) = common::parse(&ssl_data, &ssl_structure, "big") { + if let Ok(ssl_header) = common::parse(ssl_data, &ssl_structure, "big") { return Ok(OpenSSLCryptHeader { salt: ssl_header["salt"], }); } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/packimg.rs b/src/structures/packimg.rs index d12c3dd14..b5398822b 100644 --- a/src/structures/packimg.rs +++ b/src/structures/packimg.rs @@ -20,12 +20,12 @@ pub fn parse_packimg_header(packimg_data: &[u8]) -> Result Result { // Reserved bit in block type field const BLOCK_TYPE_RESERVED_MASK: usize = 0x80000000; @@ -51,7 +51,7 @@ pub fn parse_pcapng_block( } } - return Err(StructureError); + Err(StructureError) } #[derive(Debug, Default, Clone)] @@ -98,5 +98,5 @@ pub fn parse_pcapng_section_block(block_data: &[u8]) -> Result Result Result 0 { return Ok(image_size); - } else { - return Err(StructureError); } + + Err(StructureError) } diff --git a/src/structures/pe.rs b/src/structures/pe.rs index dd793e21c..617e5c72f 100644 --- a/src/structures/pe.rs +++ b/src/structures/pe.rs @@ -129,5 +129,5 @@ pub fn parse_pe_header(pe_data: &[u8]) -> Result { } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/png.rs b/src/structures/png.rs index f5eb70817..6857eeb00 100644 --- a/src/structures/png.rs +++ b/src/structures/png.rs @@ -19,12 +19,12 @@ pub fn parse_png_chunk_header(chunk_data: &[u8]) -> Result Result { } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/rar.rs b/src/structures/rar.rs index f78e44242..974b0d27d 100644 --- a/src/structures/rar.rs +++ b/src/structures/rar.rs @@ -25,5 +25,5 @@ pub fn parse_rar_archive_header(rar_data: &[u8]) -> Result Result ]; // Parse the riff header - if let Ok(riff_header) = common::parse(&riff_data, &riff_structure, "little") { + if let Ok(riff_header) = common::parse(riff_data, &riff_structure, "little") { // Sanity check expected magic bytes if riff_header["magic1"] == MAGIC1 && riff_header["magic2"] == MAGIC2 { // Get the RIFF type string (e.g., "WAV") @@ -39,5 +39,5 @@ pub fn parse_riff_header(riff_data: &[u8]) -> Result } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/romfs.rs b/src/structures/romfs.rs index 155d49f7d..d2680d298 100644 --- a/src/structures/romfs.rs +++ b/src/structures/romfs.rs @@ -35,7 +35,7 @@ pub fn parse_romfs_header(romfs_data: &[u8]) -> Result Result Result 0 { + if !file_name.is_empty() { // Instantiate a new RomFSEntry structure let mut file_header = RomFSFileHeader { ..Default::default() @@ -144,7 +144,7 @@ pub fn parse_romfs_file_entry(romfs_data: &[u8]) -> Result usize { padding = ALIGNMENT - remainder; } - return x + padding; + x + padding } /// Pretty simple checksum used by RomFS @@ -182,5 +182,5 @@ fn romfs_crc_valid(crc_data: &[u8]) -> bool { return sum == 0; } - return false; + false } diff --git a/src/structures/rtk.rs b/src/structures/rtk.rs index 75b7938f0..ce4df113d 100644 --- a/src/structures/rtk.rs +++ b/src/structures/rtk.rs @@ -33,5 +33,5 @@ pub fn parse_rtk_header(rtk_data: &[u8]) -> Result { return Ok(result); } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/seama.rs b/src/structures/seama.rs index 5ec76e8db..0f74e77b0 100644 --- a/src/structures/seama.rs +++ b/src/structures/seama.rs @@ -24,11 +24,11 @@ pub fn parse_seama_header(seama_data: &[u8]) -> Result { return Err(StructureError); } @@ -54,5 +54,5 @@ pub fn parse_seama_header(seama_data: &[u8]) -> Result Result Result Result { let squashfs_v4_uid_table_structure = vec![("uid_block_ptr", "u64")]; let squashfs_v3_uid_table_structure = vec![("uid_block_ptr", "u32")]; @@ -173,19 +173,19 @@ pub fn parse_squashfs_uid_entry( if version == 4 { match common::parse(uid_data, &squashfs_v4_uid_table_structure, endianness) { Err(e) => { - return Err(e); + Err(e) } Ok(uidv4) => { - return Ok(uidv4["uid_block_ptr"]); + Ok(uidv4["uid_block_ptr"]) } } } else { match common::parse(uid_data, &squashfs_v3_uid_table_structure, endianness) { Err(e) => { - return Err(e); + Err(e) } Ok(uidv3) => { - return Ok(uidv3["uid_block_ptr"]); + Ok(uidv3["uid_block_ptr"]) } } } diff --git a/src/structures/svg.rs b/src/structures/svg.rs index 9787efca1..b0b67ae90 100644 --- a/src/structures/svg.rs +++ b/src/structures/svg.rs @@ -30,15 +30,15 @@ pub fn parse_svg_image(svg_data: &[u8]) -> Result { break; } Ok(svg_tag) => { - if svg_tag.is_head == true { + if svg_tag.is_head { head_tag_count += 1; } - if svg_tag.is_open == true { + if svg_tag.is_open { unclosed_svg_tags += 1; } - if svg_tag.is_close == true { + if svg_tag.is_close { unclosed_svg_tags -= 1; } @@ -57,7 +57,7 @@ pub fn parse_svg_image(svg_data: &[u8]) -> Result { } } - return Err(StructureError); + Err(StructureError) } /// Stores info about a parsed SVG tag @@ -94,5 +94,5 @@ fn parse_svg_tag(tag_data: &[u8]) -> Result { } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/tplink.rs b/src/structures/tplink.rs index 4f15557d9..fceb5e45b 100644 --- a/src/structures/tplink.rs +++ b/src/structures/tplink.rs @@ -67,5 +67,5 @@ pub fn parse_tplink_header(tplink_data: &[u8]) -> Result Result } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/ubi.rs b/src/structures/ubi.rs index 69dc8f056..cd0584468 100644 --- a/src/structures/ubi.rs +++ b/src/structures/ubi.rs @@ -76,7 +76,7 @@ pub fn parse_ubi_superblock_header(ubi_data: &[u8]) -> Result Result Result(); // Parse the volume header - if let Ok(ubi_vol_header) = common::parse(&ubi_data, &ubi_vol_structure, "big") { + if let Ok(ubi_vol_header) = common::parse(ubi_data, &ubi_vol_structure, "big") { // Sanity check padding fields, they should all be null if ubi_vol_header["padding1"] == 0 && ubi_vol_header["padding2"] == 0 @@ -183,11 +183,11 @@ pub fn parse_ubi_volume_header(ubi_data: &[u8]) -> Result usize { const UBI_CRC_INIT: u32 = 0xFFFFFFFF; - return ((!crc32(data)) & UBI_CRC_INIT) as usize; + ((!crc32(data)) & UBI_CRC_INIT) as usize } diff --git a/src/structures/uefi.rs b/src/structures/uefi.rs index f3d8715b1..b826780ed 100644 --- a/src/structures/uefi.rs +++ b/src/structures/uefi.rs @@ -43,7 +43,7 @@ pub fn parse_uefi_volume_header(uefi_data: &[u8]) -> Result Result Result usize { // Header checksum has to be nulled out to calculate the CRC let mut uimage_header: Vec = hdr.to_vec(); - for i in HEADER_CRC_START..HEADER_CRC_END { - uimage_header[i] = 0; + for crc_byte in uimage_header.iter_mut().take(HEADER_CRC_END).skip(HEADER_CRC_START) { + *crc_byte = 0; } - return crc32(&uimage_header) as usize; + crc32(&uimage_header) as usize } diff --git a/src/structures/vxworks.rs b/src/structures/vxworks.rs index db9607c68..e194110e7 100644 --- a/src/structures/vxworks.rs +++ b/src/structures/vxworks.rs @@ -14,7 +14,7 @@ pub struct VxWorksSymbolTableEntry { /// Parse a single VxWorks symbol table entry pub fn parse_symtab_entry( symbol_data: &[u8], - endianness: &String, + endianness: &str, ) -> Result { // This *seems* to be the correct structure for a symbol table entry, it may be different for different VxWorks versions... let symtab_structure = vec![ @@ -34,7 +34,7 @@ pub fn parse_symtab_entry( let symtab_structure_size: usize = common::size(&symtab_structure); // Parse the symbol table entry - if let Ok(symbol_entry) = common::parse(&symbol_data, &symtab_structure, endianness) { + if let Ok(symbol_entry) = common::parse(symbol_data, &symtab_structure, endianness) { // Sanity check expected values in the symbol table entry if allowed_symbol_types.contains_key(&symbol_entry["type"]) { if symbol_entry["name_ptr"] != 0 && symbol_entry["value_ptr"] != 0 { @@ -48,7 +48,7 @@ pub fn parse_symtab_entry( } } - return Err(StructureError); + Err(StructureError) } /// Detect a symbol table entry's endianness @@ -66,5 +66,5 @@ pub fn get_symtab_endianness(symbol_data: &[u8]) -> Result Result { } } - return Err(StructureError); + Err(StructureError) } /// Parse and validate an XZ footer, returns the footer size @@ -52,5 +52,5 @@ pub fn parse_xz_footer(xz_data: &[u8]) -> Result { } } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/yaffs.rs b/src/structures/yaffs.rs index 11d11362e..164a09c0e 100644 --- a/src/structures/yaffs.rs +++ b/src/structures/yaffs.rs @@ -38,7 +38,7 @@ pub fn parse_yaffs_obj_header( } } - return Err(StructureError); + Err(StructureError) } /// Stores info about a YAFFS file header @@ -70,5 +70,5 @@ pub fn parse_yaffs_file_header( }); } - return Err(StructureError); + Err(StructureError) } diff --git a/src/structures/zip.rs b/src/structures/zip.rs index 92540c85a..0582f04c8 100644 --- a/src/structures/zip.rs +++ b/src/structures/zip.rs @@ -34,7 +34,7 @@ pub fn parse_zip_header(zip_data: &[u8]) -> Result { } } - return Err(StructureError); + Err(StructureError) } /// Stores info about a ZIP end-of-central-directory header @@ -75,5 +75,5 @@ pub fn parse_eocd_header(eocd_data: &[u8]) -> Result Result } } - return Err(StructureError); + Err(StructureError) } /// Stores info about a ZSTD block header @@ -107,5 +107,5 @@ pub fn parse_block_header(block_data: &[u8]) -> Result Date: Sat, 19 Oct 2024 15:32:41 -0400 Subject: [PATCH 002/131] More linting --- src/structures/jboot.rs | 6 +++--- src/structures/jffs2.rs | 2 +- src/structures/luks.rs | 6 +++--- src/structures/lz4.rs | 4 ++-- src/structures/lzfse.rs | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/structures/jboot.rs b/src/structures/jboot.rs index 22c87e5d9..484661095 100644 --- a/src/structures/jboot.rs +++ b/src/structures/jboot.rs @@ -208,12 +208,12 @@ fn sch2_header_crc(sch2_header_bytes: &[u8]) -> usize { let mut crc_data: Vec = sch2_header_bytes.to_vec(); // Header CRC field has to be NULL'd out - for i in HEADER_CRC_START..HEADER_CRC_END { - crc_data[i] = 0; + for crc_byte in crc_data.iter_mut().take(HEADER_CRC_END).skip(HEADER_CRC_START) { + *crc_byte = 0; } crc = crc32(&crc_data) as usize; } - return crc; + crc } diff --git a/src/structures/jffs2.rs b/src/structures/jffs2.rs index a3bb893c9..fd25361af 100644 --- a/src/structures/jffs2.rs +++ b/src/structures/jffs2.rs @@ -69,5 +69,5 @@ pub fn parse_jffs2_node_header(node_data: &[u8]) -> Result usize { - return (crc32_v2::crc32(0xFFFFFFFF, &file_data) ^ 0xFFFFFFFF) as usize; + (crc32_v2::crc32(0xFFFFFFFF, file_data) ^ 0xFFFFFFFF) as usize } diff --git a/src/structures/luks.rs b/src/structures/luks.rs index bd6f7b73f..48530f417 100644 --- a/src/structures/luks.rs +++ b/src/structures/luks.rs @@ -49,7 +49,7 @@ pub fn parse_luks_header(luks_data: &[u8]) -> Result luks_hdr_info.hashfn = get_cstring(hashfn_bytes); // Make sure there was actually a string at the expected hash function offset - if luks_hdr_info.hashfn.len() > 0 { + if !luks_hdr_info.hashfn.is_empty() { // Need to process v1 and v2 headers differently if luks_hdr_info.version == 1 { // Get the cipher algorithm string @@ -65,8 +65,8 @@ pub fn parse_luks_header(luks_data: &[u8]) -> Result luks_hdr_info.cipher_mode = get_cstring(cipher_mode_bytes); // Make sure there were valid strings specified for both cipher algo and cipher mode - if luks_hdr_info.cipher_mode.len() > 0 - && luks_hdr_info.cipher_algorithm.len() > 0 + if !luks_hdr_info.cipher_mode.is_empty() + && !luks_hdr_info.cipher_algorithm.is_empty() { return Ok(luks_hdr_info); } diff --git a/src/structures/lz4.rs b/src/structures/lz4.rs index a7bc69862..eac5435bf 100644 --- a/src/structures/lz4.rs +++ b/src/structures/lz4.rs @@ -63,7 +63,7 @@ pub fn parse_lz4_file_header(lz4_data: &[u8]) -> Result> 8) & 0xFF) as u8; + ((xxhash_rust::xxh32::xxh32(crc_data, 0) >> 8) & 0xFF) as u8; // Make sure the CRC's match if *actual_crc == calculated_crc { @@ -120,7 +120,7 @@ pub fn parse_lz4_block_header( lz4_block.last_block = block_header["block_size"] == END_MARKER; // If a checksum is present, it will be an extra 4 bytes at the end of the block - if checksum_present == true { + if checksum_present { lz4_block.checksum_size = CHECKSUM_SIZE; } diff --git a/src/structures/lzfse.rs b/src/structures/lzfse.rs index 88209eff4..83155b56c 100644 --- a/src/structures/lzfse.rs +++ b/src/structures/lzfse.rs @@ -44,11 +44,11 @@ pub fn parse_lzfse_block_header(lzfse_data: &[u8]) -> Result Result { // This is easy; it's just the 4-byte magic bytes marking the end-of-stream - return Ok(LZFSEBlock { + Ok(LZFSEBlock { eof: true, data_size: 0, header_size: 4, - }); + }) } /// Parse an uncompressed LZFSE block header From 56be39411b4c8f56f4c9eb785b4c17b19a2e9631 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 19 Oct 2024 17:43:48 -0400 Subject: [PATCH 003/131] More lint fixes --- src/extractors/androidsparse.rs | 2 +- src/extractors/arcadyan.rs | 2 +- src/extractors/bzip2.rs | 2 +- src/extractors/common.rs | 2 +- src/extractors/gif.rs | 2 +- src/extractors/gzip.rs | 2 +- src/extractors/inflate.rs | 2 +- src/extractors/jboot.rs | 2 +- src/extractors/jpeg.rs | 2 +- src/extractors/lzma.rs | 2 +- src/extractors/mbr.rs | 2 +- src/extractors/pcap.rs | 2 +- src/extractors/pem.rs | 8 ++++---- src/extractors/png.rs | 2 +- src/extractors/riff.rs | 2 +- src/extractors/romfs.rs | 2 +- src/extractors/svg.rs | 2 +- src/extractors/trx.rs | 2 +- src/extractors/uimage.rs | 2 +- src/extractors/vxworks.rs | 2 +- src/extractors/zlib.rs | 2 +- src/signatures/aes.rs | 6 +++--- src/signatures/androidsparse.rs | 6 +++--- src/signatures/arcadyan.rs | 6 +++--- src/signatures/bzip2.rs | 8 ++++---- src/signatures/cab.rs | 4 ++-- src/signatures/cfe.rs | 4 ++-- src/signatures/chk.rs | 4 ++-- src/signatures/common.rs | 2 +- src/signatures/compressd.rs | 4 ++-- src/signatures/copyright.rs | 6 +++--- src/signatures/cpio.rs | 4 ++-- src/signatures/cramfs.rs | 7 ++----- src/signatures/deb.rs | 4 ++-- src/signatures/dlob.rs | 4 ++-- src/signatures/dmg.rs | 4 ++-- src/signatures/dtb.rs | 4 ++-- src/signatures/ecos.rs | 6 +++--- src/signatures/efigpt.rs | 7 ++----- src/signatures/elf.rs | 4 ++-- src/signatures/ext.rs | 6 +++--- src/signatures/fat.rs | 4 ++-- src/signatures/gif.rs | 6 +++--- src/signatures/gpg.rs | 6 +++--- src/signatures/gzip.rs | 6 +++--- src/signatures/hashes.rs | 17 +++++++---------- src/signatures/iso9660.rs | 4 ++-- src/signatures/jboot.rs | 18 +++++++++--------- src/signatures/jffs2.rs | 6 +++--- src/signatures/jpeg.rs | 8 ++++---- src/signatures/linux.rs | 12 ++++++------ src/signatures/luks.rs | 4 ++-- src/signatures/lz4.rs | 4 ++-- src/signatures/lzfse.rs | 8 ++++---- src/signatures/lzma.rs | 6 +++--- src/signatures/lzop.rs | 4 ++-- src/signatures/mbr.rs | 6 +++--- src/signatures/openssl.rs | 4 ++-- src/signatures/packimg.rs | 7 ++----- src/signatures/pcap.rs | 7 ++----- src/signatures/pchrom.rs | 7 ++----- src/signatures/pdf.rs | 4 ++-- src/signatures/pe.rs | 6 +++--- src/signatures/pem.rs | 10 +++++----- src/signatures/pjl.rs | 4 ++-- src/signatures/png.rs | 6 +++--- src/signatures/qnx.rs | 7 ++----- src/signatures/rar.rs | 6 +++--- src/signatures/riff.rs | 4 ++-- src/signatures/romfs.rs | 6 +++--- src/signatures/rsa.rs | 8 ++++---- src/signatures/rtk.rs | 4 ++-- src/signatures/seama.rs | 6 +++--- src/signatures/sevenzip.rs | 7 ++----- src/signatures/squashfs.rs | 9 +++------ src/signatures/srec.rs | 6 +++--- src/signatures/svg.rs | 6 +++--- src/signatures/tarball.rs | 29 +++++++++++++---------------- src/signatures/tplink.rs | 7 ++----- src/signatures/trx.rs | 6 +++--- src/signatures/ubi.rs | 10 +++++----- src/signatures/uefi.rs | 10 +++++----- src/signatures/uimage.rs | 9 +++------ src/signatures/vxworks.rs | 14 +++++++------- src/signatures/xz.rs | 4 ++-- src/signatures/yaffs.rs | 8 ++++---- src/signatures/zip.rs | 10 +++++----- src/signatures/zlib.rs | 10 +++++----- src/signatures/zstd.rs | 10 +++++----- src/structures/androidsparse.rs | 6 +----- src/structures/cab.rs | 2 +- src/structures/chk.rs | 4 ++-- src/structures/common.rs | 10 +++++----- src/structures/cpio.rs | 4 ++-- src/structures/cramfs.rs | 2 +- src/structures/deb.rs | 7 ++----- src/structures/efigpt.rs | 4 ++-- src/structures/elf.rs | 2 +- src/structures/gif.rs | 2 +- src/structures/gzip.rs | 2 +- src/structures/jboot.rs | 6 +++++- src/structures/jffs2.rs | 3 +-- src/structures/pchrom.rs | 2 +- src/structures/squashfs.rs | 16 ++++------------ src/structures/uimage.rs | 6 +++++- 105 files changed, 276 insertions(+), 320 deletions(-) diff --git a/src/extractors/androidsparse.rs b/src/extractors/androidsparse.rs index b05006b8a..9456bdbba 100644 --- a/src/extractors/androidsparse.rs +++ b/src/extractors/androidsparse.rs @@ -12,7 +12,7 @@ pub fn android_sparse_extractor() -> Extractor { /// Android sparse internal extractor pub fn extract_android_sparse( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/arcadyan.rs b/src/extractors/arcadyan.rs index 72b6ede9f..6b5ceb5fe 100644 --- a/src/extractors/arcadyan.rs +++ b/src/extractors/arcadyan.rs @@ -11,7 +11,7 @@ pub fn obfuscated_lzma_extractor() -> Extractor { /// Internal extractor for Arcadyn Obfuscated LZMA pub fn extract_obfuscated_lzma( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/bzip2.rs b/src/extractors/bzip2.rs index 074d7310c..101c567bc 100644 --- a/src/extractors/bzip2.rs +++ b/src/extractors/bzip2.rs @@ -11,7 +11,7 @@ pub fn bzip2_extractor() -> Extractor { /// Internal extractor for decompressing BZIP2 data pub fn bzip2_decompressor( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/common.rs b/src/extractors/common.rs index 7456771d7..000a623d7 100644 --- a/src/extractors/common.rs +++ b/src/extractors/common.rs @@ -24,7 +24,7 @@ pub struct ExtractionError; /// Built-in internal extractors must provide a function conforming to this definition. /// Arguments: file_data, offset, output_directory. -pub type InternalExtractor = fn(&Vec, usize, Option<&String>) -> ExtractionResult; +pub type InternalExtractor = fn(&[u8], usize, Option<&String>) -> ExtractionResult; /// Enum to define either an Internal or External extractor type #[derive(Debug, Default, Clone, Eq, PartialEq, Ord, PartialOrd)] diff --git a/src/extractors/gif.rs b/src/extractors/gif.rs index 43f64e8f0..9b2c39377 100644 --- a/src/extractors/gif.rs +++ b/src/extractors/gif.rs @@ -14,7 +14,7 @@ pub fn gif_extractor() -> Extractor { /// Parses and carves a GIF image from a file pub fn extract_gif_image( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/gzip.rs b/src/extractors/gzip.rs index 1b2b9377e..3e92de104 100644 --- a/src/extractors/gzip.rs +++ b/src/extractors/gzip.rs @@ -12,7 +12,7 @@ pub fn gzip_extractor() -> Extractor { /// Internal extractor for gzip compressed data pub fn gzip_decompress( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/inflate.rs b/src/extractors/inflate.rs index 47e9c775e..3c3b18f9e 100644 --- a/src/extractors/inflate.rs +++ b/src/extractors/inflate.rs @@ -15,7 +15,7 @@ pub fn inflate_extractor() -> Extractor { /// Internal extractor for inflating deflated data. pub fn inflate_decompressor( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/jboot.rs b/src/extractors/jboot.rs index 858d89e05..3774138bd 100644 --- a/src/extractors/jboot.rs +++ b/src/extractors/jboot.rs @@ -12,7 +12,7 @@ pub fn sch2_extractor() -> Extractor { /// Extract the kernel described by a JBOOT SCH2 header pub fn extract_jboot_sch2_kernel( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/jpeg.rs b/src/extractors/jpeg.rs index 982564215..73eb84698 100644 --- a/src/extractors/jpeg.rs +++ b/src/extractors/jpeg.rs @@ -12,7 +12,7 @@ pub fn jpeg_extractor() -> Extractor { /// Internal extractor for carving JPEG images to disk pub fn extract_jpeg_image( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/lzma.rs b/src/extractors/lzma.rs index ed58382f3..46261cc37 100644 --- a/src/extractors/lzma.rs +++ b/src/extractors/lzma.rs @@ -11,7 +11,7 @@ pub fn lzma_extractor() -> Extractor { /// Internal extractor for decompressing LZMA/XZ data streams pub fn lzma_decompress( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/mbr.rs b/src/extractors/mbr.rs index f2dc6b927..6eb133fb8 100644 --- a/src/extractors/mbr.rs +++ b/src/extractors/mbr.rs @@ -11,7 +11,7 @@ pub fn mbr_extractor() -> Extractor { /// Validate and extract partitions from an MBR pub fn extract_mbr_partitions( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/pcap.rs b/src/extractors/pcap.rs index 483aa9f97..4fcb93a31 100644 --- a/src/extractors/pcap.rs +++ b/src/extractors/pcap.rs @@ -13,7 +13,7 @@ pub fn pcapng_extractor() -> Extractor { /// Carves a pcap-ng file to disk pub fn pcapng_carver( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/pem.rs b/src/extractors/pem.rs index 58f5bf0fc..ede2e5f7c 100644 --- a/src/extractors/pem.rs +++ b/src/extractors/pem.rs @@ -20,7 +20,7 @@ pub fn pem_certificate_extractor() -> Extractor { } pub fn pem_certificate_carver( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { @@ -34,7 +34,7 @@ pub fn pem_certificate_carver( } pub fn pem_key_carver( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { @@ -43,7 +43,7 @@ pub fn pem_key_carver( } pub fn pem_carver( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, fname: Option<&str>, @@ -68,7 +68,7 @@ pub fn pem_carver( return result; } -fn get_pem_size(file_data: &Vec, start_of_pem_offset: usize) -> Option { +fn get_pem_size(file_data: &[u8], start_of_pem_offset: usize) -> Option { let eof_markers = vec![ b"-----END PUBLIC KEY-----".to_vec(), b"-----END CERTIFICATE-----".to_vec(), diff --git a/src/extractors/png.rs b/src/extractors/png.rs index 4797803cd..71ebbda18 100644 --- a/src/extractors/png.rs +++ b/src/extractors/png.rs @@ -12,7 +12,7 @@ pub fn png_extractor() -> Extractor { /// Internal extractor for carving PNG files to disk pub fn extract_png_image( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/riff.rs b/src/extractors/riff.rs index 53a95681f..d4d6a2d5d 100644 --- a/src/extractors/riff.rs +++ b/src/extractors/riff.rs @@ -12,7 +12,7 @@ pub fn riff_extractor() -> Extractor { /// Internal extractor for carving RIFF files to disk pub fn extract_riff_image( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/romfs.rs b/src/extractors/romfs.rs index 3911b03dd..69e04785f 100644 --- a/src/extractors/romfs.rs +++ b/src/extractors/romfs.rs @@ -36,7 +36,7 @@ pub fn romfs_extractor() -> Extractor { /// Internal RomFS extractor pub fn extract_romfs( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/svg.rs b/src/extractors/svg.rs index 74b3cfc84..e7cfbb4aa 100644 --- a/src/extractors/svg.rs +++ b/src/extractors/svg.rs @@ -12,7 +12,7 @@ pub fn svg_extractor() -> Extractor { /// Internal extractor for carving SVG images to disk pub fn extract_svg_image( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/trx.rs b/src/extractors/trx.rs index 97fb38719..3676a0b16 100644 --- a/src/extractors/trx.rs +++ b/src/extractors/trx.rs @@ -12,7 +12,7 @@ pub fn trx_extractor() -> Extractor { /// Internal extractor for TRX partitions pub fn extract_trx_partitions( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/uimage.rs b/src/extractors/uimage.rs index 91933385c..a6d26a2f7 100644 --- a/src/extractors/uimage.rs +++ b/src/extractors/uimage.rs @@ -10,7 +10,7 @@ pub fn uimage_extractor() -> Extractor { } pub fn extract_uimage( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/vxworks.rs b/src/extractors/vxworks.rs index f2337352d..3fc63dbd4 100644 --- a/src/extractors/vxworks.rs +++ b/src/extractors/vxworks.rs @@ -16,7 +16,7 @@ pub fn vxworks_symtab_extractor() -> Extractor { /// Internal extractor for writing VxWorks symbol tables to JSON pub fn extract_symbol_table( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/extractors/zlib.rs b/src/extractors/zlib.rs index 57b5d4c05..ac7f86eb7 100644 --- a/src/extractors/zlib.rs +++ b/src/extractors/zlib.rs @@ -11,7 +11,7 @@ pub fn zlib_extractor() -> Extractor { /// Internal extractor for decompressing ZLIB data pub fn zlib_decompress( - file_data: &Vec, + file_data: &[u8], offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { diff --git a/src/signatures/aes.rs b/src/signatures/aes.rs index 0a711e88e..727960edf 100644 --- a/src/signatures/aes.rs +++ b/src/signatures/aes.rs @@ -5,15 +5,15 @@ pub const DESCRIPTION: &str = "AES S-Box"; /// AES S-box magic bytes pub fn aes_sbox_magic() -> Vec> { - return vec![ + vec![ b"\x63\x7C\x77\x7B\xF2\x6B\x6F\xC5".to_vec(), b"\x52\x09\x6A\xD5\x30\x36\xA5\x38".to_vec(), - ]; + ] } /// Validates the AES S-Box pub fn aes_sbox_parser( - _file_data: &Vec, + _file_data: &[u8], offset: usize, ) -> Result { // Successful return value diff --git a/src/signatures/androidsparse.rs b/src/signatures/androidsparse.rs index d4eeda239..6937eb34d 100644 --- a/src/signatures/androidsparse.rs +++ b/src/signatures/androidsparse.rs @@ -7,12 +7,12 @@ pub const DESCRIPTION: &str = "Android sparse image"; /// Magic bytes for Android Sparse files pub fn android_sparse_magic() -> Vec> { - return vec![b"\x3A\xFF\x26\xED".to_vec()]; + vec![b"\x3A\xFF\x26\xED".to_vec()] } /// Parses Android Sparse files pub fn android_sparse_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // Default result, returned on success @@ -26,7 +26,7 @@ pub fn android_sparse_parser( // Do a dry-run extraction let dry_run = extract_android_sparse(file_data, offset, None); - if dry_run.success == true { + if dry_run.success { if let Some(total_size) = dry_run.size { // Dry-run went OK, parse the header to get some useful info to report if let Ok(header) = parse_android_sparse_header(&file_data[offset..]) { diff --git a/src/signatures/arcadyan.rs b/src/signatures/arcadyan.rs index 20268ec74..fff70f4ea 100644 --- a/src/signatures/arcadyan.rs +++ b/src/signatures/arcadyan.rs @@ -6,12 +6,12 @@ pub const DESCRIPTION: &str = "Arcadyan obfuscated LZMA"; /// Obfuscated Arcadyan LZMA magic bytes pub fn obfuscated_lzma_magic() -> Vec> { - return vec![b"\x00\xD5\x08\x00".to_vec()]; + vec![b"\x00\xD5\x08\x00".to_vec()] } /// Parses obfuscated Arcadyan LZMA data pub fn obfuscated_lzma_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // Magic bytes are 0x68 bytes into the actual file @@ -33,7 +33,7 @@ pub fn obfuscated_lzma_parser( let dry_run = extract_obfuscated_lzma(file_data, start_offset, None); // If dry-run was successful, return success - if dry_run.success == true { + if dry_run.success { // Report the actual start of file data result.offset = start_offset; return Ok(result); diff --git a/src/signatures/bzip2.rs b/src/signatures/bzip2.rs index 5c6c92207..04f618477 100644 --- a/src/signatures/bzip2.rs +++ b/src/signatures/bzip2.rs @@ -6,7 +6,7 @@ pub const DESCRIPTION: &str = "bzip2 compressed data"; /// Bzip2 magic bytes; includes the magic bytes, version number, block size, and compressed magic signature pub fn bzip2_magic() -> Vec> { - return vec![ + vec![ b"BZh91AY&SY".to_vec(), b"BZh81AY&SY".to_vec(), b"BZh71AY&SY".to_vec(), @@ -16,11 +16,11 @@ pub fn bzip2_magic() -> Vec> { b"BZh31AY&SY".to_vec(), b"BZh21AY&SY".to_vec(), b"BZh11AY&SY".to_vec(), - ]; + ] } /// Bzip2 header parser -pub fn bzip2_parser(file_data: &Vec, offset: usize) -> Result { +pub fn bzip2_parser(file_data: &[u8], offset: usize) -> Result { // Return value let mut result = SignatureResult { description: DESCRIPTION.to_string(), @@ -31,7 +31,7 @@ pub fn bzip2_parser(file_data: &Vec, offset: usize) -> Result Vec> { - return vec![b"MSCF\x00\x00\x00\x00".to_vec()]; + vec![b"MSCF\x00\x00\x00\x00".to_vec()] } /// Parses and cabinet file signature -pub fn cab_parser(file_data: &Vec, offset: usize) -> Result { +pub fn cab_parser(file_data: &[u8], offset: usize) -> Result { // Parse the CAB header if let Ok(cab_header) = parse_cab_header(&file_data[offset..]) { let available_data = file_data.len() - offset; diff --git a/src/signatures/cfe.rs b/src/signatures/cfe.rs index 53b8a59d1..82aa4121e 100644 --- a/src/signatures/cfe.rs +++ b/src/signatures/cfe.rs @@ -7,11 +7,11 @@ pub const DESCRIPTION: &str = "CFE bootloader"; /// CFE bootloader always contains this string pub fn cfe_magic() -> Vec> { - return vec![b"CFE1CFE1".to_vec()]; + vec![b"CFE1CFE1".to_vec()] } /// Validate the CFE signature -pub fn cfe_parser(_file_data: &Vec, offset: usize) -> Result { +pub fn cfe_parser(_file_data: &[u8], offset: usize) -> Result { // Magic bytes occur this many bytes into the bootloader const CFE_MAGIC_OFFSET: usize = 28; diff --git a/src/signatures/chk.rs b/src/signatures/chk.rs index 95c5bf2c7..5bc1a4db7 100644 --- a/src/signatures/chk.rs +++ b/src/signatures/chk.rs @@ -6,11 +6,11 @@ pub const DESCRIPTION: &str = "CHK firmware header"; /// CHK firmware always start with these bytes pub fn chk_magic() -> Vec> { - return vec![b"\x2A\x23\x24\x5E".to_vec()]; + vec![b"\x2A\x23\x24\x5E".to_vec()] } /// Parse and validate CHK headers -pub fn chk_parser(file_data: &Vec, offset: usize) -> Result { +pub fn chk_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/common.rs b/src/signatures/common.rs index 6b98d5723..c31b521cd 100644 --- a/src/signatures/common.rs +++ b/src/signatures/common.rs @@ -21,7 +21,7 @@ pub struct SignatureError; /// Each signature parser is responsible for parsing and validating signature candidates. /// /// They must return either a SignatureResult struct if validation succeeds, or a SignatureError if validation fails. -pub type SignatureParser = fn(&Vec, usize) -> Result; +pub type SignatureParser = fn(&[u8], usize) -> Result; /// Describes a valid identified file signature /// diff --git a/src/signatures/compressd.rs b/src/signatures/compressd.rs index d11f4c46f..502fb0d4d 100644 --- a/src/signatures/compressd.rs +++ b/src/signatures/compressd.rs @@ -5,12 +5,12 @@ pub const DESCRIPTION: &str = "compress'd data"; /// Compress'd files always start with these bytes pub fn compressd_magic() -> Vec> { - return vec![b"\x1F\x9D\x90".to_vec()]; + vec![b"\x1F\x9D\x90".to_vec()] } /// "Validate" the compress'd header pub fn compressd_parser( - _file_data: &Vec, + _file_data: &[u8], offset: usize, ) -> Result { // Successful return value; confidence is medium since this only matches magic bytes at the beginning of a file diff --git a/src/signatures/copyright.rs b/src/signatures/copyright.rs index 65f50b92b..9fd0da875 100644 --- a/src/signatures/copyright.rs +++ b/src/signatures/copyright.rs @@ -6,16 +6,16 @@ pub const DESCRIPTION: &str = "Copyright text"; /// Magic copyright strings to search for pub fn copyright_magic() -> Vec> { - return vec![ + vec![ b"copyright".to_vec(), b"Copyright".to_vec(), b"COPYRIGHT".to_vec(), - ]; + ] } /// Parse copyright magic candidates pub fn copyright_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // Size of "copright" string diff --git a/src/signatures/cpio.rs b/src/signatures/cpio.rs index 80a9f5bb7..5b75a0c6c 100644 --- a/src/signatures/cpio.rs +++ b/src/signatures/cpio.rs @@ -7,11 +7,11 @@ pub const DESCRIPTION: &str = "CPIO ASCII archive"; /// Magic bytes for CPIO archives with and without CRC's pub fn cpio_magic() -> Vec> { - return vec![b"070701".to_vec(), b"070702".to_vec()]; + vec![b"070701".to_vec(), b"070702".to_vec()] } /// Parse and validate CPIO archives -pub fn cpio_parser(file_data: &Vec, offset: usize) -> Result { +pub fn cpio_parser(file_data: &[u8], offset: usize) -> Result { // The last CPIO entry will have this file name const EOF_MARKER: &str = "TRAILER!!!"; diff --git a/src/signatures/cramfs.rs b/src/signatures/cramfs.rs index aca97b147..2ad4304c3 100644 --- a/src/signatures/cramfs.rs +++ b/src/signatures/cramfs.rs @@ -9,14 +9,11 @@ pub const DESCRIPTION: &str = "CramFS filesystem"; /// This is technically the CramFS "signature", not the magic bytes, but it's endian-agnostic pub fn cramfs_magic() -> Vec> { - return vec![b"Compressed ROMFS".to_vec()]; + vec![b"Compressed ROMFS".to_vec()] } /// Parse and validate the CramFS header -pub fn cramfs_parser( - file_data: &Vec, - offset: usize, -) -> Result { +pub fn cramfs_parser(file_data: &[u8], offset: usize) -> Result { // Some constant relative offsets const SIGNATURE_OFFSET: usize = 16; const CRC_START_OFFSET: usize = 32; diff --git a/src/signatures/deb.rs b/src/signatures/deb.rs index c40800c66..24a42e00f 100644 --- a/src/signatures/deb.rs +++ b/src/signatures/deb.rs @@ -6,11 +6,11 @@ pub const DESCRIPTION: &str = "Debian package file"; /// Debian archives always start with these bytes pub fn deb_magic() -> Vec> { - return vec![b"!\ndebian-binary\x20\x20\x20".to_vec()]; + vec![b"!\ndebian-binary\x20\x20\x20".to_vec()] } /// Validates debian archive signatures -pub fn deb_parser(file_data: &Vec, offset: usize) -> Result { +pub fn deb_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/dlob.rs b/src/signatures/dlob.rs index b5228944f..789991f04 100644 --- a/src/signatures/dlob.rs +++ b/src/signatures/dlob.rs @@ -6,11 +6,11 @@ pub const DESCRIPTION: &str = "DLOB firmware header"; /// DLOB firmware images always start with these bytes pub fn dlob_magic() -> Vec> { - return vec![b"\x5e\xa3\xa4\x17".to_vec()]; + vec![b"\x5e\xa3\xa4\x17".to_vec()] } /// Validates the DLOB header -pub fn dlob_parser(file_data: &Vec, offset: usize) -> Result { +pub fn dlob_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/dmg.rs b/src/signatures/dmg.rs index 1acd5df69..ddece701c 100644 --- a/src/signatures/dmg.rs +++ b/src/signatures/dmg.rs @@ -8,11 +8,11 @@ pub const DESCRIPTION: &str = "Apple Disk iMaGe"; /// 4-byte magic, 4-byte version (v4), 4-byte structure size (0x0200). /// This is actually the magic bytes of the DMG footer, there is no standard header format. pub fn dmg_magic() -> Vec> { - return vec![b"koly\x00\x00\x00\x04\x00\x00\x02\x00".to_vec()]; + vec![b"koly\x00\x00\x00\x04\x00\x00\x02\x00".to_vec()] } /// Validates the DMG footer -pub fn dmg_parser(file_data: &Vec, offset: usize) -> Result { +pub fn dmg_parser(file_data: &[u8], offset: usize) -> Result { // Confidence is set to HIGH + 1 to ensure this overrides other signatures. // DMG's typically start with compressed data, and the file should be treated // as a DMG, not just compressed data. diff --git a/src/signatures/dtb.rs b/src/signatures/dtb.rs index f487c8e55..239efcd60 100644 --- a/src/signatures/dtb.rs +++ b/src/signatures/dtb.rs @@ -6,11 +6,11 @@ pub const DESCRIPTION: &str = "Device tree blob (DTB)"; /// DTB files start with these magic bytes pub fn dtb_magic() -> Vec> { - return vec![b"\xD0\x0D\xFE\xED".to_vec()]; + vec![b"\xD0\x0D\xFE\xED".to_vec()] } /// Validates the DTB header -pub fn dtb_parser(file_data: &Vec, offset: usize) -> Result { +pub fn dtb_parser(file_data: &[u8], offset: usize) -> Result { // Sucessful result let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/ecos.rs b/src/signatures/ecos.rs index f7d680c58..79d1649bf 100644 --- a/src/signatures/ecos.rs +++ b/src/signatures/ecos.rs @@ -17,17 +17,17 @@ pub fn exception_handler_magic() -> Vec> { * jr $k1 * nop */ - return vec![ + vec![ b"\x00\x68\x1A\x40\x00\x00\x00\x00\x7F\x00\x5A\x33".to_vec(), b"\x00\x68\x1A\x40\x7F\x00\x5A\x33".to_vec(), b"\x40\x1A\x68\x00\x00\x00\x00\x00\x33\x5A\x00\x7F".to_vec(), b"\x40\x1A\x68\x00\x33\x5A\x00\x7F".to_vec(), - ]; + ] } /// Parses the eCos exception handler signature pub fn exception_handler_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // Successful return value diff --git a/src/signatures/efigpt.rs b/src/signatures/efigpt.rs index d65384859..3b1dff4a6 100644 --- a/src/signatures/efigpt.rs +++ b/src/signatures/efigpt.rs @@ -6,14 +6,11 @@ pub const DESCRIPTION: &str = "EFI Global Partition Table"; /// EFI GPT always contains these bytes pub fn efigpt_magic() -> Vec> { - return vec![b"\x55\xAAEFI PART".to_vec()]; + vec![b"\x55\xAAEFI PART".to_vec()] } /// Validates the EFI GPT header -pub fn efigpt_parser( - file_data: &Vec, - offset: usize, -) -> Result { +pub fn efigpt_parser(file_data: &[u8], offset: usize) -> Result { // Offset of magic bytes from the start of the MBR const MAGIC_OFFSET: usize = 0x01FE; diff --git a/src/signatures/elf.rs b/src/signatures/elf.rs index be4fbcde2..1f2665074 100644 --- a/src/signatures/elf.rs +++ b/src/signatures/elf.rs @@ -6,11 +6,11 @@ pub const DESCRIPTION: &str = "ELF binary"; /// ELF files start with these bytes pub fn elf_magic() -> Vec> { - return vec![b"\x7FELF".to_vec()]; + vec![b"\x7FELF".to_vec()] } /// Parse and validate the ELF header -pub fn elf_parser(file_data: &Vec, offset: usize) -> Result { +pub fn elf_parser(file_data: &[u8], offset: usize) -> Result { // Successful result let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/ext.rs b/src/signatures/ext.rs index 4e17f5b14..479de837a 100644 --- a/src/signatures/ext.rs +++ b/src/signatures/ext.rs @@ -12,18 +12,18 @@ pub fn ext_magic() -> Vec> { * as well as the minor version number (assumed to be 0). * This means fewer false positive matches, and less time spent validating false positives. */ - return vec![ + vec![ b"\x53\xEF\x01\x00\x01\x00\x00\x00".to_vec(), b"\x53\xEF\x01\x00\x02\x00\x00\x00".to_vec(), b"\x53\xEF\x01\x00\x03\x00\x00\x00".to_vec(), b"\x53\xEF\x02\x00\x01\x00\x00\x00".to_vec(), b"\x53\xEF\x02\x00\x02\x00\x00\x00".to_vec(), b"\x53\xEF\x02\x00\x03\x00\x00\x00".to_vec(), - ]; + ] } /// Parse the EXT signature -pub fn ext_parser(file_data: &Vec, offset: usize) -> Result { +pub fn ext_parser(file_data: &[u8], offset: usize) -> Result { // Offset inside the EXT image where the magic bytes reside const MAGIC_OFFSET: usize = 1080; diff --git a/src/signatures/fat.rs b/src/signatures/fat.rs index 5754b26ca..4aa91ca66 100644 --- a/src/signatures/fat.rs +++ b/src/signatures/fat.rs @@ -9,11 +9,11 @@ pub const MAGIC_OFFSET: usize = 0x01FE; /// FAT always contains these bytes pub fn fat_magic() -> Vec> { - return vec![b"\x55\xAA".to_vec()]; + vec![b"\x55\xAA".to_vec()] } /// Validates the FAT header -pub fn fat_parser(file_data: &Vec, offset: usize) -> Result { +pub fn fat_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { description: DESCRIPTION.to_string(), diff --git a/src/signatures/gif.rs b/src/signatures/gif.rs index 61408ab38..b2a40eaf4 100644 --- a/src/signatures/gif.rs +++ b/src/signatures/gif.rs @@ -8,11 +8,11 @@ pub const DESCRIPTION: &str = "GIF image"; /// GIF images always start with these bytes pub fn gif_magic() -> Vec> { // https://giflib.sourceforge.net/whatsinagif/bits_and_bytes.html - return vec![b"GIF87a".to_vec(), b"GIF89a".to_vec()]; + vec![b"GIF87a".to_vec(), b"GIF89a".to_vec()] } /// Validates the GIF header -pub fn gif_parser(file_data: &Vec, offset: usize) -> Result { +pub fn gif_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { offset: offset, @@ -24,7 +24,7 @@ pub fn gif_parser(file_data: &Vec, offset: usize) -> Result Vec> { - return vec![b"\xA3\x01".to_vec()]; + vec![b"\xA3\x01".to_vec()] } /// Validates GPG signatures pub fn gpg_signed_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // Success result; confidence is high since this signature is only reported what it starts at the beginning of a file @@ -31,7 +31,7 @@ pub fn gpg_signed_parser( let decompression_dry_run = zlib_decompress(&file_data, offset, None); // If the decompression dry run was a success, this signature is almost certianly valid - if decompression_dry_run.success == true { + if decompression_dry_run.success { return Ok(result); } } diff --git a/src/signatures/gzip.rs b/src/signatures/gzip.rs index 054f49ed1..0efdddf16 100644 --- a/src/signatures/gzip.rs +++ b/src/signatures/gzip.rs @@ -8,11 +8,11 @@ pub const DESCRIPTION: &str = "gzip compressed data"; /// Gzip magic bytes, plus compression type field (always 8 for deflate) pub fn gzip_magic() -> Vec> { - return vec![b"\x1f\x8b\x08".to_vec()]; + vec![b"\x1f\x8b\x08".to_vec()] } /// Validates gzip signatures -pub fn gzip_parser(file_data: &Vec, offset: usize) -> Result { +pub fn gzip_parser(file_data: &[u8], offset: usize) -> Result { // Length of the GZIP CRC located at the end of the deflate data stream const GZIP_CRC_SIZE: usize = 4; // Length of the ISIZE field located after the CRC field @@ -22,7 +22,7 @@ pub fn gzip_parser(file_data: &Vec, offset: usize) -> Result Vec> { // Order matters! See hash_endianness(). - return vec![ + vec![ // Big endian b"\x00\x00\x00\x00\x77\x07\x30\x96\xEE\x0E\x61\x2C\x99\x09\x51\xBA".to_vec(), // Little endian b"\x00\x00\x00\x00\x96\x30\x07\x77\x2C\x61\x0E\xEE\xBA\x51\x09\x99".to_vec(), - ]; + ] } /// SHA256 constants pub fn sha256_magic() -> Vec> { // Order matters! See hash_endianness(). - return vec![ + vec![ // Big endian b"\x42\x8a\x2f\x98\x71\x37\x44\x91\xb5\xc0\xfb\xcf\xe9\xb5\xdb\xa5".to_vec(), // Little endian b"\x98\x2f\x8a\x42\x91\x44\x37\x71\xcf\xfb\xc0\xb5\xa5\xdb\xb5\xe9".to_vec(), - ]; + ] } -pub fn crc32_parser(file_data: &Vec, offset: usize) -> Result { +pub fn crc32_parser(file_data: &[u8], offset: usize) -> Result { // Just return a success with some extra description info let result = SignatureResult { description: format!( @@ -45,10 +45,7 @@ pub fn crc32_parser(file_data: &Vec, offset: usize) -> Result, - offset: usize, -) -> Result { +pub fn sha256_parser(file_data: &[u8], offset: usize) -> Result { // Just return a success with some extra description info let result = SignatureResult { description: format!( @@ -65,7 +62,7 @@ pub fn sha256_parser( } /// Detects hash contstant endianess -fn hash_endianess(file_data: &Vec, offset: usize, magics: Vec>) -> String { +fn hash_endianess(file_data: &[u8], offset: usize, magics: Vec>) -> String { let mut endianness: String = "little".to_string(); let this_magic = &file_data[offset..offset + HASH_MAGIC_LEN]; diff --git a/src/signatures/iso9660.rs b/src/signatures/iso9660.rs index 47717ac18..72bdc070d 100644 --- a/src/signatures/iso9660.rs +++ b/src/signatures/iso9660.rs @@ -6,11 +6,11 @@ pub const DESCRIPTION: &str = "ISO9660 primary volume"; /// ISOs start with these magic bytes pub fn iso_magic() -> Vec> { - return vec![b"\x01CD001\x01\x00".to_vec()]; + vec![b"\x01CD001\x01\x00".to_vec()] } /// Validate ISO signatures -pub fn iso_parser(file_data: &Vec, offset: usize) -> Result { +pub fn iso_parser(file_data: &[u8], offset: usize) -> Result { // Offset from the beginning of the ISO image to the magic bytes const ISO_MAGIC_OFFSET: usize = 32768; diff --git a/src/signatures/jboot.rs b/src/signatures/jboot.rs index 8c3c66933..89641e9d0 100644 --- a/src/signatures/jboot.rs +++ b/src/signatures/jboot.rs @@ -13,30 +13,30 @@ pub const JBOOT_SCH2_DESCRIPTION: &str = "JBOOT SCH2 header"; /// JBOOT firmware header magic bytes pub fn jboot_arm_magic() -> Vec> { - return vec![ + vec![ b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42\x48\x02\x00\x00\x00" .to_vec(), - ]; + ] } /// JBOOT STAG header magic bytes pub fn jboot_stag_magic() -> Vec> { - return vec![b"\x04\x04\x24\x2B".to_vec(), b"\xFF\x04\x24\x2B".to_vec()]; + vec![b"\x04\x04\x24\x2B".to_vec(), b"\xFF\x04\x24\x2B".to_vec()] } /// JBOOT SCH2 header magic bytes pub fn jboot_sch2_magic() -> Vec> { - return vec![ + vec![ b"\x24\x21\x00\x02".to_vec(), b"\x24\x21\x01\x02".to_vec(), b"\x24\x21\x02\x02".to_vec(), b"\x24\x21\x03\x02".to_vec(), - ]; + ] } /// Parse and validate the JBOOT ARM header pub fn jboot_arm_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // Magic bytes start at this offset into the header @@ -74,7 +74,7 @@ pub fn jboot_arm_parser( /// Parse and validate a JBOOT STAG header pub fn jboot_stag_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // Successful return value @@ -112,7 +112,7 @@ pub fn jboot_stag_parser( /// Parse and validate a JBOOT SCH2 header pub fn jboot_sch2_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // Successful return value @@ -125,7 +125,7 @@ pub fn jboot_sch2_parser( let dry_run = extract_jboot_sch2_kernel(file_data, offset, None); - if dry_run.success == true { + if dry_run.success { if let Some(total_size) = dry_run.size { if let Ok(sch2_header) = parse_jboot_sch2_header(&file_data[offset..]) { result.size = total_size; diff --git a/src/signatures/jffs2.rs b/src/signatures/jffs2.rs index 8058379db..23167133a 100644 --- a/src/signatures/jffs2.rs +++ b/src/signatures/jffs2.rs @@ -12,18 +12,18 @@ pub fn jffs2_magic() -> Vec> { * These assume that the first JFFS2 node will be a directory, inode, or clean marker type. * Longer signatures are less prone to false positive matches. */ - return vec![ + vec![ b"\x19\x85\xe0\x01".to_vec(), b"\x19\x85\xe0\x02".to_vec(), b"\x19\x85\x20\x03".to_vec(), b"\x85\x19\x01\xe0".to_vec(), b"\x85\x19\x02\xe0".to_vec(), b"\x85\x19\x03\x20".to_vec(), - ]; + ] } /// Parse and validate a JFFS2 image -pub fn jffs2_parser(file_data: &Vec, offset: usize) -> Result { +pub fn jffs2_parser(file_data: &[u8], offset: usize) -> Result { // Useful contstants const MAX_PAGE_SIZE: usize = 0x10000; const MIN_VALID_NODE_COUNT: usize = 2; diff --git a/src/signatures/jpeg.rs b/src/signatures/jpeg.rs index b61b1463c..817426d64 100644 --- a/src/signatures/jpeg.rs +++ b/src/signatures/jpeg.rs @@ -6,17 +6,17 @@ pub const DESCRIPTION: &str = "JPEG image"; /// JPEG magic bytes pub fn jpeg_magic() -> Vec> { - return vec![ + vec![ /* * Works for normal jpegs but not exif. * See: https://github.com/corkami/formats/blob/master/image/jpeg.md */ b"\xFF\xD8\xFF\xE0\x00\x10JFIF\x00".to_vec(), - ]; + ] } /// Parse a JPEG image -pub fn jpeg_parser(file_data: &Vec, offset: usize) -> Result { +pub fn jpeg_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { offset: offset, @@ -29,7 +29,7 @@ pub fn jpeg_parser(file_data: &Vec, offset: usize) -> Result Vec> { - return vec![b"Linux\x20version\x20".to_vec()]; + vec![b"Linux\x20version\x20".to_vec()] } /// Magic bytes for a linux ARM64 boot image pub fn linux_arm64_boot_image_magic() -> Vec> { - return vec![b"\x00\x00\x00\x00\x00\x00\x00\x00ARMd".to_vec()]; + vec![b"\x00\x00\x00\x00\x00\x00\x00\x00ARMd".to_vec()] } /// Validate a linux ARM64 boot image signature pub fn linux_arm64_boot_image_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // Magic bytes are 56 bytes into the image @@ -59,7 +59,7 @@ pub fn linux_arm64_boot_image_parser( /// Validate a linux boot image signature pub fn linux_boot_image_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // There should be the string "!HdrS" 514 bytes from the start of the magic signature @@ -92,7 +92,7 @@ pub fn linux_boot_image_parser( /// Validate a linux kernel version signature and detect if a symbol table is present pub fn linux_kernel_version_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // Kernel version string format is expected to be something like: diff --git a/src/signatures/luks.rs b/src/signatures/luks.rs index 78287375e..7829f0914 100644 --- a/src/signatures/luks.rs +++ b/src/signatures/luks.rs @@ -6,11 +6,11 @@ pub const DESCRIPTION: &str = "LUKS header"; /// LUKS Headers start with these bytes pub fn luks_magic() -> Vec> { - return vec![b"LUKS\xBA\xBE".to_vec()]; + vec![b"LUKS\xBA\xBE".to_vec()] } /// Parse and validate the LUKS header -pub fn luks_parser(file_data: &Vec, offset: usize) -> Result { +pub fn luks_parser(file_data: &[u8], offset: usize) -> Result { // Successful result let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/lz4.rs b/src/signatures/lz4.rs index f977fd106..5a0e79e30 100644 --- a/src/signatures/lz4.rs +++ b/src/signatures/lz4.rs @@ -7,11 +7,11 @@ pub const DESCRIPTION: &str = "LZ4 compressed data"; /// LZ4 files start with these magic bytes pub fn lz4_magic() -> Vec> { - return vec![b"\x04\x22\x4D\x18".to_vec()]; + vec![b"\x04\x22\x4D\x18".to_vec()] } /// Validate a LZ4 signature -pub fn lz4_parser(file_data: &Vec, offset: usize) -> Result { +pub fn lz4_parser(file_data: &[u8], offset: usize) -> Result { // Checksums are 4 bytes in length const CONTENT_CHECKSUM_LEN: usize = 4; diff --git a/src/signatures/lzfse.rs b/src/signatures/lzfse.rs index 016760495..a9ed03d83 100644 --- a/src/signatures/lzfse.rs +++ b/src/signatures/lzfse.rs @@ -7,16 +7,16 @@ pub const DESCRIPTION: &str = "LZFSE compressed data"; /// LZFSE block magics pub fn lzfse_magic() -> Vec> { - return vec![ + vec![ b"bvx-".to_vec(), b"bvx1".to_vec(), b"bvx2".to_vec(), b"bvxn".to_vec(), - ]; + ] } /// Validate LZFSE signatures -pub fn lzfse_parser(file_data: &Vec, offset: usize) -> Result { +pub fn lzfse_parser(file_data: &[u8], offset: usize) -> Result { let mut result = SignatureResult { offset: offset, confidence: CONFIDENCE_HIGH, @@ -38,7 +38,7 @@ pub fn lzfse_parser(file_data: &Vec, offset: usize) -> Result Vec> { } } - return magic_signatures; + magic_signatures } /// Validate LZMA signatures -pub fn lzma_parser(file_data: &Vec, offset: usize) -> Result { +pub fn lzma_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { offset: offset, @@ -64,7 +64,7 @@ pub fn lzma_parser(file_data: &Vec, offset: usize) -> Result Vec> { - return vec![b"\x89LZO\x00\x0D\x0A\x1A\x0A".to_vec()]; + vec![b"\x89LZO\x00\x0D\x0A\x1A\x0A".to_vec()] } /// Validate an LZOP signature -pub fn lzop_parser(file_data: &Vec, offset: usize) -> Result { +pub fn lzop_parser(file_data: &[u8], offset: usize) -> Result { // Success retrun value let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/mbr.rs b/src/signatures/mbr.rs index 486284b7d..8e48a75b1 100644 --- a/src/signatures/mbr.rs +++ b/src/signatures/mbr.rs @@ -10,11 +10,11 @@ pub const MAGIC_OFFSET: usize = 0x01FE; /// MBR always contains these bytes pub fn mbr_magic() -> Vec> { - return vec![b"\x55\xAA".to_vec()]; + vec![b"\x55\xAA".to_vec()] } /// Validates the MBR header -pub fn mbr_parser(file_data: &Vec, offset: usize) -> Result { +pub fn mbr_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { description: DESCRIPTION.to_string(), @@ -31,7 +31,7 @@ pub fn mbr_parser(file_data: &Vec, offset: usize) -> Result Vec> { - return vec![b"Salted__".to_vec()]; + vec![b"Salted__".to_vec()] } /// Validate an openssl signature pub fn openssl_crypt_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // Success return value diff --git a/src/signatures/packimg.rs b/src/signatures/packimg.rs index 1275637cd..ffd369f89 100644 --- a/src/signatures/packimg.rs +++ b/src/signatures/packimg.rs @@ -6,14 +6,11 @@ pub const DESCRIPTION: &str = "PackImg firmware header"; /// PackIMG magic bytes pub fn packimg_magic() -> Vec> { - return vec![b"--PaCkImGs--".to_vec()]; + vec![b"--PaCkImGs--".to_vec()] } /// Parse a PackIMG signature -pub fn packimg_parser( - file_data: &Vec, - offset: usize, -) -> Result { +pub fn packimg_parser(file_data: &[u8], offset: usize) -> Result { let mut result = SignatureResult { offset: offset, description: DESCRIPTION.to_string(), diff --git a/src/signatures/pcap.rs b/src/signatures/pcap.rs index 190c3612b..6736f1b2f 100644 --- a/src/signatures/pcap.rs +++ b/src/signatures/pcap.rs @@ -6,14 +6,11 @@ pub const PCAPNG_DESCRIPTION: &str = "Pcap-NG capture file"; /// Pcap-NG files always start with these bytes pub fn pcapng_magic() -> Vec> { - return vec![b"\x0A\x0D\x0D\x0A".to_vec()]; + vec![b"\x0A\x0D\x0D\x0A".to_vec()] } /// Parses and validates the Pcap-NG file -pub fn pcapng_parser( - file_data: &Vec, - offset: usize, -) -> Result { +pub fn pcapng_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/pchrom.rs b/src/signatures/pchrom.rs index 23f45cdce..a9c256399 100644 --- a/src/signatures/pchrom.rs +++ b/src/signatures/pchrom.rs @@ -6,14 +6,11 @@ pub const DESCRIPTION: &str = "Intel serial flash for PCH ROM"; /// PCH ROM magic bytes pub fn pch_rom_magic() -> Vec> { - return vec![b"\x5a\xa5\xf0\x0f".to_vec()]; + vec![b"\x5a\xa5\xf0\x0f".to_vec()] } /// Validate a PCH ROM signature -pub fn pch_rom_parser( - file_data: &Vec, - offset: usize, -) -> Result { +pub fn pch_rom_parser(file_data: &[u8], offset: usize) -> Result { // Magic bytes begin at this offset from the start of file const MAGIC_OFFSET: usize = 16; diff --git a/src/signatures/pdf.rs b/src/signatures/pdf.rs index 06855f2df..28cadb23a 100644 --- a/src/signatures/pdf.rs +++ b/src/signatures/pdf.rs @@ -6,11 +6,11 @@ pub const DESCRIPTION: &str = "PDF document"; /// PDF magic bytes pub fn pdf_magic() -> Vec> { // This assumes a major version of 1 - return vec![b"%PDF-1.".to_vec()]; + vec![b"%PDF-1.".to_vec()] } /// Validate a PDF signature -pub fn pdf_parser(file_data: &Vec, offset: usize) -> Result { +pub fn pdf_parser(file_data: &[u8], offset: usize) -> Result { // More than enough data for our needs const MIN_PDF_SIZE: usize = 16; diff --git a/src/signatures/pe.rs b/src/signatures/pe.rs index c76eb8ee4..e5203702a 100644 --- a/src/signatures/pe.rs +++ b/src/signatures/pe.rs @@ -10,14 +10,14 @@ pub fn pe_magic() -> Vec> { * This matches the first 16 bytes of a DOS header, from e_magic through e_ss. * Note that these values may differ in some special cases, but these are common ones. */ - return vec![ + vec![ b"\x4d\x5a\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xff\xff\x00\x00".to_vec(), b"\x4d\x5a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".to_vec(), - ]; + ] } /// Validate a PE header -pub fn pe_parser(file_data: &Vec, offset: usize) -> Result { +pub fn pe_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/pem.rs b/src/signatures/pem.rs index 3086ac63c..e51c4541d 100644 --- a/src/signatures/pem.rs +++ b/src/signatures/pem.rs @@ -10,27 +10,27 @@ pub const PEM_CERTIFICATE_DESCRIPTION: &str = "PEM certificate"; /// Public key magic pub fn pem_public_key_magic() -> Vec> { - return vec![b"-----BEGIN PUBLIC KEY-----".to_vec()]; + vec![b"-----BEGIN PUBLIC KEY-----".to_vec()] } /// Private key magics pub fn pem_private_key_magic() -> Vec> { - return vec![ + vec![ b"-----BEGIN PRIVATE KEY-----".to_vec(), b"-----BEGIN EC PRIVATE KEY-----".to_vec(), b"-----BEGIN RSA PRIVATE KEY-----".to_vec(), b"-----BEGIN DSA PRIVATE KEY-----".to_vec(), b"-----BEGIN OPENSSH PRIVATE KEY-----".to_vec(), - ]; + ] } /// Certificate magic pub fn pem_certificate_magic() -> Vec> { - return vec![b"-----BEGIN CERTIFICATE-----".to_vec()]; + vec![b"-----BEGIN CERTIFICATE-----".to_vec()] } /// Validates both PEM certificate and key signatures -pub fn pem_parser(file_data: &Vec, offset: usize) -> Result { +pub fn pem_parser(file_data: &[u8], offset: usize) -> Result { // Enough bytes to uniquely differentiate certs from keys const MIN_PEM_LEN: usize = 26; diff --git a/src/signatures/pjl.rs b/src/signatures/pjl.rs index f986c7197..a928a688d 100644 --- a/src/signatures/pjl.rs +++ b/src/signatures/pjl.rs @@ -6,11 +6,11 @@ pub const DESCRIPTION: &str = "HP Printer Job Language data"; /// PJL files typically start with these bytes pub fn pjl_magic() -> Vec> { - return vec![b"\x1B%-12345X@PJL".to_vec()]; + vec![b"\x1B%-12345X@PJL".to_vec()] } /// Parses display info for the PJL -pub fn pjl_parser(file_data: &Vec, offset: usize) -> Result { +pub fn pjl_parser(file_data: &[u8], offset: usize) -> Result { // Offset to the first "@PJL" string const PJL_COMMANDS_OFFSET: usize = 9; diff --git a/src/signatures/png.rs b/src/signatures/png.rs index 7688ed7c4..831500ae3 100644 --- a/src/signatures/png.rs +++ b/src/signatures/png.rs @@ -10,11 +10,11 @@ pub fn png_magic() -> Vec> { * PNG magic, followed by chunk size and IHDR chunk type. * IHDR must be the first chunk type, and it is a fixed size of 0x0000000D bytes. */ - return vec![b"\x89PNG\x0D\x0A\x1A\x0A\x00\x00\x00\x0DIHDR".to_vec()]; + vec![b"\x89PNG\x0D\x0A\x1A\x0A\x00\x00\x00\x0DIHDR".to_vec()] } /// Validate a PNG signature -pub fn png_parser(file_data: &Vec, offset: usize) -> Result { +pub fn png_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { offset: offset, @@ -27,7 +27,7 @@ pub fn png_parser(file_data: &Vec, offset: usize) -> Result Vec> { * Assumes little endian. * Includes the magic bytes (u32) and version number (u16), which must be 1. */ - return vec![b"\xEB\x7E\xFF\x00\x01\x00".to_vec()]; + vec![b"\xEB\x7E\xFF\x00\x01\x00".to_vec()] } /// Validate a QNX IFS signature -pub fn qnx_ifs_parser( - file_data: &Vec, - offset: usize, -) -> Result { +pub fn qnx_ifs_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/rar.rs b/src/signatures/rar.rs index 6b0dcebf8..427dbe1e0 100644 --- a/src/signatures/rar.rs +++ b/src/signatures/rar.rs @@ -8,11 +8,11 @@ pub const DESCRIPTION: &str = "RAR archive"; /// RAR magic bytes for both v4 and v5 pub fn rar_magic() -> Vec> { - return vec![b"Rar!\x1A\x07".to_vec()]; + vec![b"Rar!\x1A\x07".to_vec()] } /// Validate RAR signature -pub fn rar_parser(file_data: &Vec, offset: usize) -> Result { +pub fn rar_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { offset: offset, @@ -58,7 +58,7 @@ fn get_rar_size(file_data: &[u8], rar_version: usize) -> Result Vec> { - return vec![b"RIFF".to_vec()]; + vec![b"RIFF".to_vec()] } /// Validate RIFF signatures -pub fn riff_parser(file_data: &Vec, offset: usize) -> Result { +pub fn riff_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/romfs.rs b/src/signatures/romfs.rs index af953ab45..adffc57f6 100644 --- a/src/signatures/romfs.rs +++ b/src/signatures/romfs.rs @@ -7,11 +7,11 @@ pub const DESCRIPTION: &str = "RomFS filesystem"; /// ROMFS magic bytes pub fn romfs_magic() -> Vec> { - return vec![b"-rom1fs-".to_vec()]; + vec![b"-rom1fs-".to_vec()] } /// Validate a ROMFS signature -pub fn romfs_parser(file_data: &Vec, offset: usize) -> Result { +pub fn romfs_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { description: DESCRIPTION.to_string(), @@ -24,7 +24,7 @@ pub fn romfs_parser(file_data: &Vec, offset: usize) -> Result Vec { - return vec![ + vec![ // 1024b RSA key RSAKeyDefinition { magic: b"\x84\x8C\x03".to_vec(), @@ -130,7 +130,7 @@ fn rsa_key_definitions() -> Vec { ], )]), }, - ]; + ] } /// RSA crypto magic bytes @@ -141,11 +141,11 @@ pub fn rsa_magic() -> Vec> { magics.push(key_definition.magic.clone()); } - return magics; + magics } /// Validates an RSA encrypted file header -pub fn rsa_parser(file_data: &Vec, offset: usize) -> Result { +pub fn rsa_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/rtk.rs b/src/signatures/rtk.rs index 75ff9ae94..47edf7488 100644 --- a/src/signatures/rtk.rs +++ b/src/signatures/rtk.rs @@ -6,11 +6,11 @@ pub const DESCRIPTION: &str = "RTK firmware header"; /// RTK firmware images always start with these bytes pub fn rtk_magic() -> Vec> { - return vec![b"RTK0".to_vec()]; + vec![b"RTK0".to_vec()] } /// Validates the RTK header -pub fn rtk_parser(file_data: &Vec, offset: usize) -> Result { +pub fn rtk_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/seama.rs b/src/signatures/seama.rs index e6821026d..45d09113c 100644 --- a/src/signatures/seama.rs +++ b/src/signatures/seama.rs @@ -6,14 +6,14 @@ pub const DESCRIPTION: &str = "SEAMA firmware header"; /// SEAMA magic bytes, big and little endian pub fn seama_magic() -> Vec> { - return vec![ + vec![ b"\x5E\xA3\xA4\x17\x00\x00".to_vec(), b"\x17\xA4\xA3\x5E\x00\x00".to_vec(), - ]; + ] } /// Validate SEAMA signatures -pub fn seama_parser(file_data: &Vec, offset: usize) -> Result { +pub fn seama_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/sevenzip.rs b/src/signatures/sevenzip.rs index 7e4320737..f936cbb04 100644 --- a/src/signatures/sevenzip.rs +++ b/src/signatures/sevenzip.rs @@ -7,14 +7,11 @@ pub const DESCRIPTION: &str = "7-zip archive data"; /// 7zip magic bytes pub fn sevenzip_magic() -> Vec> { - return vec![b"7z\xbc\xaf\x27\x1c".to_vec()]; + vec![b"7z\xbc\xaf\x27\x1c".to_vec()] } /// Validates 7zip signatures -pub fn sevenzip_parser( - file_data: &Vec, - offset: usize, -) -> Result { +pub fn sevenzip_parser(file_data: &[u8], offset: usize) -> Result { // Parse the 7z header if let Ok(sevenzip_header) = parse_7z_header(&file_data[offset..]) { // Calculate the start and end offsets that the next header CRC was calculated over diff --git a/src/signatures/squashfs.rs b/src/signatures/squashfs.rs index b73c86557..0d6668193 100644 --- a/src/signatures/squashfs.rs +++ b/src/signatures/squashfs.rs @@ -9,7 +9,7 @@ pub const DESCRIPTION: &str = "SquashFS file system"; /// All of the known magic bytes that could indicate the beginning of a SquashFS image pub fn squashfs_magic() -> Vec> { - return vec![ + vec![ b"sqsh".to_vec(), b"hsqs".to_vec(), b"sqlz".to_vec(), @@ -17,14 +17,11 @@ pub fn squashfs_magic() -> Vec> { b"tqsh".to_vec(), b"hsqt".to_vec(), b"shsq".to_vec(), - ]; + ] } /// Responsible for parsing and validating a suspected SquashFS image header -pub fn squashfs_parser( - file_data: &Vec, - offset: usize, -) -> Result { +pub fn squashfs_parser(file_data: &[u8], offset: usize) -> Result { const SQUASHFSV4: usize = 4; let squashfs_compression_types = HashMap::from([ diff --git a/src/signatures/srec.rs b/src/signatures/srec.rs index 70ef7ba3a..a17b34d9b 100644 --- a/src/signatures/srec.rs +++ b/src/signatures/srec.rs @@ -8,16 +8,16 @@ pub const SREC_SHORT_DESCRIPTION: &str = "Motorola S-record (generic)"; /// Generic, short signature for s-records, should only be matched at the beginning of a file pub fn srec_short_magic() -> Vec> { - return vec![b"S0".to_vec()]; + vec![b"S0".to_vec()] } /// This assumes a srec header with the hex encoded string of "HDR" pub fn srec_magic() -> Vec> { - return vec![b"S00600004844521B".to_vec()]; + vec![b"S00600004844521B".to_vec()] } /// Validates a SREC signature -pub fn srec_parser(file_data: &Vec, offset: usize) -> Result { +pub fn srec_parser(file_data: &[u8], offset: usize) -> Result { // \r and \n const UNIX_TERMINATING_CHARACTER: u8 = 0x0A; const WINDOWS_TERMINATING_CHARACTER: u8 = 0x0D; diff --git a/src/signatures/svg.rs b/src/signatures/svg.rs index 9b8df4fea..a946ec594 100644 --- a/src/signatures/svg.rs +++ b/src/signatures/svg.rs @@ -6,11 +6,11 @@ pub const DESCRIPTION: &str = "SVG image"; /// SVG magic bytes pub fn svg_magic() -> Vec> { - return vec![b", offset: usize) -> Result { +pub fn svg_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { offset: offset, @@ -23,7 +23,7 @@ pub fn svg_parser(file_data: &Vec, offset: usize) -> Result Vec> { - return vec![b"ustar\x00".to_vec(), b"ustar\x20\x20\x00".to_vec()]; + vec![b"ustar\x00".to_vec(), b"ustar\x20\x20\x00".to_vec()] } /// Validate tarball signatures -pub fn tarball_parser( - file_data: &Vec, - offset: usize, -) -> Result { +pub fn tarball_parser(file_data: &[u8], offset: usize) -> Result { // Stores the running total size of the tarball let mut tarball_total_size: usize = 0; @@ -52,7 +49,7 @@ pub fn tarball_parser( } Some(tarball_header_block) => { // Bad checksum? Quit processing headers. - if header_checksum_is_valid(tarball_header_block) == false { + if !header_checksum_is_valid(tarball_header_block) { break; } @@ -106,15 +103,15 @@ fn header_checksum_is_valid(header_block: &[u8]) -> bool { let reported_checksum = tarball_octal(checksum_value_string); let mut sum: usize = 0; - for i in 0..header_block.len() { - if i >= TARBALL_CHECKSUM_START && i < TARBALL_CHECKSUM_END { - sum = sum + 0x20; + for (i, header_byte) in header_block.iter().enumerate() { + if (TARBALL_CHECKSUM_START..TARBALL_CHECKSUM_END).contains(&i) { + sum += 0x20; } else { - sum = sum + (header_block[i] as usize); + sum += (*header_byte as usize); } } - return sum == reported_checksum; + sum == reported_checksum } /// Returns the size of a tarball entry, including header and data @@ -147,15 +144,15 @@ fn tarball_entry_size(tarball_entry_data: &[u8]) -> Result usize { let mut num: usize = 0; - for i in 0..octal_string.len() { + for octal_char in octal_string { // ASCII octal values should be ASCII - if octal_string[i] < 0x30 || octal_string[i] > 0x39 { + if *octal_char < 0x30 || *octal_char > 0x39 { break; } else { - num = num * 8; - num = num + (octal_string[i] as usize) - 0x30; + num *= 8; + num = num + (*octal_char as usize) - 0x30; } } - return num; + num } diff --git a/src/signatures/tplink.rs b/src/signatures/tplink.rs index 92214f2af..b6149afba 100644 --- a/src/signatures/tplink.rs +++ b/src/signatures/tplink.rs @@ -6,14 +6,11 @@ pub const DESCRIPTION: &str = "TP-Link firmware header"; /// TP-Link firmware headers start with these bytes pub fn tplink_magic() -> Vec> { - return vec![b"\x01\x00\x00\x00TP-LINK Technologies\x00\x00\x00\x00ver. 1.0".to_vec()]; + vec![b"\x01\x00\x00\x00TP-LINK Technologies\x00\x00\x00\x00ver. 1.0".to_vec()] } /// Validates the TP-Link header -pub fn tplink_parser( - file_data: &Vec, - offset: usize, -) -> Result { +pub fn tplink_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/trx.rs b/src/signatures/trx.rs index 07f474818..5d56ec33d 100644 --- a/src/signatures/trx.rs +++ b/src/signatures/trx.rs @@ -7,11 +7,11 @@ pub const DESCRIPTION: &str = "TRX firmware image"; /// TRX magic bytes pub fn trx_magic() -> Vec> { - return vec![b"HDR0".to_vec()]; + vec![b"HDR0".to_vec()] } /// Validates a TRX signature -pub fn trx_parser(file_data: &Vec, offset: usize) -> Result { +pub fn trx_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { offset: offset, @@ -23,7 +23,7 @@ pub fn trx_parser(file_data: &Vec, offset: usize) -> Result Vec> { - return vec![b"UBI#\x01\x00\x00\x00".to_vec()]; + vec![b"UBI#\x01\x00\x00\x00".to_vec()] } /// UBI node magic; this matches *any* UBI node, but ubifs_parser ensures that only superblock nodes are reported pub fn ubifs_magic() -> Vec> { - return vec![b"\x31\x18\x10\x06".to_vec()]; + vec![b"\x31\x18\x10\x06".to_vec()] } /// Validates a UBIFS signature -pub fn ubifs_parser(file_data: &Vec, offset: usize) -> Result { +pub fn ubifs_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { offset: offset, @@ -41,7 +41,7 @@ pub fn ubifs_parser(file_data: &Vec, offset: usize) -> Result, offset: usize) -> Result { +pub fn ubi_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { offset: offset, @@ -91,7 +91,7 @@ fn get_ubi_image_size(ubi_data: &[u8]) -> Result { let this_volume_offset: usize = magic_match.start(); // Parse the volume header - if let Ok(_) = parse_ubi_volume_header(&ubi_data[this_volume_offset..]) { + if parse_ubi_volume_header(&ubi_data[this_volume_offset..]).is_ok() { // Header looks valid, increment the block count block_count += 1; diff --git a/src/signatures/uefi.rs b/src/signatures/uefi.rs index 985baa10d..1f57dee4d 100644 --- a/src/signatures/uefi.rs +++ b/src/signatures/uefi.rs @@ -7,21 +7,21 @@ pub const CAPSULE_DESCRIPTION: &str = "UEFI capsule image"; /// UEFI volume magic bytes pub fn uefi_volume_magic() -> Vec> { - return vec![b"_FVH".to_vec()]; + vec![b"_FVH".to_vec()] } /// UEFI capsule GUIDs pub fn uefi_capsule_magic() -> Vec> { - return vec![ + vec![ b"\xBD\x86\x66\x3B\x76\x0D\x30\x40\xB7\x0E\xB5\x51\x9E\x2F\xC5\xA0".to_vec(), // EFI capsule GUID b"\x8B\xA6\x3C\x4A\x23\x77\xFB\x48\x80\x3D\x57\x8C\xC1\xFE\xC4\x4D".to_vec(), // EFI2 capsule GUID b"\xB9\x82\x91\x53\xB5\xAB\x91\x43\xB6\x9A\xE3\xA9\x43\xF7\x2F\xCC".to_vec(), // UEFI capsule GUID - ]; + ] } /// Validates UEFI volume signatures pub fn uefi_volume_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // The magic signature begins this many bytes from the start of the UEFI volume @@ -62,7 +62,7 @@ pub fn uefi_volume_parser( /// Validates UEFI capsule signatures pub fn uefi_capsule_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // Success return value diff --git a/src/signatures/uimage.rs b/src/signatures/uimage.rs index a80ec11de..1f51bf60b 100644 --- a/src/signatures/uimage.rs +++ b/src/signatures/uimage.rs @@ -8,14 +8,11 @@ pub const DESCRIPTION: &str = "uImage firmware image"; /// uImage magic bytes pub fn uimage_magic() -> Vec> { - return vec![b"\x27\x05\x19\x56".to_vec()]; + vec![b"\x27\x05\x19\x56".to_vec()] } /// Validates uImage signatures -pub fn uimage_parser( - file_data: &Vec, - offset: usize, -) -> Result { +pub fn uimage_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { size: 0, @@ -28,7 +25,7 @@ pub fn uimage_parser( // Do an extraction dry-run let dry_run = extract_uimage(file_data, offset, None); - if dry_run.success == true { + if dry_run.success { if let Some(uimage_size) = dry_run.size { // Extraction dry-run ok, parse the header to display some useful info if let Ok(uimage_header) = parse_uimage_header(&file_data[offset..]) { diff --git a/src/signatures/vxworks.rs b/src/signatures/vxworks.rs index f8da708ab..447b642ec 100644 --- a/src/signatures/vxworks.rs +++ b/src/signatures/vxworks.rs @@ -9,25 +9,25 @@ pub const WIND_KERNEL_DESCRIPTION: &str = "VxWorks WIND kernel version"; /// WIND kernel version magic pub fn wind_kernel_magic() -> Vec> { // Magic version string for WIND kernels - return vec![b"WIND version ".to_vec()]; + vec![b"WIND version ".to_vec()] } /// VxWorks symbol table magic bytes pub fn symbol_table_magic() -> Vec> { // These magic bytes match the type and group fields in the VxWorks symbol table, for both big and little endian targets - return vec![ + vec![ b"\x00\x00\x05\x00\x00\x00\x00\x00".to_vec(), b"\x00\x00\x07\x00\x00\x00\x00\x00".to_vec(), b"\x00\x00\x09\x00\x00\x00\x00\x00".to_vec(), b"\x00\x05\x00\x00\x00\x00\x00\x00".to_vec(), b"\x00\x07\x00\x00\x00\x00\x00\x00".to_vec(), b"\x00\x09\x00\x00\x00\x00\x00\x00".to_vec(), - ]; + ] } /// Validates WIND kernel version signatures pub fn wind_kernel_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // Length of the magic signatures bytes @@ -48,7 +48,7 @@ pub fn wind_kernel_parser( let version_string = get_cstring(version_bytes); // Make sure we got a string - if version_string.len() > 0 { + if !version_string.is_empty() { result.size = MAGIC_SIZE + version_string.len(); result.description = format!("{} {}", result.description, version_string); return Ok(result); @@ -60,7 +60,7 @@ pub fn wind_kernel_parser( /// Validates VxWorks symbol table signatures pub fn symbol_table_parser( - file_data: &Vec, + file_data: &[u8], offset: usize, ) -> Result { // The magic bytes start at this offset from the beginning of the symbol table @@ -81,7 +81,7 @@ pub fn symbol_table_parser( let dry_run = extract_symbol_table(file_data, symtab_start, None); // If dry run was a success, this is very likely a valid symbol table - if dry_run.success == true { + if dry_run.success { // Get the size of the symbol table from the dry-run if let Some(symtab_size) = dry_run.size { result.size = symtab_size; diff --git a/src/signatures/xz.rs b/src/signatures/xz.rs index 34ccf6b49..94a8d6a55 100644 --- a/src/signatures/xz.rs +++ b/src/signatures/xz.rs @@ -7,11 +7,11 @@ pub const DESCRIPTION: &str = "XZ compressed data"; /// XZ magic bytes pub fn xz_magic() -> Vec> { - return vec![b"\xFD\x37\x7a\x58\x5a\x00".to_vec()]; + vec![b"\xFD\x37\x7a\x58\x5a\x00".to_vec()] } /// Validates XZ signatures -pub fn xz_parser(file_data: &Vec, offset: usize) -> Result { +pub fn xz_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { offset: offset, diff --git a/src/signatures/yaffs.rs b/src/signatures/yaffs.rs index 7c3446920..55211e5a5 100644 --- a/src/signatures/yaffs.rs +++ b/src/signatures/yaffs.rs @@ -10,16 +10,16 @@ pub const DESCRIPTION: &str = "YAFFSv2 filesystem"; /// Expect the first YAFFS entry to be either a directory (0x00000003) or file (0x00000001), big or little endian pub fn yaffs_magic() -> Vec> { - return vec![ + vec![ b"\x03\x00\x00\x00\x01\x00\x00\x00\xFF\xFF".to_vec(), b"\x00\x00\x00\x03\x00\x00\x00\x01\xFF\xFF".to_vec(), b"\x01\x00\x00\x00\x01\x00\x00\x00\xFF\xFF".to_vec(), b"\x00\x00\x00\x01\x00\x00\x00\x01\xFF\xFF".to_vec(), - ]; + ] } /// Validate a YAFFS signature -pub fn yaffs_parser(file_data: &Vec, offset: usize) -> Result { +pub fn yaffs_parser(file_data: &[u8], offset: usize) -> Result { // Max page size + max spare size const MAX_OBJ_SIZE: usize = 16896; const BIG_ENDIAN_FIRST_BYTE: u8 = 0; @@ -116,7 +116,7 @@ fn get_spare_size( if let Some(obj_header_data) = file_data.get(next_obj_offset..) { // Attempt to parse this data as a YAFFS object header - if let Ok(_) = parse_yaffs_obj_header(obj_header_data, endianness) { + if parse_yaffs_obj_header(obj_header_data, endianness).is_ok() { return Ok(*spare_size); } } diff --git a/src/signatures/zip.rs b/src/signatures/zip.rs index 752b98597..378653ec3 100644 --- a/src/signatures/zip.rs +++ b/src/signatures/zip.rs @@ -7,11 +7,11 @@ pub const DESCRIPTION: &str = "ZIP archive"; /// ZIP file entry magic bytes pub fn zip_magic() -> Vec> { - return vec![b"PK\x03\x04".to_vec()]; + vec![b"PK\x03\x04".to_vec()] } /// Validates a ZIP file entry signature -pub fn zip_parser(file_data: &Vec, offset: usize) -> Result { +pub fn zip_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { offset: offset, @@ -21,9 +21,9 @@ pub fn zip_parser(file_data: &Vec, offset: usize) -> Result, offset: usize) -> Result { +fn find_zip_eof(file_data: &[u8], offset: usize) -> Result { // This magic string assumes that the disk_number and central_directory_disk_number are 0 const ZIP_EOCD_MAGIC: &[u8; 8] = b"PK\x05\x06\x00\x00\x00\x00"; diff --git a/src/signatures/zlib.rs b/src/signatures/zlib.rs index ae0cc01c9..9d9352a15 100644 --- a/src/signatures/zlib.rs +++ b/src/signatures/zlib.rs @@ -6,15 +6,15 @@ pub const DESCRIPTION: &str = "Zlib compressed file"; /// Zlib magic bytes pub fn zlib_magic() -> Vec> { - return vec![ + vec![ b"\x78\x9c".to_vec(), b"\x78\xDA".to_vec(), b"\x78\x5E".to_vec(), - ]; + ] } /// Validate a zlib signature -pub fn zlib_parser(file_data: &Vec, offset: usize) -> Result { +pub fn zlib_parser(file_data: &[u8], offset: usize) -> Result { let mut result = SignatureResult { offset: offset, confidence: CONFIDENCE_HIGH, @@ -25,10 +25,10 @@ pub fn zlib_parser(file_data: &Vec, offset: usize) -> Result Vec> { - return vec![b"\x28\xb5\x2f\xfd".to_vec()]; + vec![b"\x28\xb5\x2f\xfd".to_vec()] } /// Validate a ZSTD signature -pub fn zstd_parser(file_data: &Vec, offset: usize) -> Result { +pub fn zstd_parser(file_data: &[u8], offset: usize) -> Result { // Size of checksum value at EOF const EOF_CHECKSUM_SIZE: usize = 4; @@ -37,7 +37,7 @@ pub fn zstd_parser(file_data: &Vec, offset: usize) -> Result, offset: usize) -> Result, offset: usize) -> Result Result Result let board_id_end: usize = chk_header["header_size"]; if let Some(board_id_raw_bytes) = header_data.get(board_id_start..board_id_end) { - let board_id_string = get_cstring(&board_id_raw_bytes); + let board_id_string = get_cstring(board_id_raw_bytes); // We expect that there must be a valid board ID string - if board_id_string.len() > 0 { + if !board_id_string.is_empty() { return Ok(CHKHeader { board_id: board_id_string.clone(), header_size: chk_header["header_size"], diff --git a/src/structures/common.rs b/src/structures/common.rs index c01efa4b1..dd0c29f55 100644 --- a/src/structures/common.rs +++ b/src/structures/common.rs @@ -67,7 +67,7 @@ pub fn parse( for (name, ctype) in structure { let data_type: String = ctype.to_string(); - csize = type_to_size(&ctype); + csize = type_to_size(ctype); if csize == std::mem::size_of::() { // u8, endianness doesn't matter @@ -123,7 +123,7 @@ pub fn parse( return Ok(parsed_structure); } - return Err(StructureError); + Err(StructureError) } /// Returns the size of a given structure definition. @@ -151,7 +151,7 @@ pub fn size(structure: &Vec<(&str, &str)>) -> usize { struct_size += type_to_size(ctype); } - return struct_size; + struct_size } /// Returns the size of a give type string @@ -160,9 +160,9 @@ fn type_to_size(ctype: &str) -> usize { let size_lookup_table: HashMap<&str, usize> = HashMap::from([("u8", 1), ("u16", 2), ("u24", 3), ("u32", 4), ("u64", 8)]); - if size_lookup_table.contains_key(ctype) == false { + if !size_lookup_table.contains_key(ctype) { panic!("Unknown size for structure type '{}'!", ctype); } - return size_lookup_table[ctype]; + size_lookup_table[ctype] } diff --git a/src/structures/cpio.rs b/src/structures/cpio.rs index 8077d7c35..1be83408b 100644 --- a/src/structures/cpio.rs +++ b/src/structures/cpio.rs @@ -76,8 +76,8 @@ pub fn parse_cpio_entry_header(cpio_data: &[u8]) -> Result usize { let modulus: usize = n % 4; if modulus == 0 { - return 0; + 0 } else { - return 4 - modulus; + 4 - modulus } } diff --git a/src/structures/cramfs.rs b/src/structures/cramfs.rs index a2ae18f14..6635686a0 100644 --- a/src/structures/cramfs.rs +++ b/src/structures/cramfs.rs @@ -41,7 +41,7 @@ pub fn parse_cramfs_header(cramfs_data: &[u8]) -> Result Result { // Convert the raw bytes into an ASCII string if let Ok(control_file_size_str) = String::from_utf8(control_file_size_data.to_vec()) { // Trim white space from the string and convert to an integer value - if let Ok(control_file_size) = usize::from_str_radix(&control_file_size_str.trim(), 10) - { + if let Ok(control_file_size) = control_file_size_str.trim().parse::() { // Calculate the offsets to the decimal ASCII string that contains the data file size let data_file_size_start: usize = CONTROL_FILE_SIZE_END + END_MARKER_SIZE @@ -42,9 +41,7 @@ pub fn parse_deb_header(deb_data: &[u8]) -> Result { if let Ok(data_file_size_str) = String::from_utf8(data_file_size_data.to_vec()) { // Trim whitespace from the string and convert to an integer value - if let Ok(data_file_size) = - usize::from_str_radix(&data_file_size_str.trim(), 10) - { + if let Ok(data_file_size) = data_file_size_str.trim().parse::() { // Total file size is the end of the file data size ASCII field, plus the 2-byte end marker, plus the length of the following data file // TODO: This size seems to be short by 2 bytes? Not a big deal for our purposes, but still... deb_header.file_size = diff --git a/src/structures/efigpt.rs b/src/structures/efigpt.rs index 76ea006bb..a6c63e0ec 100644 --- a/src/structures/efigpt.rs +++ b/src/structures/efigpt.rs @@ -128,10 +128,10 @@ fn parse_gpt_partition_entry(entry_data: &[u8]) -> Option { } } - return None; + None } // Convert LBA to offset fn lba_to_offset(lba: usize) -> usize { - return lba * BLOCK_SIZE; + lba * BLOCK_SIZE } diff --git a/src/structures/elf.rs b/src/structures/elf.rs index 623ea8e4b..43bbb328a 100644 --- a/src/structures/elf.rs +++ b/src/structures/elf.rs @@ -162,7 +162,7 @@ pub fn parse_elf_header(elf_data: &[u8]) -> Result { if let Some(elf_info_raw) = elf_data.get(elf_info_start..elf_info_end) { // Parse the remaining info from the ELF header if let Ok(elf_info) = common::parse( - &elf_info_raw, + elf_info_raw, &elf_info_structure, elf_endianness[&e_ident["endianness"]], ) { diff --git a/src/structures/gif.rs b/src/structures/gif.rs index 2b49eac3c..14cd33055 100644 --- a/src/structures/gif.rs +++ b/src/structures/gif.rs @@ -57,7 +57,7 @@ fn parse_gif_flags(flags: usize) -> GIFFlags { retval.color_table_size = 3 * usize::pow(2, encoded_table_size); } - return retval; + retval } /// Parses an image descriptor; returns the total size of the descriptor and following image data diff --git a/src/structures/gzip.rs b/src/structures/gzip.rs index 0dc506f28..0efe965b6 100644 --- a/src/structures/gzip.rs +++ b/src/structures/gzip.rs @@ -87,7 +87,7 @@ pub fn parse_gzip_header(header_data: &[u8]) -> Result { // Parse the extra header and update the header_info.size to include this data match common::parse( - &extra_header_data, + extra_header_data, &gzip_extra_header_structure, "little", ) { diff --git a/src/structures/jboot.rs b/src/structures/jboot.rs index 484661095..1f87ae01e 100644 --- a/src/structures/jboot.rs +++ b/src/structures/jboot.rs @@ -208,7 +208,11 @@ fn sch2_header_crc(sch2_header_bytes: &[u8]) -> usize { let mut crc_data: Vec = sch2_header_bytes.to_vec(); // Header CRC field has to be NULL'd out - for crc_byte in crc_data.iter_mut().take(HEADER_CRC_END).skip(HEADER_CRC_START) { + for crc_byte in crc_data + .iter_mut() + .take(HEADER_CRC_END) + .skip(HEADER_CRC_START) + { *crc_byte = 0; } diff --git a/src/structures/jffs2.rs b/src/structures/jffs2.rs index fd25361af..a16306de5 100644 --- a/src/structures/jffs2.rs +++ b/src/structures/jffs2.rs @@ -35,8 +35,7 @@ pub fn parse_jffs2_node_header(node_data: &[u8]) -> Result 0 { return Ok(image_size); } - + Err(StructureError) } diff --git a/src/structures/squashfs.rs b/src/structures/squashfs.rs index 081e8d2ea..7a16f76d4 100644 --- a/src/structures/squashfs.rs +++ b/src/structures/squashfs.rs @@ -172,21 +172,13 @@ pub fn parse_squashfs_uid_entry( // Parse one entry from the UID table if version == 4 { match common::parse(uid_data, &squashfs_v4_uid_table_structure, endianness) { - Err(e) => { - Err(e) - } - Ok(uidv4) => { - Ok(uidv4["uid_block_ptr"]) - } + Err(e) => Err(e), + Ok(uidv4) => Ok(uidv4["uid_block_ptr"]), } } else { match common::parse(uid_data, &squashfs_v3_uid_table_structure, endianness) { - Err(e) => { - Err(e) - } - Ok(uidv3) => { - Ok(uidv3["uid_block_ptr"]) - } + Err(e) => Err(e), + Ok(uidv3) => Ok(uidv3["uid_block_ptr"]), } } } diff --git a/src/structures/uimage.rs b/src/structures/uimage.rs index 730e3a525..5025d35f9 100644 --- a/src/structures/uimage.rs +++ b/src/structures/uimage.rs @@ -199,7 +199,11 @@ fn calculate_uimage_header_checksum(hdr: &[u8]) -> usize { // Header checksum has to be nulled out to calculate the CRC let mut uimage_header: Vec = hdr.to_vec(); - for crc_byte in uimage_header.iter_mut().take(HEADER_CRC_END).skip(HEADER_CRC_START) { + for crc_byte in uimage_header + .iter_mut() + .take(HEADER_CRC_END) + .skip(HEADER_CRC_START) + { *crc_byte = 0; } From 8583de5f041aac75e4969cc617bb11cd25739320 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sun, 20 Oct 2024 12:16:30 -0400 Subject: [PATCH 004/131] Lint fixes in signatures --- src/magic.rs | 1809 ++++++++++++++++++------------------- src/signatures/cpio.rs | 2 +- src/signatures/cramfs.rs | 8 +- src/signatures/dmg.rs | 4 +- src/signatures/ecos.rs | 2 +- src/signatures/gpg.rs | 2 +- src/signatures/gzip.rs | 2 +- src/signatures/hashes.rs | 6 +- src/signatures/jffs2.rs | 2 +- src/signatures/linux.rs | 2 +- src/signatures/lz4.rs | 4 +- src/signatures/pcap.rs | 2 +- src/signatures/pdf.rs | 4 +- src/signatures/pem.rs | 12 +- src/signatures/tarball.rs | 2 +- 15 files changed, 895 insertions(+), 968 deletions(-) diff --git a/src/magic.rs b/src/magic.rs index 3a04c5026..a11c03300 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -3,947 +3,870 @@ use crate::signatures; /// Returns a list of all supported signatures, including their "magic" byte patterns, parser functions, and any associated extractor. pub fn patterns() -> Vec { - let mut binary_signatures: Vec = vec![]; - - // gzip - binary_signatures.push(signatures::common::Signature { - name: "gzip".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::gzip::gzip_magic(), - parser: signatures::gzip::gzip_parser, - description: signatures::gzip::DESCRIPTION.to_string(), - extractor: Some(extractors::gzip::gzip_extractor()), - }); - - // .deb - binary_signatures.push(signatures::common::Signature { - name: "deb".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::deb::deb_magic(), - parser: signatures::deb::deb_parser, - description: signatures::deb::DESCRIPTION.to_string(), - extractor: None, - }); - - // 7-zip - binary_signatures.push(signatures::common::Signature { - name: "7zip".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::sevenzip::sevenzip_magic(), - parser: signatures::sevenzip::sevenzip_parser, - description: signatures::sevenzip::DESCRIPTION.to_string(), - extractor: Some(extractors::sevenzip::sevenzip_extractor()), - }); - - // xz - binary_signatures.push(signatures::common::Signature { - name: "xz".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::xz::xz_magic(), - parser: signatures::xz::xz_parser, - description: signatures::xz::DESCRIPTION.to_string(), - extractor: Some(extractors::lzma::lzma_extractor()), - }); - - // tarball - binary_signatures.push(signatures::common::Signature { - name: "tarball".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::tarball::tarball_magic(), - parser: signatures::tarball::tarball_parser, - description: signatures::tarball::DESCRIPTION.to_string(), - extractor: Some(extractors::tarball::tarball_extractor()), - }); - - // squashfs - binary_signatures.push(signatures::common::Signature { - name: "squashfs".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::squashfs::squashfs_magic(), - parser: signatures::squashfs::squashfs_parser, - description: signatures::squashfs::DESCRIPTION.to_string(), - extractor: Some(extractors::squashfs::squashfs_extractor()), - }); - - // dlob - binary_signatures.push(signatures::common::Signature { - name: "dlob".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::dlob::dlob_magic(), - parser: signatures::dlob::dlob_parser, - description: signatures::dlob::DESCRIPTION.to_string(), - extractor: None, - }); - - // lzma - binary_signatures.push(signatures::common::Signature { - name: "lzma".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::lzma::lzma_magic(), - parser: signatures::lzma::lzma_parser, - description: signatures::lzma::DESCRIPTION.to_string(), - //extractor: Some(extractors::sevenzip::sevenzip_extractor()), - extractor: Some(extractors::lzma::lzma_extractor()), - }); - - // bzip2 - binary_signatures.push(signatures::common::Signature { - name: "bzip2".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::bzip2::bzip2_magic(), - parser: signatures::bzip2::bzip2_parser, - description: signatures::bzip2::DESCRIPTION.to_string(), - extractor: Some(extractors::bzip2::bzip2_extractor()), - }); - - // uimage - binary_signatures.push(signatures::common::Signature { - name: "uimage".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::uimage::uimage_magic(), - parser: signatures::uimage::uimage_parser, - description: signatures::uimage::DESCRIPTION.to_string(), - extractor: Some(extractors::uimage::uimage_extractor()), - }); - - // packimg header - binary_signatures.push(signatures::common::Signature { - name: "packimg".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::packimg::packimg_magic(), - parser: signatures::packimg::packimg_parser, - description: signatures::packimg::DESCRIPTION.to_string(), - extractor: None, - }); - - // crc32 constants - binary_signatures.push(signatures::common::Signature { - name: "crc32".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::hashes::crc32_magic(), - parser: signatures::hashes::crc32_parser, - description: signatures::hashes::CRC32_DESCRIPTION.to_string(), - extractor: None, - }); - - // sha256 constants - binary_signatures.push(signatures::common::Signature { - name: "sha256".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::hashes::sha256_magic(), - parser: signatures::hashes::sha256_parser, - description: signatures::hashes::SHA256_DESCRIPTION.to_string(), - extractor: None, - }); - - // cpio - binary_signatures.push(signatures::common::Signature { - name: "cpio".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::cpio::cpio_magic(), - parser: signatures::cpio::cpio_parser, - description: signatures::cpio::DESCRIPTION.to_string(), - extractor: Some(extractors::sevenzip::sevenzip_extractor()), - }); - - // iso9660 primary volume - binary_signatures.push(signatures::common::Signature { - name: "iso9660".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::iso9660::iso_magic(), - parser: signatures::iso9660::iso_parser, - description: signatures::iso9660::DESCRIPTION.to_string(), - extractor: Some(extractors::tsk::tsk_extractor()), - }); - - // linux kernel - binary_signatures.push(signatures::common::Signature { - name: "linux_kernel".to_string(), - short: false, - magic_offset: 0, - always_display: true, - magic: signatures::linux::linux_kernel_version_magic(), - parser: signatures::linux::linux_kernel_version_parser, - description: signatures::linux::LINUX_KERNEL_VERSION_DESCRIPTION.to_string(), - extractor: Some(extractors::linux::linux_kernel_extractor()), - }); - - // linux boot image - binary_signatures.push(signatures::common::Signature { - name: "linux_boot_image".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::linux::linux_boot_image_magic(), - parser: signatures::linux::linux_boot_image_parser, - description: signatures::linux::LINUX_BOOT_IMAGE_DESCRIPTION.to_string(), - extractor: None, - }); - - // zstd - binary_signatures.push(signatures::common::Signature { - name: "zstd".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::zstd::zstd_magic(), - parser: signatures::zstd::zstd_parser, - description: signatures::zstd::DESCRIPTION.to_string(), - extractor: Some(extractors::zstd::zstd_extractor()), - }); - - // zip - binary_signatures.push(signatures::common::Signature { - name: "zip".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::zip::zip_magic(), - parser: signatures::zip::zip_parser, - description: signatures::zip::DESCRIPTION.to_string(), - extractor: Some(extractors::zip::zip_extractor()), - }); - - // Intel PCH ROM - binary_signatures.push(signatures::common::Signature { - name: "pchrom".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::pchrom::pch_rom_magic(), - parser: signatures::pchrom::pch_rom_parser, - description: signatures::pchrom::DESCRIPTION.to_string(), - extractor: Some(extractors::uefi::uefi_extractor()), - }); - - // UEFI PI volume - binary_signatures.push(signatures::common::Signature { - name: "uefi_pi_volume".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::uefi::uefi_volume_magic(), - parser: signatures::uefi::uefi_volume_parser, - description: signatures::uefi::VOLUME_DESCRIPTION.to_string(), - extractor: Some(extractors::uefi::uefi_extractor()), - }); - - // UEFI capsule image - binary_signatures.push(signatures::common::Signature { - name: "uefi_capsule".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::uefi::uefi_capsule_magic(), - parser: signatures::uefi::uefi_capsule_parser, - description: signatures::uefi::CAPSULE_DESCRIPTION.to_string(), - extractor: Some(extractors::uefi::uefi_extractor()), - }); - - // PDF document - binary_signatures.push(signatures::common::Signature { - name: "pdf".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::pdf::pdf_magic(), - parser: signatures::pdf::pdf_parser, - description: signatures::pdf::DESCRIPTION.to_string(), - extractor: None, - }); - - // ELF - binary_signatures.push(signatures::common::Signature { - name: "elf".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::elf::elf_magic(), - parser: signatures::elf::elf_parser, - description: signatures::elf::DESCRIPTION.to_string(), - extractor: None, - }); - - // CramFS - binary_signatures.push(signatures::common::Signature { - name: "cramfs".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::cramfs::cramfs_magic(), - parser: signatures::cramfs::cramfs_parser, - description: signatures::cramfs::DESCRIPTION.to_string(), - extractor: Some(extractors::sevenzip::sevenzip_extractor()), - }); - - // QNX IFS - // TODO: The signature and extractor are untested. Need a sample IFS image. - binary_signatures.push(signatures::common::Signature { - name: "qnx_ifs".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::qnx::qnx_ifs_magic(), - parser: signatures::qnx::qnx_ifs_parser, - description: signatures::qnx::IFS_DESCRIPTION.to_string(), - extractor: Some(extractors::dumpifs::dumpifs_extractor()), - }); - - // RomFS - binary_signatures.push(signatures::common::Signature { - name: "romfs".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::romfs::romfs_magic(), - parser: signatures::romfs::romfs_parser, - description: signatures::romfs::DESCRIPTION.to_string(), - extractor: Some(extractors::romfs::romfs_extractor()), - }); - - // EXT - binary_signatures.push(signatures::common::Signature { - name: "ext".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::ext::ext_magic(), - parser: signatures::ext::ext_parser, - description: signatures::ext::DESCRIPTION.to_string(), - extractor: Some(extractors::tsk::tsk_extractor()), - }); - - // CAB archive - binary_signatures.push(signatures::common::Signature { - name: "cab".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::cab::cab_magic(), - parser: signatures::cab::cab_parser, - description: signatures::cab::DESCRIPTION.to_string(), - extractor: Some(extractors::cab::cab_extractor()), - }); - - // JFFS2 - binary_signatures.push(signatures::common::Signature { - name: "jffs2".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::jffs2::jffs2_magic(), - parser: signatures::jffs2::jffs2_parser, - description: signatures::jffs2::DESCRIPTION.to_string(), - extractor: Some(extractors::jffs2::jffs2_extractor()), - }); - - // YAFFS - binary_signatures.push(signatures::common::Signature { - name: "yaffs".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::yaffs::yaffs_magic(), - parser: signatures::yaffs::yaffs_parser, - description: signatures::yaffs::DESCRIPTION.to_string(), - extractor: Some(extractors::yaffs2::yaffs2_extractor()), - }); - - // lz4 - binary_signatures.push(signatures::common::Signature { - name: "lz4".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::lz4::lz4_magic(), - parser: signatures::lz4::lz4_parser, - description: signatures::lz4::DESCRIPTION.to_string(), - extractor: Some(extractors::lz4::lz4_extractor()), - }); - - // lzop - binary_signatures.push(signatures::common::Signature { - name: "lzop".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::lzop::lzop_magic(), - parser: signatures::lzop::lzop_parser, - description: signatures::lzop::DESCRIPTION.to_string(), - extractor: Some(extractors::lzop::lzop_extractor()), - }); - - // lzop - binary_signatures.push(signatures::common::Signature { - name: "pe".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::pe::pe_magic(), - parser: signatures::pe::pe_parser, - description: signatures::pe::DESCRIPTION.to_string(), - extractor: None, - }); - - // zlib - binary_signatures.push(signatures::common::Signature { - name: "zlib".to_string(), - // The magic bytes for this signature are only 2 bytes, only match on the beginning of a file - short: true, - magic_offset: 0, - always_display: false, - magic: signatures::zlib::zlib_magic(), - parser: signatures::zlib::zlib_parser, - description: signatures::zlib::DESCRIPTION.to_string(), - extractor: Some(extractors::zlib::zlib_extractor()), - }); - - // gpg signed data - binary_signatures.push(signatures::common::Signature { - name: "gpg_signed".to_string(), - // The magic bytes for this signature are only 2 bytes, only match on the beginning of a file - short: true, - magic_offset: 0, - always_display: false, - magic: signatures::gpg::gpg_signed_magic(), - parser: signatures::gpg::gpg_signed_parser, - description: signatures::gpg::GPG_SIGNED_DESCRIPTION.to_string(), - extractor: Some(extractors::zlib::zlib_extractor()), - }); - - // pem certificates - binary_signatures.push(signatures::common::Signature { - name: "pem_certificate".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::pem::pem_certificate_magic(), - parser: signatures::pem::pem_parser, - description: signatures::pem::PEM_CERTIFICATE_DESCRIPTION.to_string(), - extractor: Some(extractors::pem::pem_certificate_extractor()), - }); - - // pem public keys - binary_signatures.push(signatures::common::Signature { - name: "pem_public_key".to_string(), - short: false, - magic_offset: 0, - always_display: true, - magic: signatures::pem::pem_public_key_magic(), - parser: signatures::pem::pem_parser, - description: signatures::pem::PEM_PUBLIC_KEY_DESCRIPTION.to_string(), - extractor: Some(extractors::pem::pem_key_extractor()), - }); - - // pem private keys - binary_signatures.push(signatures::common::Signature { - name: "pem_private_key".to_string(), - short: false, - magic_offset: 0, - always_display: true, - magic: signatures::pem::pem_private_key_magic(), - parser: signatures::pem::pem_parser, - description: signatures::pem::PEM_PRIVATE_KEY_DESCRIPTION.to_string(), - extractor: Some(extractors::pem::pem_key_extractor()), - }); - - // netgear chk - binary_signatures.push(signatures::common::Signature { - name: "chk".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::chk::chk_magic(), - parser: signatures::chk::chk_parser, - description: signatures::chk::DESCRIPTION.to_string(), - extractor: None, - }); - - // trx - binary_signatures.push(signatures::common::Signature { - name: "trx".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::trx::trx_magic(), - parser: signatures::trx::trx_parser, - description: signatures::trx::DESCRIPTION.to_string(), - extractor: Some(extractors::trx::trx_extractor()), - }); - - // Motorola S-record - binary_signatures.push(signatures::common::Signature { - name: "srecord".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::srec::srec_magic(), - parser: signatures::srec::srec_parser, - description: signatures::srec::SREC_DESCRIPTION.to_string(), - extractor: Some(extractors::srec::srec_extractor()), - }); - - // Motorola S-record (generic) - binary_signatures.push(signatures::common::Signature { - name: "srecord_generic".to_string(), - short: true, - magic_offset: 0, - always_display: false, - magic: signatures::srec::srec_short_magic(), - parser: signatures::srec::srec_parser, - description: signatures::srec::SREC_SHORT_DESCRIPTION.to_string(), - extractor: Some(extractors::srec::srec_extractor()), - }); - - // Android sparse - binary_signatures.push(signatures::common::Signature { - name: "android_sparse".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::androidsparse::android_sparse_magic(), - parser: signatures::androidsparse::android_sparse_parser, - description: signatures::androidsparse::DESCRIPTION.to_string(), - extractor: Some(extractors::androidsparse::android_sparse_extractor()), - }); - - // device tree blob - binary_signatures.push(signatures::common::Signature { - name: "dtb".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::dtb::dtb_magic(), - parser: signatures::dtb::dtb_parser, - description: signatures::dtb::DESCRIPTION.to_string(), - extractor: Some(extractors::dtb::dtb_extractor()), - }); - - // ubi - binary_signatures.push(signatures::common::Signature { - name: "ubi".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::ubi::ubi_magic(), - parser: signatures::ubi::ubi_parser, - description: signatures::ubi::UBI_IMAGE_DESCRIPTION.to_string(), - extractor: Some(extractors::ubi::ubi_extractor()), - }); - - // ubifs - binary_signatures.push(signatures::common::Signature { - name: "ubifs".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::ubi::ubifs_magic(), - parser: signatures::ubi::ubifs_parser, - description: signatures::ubi::UBI_FS_DESCRIPTION.to_string(), - extractor: Some(extractors::ubi::ubifs_extractor()), - }); - - // cfe bootloader - binary_signatures.push(signatures::common::Signature { - name: "cfe".to_string(), - short: false, - magic_offset: 0, - always_display: true, - magic: signatures::cfe::cfe_magic(), - parser: signatures::cfe::cfe_parser, - description: signatures::cfe::DESCRIPTION.to_string(), - extractor: None, - }); - - // SEAMA firmware header - binary_signatures.push(signatures::common::Signature { - name: "seama".to_string(), - short: false, - magic_offset: 0, - always_display: true, - magic: signatures::seama::seama_magic(), - parser: signatures::seama::seama_parser, - description: signatures::seama::DESCRIPTION.to_string(), - extractor: None, - }); - - // compress'd - binary_signatures.push(signatures::common::Signature { - name: "compressd".to_string(), - short: true, - magic_offset: 0, - always_display: false, - magic: signatures::compressd::compressd_magic(), - parser: signatures::compressd::compressd_parser, - description: signatures::compressd::DESCRIPTION.to_string(), - extractor: Some(extractors::sevenzip::sevenzip_extractor()), - }); - - // rar archive - binary_signatures.push(signatures::common::Signature { - name: "rar".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::rar::rar_magic(), - parser: signatures::rar::rar_parser, - description: signatures::rar::DESCRIPTION.to_string(), - extractor: Some(extractors::rar::rar_extractor()), - }); - - // PNG image - binary_signatures.push(signatures::common::Signature { - name: "png".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::png::png_magic(), - parser: signatures::png::png_parser, - description: signatures::png::DESCRIPTION.to_string(), - extractor: Some(extractors::png::png_extractor()), - }); - - // JPEG image - binary_signatures.push(signatures::common::Signature { - name: "jpeg".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::jpeg::jpeg_magic(), - parser: signatures::jpeg::jpeg_parser, - description: signatures::jpeg::DESCRIPTION.to_string(), - extractor: Some(extractors::jpeg::jpeg_extractor()), - }); - - // arcadyan obfuscated lzma - binary_signatures.push(signatures::common::Signature { - name: "arcadyan".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::arcadyan::obfuscated_lzma_magic(), - parser: signatures::arcadyan::obfuscated_lzma_parser, - description: signatures::arcadyan::DESCRIPTION.to_string(), - extractor: Some(extractors::arcadyan::obfuscated_lzma_extractor()), - }); - - // copyright text - binary_signatures.push(signatures::common::Signature { - name: "copyright".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::copyright::copyright_magic(), - parser: signatures::copyright::copyright_parser, - description: signatures::copyright::DESCRIPTION.to_string(), - extractor: None, - }); - - // WIND kernel version - binary_signatures.push(signatures::common::Signature { - name: "wind_kernel".to_string(), - short: false, - magic_offset: 0, - always_display: true, - magic: signatures::vxworks::wind_kernel_magic(), - parser: signatures::vxworks::wind_kernel_parser, - description: signatures::vxworks::WIND_KERNEL_DESCRIPTION.to_string(), - extractor: None, - }); - - // vxworks symbol table - binary_signatures.push(signatures::common::Signature { - name: "vxworks_symtab".to_string(), - short: false, - magic_offset: 0, - always_display: true, - magic: signatures::vxworks::symbol_table_magic(), - parser: signatures::vxworks::symbol_table_parser, - description: signatures::vxworks::SYMTAB_DESCRIPTION.to_string(), - extractor: Some(extractors::vxworks::vxworks_symtab_extractor()), - }); - - // ecos mips exception handler - binary_signatures.push(signatures::common::Signature { - name: "ecos".to_string(), - short: false, - magic_offset: 0, - always_display: true, - magic: signatures::ecos::exception_handler_magic(), - parser: signatures::ecos::exception_handler_parser, - description: signatures::ecos::EXCEPTION_HANDLER_DESCRIPTION.to_string(), - extractor: None, - }); - - // dmg - binary_signatures.push(signatures::common::Signature { - name: "dmg".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::dmg::dmg_magic(), - parser: signatures::dmg::dmg_parser, - description: signatures::dmg::DESCRIPTION.to_string(), - extractor: Some(extractors::dmg::dmg_extractor()), - }); - - // riff - binary_signatures.push(signatures::common::Signature { - name: "riff".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::riff::riff_magic(), - parser: signatures::riff::riff_parser, - description: signatures::riff::DESCRIPTION.to_string(), - extractor: Some(extractors::riff::riff_extractor()), - }); - - // openssl - binary_signatures.push(signatures::common::Signature { - name: "openssl".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::openssl::openssl_crypt_magic(), - parser: signatures::openssl::openssl_crypt_parser, - description: signatures::openssl::DESCRIPTION.to_string(), - extractor: None, - }); - - // lzfse - binary_signatures.push(signatures::common::Signature { - name: "lzfse".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::lzfse::lzfse_magic(), - parser: signatures::lzfse::lzfse_parser, - description: signatures::lzfse::DESCRIPTION.to_string(), - extractor: Some(extractors::lzfse::lzfse_extractor()), - }); - - // MBR - binary_signatures.push(signatures::common::Signature { - name: "mbr".to_string(), - short: true, - magic_offset: signatures::mbr::MAGIC_OFFSET, - always_display: true, - magic: signatures::mbr::mbr_magic(), - parser: signatures::mbr::mbr_parser, - description: signatures::mbr::DESCRIPTION.to_string(), - extractor: Some(extractors::mbr::mbr_extractor()), - }); - - // tp-link - binary_signatures.push(signatures::common::Signature { - name: "tplink".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::tplink::tplink_magic(), - parser: signatures::tplink::tplink_parser, - description: signatures::tplink::DESCRIPTION.to_string(), - extractor: None, - }); - - // HP PJL - binary_signatures.push(signatures::common::Signature { - name: "pjl".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::pjl::pjl_magic(), - parser: signatures::pjl::pjl_parser, - description: signatures::pjl::DESCRIPTION.to_string(), - extractor: None, - }); - - // JBOOT ARM firmware image - binary_signatures.push(signatures::common::Signature { - name: "jboot_arm".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::jboot::jboot_arm_magic(), - parser: signatures::jboot::jboot_arm_parser, - description: signatures::jboot::JBOOT_ARM_DESCRIPTION.to_string(), - extractor: None, - }); - - // JBOOT STAG header - binary_signatures.push(signatures::common::Signature { - name: "jboot_stag".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::jboot::jboot_stag_magic(), - parser: signatures::jboot::jboot_stag_parser, - description: signatures::jboot::JBOOT_STAG_DESCRIPTION.to_string(), - extractor: None, - }); - - // JBOOT SCH2 header - binary_signatures.push(signatures::common::Signature { - name: "jboot_sch2".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::jboot::jboot_sch2_magic(), - parser: signatures::jboot::jboot_sch2_parser, - description: signatures::jboot::JBOOT_SCH2_DESCRIPTION.to_string(), - extractor: Some(extractors::jboot::sch2_extractor()), - }); - - // pcap-ng - binary_signatures.push(signatures::common::Signature { - name: "pcapng".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::pcap::pcapng_magic(), - parser: signatures::pcap::pcapng_parser, - description: signatures::pcap::PCAPNG_DESCRIPTION.to_string(), - extractor: Some(extractors::pcap::pcapng_extractor()), - }); - - // RSA encrypted data - binary_signatures.push(signatures::common::Signature { - name: "rsa".to_string(), - short: false, - magic_offset: 0, - always_display: true, - magic: signatures::rsa::rsa_magic(), - parser: signatures::rsa::rsa_parser, - description: signatures::rsa::DESCRIPTION.to_string(), - extractor: None, - }); - - // GIF image - binary_signatures.push(signatures::common::Signature { - name: "gif".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::gif::gif_magic(), - parser: signatures::gif::gif_parser, - description: signatures::gif::DESCRIPTION.to_string(), - extractor: Some(extractors::gif::gif_extractor()), - }); - - // SVG image - binary_signatures.push(signatures::common::Signature { - name: "svg".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::svg::svg_magic(), - parser: signatures::svg::svg_parser, - description: signatures::svg::DESCRIPTION.to_string(), - extractor: Some(extractors::svg::svg_extractor()), - }); - - // Linux ARM64 boot image - binary_signatures.push(signatures::common::Signature { - name: "linux_arm64_boot_image".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::linux::linux_arm64_boot_image_magic(), - parser: signatures::linux::linux_arm64_boot_image_parser, - description: signatures::linux::LINUX_ARM64_BOOT_IMAGE_DESCRIPTION.to_string(), - extractor: None, - }); - - // FAT - binary_signatures.push(signatures::common::Signature { - name: "fat".to_string(), - short: true, - magic_offset: signatures::fat::MAGIC_OFFSET, - always_display: false, - magic: signatures::fat::fat_magic(), - parser: signatures::fat::fat_parser, - description: signatures::fat::DESCRIPTION.to_string(), - extractor: Some(extractors::tsk::tsk_extractor()), - }); - - // EFI GPT - binary_signatures.push(signatures::common::Signature { - name: "efigpt".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::efigpt::efigpt_magic(), - parser: signatures::efigpt::efigpt_parser, - description: signatures::efigpt::DESCRIPTION.to_string(), - extractor: Some(extractors::sevenzip::sevenzip_extractor()), - }); - - // RTK firmware header - binary_signatures.push(signatures::common::Signature { - name: "rtk".to_string(), - short: true, - magic_offset: 0, - always_display: false, - magic: signatures::rtk::rtk_magic(), - parser: signatures::rtk::rtk_parser, - description: signatures::rtk::DESCRIPTION.to_string(), - extractor: None, - }); - - // AES S-Box - binary_signatures.push(signatures::common::Signature { - name: "aes_sbox".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::aes::aes_sbox_magic(), - parser: signatures::aes::aes_sbox_parser, - description: signatures::aes::DESCRIPTION.to_string(), - extractor: None, - }); - - // LUKS - binary_signatures.push(signatures::common::Signature { - name: "luks".to_string(), - short: false, - magic_offset: 0, - always_display: false, - magic: signatures::luks::luks_magic(), - parser: signatures::luks::luks_parser, - description: signatures::luks::DESCRIPTION.to_string(), - extractor: None, - }); - - return binary_signatures; + let binary_signatures: Vec = vec![ + // gzip + signatures::common::Signature { + name: "gzip".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::gzip::gzip_magic(), + parser: signatures::gzip::gzip_parser, + description: signatures::gzip::DESCRIPTION.to_string(), + extractor: Some(extractors::gzip::gzip_extractor()), + }, + // .deb + signatures::common::Signature { + name: "deb".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::deb::deb_magic(), + parser: signatures::deb::deb_parser, + description: signatures::deb::DESCRIPTION.to_string(), + extractor: None, + }, + // 7-zip + signatures::common::Signature { + name: "7zip".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::sevenzip::sevenzip_magic(), + parser: signatures::sevenzip::sevenzip_parser, + description: signatures::sevenzip::DESCRIPTION.to_string(), + extractor: Some(extractors::sevenzip::sevenzip_extractor()), + }, + // xz + signatures::common::Signature { + name: "xz".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::xz::xz_magic(), + parser: signatures::xz::xz_parser, + description: signatures::xz::DESCRIPTION.to_string(), + extractor: Some(extractors::lzma::lzma_extractor()), + }, + // tarball + signatures::common::Signature { + name: "tarball".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::tarball::tarball_magic(), + parser: signatures::tarball::tarball_parser, + description: signatures::tarball::DESCRIPTION.to_string(), + extractor: Some(extractors::tarball::tarball_extractor()), + }, + // squashfs + signatures::common::Signature { + name: "squashfs".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::squashfs::squashfs_magic(), + parser: signatures::squashfs::squashfs_parser, + description: signatures::squashfs::DESCRIPTION.to_string(), + extractor: Some(extractors::squashfs::squashfs_extractor()), + }, + // dlob + signatures::common::Signature { + name: "dlob".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::dlob::dlob_magic(), + parser: signatures::dlob::dlob_parser, + description: signatures::dlob::DESCRIPTION.to_string(), + extractor: None, + }, + // lzma + signatures::common::Signature { + name: "lzma".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::lzma::lzma_magic(), + parser: signatures::lzma::lzma_parser, + description: signatures::lzma::DESCRIPTION.to_string(), + //extractor: Some(extractors::sevenzip::sevenzip_extractor()), + extractor: Some(extractors::lzma::lzma_extractor()), + }, + // bzip2 + signatures::common::Signature { + name: "bzip2".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::bzip2::bzip2_magic(), + parser: signatures::bzip2::bzip2_parser, + description: signatures::bzip2::DESCRIPTION.to_string(), + extractor: Some(extractors::bzip2::bzip2_extractor()), + }, + // uimage + signatures::common::Signature { + name: "uimage".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::uimage::uimage_magic(), + parser: signatures::uimage::uimage_parser, + description: signatures::uimage::DESCRIPTION.to_string(), + extractor: Some(extractors::uimage::uimage_extractor()), + }, + // packimg header + signatures::common::Signature { + name: "packimg".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::packimg::packimg_magic(), + parser: signatures::packimg::packimg_parser, + description: signatures::packimg::DESCRIPTION.to_string(), + extractor: None, + }, + // crc32 constants + signatures::common::Signature { + name: "crc32".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::hashes::crc32_magic(), + parser: signatures::hashes::crc32_parser, + description: signatures::hashes::CRC32_DESCRIPTION.to_string(), + extractor: None, + }, + // sha256 constants + signatures::common::Signature { + name: "sha256".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::hashes::sha256_magic(), + parser: signatures::hashes::sha256_parser, + description: signatures::hashes::SHA256_DESCRIPTION.to_string(), + extractor: None, + }, + // cpio + signatures::common::Signature { + name: "cpio".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::cpio::cpio_magic(), + parser: signatures::cpio::cpio_parser, + description: signatures::cpio::DESCRIPTION.to_string(), + extractor: Some(extractors::sevenzip::sevenzip_extractor()), + }, + // iso9660 primary volume + signatures::common::Signature { + name: "iso9660".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::iso9660::iso_magic(), + parser: signatures::iso9660::iso_parser, + description: signatures::iso9660::DESCRIPTION.to_string(), + extractor: Some(extractors::tsk::tsk_extractor()), + }, + // linux kernel + signatures::common::Signature { + name: "linux_kernel".to_string(), + short: false, + magic_offset: 0, + always_display: true, + magic: signatures::linux::linux_kernel_version_magic(), + parser: signatures::linux::linux_kernel_version_parser, + description: signatures::linux::LINUX_KERNEL_VERSION_DESCRIPTION.to_string(), + extractor: Some(extractors::linux::linux_kernel_extractor()), + }, + // linux boot image + signatures::common::Signature { + name: "linux_boot_image".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::linux::linux_boot_image_magic(), + parser: signatures::linux::linux_boot_image_parser, + description: signatures::linux::LINUX_BOOT_IMAGE_DESCRIPTION.to_string(), + extractor: None, + }, + // zstd + signatures::common::Signature { + name: "zstd".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::zstd::zstd_magic(), + parser: signatures::zstd::zstd_parser, + description: signatures::zstd::DESCRIPTION.to_string(), + extractor: Some(extractors::zstd::zstd_extractor()), + }, + // zip + signatures::common::Signature { + name: "zip".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::zip::zip_magic(), + parser: signatures::zip::zip_parser, + description: signatures::zip::DESCRIPTION.to_string(), + extractor: Some(extractors::zip::zip_extractor()), + }, + // Intel PCH ROM + signatures::common::Signature { + name: "pchrom".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::pchrom::pch_rom_magic(), + parser: signatures::pchrom::pch_rom_parser, + description: signatures::pchrom::DESCRIPTION.to_string(), + extractor: Some(extractors::uefi::uefi_extractor()), + }, + // UEFI PI volume + signatures::common::Signature { + name: "uefi_pi_volume".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::uefi::uefi_volume_magic(), + parser: signatures::uefi::uefi_volume_parser, + description: signatures::uefi::VOLUME_DESCRIPTION.to_string(), + extractor: Some(extractors::uefi::uefi_extractor()), + }, + // UEFI capsule image + signatures::common::Signature { + name: "uefi_capsule".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::uefi::uefi_capsule_magic(), + parser: signatures::uefi::uefi_capsule_parser, + description: signatures::uefi::CAPSULE_DESCRIPTION.to_string(), + extractor: Some(extractors::uefi::uefi_extractor()), + }, + // PDF document + signatures::common::Signature { + name: "pdf".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::pdf::pdf_magic(), + parser: signatures::pdf::pdf_parser, + description: signatures::pdf::DESCRIPTION.to_string(), + extractor: None, + }, + // ELF + signatures::common::Signature { + name: "elf".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::elf::elf_magic(), + parser: signatures::elf::elf_parser, + description: signatures::elf::DESCRIPTION.to_string(), + extractor: None, + }, + // CramFS + signatures::common::Signature { + name: "cramfs".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::cramfs::cramfs_magic(), + parser: signatures::cramfs::cramfs_parser, + description: signatures::cramfs::DESCRIPTION.to_string(), + extractor: Some(extractors::sevenzip::sevenzip_extractor()), + }, + // QNX IFS + // TODO: The signature and extractor are untested. Need a sample IFS image. + signatures::common::Signature { + name: "qnx_ifs".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::qnx::qnx_ifs_magic(), + parser: signatures::qnx::qnx_ifs_parser, + description: signatures::qnx::IFS_DESCRIPTION.to_string(), + extractor: Some(extractors::dumpifs::dumpifs_extractor()), + }, + // RomFS + signatures::common::Signature { + name: "romfs".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::romfs::romfs_magic(), + parser: signatures::romfs::romfs_parser, + description: signatures::romfs::DESCRIPTION.to_string(), + extractor: Some(extractors::romfs::romfs_extractor()), + }, + // EXT + signatures::common::Signature { + name: "ext".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::ext::ext_magic(), + parser: signatures::ext::ext_parser, + description: signatures::ext::DESCRIPTION.to_string(), + extractor: Some(extractors::tsk::tsk_extractor()), + }, + // CAB archive + signatures::common::Signature { + name: "cab".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::cab::cab_magic(), + parser: signatures::cab::cab_parser, + description: signatures::cab::DESCRIPTION.to_string(), + extractor: Some(extractors::cab::cab_extractor()), + }, + // JFFS2 + signatures::common::Signature { + name: "jffs2".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::jffs2::jffs2_magic(), + parser: signatures::jffs2::jffs2_parser, + description: signatures::jffs2::DESCRIPTION.to_string(), + extractor: Some(extractors::jffs2::jffs2_extractor()), + }, + // YAFFS + signatures::common::Signature { + name: "yaffs".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::yaffs::yaffs_magic(), + parser: signatures::yaffs::yaffs_parser, + description: signatures::yaffs::DESCRIPTION.to_string(), + extractor: Some(extractors::yaffs2::yaffs2_extractor()), + }, + // lz4 + signatures::common::Signature { + name: "lz4".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::lz4::lz4_magic(), + parser: signatures::lz4::lz4_parser, + description: signatures::lz4::DESCRIPTION.to_string(), + extractor: Some(extractors::lz4::lz4_extractor()), + }, + // lzop + signatures::common::Signature { + name: "lzop".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::lzop::lzop_magic(), + parser: signatures::lzop::lzop_parser, + description: signatures::lzop::DESCRIPTION.to_string(), + extractor: Some(extractors::lzop::lzop_extractor()), + }, + // lzop + signatures::common::Signature { + name: "pe".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::pe::pe_magic(), + parser: signatures::pe::pe_parser, + description: signatures::pe::DESCRIPTION.to_string(), + extractor: None, + }, + // zlib + signatures::common::Signature { + name: "zlib".to_string(), + // The magic bytes for this signature are only 2 bytes, only match on the beginning of a file + short: true, + magic_offset: 0, + always_display: false, + magic: signatures::zlib::zlib_magic(), + parser: signatures::zlib::zlib_parser, + description: signatures::zlib::DESCRIPTION.to_string(), + extractor: Some(extractors::zlib::zlib_extractor()), + }, + // gpg signed data + signatures::common::Signature { + name: "gpg_signed".to_string(), + // The magic bytes for this signature are only 2 bytes, only match on the beginning of a file + short: true, + magic_offset: 0, + always_display: false, + magic: signatures::gpg::gpg_signed_magic(), + parser: signatures::gpg::gpg_signed_parser, + description: signatures::gpg::GPG_SIGNED_DESCRIPTION.to_string(), + extractor: Some(extractors::zlib::zlib_extractor()), + }, + // pem certificates + signatures::common::Signature { + name: "pem_certificate".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::pem::pem_certificate_magic(), + parser: signatures::pem::pem_parser, + description: signatures::pem::PEM_CERTIFICATE_DESCRIPTION.to_string(), + extractor: Some(extractors::pem::pem_certificate_extractor()), + }, + // pem public keys + signatures::common::Signature { + name: "pem_public_key".to_string(), + short: false, + magic_offset: 0, + always_display: true, + magic: signatures::pem::pem_public_key_magic(), + parser: signatures::pem::pem_parser, + description: signatures::pem::PEM_PUBLIC_KEY_DESCRIPTION.to_string(), + extractor: Some(extractors::pem::pem_key_extractor()), + }, + // pem private keys + signatures::common::Signature { + name: "pem_private_key".to_string(), + short: false, + magic_offset: 0, + always_display: true, + magic: signatures::pem::pem_private_key_magic(), + parser: signatures::pem::pem_parser, + description: signatures::pem::PEM_PRIVATE_KEY_DESCRIPTION.to_string(), + extractor: Some(extractors::pem::pem_key_extractor()), + }, + // netgear chk + signatures::common::Signature { + name: "chk".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::chk::chk_magic(), + parser: signatures::chk::chk_parser, + description: signatures::chk::DESCRIPTION.to_string(), + extractor: None, + }, + // trx + signatures::common::Signature { + name: "trx".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::trx::trx_magic(), + parser: signatures::trx::trx_parser, + description: signatures::trx::DESCRIPTION.to_string(), + extractor: Some(extractors::trx::trx_extractor()), + }, + // Motorola S-record + signatures::common::Signature { + name: "srecord".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::srec::srec_magic(), + parser: signatures::srec::srec_parser, + description: signatures::srec::SREC_DESCRIPTION.to_string(), + extractor: Some(extractors::srec::srec_extractor()), + }, + // Motorola S-record (generic) + signatures::common::Signature { + name: "srecord_generic".to_string(), + short: true, + magic_offset: 0, + always_display: false, + magic: signatures::srec::srec_short_magic(), + parser: signatures::srec::srec_parser, + description: signatures::srec::SREC_SHORT_DESCRIPTION.to_string(), + extractor: Some(extractors::srec::srec_extractor()), + }, + // Android sparse + signatures::common::Signature { + name: "android_sparse".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::androidsparse::android_sparse_magic(), + parser: signatures::androidsparse::android_sparse_parser, + description: signatures::androidsparse::DESCRIPTION.to_string(), + extractor: Some(extractors::androidsparse::android_sparse_extractor()), + }, + // device tree blob + signatures::common::Signature { + name: "dtb".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::dtb::dtb_magic(), + parser: signatures::dtb::dtb_parser, + description: signatures::dtb::DESCRIPTION.to_string(), + extractor: Some(extractors::dtb::dtb_extractor()), + }, + // ubi + signatures::common::Signature { + name: "ubi".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::ubi::ubi_magic(), + parser: signatures::ubi::ubi_parser, + description: signatures::ubi::UBI_IMAGE_DESCRIPTION.to_string(), + extractor: Some(extractors::ubi::ubi_extractor()), + }, + // ubifs + signatures::common::Signature { + name: "ubifs".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::ubi::ubifs_magic(), + parser: signatures::ubi::ubifs_parser, + description: signatures::ubi::UBI_FS_DESCRIPTION.to_string(), + extractor: Some(extractors::ubi::ubifs_extractor()), + }, + // cfe bootloader + signatures::common::Signature { + name: "cfe".to_string(), + short: false, + magic_offset: 0, + always_display: true, + magic: signatures::cfe::cfe_magic(), + parser: signatures::cfe::cfe_parser, + description: signatures::cfe::DESCRIPTION.to_string(), + extractor: None, + }, + // SEAMA firmware header + signatures::common::Signature { + name: "seama".to_string(), + short: false, + magic_offset: 0, + always_display: true, + magic: signatures::seama::seama_magic(), + parser: signatures::seama::seama_parser, + description: signatures::seama::DESCRIPTION.to_string(), + extractor: None, + }, + // compress'd + signatures::common::Signature { + name: "compressd".to_string(), + short: true, + magic_offset: 0, + always_display: false, + magic: signatures::compressd::compressd_magic(), + parser: signatures::compressd::compressd_parser, + description: signatures::compressd::DESCRIPTION.to_string(), + extractor: Some(extractors::sevenzip::sevenzip_extractor()), + }, + // rar archive + signatures::common::Signature { + name: "rar".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::rar::rar_magic(), + parser: signatures::rar::rar_parser, + description: signatures::rar::DESCRIPTION.to_string(), + extractor: Some(extractors::rar::rar_extractor()), + }, + // PNG image + signatures::common::Signature { + name: "png".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::png::png_magic(), + parser: signatures::png::png_parser, + description: signatures::png::DESCRIPTION.to_string(), + extractor: Some(extractors::png::png_extractor()), + }, + // JPEG image + signatures::common::Signature { + name: "jpeg".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::jpeg::jpeg_magic(), + parser: signatures::jpeg::jpeg_parser, + description: signatures::jpeg::DESCRIPTION.to_string(), + extractor: Some(extractors::jpeg::jpeg_extractor()), + }, + // arcadyan obfuscated lzma + signatures::common::Signature { + name: "arcadyan".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::arcadyan::obfuscated_lzma_magic(), + parser: signatures::arcadyan::obfuscated_lzma_parser, + description: signatures::arcadyan::DESCRIPTION.to_string(), + extractor: Some(extractors::arcadyan::obfuscated_lzma_extractor()), + }, + // copyright text + signatures::common::Signature { + name: "copyright".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::copyright::copyright_magic(), + parser: signatures::copyright::copyright_parser, + description: signatures::copyright::DESCRIPTION.to_string(), + extractor: None, + }, + // WIND kernel version + signatures::common::Signature { + name: "wind_kernel".to_string(), + short: false, + magic_offset: 0, + always_display: true, + magic: signatures::vxworks::wind_kernel_magic(), + parser: signatures::vxworks::wind_kernel_parser, + description: signatures::vxworks::WIND_KERNEL_DESCRIPTION.to_string(), + extractor: None, + }, + // vxworks symbol table + signatures::common::Signature { + name: "vxworks_symtab".to_string(), + short: false, + magic_offset: 0, + always_display: true, + magic: signatures::vxworks::symbol_table_magic(), + parser: signatures::vxworks::symbol_table_parser, + description: signatures::vxworks::SYMTAB_DESCRIPTION.to_string(), + extractor: Some(extractors::vxworks::vxworks_symtab_extractor()), + }, + // ecos mips exception handler + signatures::common::Signature { + name: "ecos".to_string(), + short: false, + magic_offset: 0, + always_display: true, + magic: signatures::ecos::exception_handler_magic(), + parser: signatures::ecos::exception_handler_parser, + description: signatures::ecos::EXCEPTION_HANDLER_DESCRIPTION.to_string(), + extractor: None, + }, + // dmg + signatures::common::Signature { + name: "dmg".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::dmg::dmg_magic(), + parser: signatures::dmg::dmg_parser, + description: signatures::dmg::DESCRIPTION.to_string(), + extractor: Some(extractors::dmg::dmg_extractor()), + }, + // riff + signatures::common::Signature { + name: "riff".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::riff::riff_magic(), + parser: signatures::riff::riff_parser, + description: signatures::riff::DESCRIPTION.to_string(), + extractor: Some(extractors::riff::riff_extractor()), + }, + // openssl + signatures::common::Signature { + name: "openssl".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::openssl::openssl_crypt_magic(), + parser: signatures::openssl::openssl_crypt_parser, + description: signatures::openssl::DESCRIPTION.to_string(), + extractor: None, + }, + // lzfse + signatures::common::Signature { + name: "lzfse".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::lzfse::lzfse_magic(), + parser: signatures::lzfse::lzfse_parser, + description: signatures::lzfse::DESCRIPTION.to_string(), + extractor: Some(extractors::lzfse::lzfse_extractor()), + }, + // MBR + signatures::common::Signature { + name: "mbr".to_string(), + short: true, + magic_offset: signatures::mbr::MAGIC_OFFSET, + always_display: true, + magic: signatures::mbr::mbr_magic(), + parser: signatures::mbr::mbr_parser, + description: signatures::mbr::DESCRIPTION.to_string(), + extractor: Some(extractors::mbr::mbr_extractor()), + }, + // tp-link + signatures::common::Signature { + name: "tplink".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::tplink::tplink_magic(), + parser: signatures::tplink::tplink_parser, + description: signatures::tplink::DESCRIPTION.to_string(), + extractor: None, + }, + // HP PJL + signatures::common::Signature { + name: "pjl".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::pjl::pjl_magic(), + parser: signatures::pjl::pjl_parser, + description: signatures::pjl::DESCRIPTION.to_string(), + extractor: None, + }, + // JBOOT ARM firmware image + signatures::common::Signature { + name: "jboot_arm".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::jboot::jboot_arm_magic(), + parser: signatures::jboot::jboot_arm_parser, + description: signatures::jboot::JBOOT_ARM_DESCRIPTION.to_string(), + extractor: None, + }, + // JBOOT STAG header + signatures::common::Signature { + name: "jboot_stag".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::jboot::jboot_stag_magic(), + parser: signatures::jboot::jboot_stag_parser, + description: signatures::jboot::JBOOT_STAG_DESCRIPTION.to_string(), + extractor: None, + }, + // JBOOT SCH2 header + signatures::common::Signature { + name: "jboot_sch2".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::jboot::jboot_sch2_magic(), + parser: signatures::jboot::jboot_sch2_parser, + description: signatures::jboot::JBOOT_SCH2_DESCRIPTION.to_string(), + extractor: Some(extractors::jboot::sch2_extractor()), + }, + // pcap-ng + signatures::common::Signature { + name: "pcapng".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::pcap::pcapng_magic(), + parser: signatures::pcap::pcapng_parser, + description: signatures::pcap::PCAPNG_DESCRIPTION.to_string(), + extractor: Some(extractors::pcap::pcapng_extractor()), + }, + // RSA encrypted data + signatures::common::Signature { + name: "rsa".to_string(), + short: false, + magic_offset: 0, + always_display: true, + magic: signatures::rsa::rsa_magic(), + parser: signatures::rsa::rsa_parser, + description: signatures::rsa::DESCRIPTION.to_string(), + extractor: None, + }, + // GIF image + signatures::common::Signature { + name: "gif".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::gif::gif_magic(), + parser: signatures::gif::gif_parser, + description: signatures::gif::DESCRIPTION.to_string(), + extractor: Some(extractors::gif::gif_extractor()), + }, + // SVG image + signatures::common::Signature { + name: "svg".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::svg::svg_magic(), + parser: signatures::svg::svg_parser, + description: signatures::svg::DESCRIPTION.to_string(), + extractor: Some(extractors::svg::svg_extractor()), + }, + // Linux ARM64 boot image + signatures::common::Signature { + name: "linux_arm64_boot_image".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::linux::linux_arm64_boot_image_magic(), + parser: signatures::linux::linux_arm64_boot_image_parser, + description: signatures::linux::LINUX_ARM64_BOOT_IMAGE_DESCRIPTION.to_string(), + extractor: None, + }, + // FAT + signatures::common::Signature { + name: "fat".to_string(), + short: true, + magic_offset: signatures::fat::MAGIC_OFFSET, + always_display: false, + magic: signatures::fat::fat_magic(), + parser: signatures::fat::fat_parser, + description: signatures::fat::DESCRIPTION.to_string(), + extractor: Some(extractors::tsk::tsk_extractor()), + }, + // EFI GPT + signatures::common::Signature { + name: "efigpt".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::efigpt::efigpt_magic(), + parser: signatures::efigpt::efigpt_parser, + description: signatures::efigpt::DESCRIPTION.to_string(), + extractor: Some(extractors::sevenzip::sevenzip_extractor()), + }, + // RTK firmware header + signatures::common::Signature { + name: "rtk".to_string(), + short: true, + magic_offset: 0, + always_display: false, + magic: signatures::rtk::rtk_magic(), + parser: signatures::rtk::rtk_parser, + description: signatures::rtk::DESCRIPTION.to_string(), + extractor: None, + }, + // AES S-Box + signatures::common::Signature { + name: "aes_sbox".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::aes::aes_sbox_magic(), + parser: signatures::aes::aes_sbox_parser, + description: signatures::aes::DESCRIPTION.to_string(), + extractor: None, + }, + // LUKS + signatures::common::Signature { + name: "luks".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::luks::luks_magic(), + parser: signatures::luks::luks_parser, + description: signatures::luks::DESCRIPTION.to_string(), + extractor: None, + }, + ]; + + binary_signatures } diff --git a/src/signatures/cpio.rs b/src/signatures/cpio.rs index 5b75a0c6c..f997bc4cb 100644 --- a/src/signatures/cpio.rs +++ b/src/signatures/cpio.rs @@ -42,7 +42,7 @@ pub fn cpio_parser(file_data: &[u8], offset: usize) -> Result { // Sanity check the magic bytes - if cpio_magic().contains(&cpio_header.magic) == false { + if !cpio_magic().contains(&cpio_header.magic) { break; } diff --git a/src/signatures/cramfs.rs b/src/signatures/cramfs.rs index 2ad4304c3..860433fe6 100644 --- a/src/signatures/cramfs.rs +++ b/src/signatures/cramfs.rs @@ -42,8 +42,12 @@ pub fn cramfs_parser(file_data: &[u8], offset: usize) -> Result = cramfs_image_data.to_vec(); // Null out the checksum field - for i in CRC_START_OFFSET..CRC_END_OFFSET { - cramfs_image[i] = 0; + for crc_byte in cramfs_image + .iter_mut() + .take(CRC_END_OFFSET) + .skip(CRC_START_OFFSET) + { + *crc_byte = 0; } // For displaying an error message in the description diff --git a/src/signatures/dmg.rs b/src/signatures/dmg.rs index ddece701c..6a30472e2 100644 --- a/src/signatures/dmg.rs +++ b/src/signatures/dmg.rs @@ -42,7 +42,7 @@ pub fn dmg_parser(file_data: &[u8], offset: usize) -> Result= dmg_footer.data_length { // Report the result @@ -80,5 +80,5 @@ fn find_xml_property_list(file_data: &[u8]) -> Option { } } - return None; + None } diff --git a/src/signatures/ecos.rs b/src/signatures/ecos.rs index 79d1649bf..ffff3cd2a 100644 --- a/src/signatures/ecos.rs +++ b/src/signatures/ecos.rs @@ -46,5 +46,5 @@ pub fn exception_handler_parser( } result.description = format!("{}, MIPS {} endian", result.description, endianness); - return Ok(result); + Ok(result) } diff --git a/src/signatures/gpg.rs b/src/signatures/gpg.rs index d76b88812..cfc355058 100644 --- a/src/signatures/gpg.rs +++ b/src/signatures/gpg.rs @@ -28,7 +28,7 @@ pub fn gpg_signed_parser( * GPG signed files are just zlib compressed files with the zlib magic bytes replaced with the GPG magic bytes. * Decompress the signed file; no output directory specified, dry run only. */ - let decompression_dry_run = zlib_decompress(&file_data, offset, None); + let decompression_dry_run = zlib_decompress(file_data, offset, None); // If the decompression dry run was a success, this signature is almost certianly valid if decompression_dry_run.success { diff --git a/src/signatures/gzip.rs b/src/signatures/gzip.rs index 0efdddf16..5433af3c8 100644 --- a/src/signatures/gzip.rs +++ b/src/signatures/gzip.rs @@ -30,7 +30,7 @@ pub fn gzip_parser(file_data: &[u8], offset: usize) -> Result 0 { + if !gzip_header.original_name.is_empty() { original_file_name_text = format!(" original file name: \"{}\",", gzip_header.original_name); } diff --git a/src/signatures/hashes.rs b/src/signatures/hashes.rs index fa3842208..fce138344 100644 --- a/src/signatures/hashes.rs +++ b/src/signatures/hashes.rs @@ -42,7 +42,7 @@ pub fn crc32_parser(file_data: &[u8], offset: usize) -> Result Result { @@ -58,7 +58,7 @@ pub fn sha256_parser(file_data: &[u8], offset: usize) -> Result>) -> Stri endianness = "big".to_string(); } - return endianness; + endianness } diff --git a/src/signatures/jffs2.rs b/src/signatures/jffs2.rs index 23167133a..d91698c77 100644 --- a/src/signatures/jffs2.rs +++ b/src/signatures/jffs2.rs @@ -111,5 +111,5 @@ fn roundup(num: usize) -> usize { let base: f64 = 4.0; let number: f64 = num as f64; let div: f64 = number / base; - return (base * div.ceil()) as usize; + (base * div.ceil()) as usize } diff --git a/src/signatures/linux.rs b/src/signatures/linux.rs index 96141f05d..178d3064c 100644 --- a/src/signatures/linux.rs +++ b/src/signatures/linux.rs @@ -177,5 +177,5 @@ fn has_linux_symbol_table(file_data: &[u8]) -> bool { } // There should be only one match - return match_count == 1; + match_count == 1 } diff --git a/src/signatures/lz4.rs b/src/signatures/lz4.rs index 5a0e79e30..34bd3c4aa 100644 --- a/src/signatures/lz4.rs +++ b/src/signatures/lz4.rs @@ -34,7 +34,7 @@ pub fn lz4_parser(file_data: &[u8], offset: usize) -> Result Result Result Result= ASCII_ZERO { + if (ASCII_ZERO..=ASCII_NINE).contains(&version_minor) { // Update the result description to include the version number result.description = format!( "{}, version 1.{}", @@ -50,7 +50,7 @@ pub fn pdf_parser(file_data: &[u8], offset: usize) -> Result Result Result Result { } // If we found some text between the delimiters, attempt to base64 decode it - if base64_string.len() > 0 { + if !base64_string.is_empty() { // PEM contents are base64 encoded, they should decode OK; if not, it's a false positive if let Ok(decoded_data) = BASE64_STANDARD.decode(&base64_string) { return Ok(decoded_data.len()); diff --git a/src/signatures/tarball.rs b/src/signatures/tarball.rs index 0cc140c26..1f019857c 100644 --- a/src/signatures/tarball.rs +++ b/src/signatures/tarball.rs @@ -107,7 +107,7 @@ fn header_checksum_is_valid(header_block: &[u8]) -> bool { if (TARBALL_CHECKSUM_START..TARBALL_CHECKSUM_END).contains(&i) { sum += 0x20; } else { - sum += (*header_byte as usize); + sum += *header_byte as usize; } } From 8a45fa923d597eef078bb44e57fda06777f2cc9a Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sun, 20 Oct 2024 15:52:28 -0400 Subject: [PATCH 005/131] Lint fixes in extractors --- src/extractors/androidsparse.rs | 29 +++----- src/extractors/arcadyan.rs | 10 +-- src/extractors/bzip2.rs | 8 +-- src/extractors/common.rs | 113 ++++++++++++++++---------------- src/extractors/gif.rs | 6 +- src/extractors/gzip.rs | 4 +- src/extractors/inflate.rs | 6 +- src/extractors/jboot.rs | 4 +- src/extractors/jpeg.rs | 6 +- src/extractors/linux.rs | 1 - src/extractors/lzma.rs | 8 +-- src/extractors/mbr.rs | 16 ++--- src/extractors/pcap.rs | 4 +- src/extractors/pem.rs | 14 ++-- src/extractors/png.rs | 8 +-- src/extractors/riff.rs | 13 ++-- src/extractors/romfs.rs | 35 ++++------ src/extractors/svg.rs | 4 +- src/extractors/trx.rs | 8 +-- src/extractors/uefi.rs | 1 - src/extractors/uimage.rs | 6 +- src/extractors/vxworks.rs | 15 +---- src/extractors/zlib.rs | 2 +- 23 files changed, 140 insertions(+), 181 deletions(-) diff --git a/src/extractors/androidsparse.rs b/src/extractors/androidsparse.rs index 9456bdbba..6f5ed166c 100644 --- a/src/extractors/androidsparse.rs +++ b/src/extractors/androidsparse.rs @@ -18,21 +18,10 @@ pub fn extract_android_sparse( ) -> ExtractionResult { const OUTFILE_NAME: &str = "unsparsed.img"; - let dry_run: bool; let mut result = ExtractionResult { ..Default::default() }; - // Check if this is a dry-run or a full extraction - match output_directory { - Some(_) => { - dry_run = false; - } - None => { - dry_run = true; - } - } - // Parse the sparse file header if let Ok(sparse_header) = androidsparse::parse_android_sparse_header(&file_data[offset..]) { let available_data: usize = file_data.len(); @@ -50,19 +39,19 @@ pub fn extract_android_sparse( Ok(chunk_header) => { // If not a dry run, extract the data from the next chunk - if dry_run == false { + if output_directory.is_some() { let chroot = Chroot::new(output_directory); let chunk_data_start: usize = next_chunk_offset + chunk_header.header_size; let chunk_data_end: usize = chunk_data_start + chunk_header.data_size; if let Some(chunk_data) = file_data.get(chunk_data_start..chunk_data_end) { - if extract_chunk( + if !extract_chunk( &sparse_header, &chunk_header, chunk_data, &OUTFILE_NAME.to_string(), &chroot, - ) == false + ) { break; } @@ -85,7 +74,7 @@ pub fn extract_android_sparse( } } - return result; + result } // Extract a sparse file chunk to disk @@ -96,9 +85,9 @@ fn extract_chunk( outfile: &String, chroot: &Chroot, ) -> bool { - if chunk_header.is_raw == true { + if chunk_header.is_raw { // Raw chunks are just data chunks stored verbatim - if chroot.append_to_file(outfile, chunk_data) == false { + if !chroot.append_to_file(outfile, chunk_data) { return false; } } else if chunk_header.is_fill { @@ -114,7 +103,7 @@ fn extract_chunk( } // Append fill block to file - if chroot.append_to_file(outfile, &fill_block) == false { + if !chroot.append_to_file(outfile, &fill_block) { return false; } } @@ -128,11 +117,11 @@ fn extract_chunk( // Write block_count NULL blocks to disk for _ in 0..chunk_header.block_count { - if chroot.append_to_file(outfile, &null_block) == false { + if !chroot.append_to_file(outfile, &null_block) { return false; } } } - return true; + true } diff --git a/src/extractors/arcadyan.rs b/src/extractors/arcadyan.rs index 6b5ceb5fe..bfb3067d0 100644 --- a/src/extractors/arcadyan.rs +++ b/src/extractors/arcadyan.rs @@ -35,7 +35,7 @@ pub fn extract_obfuscated_lzma( } } - return result; + result } fn arcadyan_deobfuscator(obfuscated_data: &[u8]) -> Vec { @@ -72,9 +72,9 @@ fn arcadyan_deobfuscator(obfuscated_data: &[u8]) -> Vec { deobfuscated_data.extend(p3); // Nibble swap each byte in what is now "block1" - for i in BLOCK1_START..BLOCK1_END { - deobfuscated_data[i] = - ((deobfuscated_data[i] & 0x0F) << 4) + ((deobfuscated_data[i] & 0xF0) >> 4); + for swapped_byte in deobfuscated_data.iter_mut().take(BLOCK1_END).skip(BLOCK1_START) { + *swapped_byte = + ((*swapped_byte & 0x0F) << 4) + ((*swapped_byte & 0xF0) >> 4); } let mut i: usize = BLOCK1_START; @@ -88,5 +88,5 @@ fn arcadyan_deobfuscator(obfuscated_data: &[u8]) -> Vec { i += 2; } - return deobfuscated_data; + deobfuscated_data } diff --git a/src/extractors/bzip2.rs b/src/extractors/bzip2.rs index 101c567bc..4ba9dc4ba 100644 --- a/src/extractors/bzip2.rs +++ b/src/extractors/bzip2.rs @@ -63,11 +63,11 @@ pub fn bzip2_decompressor( } // Decompressed a block of data, if extraction was requested write the decompressed block to the output file - if !output_directory.is_none() { + if output_directory.is_some() { let n: usize = (decompressor.total_out() as usize) - bytes_written; let chroot = Chroot::new(output_directory); - if chroot.append_to_file(OUTPUT_FILE_NAME, &decompressed_buffer[0..n]) == false + if !chroot.append_to_file(OUTPUT_FILE_NAME, &decompressed_buffer[0..n]) { // If writing data to file fails, break break; @@ -77,12 +77,12 @@ pub fn bzip2_decompressor( } // If everything has been processed successfully, we're done; break. - if result.success == true { + if result.success { break; } } } } - return result; + result } diff --git a/src/extractors/common.rs b/src/extractors/common.rs index 000a623d7..4e83f0c51 100644 --- a/src/extractors/common.rs +++ b/src/extractors/common.rs @@ -124,7 +124,7 @@ impl Chroot { } // Create the chroot directory if it does not exist - if path::Path::new(&chroot_instance.chroot_directory).exists() == false { + if !path::Path::new(&chroot_instance.chroot_directory).exists() { match fs::create_dir_all(&chroot_instance.chroot_directory) { Ok(_) => { debug!( @@ -141,7 +141,7 @@ impl Chroot { } } - return chroot_instance; + chroot_instance } /// Joins two paths, ensuring that the final path does not traverse outside of the chroot directory. @@ -176,7 +176,7 @@ impl Chroot { // If the joined path does not start with the chroot directory, // prepend the chroot directory to the final joined path. - if joined_path.starts_with(&self.chroot_directory) == false { + if !joined_path.starts_with(&self.chroot_directory) { joined_path = format!( "{}{}{}", self.chroot_directory, @@ -185,7 +185,7 @@ impl Chroot { ); } - return self.strip_double_slash(&joined_path); + self.strip_double_slash(&joined_path) } /// Given a file path, returns a sanitized path that is chrooted inside the specified chroot directory. @@ -203,7 +203,7 @@ impl Chroot { /// assert_eq!(path, "/tmp/foobar/test.txt"); /// ``` pub fn chrooted_path(&self, file_path: impl Into) -> String { - return self.safe_path_join(file_path, &"".to_string()); + self.safe_path_join(file_path, "".to_string()) } /// Creates a regular file in the chrooted directory and writes the provided data to it. @@ -226,7 +226,7 @@ impl Chroot { pub fn create_file(&self, file_path: impl Into, file_data: &[u8]) -> bool { let safe_file_path: String = self.chrooted_path(file_path); - if path::Path::new(&safe_file_path).exists() == false { + if !path::Path::new(&safe_file_path).exists() { match fs::write(safe_file_path.clone(), file_data) { Ok(_) => { return true; @@ -242,7 +242,7 @@ impl Chroot { ); } - return false; + false } /// Carve data and write it to a new file. @@ -280,7 +280,7 @@ impl Chroot { ); } - return retval; + retval } /// Creates a device file in the chroot directory. @@ -294,7 +294,7 @@ impl Chroot { minor: usize, ) -> bool { let device_file_contents: String = format!("{} {} {}", device_type, major, minor); - return self.create_file(file_path, &device_file_contents.clone().into_bytes()); + self.create_file(file_path, &device_file_contents.clone().into_bytes()) } /// Creates a character device file in the chroot directory. @@ -323,7 +323,7 @@ impl Chroot { major: usize, minor: usize, ) -> bool { - return self.create_device(file_path, "c", major, minor); + self.create_device(file_path, "c", major, minor) } /// Creates a block device file in the chroot directory. @@ -352,7 +352,7 @@ impl Chroot { major: usize, minor: usize, ) -> bool { - return self.create_device(file_path, "b", major, minor); + self.create_device(file_path, "b", major, minor) } /// Creates a fifo file in the chroot directory. @@ -374,7 +374,7 @@ impl Chroot { /// # std::fs::remove_dir_all("/tmp/foobar"); /// ``` pub fn create_fifo(&self, file_path: impl Into) -> bool { - return self.create_file(file_path, b"fifo"); + self.create_file(file_path, b"fifo") } /// Creates a socket file in the chroot directory. @@ -396,7 +396,7 @@ impl Chroot { /// # std::fs::remove_dir_all("/tmp/foobar"); /// ``` pub fn create_socket(&self, file_path: impl Into) -> bool { - return self.create_file(file_path, b"socket"); + self.create_file(file_path, b"socket") } /// Append the provided data to the specified file in the chroot directory. @@ -421,7 +421,7 @@ impl Chroot { pub fn append_to_file(&self, file_path: impl Into, data: &[u8]) -> bool { let safe_file_path: String = self.chrooted_path(file_path); - if self.is_symlink(&safe_file_path) == false { + if !self.is_symlink(&safe_file_path) { match fs::OpenOptions::new() .create(true) .append(true) @@ -446,7 +446,7 @@ impl Chroot { error!("Attempted to append data to a symlink: {}", safe_file_path); } - return false; + false } /// Creates a directory in the chroot directory. @@ -479,7 +479,7 @@ impl Chroot { } } - return false; + false } /// Set executable permissions on an existing file in the chroot directory. @@ -537,7 +537,7 @@ impl Chroot { } } - return false; + false } /// Creates a symbolic link in the chroot directory, named `symlink_path`, which points to `target_path`. @@ -580,20 +580,17 @@ impl Chroot { safe_target = self.chrooted_path(&target); safe_target_path = path::Path::new(&safe_target); } else { - // Else, the target path is relative to the symlink file's directory - let relative_dir: String; - // Get the symlink file's parent directory path - match safe_symlink_path.parent() { + let relative_dir: String = match safe_symlink_path.parent() { None => { // There is no parent, or parent is the root directory; assume the root directory - relative_dir = path::MAIN_SEPARATOR.to_string(); + path::MAIN_SEPARATOR.to_string() } Some(parent_dir) => { // Got the parent directory - relative_dir = parent_dir.display().to_string(); + parent_dir.display().to_string() } - } + }; // Join the target path with its relative directory, ensuring it does not traverse outside // the specified chroot directory @@ -603,16 +600,16 @@ impl Chroot { #[cfg(unix)] { - match unix::fs::symlink(&safe_target_path, &safe_symlink_path) { + match unix::fs::symlink(safe_target_path, safe_symlink_path) { Ok(_) => { - return true; + true } Err(e) => { error!( "Failed to create symlink from {} -> {}: {}", symlink, target, e ); - return false; + false } } } @@ -644,12 +641,12 @@ impl Chroot { return metadata.file_type().is_symlink(); } - return false; + false } /// Replace `//` with `/`. This is for asthetics only. - fn strip_double_slash(&self, path: &String) -> String { - let mut stripped_path = path.clone(); + fn strip_double_slash(&self, path: &str) -> String { + let mut stripped_path = path.to_owned(); let single_slash = path::MAIN_SEPARATOR.to_string(); let double_slash = format!("{}{}", single_slash, single_slash); @@ -657,17 +654,17 @@ impl Chroot { stripped_path = stripped_path.replace(&double_slash, &single_slash); } - return stripped_path; + stripped_path } /// Interprets a given path containing '..' directories. - fn sanitize_path(&self, file_path: &String, preserve_root_path_sep: bool) -> String { + fn sanitize_path(&self, file_path: &str, preserve_root_path_sep: bool) -> String { const DIR_TRAVERSAL: &str = ".."; let mut exclude_indicies: Vec = vec![]; let mut sanitized_path: String = "".to_string(); - if preserve_root_path_sep == true && file_path.starts_with(path::MAIN_SEPARATOR) { + if preserve_root_path_sep && file_path.starts_with(path::MAIN_SEPARATOR) { sanitized_path = path::MAIN_SEPARATOR.to_string(); } @@ -675,9 +672,9 @@ impl Chroot { let path_parts: Vec<&str> = file_path.split(path::MAIN_SEPARATOR).collect(); // Loop through each part of the file path - for i in 0..path_parts.len() { + for (i, path_part) in path_parts.iter().enumerate() { // If this part of the path is '..', don't include it in the final sanitized path - if path_parts[i] == DIR_TRAVERSAL { + if *path_part == DIR_TRAVERSAL { exclude_indicies.push(i); if i > 0 { // Walk backwards through the path parts until a non-excluded part is found, then mark that part for exclusion as well @@ -688,24 +685,24 @@ impl Chroot { exclude_indicies.push(j); } // If this part of the path is an empty string, don't include that either (happens if the original file path has '//' in it) - } else if path_parts[i].len() == 0 { + } else if path_part.is_empty() { exclude_indicies.push(i); } } // Concatenate each non-excluded part of the file path, with each part separated by '/' - for i in 0..path_parts.len() { - if exclude_indicies.contains(&i) == false { + for (i, path_part) in path_parts.iter().enumerate() { + if !exclude_indicies.contains(&i) { sanitized_path = format!( "{}{}{}", sanitized_path, path::MAIN_SEPARATOR, - path_parts[i] + path_part ); } } - return self.strip_double_slash(&sanitized_path); + self.strip_double_slash(&sanitized_path) } } @@ -733,12 +730,12 @@ pub fn get_extracted_files(directory: &String) -> Vec { } } - return regular_files; + regular_files } /// Executes an extractor for the provided SignatureResult. pub fn execute( - file_data: &Vec, + file_data: &[u8], file_path: &String, signature: &SignatureResult, extractor: &Option, @@ -820,8 +817,8 @@ pub fn execute( result.do_not_recurse = extractor_definition.do_not_recurse; // If the extractor reported success, make sure it extracted something other than just an empty file - if result.success == true { - if was_something_extracted(&result.output_directory) == false { + if result.success { + if !was_something_extracted(&result.output_directory) { result.success = false; warn!("Extractor exited successfully, but no data was extracted"); } @@ -830,7 +827,7 @@ pub fn execute( } // Clean up extractor's output directory if extraction failed - if result.success == false { + if !result.success { if let Err(e) = fs::remove_dir_all(&output_directory) { warn!( "Failed to clean up extraction directory {} after extraction failure: {}", @@ -840,12 +837,12 @@ pub fn execute( } } - return result; + result } /// Spawn an external extractor process. fn spawn( - file_data: &Vec, + file_data: &[u8], file_path: &String, output_directory: &String, signature: &SignatureResult, @@ -882,7 +879,7 @@ fn spawn( // If the entirety of the source file is this one file type, no need to carve a copy of it, just create a symlink if signature.offset == 0 && signature.size == file_data.len() { - if chroot.create_symlink(&carved_file, file_path) == false { + if !chroot.create_symlink(&carved_file, file_path) { return Err(std::io::Error::new( std::io::ErrorKind::Other, "Failed to create carved file symlink", @@ -890,7 +887,7 @@ fn spawn( } } else { // Copy file data to carved file path - if chroot.carve_file(&carved_file, file_data, signature.offset, signature.size) == false { + if !chroot.carve_file(&carved_file, file_data, signature.offset, signature.size) { return Err(std::io::Error::new( std::io::ErrorKind::Other, "Failed to carve data to disk", @@ -910,7 +907,7 @@ fn spawn( .args(&extractor.arguments) .stdout(process::Stdio::null()) .stderr(process::Stdio::null()) - .current_dir(&output_directory) + .current_dir(output_directory) .spawn() { Err(e) => { @@ -918,7 +915,7 @@ fn spawn( "Failed to execute command {}{:?}: {}", command, extractor.arguments, e ); - return Err(e); + Err(e) } Ok(child) => { @@ -929,7 +926,7 @@ fn spawn( exit_codes: extractor.exit_codes, }; - return Ok(proc_info); + Ok(proc_info) } } } @@ -945,7 +942,7 @@ fn proc_wait(mut worker_info: ProcInfo) -> Result { error!("Failed to retreive child process status: {}", e); - return Err(ExtractionError); + Err(ExtractionError) } // Child terminated with an exit status @@ -979,10 +976,10 @@ fn proc_wait(mut worker_info: ProcInfo) -> Result Result bool { } } - return false; + false } diff --git a/src/extractors/gif.rs b/src/extractors/gif.rs index 9b2c39377..d9a0253ec 100644 --- a/src/extractors/gif.rs +++ b/src/extractors/gif.rs @@ -35,7 +35,7 @@ pub fn extract_gif_image( result.success = true; // Do extraction, if requested - if let Some(_) = output_directory { + if output_directory.is_some() { let chroot = Chroot::new(output_directory); result.success = chroot.carve_file(OUTFILE_NAME, file_data, offset, result.size.unwrap()); @@ -44,7 +44,7 @@ pub fn extract_gif_image( } } - return result; + result } /// Returns the size of the GIF data that follows the GIF header @@ -93,5 +93,5 @@ fn get_gif_data_size(gif_data: &[u8]) -> Option { } // Something went wrong, failure - return None; + None } diff --git a/src/extractors/gzip.rs b/src/extractors/gzip.rs index 3e92de104..4ec01ecf5 100644 --- a/src/extractors/gzip.rs +++ b/src/extractors/gzip.rs @@ -27,7 +27,7 @@ pub fn gzip_decompress( } // Return failure - return ExtractionResult { + ExtractionResult { ..Default::default() - }; + } } diff --git a/src/extractors/inflate.rs b/src/extractors/inflate.rs index 3c3b18f9e..e9acda5db 100644 --- a/src/extractors/inflate.rs +++ b/src/extractors/inflate.rs @@ -50,9 +50,9 @@ pub fn inflate_decompressor( } Ok(n) => { // Decompressed a block of data, if extraction was requested write the decompressed block to the output file - if n > 0 && !output_directory.is_none() { + if n > 0 && output_directory.is_some() { let chroot = Chroot::new(output_directory); - if chroot.append_to_file(OUTPUT_FILE_NAME, &decompressed_buffer[0..n]) == false + if !chroot.append_to_file(OUTPUT_FILE_NAME, &decompressed_buffer[0..n]) { // If writing data to file fails, break break; @@ -74,5 +74,5 @@ pub fn inflate_decompressor( } } - return result; + result } diff --git a/src/extractors/jboot.rs b/src/extractors/jboot.rs index 3774138bd..148188ade 100644 --- a/src/extractors/jboot.rs +++ b/src/extractors/jboot.rs @@ -37,7 +37,7 @@ pub fn extract_jboot_sch2_kernel( result.size = Some(sch2_header.header_size + sch2_header.kernel_size); result.success = true; - if let Some(_) = output_directory { + if output_directory.is_some() { let chroot = Chroot::new(output_directory); result.success = chroot.carve_file( OUTFILE_NAME, @@ -51,5 +51,5 @@ pub fn extract_jboot_sch2_kernel( } } - return result; + result } diff --git a/src/extractors/jpeg.rs b/src/extractors/jpeg.rs index 73eb84698..d5e3b438b 100644 --- a/src/extractors/jpeg.rs +++ b/src/extractors/jpeg.rs @@ -27,14 +27,14 @@ pub fn extract_jpeg_image( result.size = Some(jpeg_data_size); result.success = true; - if let Some(_) = output_directory { + if output_directory.is_some() { let chroot = Chroot::new(output_directory); result.success = chroot.carve_file(OUTFILE_NAME, file_data, offset, result.size.unwrap()); } } - return result; + result } fn get_jpeg_data_size(jpeg_data: &[u8]) -> Option { @@ -57,5 +57,5 @@ fn get_jpeg_data_size(jpeg_data: &[u8]) -> Option { return Some(eof_match.start() + EOF_SIZE); } - return None; + None } diff --git a/src/extractors/linux.rs b/src/extractors/linux.rs index 603406220..c939fb6b0 100644 --- a/src/extractors/linux.rs +++ b/src/extractors/linux.rs @@ -13,6 +13,5 @@ pub fn linux_kernel_extractor() -> extractors::common::Extractor { "linux_kernel.elf".to_string(), ], exit_codes: vec![0], - ..Default::default() } } diff --git a/src/extractors/lzma.rs b/src/extractors/lzma.rs index 46261cc37..d19531e35 100644 --- a/src/extractors/lzma.rs +++ b/src/extractors/lzma.rs @@ -81,12 +81,12 @@ pub fn lzma_decompress( } // Some data was decompressed successfully; if extraction was requested, write the data to disk. - if !output_directory.is_none() { + if output_directory.is_some() { // Number of decompressed bytes in the output buffer let n = (decompressor.total_out() as usize) - bytes_written; let chroot = Chroot::new(output_directory); - if chroot.append_to_file(OUTPUT_FILE_NAME, &output_buf[0..n]) == false { + if !chroot.append_to_file(OUTPUT_FILE_NAME, &output_buf[0..n]) { // If writing data to disk fails, report failure and break result.success = false; break; @@ -97,7 +97,7 @@ pub fn lzma_decompress( } // If result.success is true, then everything has been processed and written to disk successfully. - if result.success == true { + if result.success { break; } } @@ -105,5 +105,5 @@ pub fn lzma_decompress( } } - return result; + result } diff --git a/src/extractors/mbr.rs b/src/extractors/mbr.rs index 6eb133fb8..6d47086da 100644 --- a/src/extractors/mbr.rs +++ b/src/extractors/mbr.rs @@ -25,7 +25,7 @@ pub fn extract_mbr_partitions( // Parse the MBR header if let Ok(mbr_header) = parse_mbr_image(&file_data[offset..]) { // Make sure there is at least one valid partition - if mbr_header.partitions.len() > 0 { + if !mbr_header.partitions.is_empty() { // Make sure the reported size of the MBR does not extend beyond EOF if available_data >= mbr_header.image_size { // Everything looks ok @@ -33,15 +33,12 @@ pub fn extract_mbr_partitions( result.size = Some(mbr_header.image_size); // Do extraction if requested - if let Some(_) = output_directory { + if output_directory.is_some() { // Chroot extracted files into the output directory let chroot = Chroot::new(output_directory); - // Keep track of how many partitions have been extracted - let mut partition_count: usize = 0; - // Loop through each partition - for partition in &mbr_header.partitions { + for (partition_count, partition) in mbr_header.partitions.iter().enumerate() { // Partition names are not unique, output file will be: "_partition." let partition_name = format!("{}_partition.{}", partition.name, partition_count); @@ -55,17 +52,14 @@ pub fn extract_mbr_partitions( ); // If partition extraction failed, quit and report a failure - if result.success == false { + if !result.success { break; } - - // Increment partition counter - partition_count += 1; } } } } } - return result; + result } diff --git a/src/extractors/pcap.rs b/src/extractors/pcap.rs index 4fcb93a31..c0c899db9 100644 --- a/src/extractors/pcap.rs +++ b/src/extractors/pcap.rs @@ -65,7 +65,7 @@ pub fn pcapng_carver( result.success = true; // Do extraction if requested - if let Some(_) = output_directory { + if output_directory.is_some() { let chroot = Chroot::new(output_directory); result.success = chroot.carve_file(OUTPUT_FILE_NAME, file_data, offset, result.size.unwrap()); @@ -73,5 +73,5 @@ pub fn pcapng_carver( } } - return result; + result } diff --git a/src/extractors/pem.rs b/src/extractors/pem.rs index ede2e5f7c..251025d3e 100644 --- a/src/extractors/pem.rs +++ b/src/extractors/pem.rs @@ -25,12 +25,12 @@ pub fn pem_certificate_carver( output_directory: Option<&String>, ) -> ExtractionResult { const CERTIFICATE_FILE_NAME: &str = "pem.crt"; - return pem_carver( + pem_carver( file_data, offset, output_directory, Some(CERTIFICATE_FILE_NAME), - ); + ) } pub fn pem_key_carver( @@ -39,7 +39,7 @@ pub fn pem_key_carver( output_directory: Option<&String>, ) -> ExtractionResult { const KEY_FILE_NAME: &str = "pem.key"; - return pem_carver(file_data, offset, output_directory, Some(KEY_FILE_NAME)); + pem_carver(file_data, offset, output_directory, Some(KEY_FILE_NAME)) } pub fn pem_carver( @@ -57,7 +57,7 @@ pub fn pem_carver( result.success = true; if let Some(outfile) = fname { - if let Some(_) = output_directory { + if output_directory.is_some() { let chroot = Chroot::new(output_directory); result.success = chroot.carve_file(outfile, file_data, offset, result.size.unwrap()); @@ -65,7 +65,7 @@ pub fn pem_carver( } } - return result; + result } fn get_pem_size(file_data: &[u8], start_of_pem_offset: usize) -> Option { @@ -84,7 +84,7 @@ fn get_pem_size(file_data: &[u8], start_of_pem_offset: usize) -> Option { let grep = AhoCorasick::new(eof_markers.clone()).unwrap(); // Find the first end marker - for eof_match in grep.find_overlapping_iter(&file_data[start_of_pem_offset..]) { + if let Some(eof_match) = grep.find_overlapping_iter(&file_data[start_of_pem_offset..]).next() { let eof_marker_index: usize = eof_match.pattern().as_usize(); let mut pem_size = eof_match.start() + eof_markers[eof_marker_index].len(); @@ -100,5 +100,5 @@ fn get_pem_size(file_data: &[u8], start_of_pem_offset: usize) -> Option { return Some(pem_size); } - return None; + None } diff --git a/src/extractors/png.rs b/src/extractors/png.rs index 71ebbda18..06e5531ea 100644 --- a/src/extractors/png.rs +++ b/src/extractors/png.rs @@ -31,7 +31,7 @@ pub fn extract_png_image( result.success = true; // If extraction was requested, extract the PNG - if let Some(_) = output_directory { + if output_directory.is_some() { let chroot = Chroot::new(output_directory); result.success = chroot.carve_file(OUTFILE_NAME, file_data, offset, result.size.unwrap()); @@ -39,7 +39,7 @@ pub fn extract_png_image( } } - return result; + result } fn get_png_data_size(png_chunk_data: &[u8]) -> Option { @@ -56,11 +56,11 @@ fn get_png_data_size(png_chunk_data: &[u8]) -> Option { png_chunk_offset += chunk_header.total_size; // If this was the last chunk, then png_chunk_offset is the total size of the PNG data - if chunk_header.is_last_chunk == true { + if chunk_header.is_last_chunk { return Some(png_chunk_offset); } } } - return None; + None } diff --git a/src/extractors/riff.rs b/src/extractors/riff.rs index d4d6a2d5d..0fe6be828 100644 --- a/src/extractors/riff.rs +++ b/src/extractors/riff.rs @@ -28,19 +28,18 @@ pub fn extract_riff_image( result.size = Some(riff_header.size); result.success = true; - if let Some(_) = output_directory { - let file_path: String; + if output_directory.is_some() { let chroot = Chroot::new(output_directory); - if riff_header.chunk_type == WAV_TYPE { - file_path = WAV_OUTFILE_NAME.to_string(); + let file_path: String = if riff_header.chunk_type == WAV_TYPE { + WAV_OUTFILE_NAME.to_string() } else { - file_path = OUTFILE_NAME.to_string(); - } + OUTFILE_NAME.to_string() + }; result.success = chroot.carve_file(file_path, file_data, offset, result.size.unwrap()); } } - return result; + result } diff --git a/src/extractors/romfs.rs b/src/extractors/romfs.rs index 69e04785f..58e879fa1 100644 --- a/src/extractors/romfs.rs +++ b/src/extractors/romfs.rs @@ -40,17 +40,10 @@ pub fn extract_romfs( offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { - let do_extraction: bool; let mut result = ExtractionResult { ..Default::default() }; - // Only perform extraction if an output directory was provided - match output_directory { - None => do_extraction = false, - Some(_) => do_extraction = true, - } - // Parse the RomFS header if let Ok(romfs_header) = parse_romfs_header(&file_data[offset..]) { // Calculate start and end offsets of RomFS image @@ -62,13 +55,13 @@ pub fn extract_romfs( // Process the RomFS file entries if let Ok(root_entries) = process_romfs_entries(romfs_data, romfs_header.header_size) { // We expect at least one file entry in the root of the RomFS image - if root_entries.len() > 0 { + if !root_entries.is_empty() { // Everything looks good result.success = true; result.size = Some(romfs_header.image_size); // Do extraction, if an output directory was provided - if do_extraction { + if output_directory.is_some() { let mut file_count: usize = 0; let root_parent = "".to_string(); @@ -78,7 +71,7 @@ pub fn extract_romfs( let romfs_chroot_dir = chroot.chrooted_path(&romfs_header.volume_name); // Create the romfs output directory, ensuring that it is contained inside the specified extraction directory - if chroot.create_directory(&romfs_chroot_dir) == true { + if chroot.create_directory(&romfs_chroot_dir) { // Extract RomFS contents file_count = extract_romfs_entries( romfs_data, @@ -98,7 +91,7 @@ pub fn extract_romfs( } } - return result; + result } // Recursively processes all RomFS file entries and their children, and returns a list of RomFSEntry structures @@ -123,7 +116,7 @@ fn process_romfs_entries( */ while file_offset != 0 && is_offset_safe(available_data, file_offset, previous_file_offset) { // Sanity check, no two entries should exist at the same offset, if so, infinite recursion could ensue - if processed_entries.contains(&file_offset) == true { + if processed_entries.contains(&file_offset) { break; } else { processed_entries.push(file_offset); @@ -160,9 +153,9 @@ fn process_romfs_entries( } // Don't do anything special for '.' or '..' directory entries - if ignore_file_names.contains(&file_entry.name) == false { + if !ignore_file_names.contains(&file_entry.name) { // Symlinks need their target paths - if file_entry.symlink == true { + if file_entry.symlink { if let Some(symlink_bytes) = romfs_data.get(file_entry.offset..file_entry.offset + file_entry.size) { @@ -185,8 +178,8 @@ fn process_romfs_entries( } // Directories have children; process them - if file_entry.directory == true { - match process_romfs_entries(&romfs_data, file_entry.info) { + if file_entry.directory { + match process_romfs_entries(romfs_data, file_entry.info) { Err(e) => return Err(e), Ok(children) => file_entry.children = children, } @@ -207,7 +200,7 @@ fn process_romfs_entries( } } - return Ok(file_entries); + Ok(file_entries) } // Recursively extract all RomFS entries, returns the number of extracted files/directories @@ -252,11 +245,11 @@ fn extract_romfs_entries( continue; } - if extraction_success == true { + if extraction_success { file_count += 1; // Extract the children of a directory - if file_entry.directory == true && file_entry.children.len() > 0 { + if file_entry.directory && !file_entry.children.is_empty() { file_count += extract_romfs_entries( romfs_data, &file_entry.children, @@ -266,7 +259,7 @@ fn extract_romfs_entries( } // Make executable files executable - if file_entry.regular == true && file_entry.executable == true { + if file_entry.regular && file_entry.executable { chroot.make_executable(&file_path); } } else { @@ -275,5 +268,5 @@ fn extract_romfs_entries( } // Return the number of files extracted - return file_count; + file_count } diff --git a/src/extractors/svg.rs b/src/extractors/svg.rs index e7cfbb4aa..d7846e2a5 100644 --- a/src/extractors/svg.rs +++ b/src/extractors/svg.rs @@ -27,12 +27,12 @@ pub fn extract_svg_image( result.size = Some(svg_image.total_size); result.success = true; - if !output_directory.is_none() { + if output_directory.is_some() { let chroot = Chroot::new(output_directory); result.success = chroot.carve_file(OUTFILE_NAME, file_data, offset, result.size.unwrap()); } } - return result; + result } diff --git a/src/extractors/trx.rs b/src/extractors/trx.rs index 3676a0b16..36bb89b0e 100644 --- a/src/extractors/trx.rs +++ b/src/extractors/trx.rs @@ -34,7 +34,7 @@ pub fn extract_trx_partitions( result.size = Some(trx_header.total_size); // If extraction was requested, carve the TRX partitions - if let Some(_) = output_directory { + if output_directory.is_some() { let chroot = Chroot::new(output_directory); for i in 0..trx_header.partitions.len() { @@ -58,7 +58,7 @@ pub fn extract_trx_partitions( this_partition_size, ); - if result.success == false { + if !result.success { break; } } @@ -68,9 +68,9 @@ pub fn extract_trx_partitions( } } - return result; + result } fn trx_crc32(crc_data: &[u8]) -> usize { - return ((crc32(crc_data) ^ 0xFFFFFFFF) & 0xFFFFFFFF) as usize; + (crc32(crc_data) ^ 0xFFFFFFFF) as usize } diff --git a/src/extractors/uefi.rs b/src/extractors/uefi.rs index 3d124c669..0c901a8e3 100644 --- a/src/extractors/uefi.rs +++ b/src/extractors/uefi.rs @@ -17,6 +17,5 @@ pub fn uefi_extractor() -> extractors::common::Extractor { * Recursing into this data would result in double extractions for no good reason. */ do_not_recurse: true, - ..Default::default() } } diff --git a/src/extractors/uimage.rs b/src/extractors/uimage.rs index a6d26a2f7..35a1195ed 100644 --- a/src/extractors/uimage.rs +++ b/src/extractors/uimage.rs @@ -35,12 +35,12 @@ pub fn extract_uimage( result.size = Some(uimage_header.header_size + uimage_header.data_size); // If extraction was requested, carve the uImage data out to a file - if let Some(_) = output_directory { + if output_directory.is_some() { let chroot = Chroot::new(output_directory); let mut file_base_name: String = DEFAULT_OUTPUT_FILE_NAME.to_string(); // Use the name specified in the uImage header as the file name, if one was provided - if uimage_header.name.len() > 0 { + if !uimage_header.name.is_empty() { file_base_name = uimage_header.name.replace(" ", "_"); } @@ -53,5 +53,5 @@ pub fn extract_uimage( } } - return result; + result } diff --git a/src/extractors/vxworks.rs b/src/extractors/vxworks.rs index 3fc63dbd4..072714504 100644 --- a/src/extractors/vxworks.rs +++ b/src/extractors/vxworks.rs @@ -23,7 +23,6 @@ pub fn extract_symbol_table( const MIN_VALID_ENTRIES: usize = 250; const OUTFILE_NAME: &str = "symtab.json"; - let dry_run: bool; let mut result = ExtractionResult { ..Default::default() }; @@ -33,16 +32,6 @@ pub fn extract_symbol_table( let mut symtab_entry_offset: usize = offset; let mut symtab_entries: Vec = vec![]; - // Check if this is just a dry-run or a full extraction - match output_directory { - Some(_) => { - dry_run = false; - } - None => { - dry_run = true; - } - } - // Determine the symbol table endianness first if let Ok(endianness) = get_symtab_endianness(&file_data[symtab_entry_offset..]) { // Loop through all the symbol table entries, until we run out of data or hit an invalid entry @@ -70,7 +59,7 @@ pub fn extract_symbol_table( result.size = Some(symtab_entry_offset - offset); // This is not a drill! - if dry_run == false { + if output_directory.is_some() { let chroot = Chroot::new(output_directory); // Convert symbol table entires to JSON @@ -89,5 +78,5 @@ pub fn extract_symbol_table( } } - return result; + result } diff --git a/src/extractors/zlib.rs b/src/extractors/zlib.rs index ac7f86eb7..e0c5aed90 100644 --- a/src/extractors/zlib.rs +++ b/src/extractors/zlib.rs @@ -30,5 +30,5 @@ pub fn zlib_decompress( result.size = Some(HEADER_SIZE + deflate_size + CHECKSUM_SIZE); } - return result; + result } From fae9bfb4ad7e3583387c957ecf09c5b9d5df88f3 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sun, 20 Oct 2024 15:53:13 -0400 Subject: [PATCH 006/131] Code formatting --- src/extractors/androidsparse.rs | 3 +-- src/extractors/arcadyan.rs | 9 ++++++--- src/extractors/bzip2.rs | 3 +-- src/extractors/common.rs | 11 ++--------- src/extractors/inflate.rs | 3 +-- src/extractors/pem.rs | 5 ++++- 6 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/extractors/androidsparse.rs b/src/extractors/androidsparse.rs index 6f5ed166c..cd98e189f 100644 --- a/src/extractors/androidsparse.rs +++ b/src/extractors/androidsparse.rs @@ -51,8 +51,7 @@ pub fn extract_android_sparse( chunk_data, &OUTFILE_NAME.to_string(), &chroot, - ) - { + ) { break; } } else { diff --git a/src/extractors/arcadyan.rs b/src/extractors/arcadyan.rs index bfb3067d0..a9f996acc 100644 --- a/src/extractors/arcadyan.rs +++ b/src/extractors/arcadyan.rs @@ -72,9 +72,12 @@ fn arcadyan_deobfuscator(obfuscated_data: &[u8]) -> Vec { deobfuscated_data.extend(p3); // Nibble swap each byte in what is now "block1" - for swapped_byte in deobfuscated_data.iter_mut().take(BLOCK1_END).skip(BLOCK1_START) { - *swapped_byte = - ((*swapped_byte & 0x0F) << 4) + ((*swapped_byte & 0xF0) >> 4); + for swapped_byte in deobfuscated_data + .iter_mut() + .take(BLOCK1_END) + .skip(BLOCK1_START) + { + *swapped_byte = ((*swapped_byte & 0x0F) << 4) + ((*swapped_byte & 0xF0) >> 4); } let mut i: usize = BLOCK1_START; diff --git a/src/extractors/bzip2.rs b/src/extractors/bzip2.rs index 4ba9dc4ba..1aa861c47 100644 --- a/src/extractors/bzip2.rs +++ b/src/extractors/bzip2.rs @@ -67,8 +67,7 @@ pub fn bzip2_decompressor( let n: usize = (decompressor.total_out() as usize) - bytes_written; let chroot = Chroot::new(output_directory); - if !chroot.append_to_file(OUTPUT_FILE_NAME, &decompressed_buffer[0..n]) - { + if !chroot.append_to_file(OUTPUT_FILE_NAME, &decompressed_buffer[0..n]) { // If writing data to file fails, break break; } diff --git a/src/extractors/common.rs b/src/extractors/common.rs index 4e83f0c51..4d0fab13c 100644 --- a/src/extractors/common.rs +++ b/src/extractors/common.rs @@ -601,9 +601,7 @@ impl Chroot { #[cfg(unix)] { match unix::fs::symlink(safe_target_path, safe_symlink_path) { - Ok(_) => { - true - } + Ok(_) => true, Err(e) => { error!( "Failed to create symlink from {} -> {}: {}", @@ -693,12 +691,7 @@ impl Chroot { // Concatenate each non-excluded part of the file path, with each part separated by '/' for (i, path_part) in path_parts.iter().enumerate() { if !exclude_indicies.contains(&i) { - sanitized_path = format!( - "{}{}{}", - sanitized_path, - path::MAIN_SEPARATOR, - path_part - ); + sanitized_path = format!("{}{}{}", sanitized_path, path::MAIN_SEPARATOR, path_part); } } diff --git a/src/extractors/inflate.rs b/src/extractors/inflate.rs index e9acda5db..1a773af82 100644 --- a/src/extractors/inflate.rs +++ b/src/extractors/inflate.rs @@ -52,8 +52,7 @@ pub fn inflate_decompressor( // Decompressed a block of data, if extraction was requested write the decompressed block to the output file if n > 0 && output_directory.is_some() { let chroot = Chroot::new(output_directory); - if !chroot.append_to_file(OUTPUT_FILE_NAME, &decompressed_buffer[0..n]) - { + if !chroot.append_to_file(OUTPUT_FILE_NAME, &decompressed_buffer[0..n]) { // If writing data to file fails, break break; } diff --git a/src/extractors/pem.rs b/src/extractors/pem.rs index 251025d3e..7857bd24d 100644 --- a/src/extractors/pem.rs +++ b/src/extractors/pem.rs @@ -84,7 +84,10 @@ fn get_pem_size(file_data: &[u8], start_of_pem_offset: usize) -> Option { let grep = AhoCorasick::new(eof_markers.clone()).unwrap(); // Find the first end marker - if let Some(eof_match) = grep.find_overlapping_iter(&file_data[start_of_pem_offset..]).next() { + if let Some(eof_match) = grep + .find_overlapping_iter(&file_data[start_of_pem_offset..]) + .next() + { let eof_marker_index: usize = eof_match.pattern().as_usize(); let mut pem_size = eof_match.start() + eof_markers[eof_marker_index].len(); From 0d9922c200fb3fba4188c98f765cb777993cf283 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sun, 20 Oct 2024 16:43:03 -0400 Subject: [PATCH 007/131] Lint fixes in binwalk.rs, common.rs, lib.rs --- src/binwalk.rs | 53 ++++++++++++++++++++++++-------------------------- src/common.rs | 28 +++++++++++++------------- src/lib.rs | 16 +++++++-------- 3 files changed, 45 insertions(+), 52 deletions(-) diff --git a/src/binwalk.rs b/src/binwalk.rs index 66b308e42..88e6b6b4e 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -83,7 +83,7 @@ impl Binwalk { /// ``` #[allow(dead_code)] pub fn new() -> Binwalk { - return Binwalk::configure(None, None, None, None, None).unwrap(); + Binwalk::configure(None, None, None, None, None).unwrap() } /// Create a new Binwalk instance. @@ -171,7 +171,7 @@ impl Binwalk { // Load magic signatures for signature in signature_patterns.clone() { // Check if this signature should be included - if include_signature(&signature, &include, &exclude) == false { + if !include_signature(&signature, &include, &exclude) { continue; } @@ -185,7 +185,7 @@ impl Binwalk { // Each signature may have multiple magic bytes associated with it for pattern in signature.magic.clone() { - if signature.short == true { + if signature.short { // These are short patterns, and should only be searched for at the very beginning of a file new_instance.short_signatures.push(signature.clone()); } else { @@ -204,7 +204,7 @@ impl Binwalk { } } - return Ok(new_instance); + Ok(new_instance) } /// Scan a file for magic signatures. @@ -228,7 +228,7 @@ impl Binwalk { /// /// assert!(signature_results.len() > 0); /// ``` - pub fn scan(&self, file_data: &Vec) -> Vec { + pub fn scan(&self, file_data: &[u8]) -> Vec { const FILE_START_OFFSET: usize = 0; let mut index_adjustment: usize = 0; @@ -259,11 +259,10 @@ impl Binwalk { signature.description, magic_start ); - if let Ok(mut signature_result) = - (signature.parser)(&file_data, magic_start) + if let Ok(mut signature_result) = (signature.parser)(file_data, magic_start) { // Auto populate some signature result fields - signature_result_auto_populate(&mut signature_result, &signature); + signature_result_auto_populate(&mut signature_result, signature); // Add this signature to the file map file_map.push(signature_result.clone()); @@ -343,7 +342,7 @@ impl Binwalk { * Invoke the signature parser to parse and validate the signature. * An error indicates a false positive match for the signature type. */ - if let Ok(mut signature_result) = (signature.parser)(&file_data, magic_offset) { + if let Ok(mut signature_result) = (signature.parser)(file_data, magic_offset) { // Calculate the end of this signature's data let signature_end_offset = signature_result.offset + signature_result.size; @@ -406,7 +405,7 @@ impl Binwalk { i -= index_adjustment; // Make sure the file map index is valid - if file_map.len() == 0 || i >= file_map.len() { + if file_map.is_empty() || i >= file_map.len() { break; } @@ -498,10 +497,10 @@ impl Binwalk { // If there are more entries in the file map if next_index < file_map.len() { // Look through all remaining file map entries for one with medium to high confidence - for j in next_index..file_map.len() { - if file_map[j].confidence >= signatures::common::CONFIDENCE_MEDIUM { + for file_map_entry in file_map.iter().skip(next_index) { + if file_map_entry.confidence >= signatures::common::CONFIDENCE_MEDIUM { // If a signature of at least medium confidence is found, assume that *this* signature ends there - next_offset = file_map[j].offset; + next_offset = file_map_entry.offset; break; } } @@ -522,7 +521,7 @@ impl Binwalk { debug!("Found {} valid signatures", file_map.len()); - return file_map; + file_map } /// Extract all extractable signatures found in a file. @@ -550,7 +549,7 @@ impl Binwalk { /// ``` pub fn extract( &self, - file_data: &Vec, + file_data: &[u8], file_path: &String, file_map: &Vec, ) -> HashMap { @@ -560,7 +559,7 @@ impl Binwalk { // Spawn extractors for each extractable signature for signature in file_map { // Signatures may opt to not perform extraction; honor this request - if signature.extraction_declined == true { + if signature.extraction_declined { continue; } @@ -574,7 +573,7 @@ impl Binwalk { let mut extraction_result = extractors::common::execute(file_data, file_path, signature, &extractor); - if extraction_result.success == false { + if !extraction_result.success { debug!( "Extraction failed for {} (ID: {}) {:#X} - {:#X}", signature.name, signature.id, signature.offset, signature.size @@ -616,7 +615,7 @@ impl Binwalk { } } - return extraction_results; + extraction_results } /// Analyze a file and optionally extract the file contents. @@ -655,19 +654,19 @@ impl Binwalk { results.file_map = self.scan(&file_data); // Only extract if told to, and if there were some signatures found in this file - if do_extraction == true && results.file_map.len() > 0 { + if do_extraction && !results.file_map.is_empty() { // Extract everything we can debug!( "Submitting {} signature results to extractor", results.file_map.len() ); - results.extractions = self.extract(&file_data, &target_file, &results.file_map); + results.extractions = self.extract(&file_data, target_file, &results.file_map); } } debug!("Analysis end: {}", target_file); - return results; + results } } @@ -677,7 +676,7 @@ fn init_extraction_directory( extraction_directory: &String, ) -> Result { // Create the output directory, equivalent of mkdir -p - match fs::create_dir_all(&extraction_directory) { + match fs::create_dir_all(extraction_directory) { Ok(_) => { debug!("Created base output directory: '{}'", extraction_directory); } @@ -713,10 +712,8 @@ fn init_extraction_directory( // Create a symlink from inside the extraction directory to the specified target file #[cfg(unix)] { - match unix::fs::symlink(&target_path, &symlink_path) { - Ok(_) => { - return Ok(symlink_target_path_str); - } + match unix::fs::symlink(target_path, symlink_path) { + Ok(_) => Ok(symlink_target_path_str), Err(e) => { error!( "Failed to create symlink {} -> {}: {}", @@ -724,7 +721,7 @@ fn init_extraction_directory( target_path.display(), e ); - return Err(e); + Err(e) } } } @@ -773,7 +770,7 @@ fn include_signature( return true; } - return true; + true } /// Some SignatureResult fields need to be auto-populated. diff --git a/src/common.rs b/src/common.rs index 71110fda5..7e3d40e3d 100644 --- a/src/common.rs +++ b/src/common.rs @@ -23,16 +23,16 @@ pub fn read_file(file: impl Into) -> Result, std::io::Error> { match File::open(&file_path) { Err(e) => { error!("Failed to open file {}: {}", file_path, e); - return Err(e); + Err(e) } Ok(mut fp) => match fp.read_to_end(&mut file_data) { Err(e) => { error!("Failed to read file {} into memory: {}", file_path, e); - return Err(e); + Err(e) } Ok(file_size) => { debug!("Loaded {} bytes from {}", file_size, file_path); - return Ok(file_data); + Ok(file_data) } }, } @@ -56,7 +56,7 @@ pub fn read_file(file: impl Into) -> Result, std::io::Error> { /// assert_eq!(my_data_crc, 0xDB1720A5); /// ``` pub fn crc32(data: &[u8]) -> u32 { - return crc32_v2::crc32(0, data); + crc32_v2::crc32(0, data) } /// Converts an epoch time to a formatted time string. @@ -73,8 +73,8 @@ pub fn crc32(data: &[u8]) -> u32 { pub fn epoch_to_string(epoch_timestamp: u32) -> String { let date_time = DateTime::from_timestamp(epoch_timestamp.into(), 0); match date_time { - Some(dt) => return dt.format("%Y-%m-%d %H:%M:%S").to_string(), - None => return "".to_string(), + Some(dt) => dt.format("%Y-%m-%d %H:%M:%S").to_string(), + None => "".to_string(), } } @@ -91,7 +91,7 @@ fn get_cstring_bytes(raw_data: &[u8]) -> Vec { } } - return cstring; + cstring } /// Get a C-style NULL-terminated string from the provided array of u8 bytes. @@ -108,16 +108,14 @@ fn get_cstring_bytes(raw_data: &[u8]) -> Vec { /// assert_eq!(string, "this_is_a_c_string"); /// ``` pub fn get_cstring(raw_data: &[u8]) -> String { - let string: String; - let raw_string = get_cstring_bytes(raw_data); - match String::from_utf8(raw_string) { - Err(_) => string = "".to_string(), - Ok(s) => string = s.clone(), - } + let string: String = match String::from_utf8(raw_string) { + Err(_) => "".to_string(), + Ok(s) => s.clone(), + }; - return string; + string } /// Validates data offsets to prevent out-of-bounds access and infinite loops while parsing file formats. @@ -158,5 +156,5 @@ pub fn is_offset_safe( return false; } - return true; + true } diff --git a/src/lib.rs b/src/lib.rs index 570072673..0f4239c03 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,17 +5,15 @@ //!```no_run //! use binwalk::Binwalk; //! -//! fn main() { -//! // Create a new Binwalk instance -//! let binwalker = Binwalk::new(); +//! // Create a new Binwalk instance +//! let binwalker = Binwalk::new(); //! -//! // Read in the data you want to analyze -//! let file_data = std::fs::read("/tmp/firmware.bin").expect("Failed to read from file"); +//! // Read in the data you want to analyze +//! let file_data = std::fs::read("/tmp/firmware.bin").expect("Failed to read from file"); //! -//! // Scan the file data and print the results -//! for result in binwalker.scan(&file_data) { -//! println!("{:#?}", result); -//! } +//! // Scan the file data and print the results +//! for result in binwalker.scan(&file_data) { +//! println!("{:#?}", result); //! } //! ``` mod binwalk; From c1140ee9771c8be9eb6baf7cfaefe24c9089b6f0 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sun, 20 Oct 2024 20:54:28 -0400 Subject: [PATCH 008/131] Lint fixes in signatures & extractors --- src/binwalk.rs | 54 +++++++------- src/extractors/arcadyan.rs | 14 ++-- src/extractors/common.rs | 10 ++- src/extractors/jpeg.rs | 6 +- src/signatures/aes.rs | 2 +- src/signatures/androidsparse.rs | 2 +- src/signatures/bzip2.rs | 2 +- src/signatures/cab.rs | 2 +- src/signatures/chk.rs | 2 +- src/signatures/compressd.rs | 2 +- src/signatures/copyright.rs | 2 +- src/signatures/cpio.rs | 2 +- src/signatures/deb.rs | 2 +- src/signatures/dlob.rs | 2 +- src/signatures/dtb.rs | 2 +- src/signatures/ecos.rs | 2 +- src/signatures/elf.rs | 2 +- src/signatures/gif.rs | 2 +- src/signatures/gpg.rs | 2 +- src/signatures/gzip.rs | 2 +- src/signatures/hashes.rs | 4 +- src/signatures/jboot.rs | 4 +- src/signatures/jffs2.rs | 2 +- src/signatures/jpeg.rs | 2 +- src/signatures/linux.rs | 4 +- src/signatures/luks.rs | 2 +- src/signatures/lz4.rs | 2 +- src/signatures/lzfse.rs | 2 +- src/signatures/lzma.rs | 2 +- src/signatures/lzop.rs | 2 +- src/signatures/openssl.rs | 2 +- src/signatures/packimg.rs | 2 +- src/signatures/pcap.rs | 2 +- src/signatures/pdf.rs | 2 +- src/signatures/pe.rs | 2 +- src/signatures/pem.rs | 2 +- src/signatures/pjl.rs | 2 +- src/signatures/png.rs | 2 +- src/signatures/qnx.rs | 2 +- src/signatures/rar.rs | 2 +- src/signatures/riff.rs | 2 +- src/signatures/romfs.rs | 2 +- src/signatures/rsa.rs | 2 +- src/signatures/rtk.rs | 2 +- src/signatures/seama.rs | 2 +- src/signatures/sevenzip.rs | 2 +- src/signatures/squashfs.rs | 2 +- src/signatures/srec.rs | 2 +- src/signatures/svg.rs | 2 +- src/signatures/tarball.rs | 2 +- src/signatures/tplink.rs | 2 +- src/signatures/trx.rs | 2 +- src/signatures/ubi.rs | 4 +- src/signatures/uefi.rs | 2 +- src/signatures/uimage.rs | 2 +- src/signatures/vxworks.rs | 2 +- src/signatures/xz.rs | 2 +- src/signatures/yaffs.rs | 2 +- src/signatures/zip.rs | 2 +- src/signatures/zlib.rs | 2 +- src/signatures/zstd.rs | 2 +- src/structures/elf.rs | 72 +++++++++---------- src/structures/gzip.rs | 124 ++++++++++++++++---------------- src/structures/jboot.rs | 29 ++++---- src/structures/lzma.rs | 22 +++--- src/structures/pchrom.rs | 25 ++++--- src/structures/seama.rs | 12 ++-- src/structures/uimage.rs | 48 ++++++------- src/structures/vxworks.rs | 19 ++--- 69 files changed, 265 insertions(+), 292 deletions(-) diff --git a/src/binwalk.rs b/src/binwalk.rs index 88e6b6b4e..d86e59836 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -252,39 +252,35 @@ impl Binwalk { let magic_start = FILE_START_OFFSET + signature.magic_offset; let magic_end = magic_start + magic.len(); - if file_data.len() > magic_end { - if file_data[magic_start..magic_end] == magic { - debug!( - "Found {} short magic match at offset {:#X}", - signature.description, magic_start - ); - - if let Ok(mut signature_result) = (signature.parser)(file_data, magic_start) - { - // Auto populate some signature result fields - signature_result_auto_populate(&mut signature_result, signature); + if file_data.len() > magic_end && file_data[magic_start..magic_end] == magic { + debug!( + "Found {} short magic match at offset {:#X}", + signature.description, magic_start + ); - // Add this signature to the file map - file_map.push(signature_result.clone()); - info!( - "Found valid {} short signature at offset {:#X}", - signature_result.name, FILE_START_OFFSET - ); + if let Ok(mut signature_result) = (signature.parser)(file_data, magic_start) { + // Auto populate some signature result fields + signature_result_auto_populate(&mut signature_result, signature); - // Only update the next_valid_offset if confidence is at least medium - if signature_result.confidence >= signatures::common::CONFIDENCE_MEDIUM - { - next_valid_offset = signature_result.offset + signature_result.size; - } + // Add this signature to the file map + file_map.push(signature_result.clone()); + info!( + "Found valid {} short signature at offset {:#X}", + signature_result.name, FILE_START_OFFSET + ); - // Only one signature can match at fixed offset 0 - break; - } else { - debug!( - "{} short signature match at offset {:#X} is invalid", - signature.description, FILE_START_OFFSET - ); + // Only update the next_valid_offset if confidence is at least medium + if signature_result.confidence >= signatures::common::CONFIDENCE_MEDIUM { + next_valid_offset = signature_result.offset + signature_result.size; } + + // Only one signature can match at fixed offset 0 + break; + } else { + debug!( + "{} short signature match at offset {:#X} is invalid", + signature.description, FILE_START_OFFSET + ); } } } diff --git a/src/extractors/arcadyan.rs b/src/extractors/arcadyan.rs index a9f996acc..456616030 100644 --- a/src/extractors/arcadyan.rs +++ b/src/extractors/arcadyan.rs @@ -25,14 +25,12 @@ pub fn extract_obfuscated_lzma( let available_data: usize = file_data.len() - offset; // Sanity check data size - if available_data <= MAX_DATA_SIZE { - if available_data > MIN_DATA_SIZE { - // De-obfuscate the LZMA data - let deobfuscated_data = arcadyan_deobfuscator(&file_data[offset..]); - - // Do a decompression on the LZMA data (actual LZMA data starts 4 bytes into the deobfuscated data) - result = lzma_decompress(&deobfuscated_data, LZMA_DATA_OFFSET, output_directory); - } + if available_data <= MAX_DATA_SIZE && available_data > MIN_DATA_SIZE { + // De-obfuscate the LZMA data + let deobfuscated_data = arcadyan_deobfuscator(&file_data[offset..]); + + // Do a decompression on the LZMA data (actual LZMA data starts 4 bytes into the deobfuscated data) + result = lzma_decompress(&deobfuscated_data, LZMA_DATA_OFFSET, output_directory); } result diff --git a/src/extractors/common.rs b/src/extractors/common.rs index 4d0fab13c..6c1666b8a 100644 --- a/src/extractors/common.rs +++ b/src/extractors/common.rs @@ -810,11 +810,9 @@ pub fn execute( result.do_not_recurse = extractor_definition.do_not_recurse; // If the extractor reported success, make sure it extracted something other than just an empty file - if result.success { - if !was_something_extracted(&result.output_directory) { - result.success = false; - warn!("Extractor exited successfully, but no data was extracted"); - } + if result.success && !was_something_extracted(&result.output_directory) { + result.success = false; + warn!("Extractor exited successfully, but no data was extracted"); } } } @@ -914,7 +912,7 @@ fn spawn( Ok(child) => { // If the process was spawned successfully, return some information about the process let proc_info = ProcInfo { - child: child, + child, carved_file: carved_file.clone(), exit_codes: extractor.exit_codes, }; diff --git a/src/extractors/jpeg.rs b/src/extractors/jpeg.rs index d5e3b438b..6458d7406 100644 --- a/src/extractors/jpeg.rs +++ b/src/extractors/jpeg.rs @@ -48,10 +48,8 @@ fn get_jpeg_data_size(jpeg_data: &[u8]) -> Option { let eof_candidate: usize = eof_match.start() + EOF_SIZE; // Make sure the expected EOF marker is not immediately followed by 0xFF (which would indicate the JPEG continues...) - if eof_candidate < jpeg_data.len() { - if jpeg_data[eof_candidate] == JPEG_DELIM { - continue; - } + if eof_candidate < jpeg_data.len() && jpeg_data[eof_candidate] == JPEG_DELIM { + continue; } return Some(eof_match.start() + EOF_SIZE); diff --git a/src/signatures/aes.rs b/src/signatures/aes.rs index 727960edf..a29e4c2e8 100644 --- a/src/signatures/aes.rs +++ b/src/signatures/aes.rs @@ -18,7 +18,7 @@ pub fn aes_sbox_parser( ) -> Result { // Successful return value let result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_LOW, ..Default::default() diff --git a/src/signatures/androidsparse.rs b/src/signatures/androidsparse.rs index 6937eb34d..8113d87e2 100644 --- a/src/signatures/androidsparse.rs +++ b/src/signatures/androidsparse.rs @@ -17,7 +17,7 @@ pub fn android_sparse_parser( ) -> Result { // Default result, returned on success let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_HIGH, ..Default::default() diff --git a/src/signatures/bzip2.rs b/src/signatures/bzip2.rs index 04f618477..987a115f1 100644 --- a/src/signatures/bzip2.rs +++ b/src/signatures/bzip2.rs @@ -24,7 +24,7 @@ pub fn bzip2_parser(file_data: &[u8], offset: usize) -> Result Result Vec> { pub fn chk_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_MEDIUM, ..Default::default() diff --git a/src/signatures/compressd.rs b/src/signatures/compressd.rs index 502fb0d4d..b3ca915ea 100644 --- a/src/signatures/compressd.rs +++ b/src/signatures/compressd.rs @@ -15,7 +15,7 @@ pub fn compressd_parser( ) -> Result { // Successful return value; confidence is medium since this only matches magic bytes at the beginning of a file let result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_MEDIUM, ..Default::default() diff --git a/src/signatures/copyright.rs b/src/signatures/copyright.rs index 9fd0da875..0dbcc6c6b 100644 --- a/src/signatures/copyright.rs +++ b/src/signatures/copyright.rs @@ -23,7 +23,7 @@ pub fn copyright_parser( // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_HIGH, ..Default::default() diff --git a/src/signatures/cpio.rs b/src/signatures/cpio.rs index f997bc4cb..44b8b7de4 100644 --- a/src/signatures/cpio.rs +++ b/src/signatures/cpio.rs @@ -18,7 +18,7 @@ pub fn cpio_parser(file_data: &[u8], offset: usize) -> Result Vec> { pub fn deb_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_HIGH, ..Default::default() diff --git a/src/signatures/dlob.rs b/src/signatures/dlob.rs index 789991f04..f5cb93721 100644 --- a/src/signatures/dlob.rs +++ b/src/signatures/dlob.rs @@ -13,7 +13,7 @@ pub fn dlob_magic() -> Vec> { pub fn dlob_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_MEDIUM, ..Default::default() diff --git a/src/signatures/dtb.rs b/src/signatures/dtb.rs index 239efcd60..3dd202b9b 100644 --- a/src/signatures/dtb.rs +++ b/src/signatures/dtb.rs @@ -13,7 +13,7 @@ pub fn dtb_magic() -> Vec> { pub fn dtb_parser(file_data: &[u8], offset: usize) -> Result { // Sucessful result let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_MEDIUM, ..Default::default() diff --git a/src/signatures/ecos.rs b/src/signatures/ecos.rs index ffff3cd2a..ce765112a 100644 --- a/src/signatures/ecos.rs +++ b/src/signatures/ecos.rs @@ -32,7 +32,7 @@ pub fn exception_handler_parser( ) -> Result { // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: EXCEPTION_HANDLER_DESCRIPTION.to_string(), confidence: CONFIDENCE_LOW, ..Default::default() diff --git a/src/signatures/elf.rs b/src/signatures/elf.rs index 1f2665074..e5f2feb2d 100644 --- a/src/signatures/elf.rs +++ b/src/signatures/elf.rs @@ -13,7 +13,7 @@ pub fn elf_magic() -> Vec> { pub fn elf_parser(file_data: &[u8], offset: usize) -> Result { // Successful result let mut result = SignatureResult { - offset: offset, + offset, name: "elf".to_string(), description: DESCRIPTION.to_string(), confidence: CONFIDENCE_MEDIUM, diff --git a/src/signatures/gif.rs b/src/signatures/gif.rs index b2a40eaf4..f1708ada2 100644 --- a/src/signatures/gif.rs +++ b/src/signatures/gif.rs @@ -15,7 +15,7 @@ pub fn gif_magic() -> Vec> { pub fn gif_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_HIGH, ..Default::default() diff --git a/src/signatures/gpg.rs b/src/signatures/gpg.rs index cfc355058..223e6bda4 100644 --- a/src/signatures/gpg.rs +++ b/src/signatures/gpg.rs @@ -16,7 +16,7 @@ pub fn gpg_signed_parser( ) -> Result { // Success result; confidence is high since this signature is only reported what it starts at the beginning of a file let result = SignatureResult { - offset: offset, + offset, confidence: CONFIDENCE_HIGH, description: GPG_SIGNED_DESCRIPTION.to_string(), ..Default::default() diff --git a/src/signatures/gzip.rs b/src/signatures/gzip.rs index 5433af3c8..f2681b401 100644 --- a/src/signatures/gzip.rs +++ b/src/signatures/gzip.rs @@ -40,7 +40,7 @@ pub fn gzip_parser(file_data: &[u8], offset: usize) -> Result Result Result Result { // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: JBOOT_STAG_DESCRIPTION.to_string(), confidence: CONFIDENCE_LOW, ..Default::default() @@ -117,7 +117,7 @@ pub fn jboot_sch2_parser( ) -> Result { // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: JBOOT_SCH2_DESCRIPTION.to_string(), confidence: CONFIDENCE_HIGH, ..Default::default() diff --git a/src/signatures/jffs2.rs b/src/signatures/jffs2.rs index d91698c77..afdc1c90a 100644 --- a/src/signatures/jffs2.rs +++ b/src/signatures/jffs2.rs @@ -32,7 +32,7 @@ pub fn jffs2_parser(file_data: &[u8], offset: usize) -> Result Vec> { pub fn jpeg_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_MEDIUM, ..Default::default() diff --git a/src/signatures/linux.rs b/src/signatures/linux.rs index 178d3064c..24cd33a0b 100644 --- a/src/signatures/linux.rs +++ b/src/signatures/linux.rs @@ -68,7 +68,7 @@ pub fn linux_boot_image_parser( let result = SignatureResult { description: LINUX_BOOT_IMAGE_DESCRIPTION.to_string(), - offset: offset, + offset, size: 0, ..Default::default() }; @@ -107,7 +107,7 @@ pub fn linux_kernel_version_parser( const GCC_VERSION_STRING: &str = "gcc "; let mut result = SignatureResult { - offset: offset, + offset, confidence: CONFIDENCE_LOW, ..Default::default() }; diff --git a/src/signatures/luks.rs b/src/signatures/luks.rs index 7829f0914..a55e93537 100644 --- a/src/signatures/luks.rs +++ b/src/signatures/luks.rs @@ -13,7 +13,7 @@ pub fn luks_magic() -> Vec> { pub fn luks_parser(file_data: &[u8], offset: usize) -> Result { // Successful result let mut result = SignatureResult { - offset: offset, + offset, name: "luks".to_string(), description: DESCRIPTION.to_string(), confidence: CONFIDENCE_MEDIUM, diff --git a/src/signatures/lz4.rs b/src/signatures/lz4.rs index 34bd3c4aa..5a13c8fbf 100644 --- a/src/signatures/lz4.rs +++ b/src/signatures/lz4.rs @@ -16,7 +16,7 @@ pub fn lz4_parser(file_data: &[u8], offset: usize) -> Result Vec> { /// Validate LZFSE signatures pub fn lzfse_parser(file_data: &[u8], offset: usize) -> Result { let mut result = SignatureResult { - offset: offset, + offset, confidence: CONFIDENCE_HIGH, description: DESCRIPTION.to_string(), ..Default::default() diff --git a/src/signatures/lzma.rs b/src/signatures/lzma.rs index 6379c36cf..75856a861 100644 --- a/src/signatures/lzma.rs +++ b/src/signatures/lzma.rs @@ -48,7 +48,7 @@ pub fn lzma_magic() -> Vec> { pub fn lzma_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_HIGH, ..Default::default() diff --git a/src/signatures/lzop.rs b/src/signatures/lzop.rs index bbd6cef1e..94bbb36bb 100644 --- a/src/signatures/lzop.rs +++ b/src/signatures/lzop.rs @@ -16,7 +16,7 @@ pub fn lzop_magic() -> Vec> { pub fn lzop_parser(file_data: &[u8], offset: usize) -> Result { // Success retrun value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_HIGH, ..Default::default() diff --git a/src/signatures/openssl.rs b/src/signatures/openssl.rs index 9645d419d..b74763065 100644 --- a/src/signatures/openssl.rs +++ b/src/signatures/openssl.rs @@ -18,7 +18,7 @@ pub fn openssl_crypt_parser( ) -> Result { // Success return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_LOW, ..Default::default() diff --git a/src/signatures/packimg.rs b/src/signatures/packimg.rs index ffd369f89..e65f8c371 100644 --- a/src/signatures/packimg.rs +++ b/src/signatures/packimg.rs @@ -12,7 +12,7 @@ pub fn packimg_magic() -> Vec> { /// Parse a PackIMG signature pub fn packimg_parser(file_data: &[u8], offset: usize) -> Result { let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), ..Default::default() }; diff --git a/src/signatures/pcap.rs b/src/signatures/pcap.rs index e66ecb109..1097d8abf 100644 --- a/src/signatures/pcap.rs +++ b/src/signatures/pcap.rs @@ -13,7 +13,7 @@ pub fn pcapng_magic() -> Vec> { pub fn pcapng_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: PCAPNG_DESCRIPTION.to_string(), confidence: CONFIDENCE_HIGH, ..Default::default() diff --git a/src/signatures/pdf.rs b/src/signatures/pdf.rs index 62d1d8825..4e3503a57 100644 --- a/src/signatures/pdf.rs +++ b/src/signatures/pdf.rs @@ -25,7 +25,7 @@ pub fn pdf_parser(file_data: &[u8], offset: usize) -> Result Vec> { pub fn pe_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_MEDIUM, ..Default::default() diff --git a/src/signatures/pem.rs b/src/signatures/pem.rs index 917039f36..c01e4cb3e 100644 --- a/src/signatures/pem.rs +++ b/src/signatures/pem.rs @@ -35,7 +35,7 @@ pub fn pem_parser(file_data: &[u8], offset: usize) -> Result Result Vec> { pub fn png_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_HIGH, ..Default::default() diff --git a/src/signatures/qnx.rs b/src/signatures/qnx.rs index faf93a4b5..b44f26e3e 100644 --- a/src/signatures/qnx.rs +++ b/src/signatures/qnx.rs @@ -17,7 +17,7 @@ pub fn qnx_ifs_magic() -> Vec> { pub fn qnx_ifs_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { - offset: offset, + offset, description: IFS_DESCRIPTION.to_string(), ..Default::default() }; diff --git a/src/signatures/rar.rs b/src/signatures/rar.rs index 427dbe1e0..449a3e22a 100644 --- a/src/signatures/rar.rs +++ b/src/signatures/rar.rs @@ -15,7 +15,7 @@ pub fn rar_magic() -> Vec> { pub fn rar_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), ..Default::default() }; diff --git a/src/signatures/riff.rs b/src/signatures/riff.rs index 175e9665c..b10015177 100644 --- a/src/signatures/riff.rs +++ b/src/signatures/riff.rs @@ -13,7 +13,7 @@ pub fn riff_magic() -> Vec> { pub fn riff_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_MEDIUM, ..Default::default() diff --git a/src/signatures/romfs.rs b/src/signatures/romfs.rs index adffc57f6..442739ef7 100644 --- a/src/signatures/romfs.rs +++ b/src/signatures/romfs.rs @@ -15,7 +15,7 @@ pub fn romfs_parser(file_data: &[u8], offset: usize) -> Result Vec> { pub fn rsa_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_MEDIUM, ..Default::default() diff --git a/src/signatures/rtk.rs b/src/signatures/rtk.rs index 47edf7488..2c8a0b971 100644 --- a/src/signatures/rtk.rs +++ b/src/signatures/rtk.rs @@ -13,7 +13,7 @@ pub fn rtk_magic() -> Vec> { pub fn rtk_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_MEDIUM, ..Default::default() diff --git a/src/signatures/seama.rs b/src/signatures/seama.rs index 45d09113c..de79d7394 100644 --- a/src/signatures/seama.rs +++ b/src/signatures/seama.rs @@ -16,7 +16,7 @@ pub fn seama_magic() -> Vec> { pub fn seama_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_LOW, ..Default::default() diff --git a/src/signatures/sevenzip.rs b/src/signatures/sevenzip.rs index f936cbb04..235040571 100644 --- a/src/signatures/sevenzip.rs +++ b/src/signatures/sevenzip.rs @@ -32,7 +32,7 @@ pub fn sevenzip_parser(file_data: &[u8], offset: usize) -> Result Result Result Vec> { pub fn svg_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_MEDIUM, ..Default::default() diff --git a/src/signatures/tarball.rs b/src/signatures/tarball.rs index 1f019857c..8b4418b3c 100644 --- a/src/signatures/tarball.rs +++ b/src/signatures/tarball.rs @@ -86,7 +86,7 @@ pub fn tarball_parser(file_data: &[u8], offset: usize) -> Result Vec> { pub fn tplink_parser(file_data: &[u8], offset: usize) -> Result { // Successful return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_MEDIUM, ..Default::default() diff --git a/src/signatures/trx.rs b/src/signatures/trx.rs index 5d56ec33d..b05b34a11 100644 --- a/src/signatures/trx.rs +++ b/src/signatures/trx.rs @@ -14,7 +14,7 @@ pub fn trx_magic() -> Vec> { pub fn trx_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_HIGH, ..Default::default() diff --git a/src/signatures/ubi.rs b/src/signatures/ubi.rs index 49b8936b0..0d1155e47 100644 --- a/src/signatures/ubi.rs +++ b/src/signatures/ubi.rs @@ -23,7 +23,7 @@ pub fn ubifs_magic() -> Vec> { pub fn ubifs_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { - offset: offset, + offset, description: UBI_FS_DESCRIPTION.to_string(), confidence: CONFIDENCE_HIGH, ..Default::default() @@ -44,7 +44,7 @@ pub fn ubifs_parser(file_data: &[u8], offset: usize) -> Result Result { // Success return value let mut result = SignatureResult { - offset: offset, + offset, description: UBI_IMAGE_DESCRIPTION.to_string(), confidence: CONFIDENCE_HIGH, ..Default::default() diff --git a/src/signatures/uefi.rs b/src/signatures/uefi.rs index 1f57dee4d..dc019b3ec 100644 --- a/src/signatures/uefi.rs +++ b/src/signatures/uefi.rs @@ -68,7 +68,7 @@ pub fn uefi_capsule_parser( // Success return value let mut result = SignatureResult { description: CAPSULE_DESCRIPTION.to_string(), - offset: offset, + offset, size: 0, confidence: CONFIDENCE_MEDIUM, ..Default::default() diff --git a/src/signatures/uimage.rs b/src/signatures/uimage.rs index 1f51bf60b..f718b4285 100644 --- a/src/signatures/uimage.rs +++ b/src/signatures/uimage.rs @@ -16,7 +16,7 @@ pub fn uimage_parser(file_data: &[u8], offset: usize) -> Result Vec> { pub fn xz_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_HIGH, ..Default::default() diff --git a/src/signatures/yaffs.rs b/src/signatures/yaffs.rs index 55211e5a5..e99736714 100644 --- a/src/signatures/yaffs.rs +++ b/src/signatures/yaffs.rs @@ -26,7 +26,7 @@ pub fn yaffs_parser(file_data: &[u8], offset: usize) -> Result Vec> { pub fn zip_parser(file_data: &[u8], offset: usize) -> Result { // Success return value let mut result = SignatureResult { - offset: offset, + offset, description: DESCRIPTION.to_string(), confidence: CONFIDENCE_HIGH, ..Default::default() diff --git a/src/signatures/zlib.rs b/src/signatures/zlib.rs index 9d9352a15..171fb74cc 100644 --- a/src/signatures/zlib.rs +++ b/src/signatures/zlib.rs @@ -16,7 +16,7 @@ pub fn zlib_magic() -> Vec> { /// Validate a zlib signature pub fn zlib_parser(file_data: &[u8], offset: usize) -> Result { let mut result = SignatureResult { - offset: offset, + offset, confidence: CONFIDENCE_HIGH, description: DESCRIPTION.to_string(), ..Default::default() diff --git a/src/signatures/zstd.rs b/src/signatures/zstd.rs index fd9ad0e38..c7aa2a41d 100644 --- a/src/signatures/zstd.rs +++ b/src/signatures/zstd.rs @@ -19,7 +19,7 @@ pub fn zstd_parser(file_data: &[u8], offset: usize) -> Result Result { // Endianness doesn't matter here, and we don't know what the ELF's endianness is yet if let Ok(e_ident) = common::parse(elf_data, &elf_ident_structure, "little") { // Sanity check the e_ident fields - if e_ident["padding_1"] == 0 && e_ident["padding_2"] == 0 { - if e_ident["version"] == EXPECTED_VERSION { - if elf_classes.contains_key(&e_ident["class"]) { - if elf_osabi.contains_key(&e_ident["osabi"]) { - if elf_endianness.contains_key(&e_ident["endianness"]) { - // Set the ident info - elf_hdr_info.class = elf_classes[&e_ident["class"]].to_string(); - elf_hdr_info.osabi = elf_osabi[&e_ident["osabi"]].to_string(); - elf_hdr_info.endianness = - elf_endianness[&e_ident["endianness"]].to_string(); - - // The rest of the ELF info comes immediately after the ident structure - let elf_info_start: usize = ELF_IDENT_STRUCT_SIZE; - let elf_info_end: usize = elf_info_start + ELF_INFO_STRUCT_SIZE; - - if let Some(elf_info_raw) = elf_data.get(elf_info_start..elf_info_end) { - // Parse the remaining info from the ELF header - if let Ok(elf_info) = common::parse( - elf_info_raw, - &elf_info_structure, - elf_endianness[&e_ident["endianness"]], - ) { - // Sanity check the remaining ELF header fields - if elf_info["version"] == EXPECTED_VERSION { - if elf_types.contains_key(&elf_info["type"]) { - if elf_machines.contains_key(&elf_info["machine"]) { - // Set the ELF info fields - elf_hdr_info.exe_type = - elf_types[&elf_info["type"]].to_string(); - elf_hdr_info.machine = - elf_machines[&elf_info["machine"]].to_string(); - - return Ok(elf_hdr_info); - } - } - } - } - } - } + if e_ident["padding_1"] == 0 + && e_ident["padding_2"] == 0 + && e_ident["version"] == EXPECTED_VERSION + && elf_classes.contains_key(&e_ident["class"]) + && elf_osabi.contains_key(&e_ident["osabi"]) + && elf_endianness.contains_key(&e_ident["endianness"]) + { + // Set the ident info + elf_hdr_info.class = elf_classes[&e_ident["class"]].to_string(); + elf_hdr_info.osabi = elf_osabi[&e_ident["osabi"]].to_string(); + elf_hdr_info.endianness = elf_endianness[&e_ident["endianness"]].to_string(); + + // The rest of the ELF info comes immediately after the ident structure + let elf_info_start: usize = ELF_IDENT_STRUCT_SIZE; + let elf_info_end: usize = elf_info_start + ELF_INFO_STRUCT_SIZE; + + if let Some(elf_info_raw) = elf_data.get(elf_info_start..elf_info_end) { + // Parse the remaining info from the ELF header + if let Ok(elf_info) = common::parse( + elf_info_raw, + &elf_info_structure, + elf_endianness[&e_ident["endianness"]], + ) { + // Sanity check the remaining ELF header fields + if elf_info["version"] == EXPECTED_VERSION + && elf_types.contains_key(&elf_info["type"]) + && elf_machines.contains_key(&elf_info["machine"]) + { + // Set the ELF info fields + elf_hdr_info.exe_type = elf_types[&elf_info["type"]].to_string(); + elf_hdr_info.machine = elf_machines[&elf_info["machine"]].to_string(); + + return Ok(elf_hdr_info); } } } diff --git a/src/structures/gzip.rs b/src/structures/gzip.rs index 0efe965b6..2b890730d 100644 --- a/src/structures/gzip.rs +++ b/src/structures/gzip.rs @@ -67,82 +67,80 @@ pub fn parse_gzip_header(header_data: &[u8]) -> Result { - return Err(StructureError); - } - Some(extra_header_data) => { - // Parse the extra header and update the header_info.size to include this data - match common::parse( - extra_header_data, - &gzip_extra_header_structure, - "little", - ) { - Err(e) => { - return Err(e); - } - Ok(extra_header) => { - header_info.size += - extra_header_size + extra_header["extra_data_len"]; - } - } - } - } + if (gzip_header["flags"] & FLAG_RESERVED) == 0 + && gzip_header["compression_method"] == DEFLATE_COMPRESSION + && known_os_ids.contains_key(&gzip_header["osid"]) + { + // Set the operating system string + header_info.os = known_os_ids[&gzip_header["osid"]].to_string(); + + // Check if the optional "extra" data follows the standard Gzip header + if (gzip_header["flags"] & FLAG_EXTRA) != 0 { + // File offsets and sizes for parsing the extra header + let extra_header_size = common::size(&gzip_extra_header_structure); + let extra_header_start: usize = header_info.size; + let extra_header_end: usize = extra_header_start + extra_header_size; + + match header_data.get(extra_header_start..extra_header_end) { + None => { + return Err(StructureError); } - - // If the NULL-terminated original file name is included, it will be next - if (gzip_header["flags"] & FLAG_NAME) != 0 { - match header_data.get(header_info.size..) { - None => { - return Err(StructureError); + Some(extra_header_data) => { + // Parse the extra header and update the header_info.size to include this data + match common::parse( + extra_header_data, + &gzip_extra_header_structure, + "little", + ) { + Err(e) => { + return Err(e); } - Some(file_name_bytes) => { - header_info.original_name = get_cstring(file_name_bytes); - // The value returned by get_cstring does not include the terminating NULL byte + Ok(extra_header) => { header_info.size += - header_info.original_name.len() + NULL_BYTE_SIZE; + extra_header_size + extra_header["extra_data_len"]; } } } + } + } - // If a NULL-terminated comment is included, it will be next - if (gzip_header["flags"] & FLAG_COMMENT) != 0 { - match header_data.get(header_info.size..) { - None => { - return Err(StructureError); - } - Some(comment_bytes) => { - header_info.comment = get_cstring(comment_bytes); - // The value returned by get_cstring does not include the terminating NULL byte - header_info.size += header_info.comment.len() + NULL_BYTE_SIZE; - } - } + // If the NULL-terminated original file name is included, it will be next + if (gzip_header["flags"] & FLAG_NAME) != 0 { + match header_data.get(header_info.size..) { + None => { + return Err(StructureError); } - - // Finally, a checksum field may be included - if (gzip_header["flags"] & FLAG_CRC) != 0 { - header_info.size += CRC_SIZE; + Some(file_name_bytes) => { + header_info.original_name = get_cstring(file_name_bytes); + // The value returned by get_cstring does not include the terminating NULL byte + header_info.size += header_info.original_name.len() + NULL_BYTE_SIZE; } + } + } - // Deflate data should start at header_info.size; make sure this offset is sane - if header_data.len() >= header_info.size { - return Ok(header_info); + // If a NULL-terminated comment is included, it will be next + if (gzip_header["flags"] & FLAG_COMMENT) != 0 { + match header_data.get(header_info.size..) { + None => { + return Err(StructureError); + } + Some(comment_bytes) => { + header_info.comment = get_cstring(comment_bytes); + // The value returned by get_cstring does not include the terminating NULL byte + header_info.size += header_info.comment.len() + NULL_BYTE_SIZE; } } } + + // Finally, a checksum field may be included + if (gzip_header["flags"] & FLAG_CRC) != 0 { + header_info.size += CRC_SIZE; + } + + // Deflate data should start at header_info.size; make sure this offset is sane + if header_data.len() >= header_info.size { + return Ok(header_info); + } } } diff --git a/src/structures/jboot.rs b/src/structures/jboot.rs index 1f87ae01e..ea192b6ab 100644 --- a/src/structures/jboot.rs +++ b/src/structures/jboot.rs @@ -74,7 +74,7 @@ pub fn parse_jboot_arm_header(jboot_data: &[u8]) -> Result Result Result // Parse the lzma header if let Ok(lzma_header) = common::parse(lzma_data, &lzma_structure, "little") { - // Sanity check expected values for LZMA header fields + // Make sure the expected NULL byte is NULL if lzma_header["null_byte"] == 0 { - if lzma_header["decompressed_size"] >= MIN_SUPPORTED_DECOMPRESSED_SIZE { - if lzma_header["decompressed_size"] == LZMA_STREAM_SIZE - || lzma_header["decompressed_size"] <= MAX_SUPPORTED_DECOMPRESSED_SIZE - { - lzma_hdr_info.properties = lzma_header["properties"]; - lzma_hdr_info.dictionary_size = lzma_header["dictionary_size"]; - lzma_hdr_info.decompressed_size = lzma_header["decompressed_size"]; - - return Ok(lzma_hdr_info); - } + // Sanity check the reported decompressed size + if lzma_header["decompressed_size"] >= MIN_SUPPORTED_DECOMPRESSED_SIZE + && (lzma_header["decompressed_size"] == LZMA_STREAM_SIZE + || lzma_header["decompressed_size"] <= MAX_SUPPORTED_DECOMPRESSED_SIZE) + { + lzma_hdr_info.properties = lzma_header["properties"]; + lzma_hdr_info.dictionary_size = lzma_header["dictionary_size"]; + lzma_hdr_info.decompressed_size = lzma_header["decompressed_size"]; + + return Ok(lzma_hdr_info); } } } diff --git a/src/structures/pchrom.rs b/src/structures/pchrom.rs index 3e057ca90..367687a34 100644 --- a/src/structures/pchrom.rs +++ b/src/structures/pchrom.rs @@ -36,19 +36,18 @@ pub fn parse_pchrom_header(pch_data: &[u8]) -> Result Result= header_size { - if available_data >= total_header_size { - return Ok(SeamaHeader { - data_size: seama_header["data_size"], - header_size: total_header_size, - }); - } + if total_header_size >= header_size && available_data >= total_header_size { + return Ok(SeamaHeader { + data_size: seama_header["data_size"], + header_size: total_header_size, + }); } } } diff --git a/src/structures/uimage.rs b/src/structures/uimage.rs index 5025d35f9..41e0da4d2 100644 --- a/src/structures/uimage.rs +++ b/src/structures/uimage.rs @@ -156,33 +156,27 @@ pub fn parse_uimage_header(uimage_data: &[u8]) -> Result Date: Sun, 20 Oct 2024 21:16:56 -0400 Subject: [PATCH 009/131] Lint fixes complete --- src/cliparser.rs | 2 +- src/common.rs | 1 - src/display.rs | 57 +++++++++++++++++++++++------------------------- src/entropy.rs | 12 +++++----- src/json.rs | 14 +++++------- src/main.rs | 34 +++++++++++++---------------- 6 files changed, 54 insertions(+), 66 deletions(-) diff --git a/src/cliparser.rs b/src/cliparser.rs index 6ffddb5df..ae8461e26 100644 --- a/src/cliparser.rs +++ b/src/cliparser.rs @@ -52,5 +52,5 @@ pub struct CliArgs { } pub fn parse() -> CliArgs { - return CliArgs::parse(); + CliArgs::parse() } diff --git a/src/common.rs b/src/common.rs index 7e3d40e3d..aae12b280 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,6 +1,5 @@ //! Common Functions use chrono::prelude::DateTime; -use crc32_v2; use log::{debug, error}; use std::fs::File; use std::io::Read; diff --git a/src/display.rs b/src/display.rs index cc620c52d..14c6dab94 100644 --- a/src/display.rs +++ b/src/display.rs @@ -7,7 +7,6 @@ use std::collections::HashMap; use std::io; use std::io::Write; use std::time; -use termsize; const DELIM_CHARACTER: &str = "-"; const DEFAULT_TERMINAL_WIDTH: u16 = 200; @@ -16,24 +15,22 @@ const COLUMN1_WIDTH: usize = 35; const COLUMN2_WIDTH: usize = 35; fn terminal_width() -> usize { - let terminal_width: u16; - - match termsize::get() { - Some(ts) => terminal_width = ts.cols, - None => terminal_width = DEFAULT_TERMINAL_WIDTH, + let terminal_width: u16 = match termsize::get() { + Some(ts) => ts.cols, + None => DEFAULT_TERMINAL_WIDTH, }; - return terminal_width as usize; + terminal_width as usize } fn line_delimiter() -> String { let mut delim: String = "".to_string(); for _i in 0..terminal_width() { - delim = delim + DELIM_CHARACTER; + delim += DELIM_CHARACTER; } - return delim; + delim } fn center_text(text: &String) -> String { @@ -55,7 +52,7 @@ fn center_text(text: &String) -> String { centered_string += text; - return centered_string; + centered_string } fn pad_to_length(text: &str, len: usize) -> String { @@ -72,13 +69,13 @@ fn pad_to_length(text: &str, len: usize) -> String { } for _i in 0..pad_size { - padded_string = padded_string + " "; + padded_string += " "; } - return padded_string; + padded_string } -fn line_wrap(text: &String, prefix_size: usize) -> String { +fn line_wrap(text: &str, prefix_size: usize) -> String { let mut this_line = "".to_string(); let mut formatted_string = "".to_string(); let max_line_size: usize = terminal_width() - prefix_size; @@ -89,7 +86,7 @@ fn line_wrap(text: &String, prefix_size: usize) -> String { } else { formatted_string = formatted_string + &this_line + "\n"; for _i in 0..prefix_size { - formatted_string = formatted_string + " "; + formatted_string += " "; } this_line = word.to_string() + " "; } @@ -116,7 +113,7 @@ fn print_delimiter() { } fn print_header(title_text: &String) { - println!(""); + println!(); println!("{}", center_text(title_text).bold().magenta()); print_delimiter(); print_column_headers("DECIMAL", "HEXADECIMAL", "DESCRIPTION"); @@ -125,7 +122,7 @@ fn print_header(title_text: &String) { fn print_footer() { print_delimiter(); - println!(""); + println!(); } fn print_signature(signature: &signatures::common::SignatureResult) { @@ -169,7 +166,7 @@ fn print_extraction( .yellow(); } Some(extraction_result) => { - if extraction_result.success == true { + if extraction_result.success { extraction_message = format!( "[+] Extraction of {} data at offset {:#X} completed successfully", signature.name, signature.offset @@ -201,7 +198,7 @@ fn print_extractions( let mut extraction_result: Option<&extractors::common::ExtractionResult> = None; // Only print extraction results if an extraction was attempted or explicitly declined - if signature.extraction_declined == true { + if signature.extraction_declined { printable_extraction = true } else if extraction_results.contains_key(&signature.id) { printable_extraction = true; @@ -210,7 +207,7 @@ fn print_extractions( if printable_extraction { // Only print the delimiter line once - if delimiter_printed == false { + if !delimiter_printed { print_delimiter(); delimiter_printed = true; } @@ -220,7 +217,7 @@ fn print_extractions( } pub fn print_analysis_results(quiet: bool, extraction_attempted: bool, results: &AnalysisResults) { - if quiet == true { + if quiet { return; } @@ -253,7 +250,7 @@ pub fn print_signature_list(quiet: bool, signatures: &Vec = vec![]; let mut signature_lookup: HashMap = HashMap::new(); - if quiet == true { + if quiet { return; } @@ -306,7 +303,7 @@ pub fn print_signature_list(quiet: bool, signatures: &Vec= MS_IN_A_SECOND { - display_time = display_time / MS_IN_A_SECOND; + display_time /= MS_IN_A_SECOND; units = "seconds"; if display_time >= SECONDS_IN_A_MINUTE { - display_time = display_time / SECONDS_IN_A_MINUTE; + display_time /= SECONDS_IN_A_MINUTE; units = "minutes"; if display_time >= MINUTES_IN_AN_HOUR { - display_time = display_time / MINUTES_IN_AN_HOUR; + display_time /= MINUTES_IN_AN_HOUR; units = "hours"; } } @@ -390,14 +387,14 @@ pub fn print_stats( } pub fn print_plain(quiet: bool, msg: &str) { - if quiet == false { + if !quiet { print!("{}", msg); let _ = io::stdout().flush(); } } pub fn println_plain(quiet: bool, msg: &str) { - if quiet == false { + if !quiet { println!("{}", msg); } } diff --git a/src/entropy.rs b/src/entropy.rs index df02ada78..e3455262f 100644 --- a/src/entropy.rs +++ b/src/entropy.rs @@ -53,7 +53,7 @@ fn blocks(data: &[u8]) -> Vec { offset += block_size; } - return entropy_blocks; + entropy_blocks } /// Generate a plot of a file's entropy. @@ -81,7 +81,7 @@ pub fn plot(file_path: impl Into) -> Result { let png_path = file_entropy.file.clone(); // Make sure the output file doesn't already exist - if path::Path::new(&png_path).exists() == true { + if path::Path::new(&png_path).exists() { error!("Cannot create entropy graph {}: File exists", png_path); return Err(EntropyError); } @@ -119,14 +119,14 @@ pub fn plot(file_path: impl Into) -> Result { // Set the axis colors ctx.configure_mesh() - .axis_style(&GREEN) + .axis_style(GREEN) .x_label_style(&GREEN) .draw() .unwrap(); // Line plot of the entropy points ctx.draw_series(LineSeries::new( - points.into_iter().map(|(x, y)| (x, y)), + points, //.into_iter().map(|(x, y)| (x, y)), &YELLOW, )) .unwrap(); @@ -136,7 +136,7 @@ pub fn plot(file_path: impl Into) -> Result { * Plotter code doesn't throw any errors if graph file creation fails. * Make sure the output file was created. */ - if path::Path::new(&png_path).exists() == false { + if !path::Path::new(&png_path).exists() { error!( "Failed to create entropy graph {}: possible permissions error?", png_path @@ -144,5 +144,5 @@ pub fn plot(file_path: impl Into) -> Result { return Err(EntropyError); } - return Ok(file_entropy); + Ok(file_entropy) } diff --git a/src/json.rs b/src/json.rs index 204f5cd23..b60497fda 100644 --- a/src/json.rs +++ b/src/json.rs @@ -1,6 +1,5 @@ use log::error; use serde::{Deserialize, Serialize}; -use serde_json; use std::fs; use std::io; use std::io::Seek; @@ -23,7 +22,7 @@ pub fn log(json_file: &Option, results: JSONType) { const JSON_COMMA_SEPERATOR: &str = ",\n"; match json_file { - None => return, + None => (), Some(file_name) => { // Convert analysis results to JSON match serde_json::to_string_pretty(&results) { @@ -32,20 +31,18 @@ pub fn log(json_file: &Option, results: JSONType) { // Open file for reading and writing, create if does not already exist match fs::OpenOptions::new() .create(true) + .append(true) .read(true) - .write(true) - .open(&file_name) + .open(file_name) { Err(e) => { error!("Failed to open JSON log file '{}': {}", file_name, e); - return; } Ok(mut fp) => { // Seek to the end of the file and get the cursor position match fp.seek(io::SeekFrom::End(0)) { Err(e) => { error!("Failed to see to end of JSON file: {}", e); - return; } Ok(pos) => { if pos == 0 { @@ -82,8 +79,7 @@ pub fn log(json_file: &Option, results: JSONType) { } fn write_to_json_file(mut fp: &fs::File, data: String) { - match fp.write_all(data.as_bytes()) { - Ok(_) => return, - Err(e) => error!("Failed to write to JSON log file: {}", e), + if let Err(e) = fp.write_all(data.as_bytes()) { + error!("Failed to write to JSON log file: {}", e); } } diff --git a/src/main.rs b/src/main.rs index ae373b28e..d6cc06fa4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -49,7 +49,7 @@ fn main() { let cliargs = cliparser::parse(); // If --list was specified, just display a list of signatures and return - if cliargs.list == true { + if cliargs.list { display::print_signature_list(cliargs.quiet, &magic::patterns()); return; } @@ -60,7 +60,7 @@ fn main() { } // If entropy analysis was requested, generate the entropy graph and return - if cliargs.entropy == true { + if cliargs.entropy { display::print_plain(cliargs.quiet, "Calculating file entropy..."); if let Ok(entropy_results) = entropy::plot(cliargs.file_name.unwrap()) { @@ -80,7 +80,7 @@ fn main() { } // If extraction was requested, we need to initialize the output directory - if cliargs.extract == true { + if cliargs.extract { output_directory = Some(cliargs.directory); } @@ -143,9 +143,9 @@ fn main() { * Main loop. * Loop until all pending thread jobs are complete and there are no more files in the queue. */ - while target_files.is_empty() == false || workers.active_count() > 0 { + while !target_files.is_empty() || workers.active_count() > 0 { // If there are files waiting to be analyzed and there is at least one free thread in the pool - if target_files.is_empty() == false && workers.active_count() < workers.max_count() { + if !target_files.is_empty() && workers.active_count() < workers.max_count() { // Get the next file path from the target_files queue let target_file = target_files .pop_front() @@ -162,7 +162,7 @@ fn main() { } // Don't spin CPU cycles if there is no backlog of files to analyze - if target_files.is_empty() == true { + if target_files.is_empty() { let sleep_time = time::Duration::from_millis(1); thread::sleep(sleep_time); } @@ -187,20 +187,20 @@ fn main() { json::log(&cliargs.log, json::JSONType::Analysis(results.clone())); // Nothing found? Nothing else to do for this file. - if results.file_map.len() == 0 { + if results.file_map.is_empty() { debug!("Found no results for file {}", results.file_path); continue; } // Print analysis results to screen - if should_display(&results, file_count, cliargs.verbose) == true { + if should_display(&results, file_count, cliargs.verbose) { display::print_analysis_results(cliargs.quiet, cliargs.extract, &results); } // If running recursively, add extraction results to list of files to analyze if cliargs.matryoshka { for (_signature_id, extraction_result) in results.extractions.into_iter() { - if extraction_result.do_not_recurse == false { + if !extraction_result.do_not_recurse { for file_path in extractors::common::get_extracted_files( &extraction_result.output_directory, ) { @@ -232,22 +232,18 @@ fn should_display(results: &AnalysisResults, file_count: usize, verbose: bool) - * contain signatures that we always want displayed, or which contain extractable signatures. * This can be overridden with the --verbose command line flag. */ - if file_count == 1 || verbose == true { + if file_count == 1 || verbose || !results.extractions.is_empty() { display_results = true; } else { - if results.extractions.len() > 0 { - display_results = true; - } else { - for signature in &results.file_map { - if signature.always_display == true { - display_results = true; - break; - } + for signature in &results.file_map { + if signature.always_display { + display_results = true; + break; } } } - return display_results; + display_results } /// Spawn a worker thread to analyze a file From bc588623233357bb54dacaa207cd1cd6ea237d20 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sun, 20 Oct 2024 23:00:07 -0400 Subject: [PATCH 010/131] Added load address info to uImage output --- src/signatures/uimage.rs | 4 +++- src/structures/uimage.rs | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/signatures/uimage.rs b/src/signatures/uimage.rs index f718b4285..fd551c835 100644 --- a/src/signatures/uimage.rs +++ b/src/signatures/uimage.rs @@ -32,7 +32,7 @@ pub fn uimage_parser(file_data: &[u8], offset: usize) -> Result Result Result Date: Mon, 21 Oct 2024 14:17:17 +0200 Subject: [PATCH 011/131] feat(gh-workflow-quality): add lint check --- .github/workflows/quality.yaml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.github/workflows/quality.yaml b/.github/workflows/quality.yaml index cb22fa3d1..323632fea 100644 --- a/.github/workflows/quality.yaml +++ b/.github/workflows/quality.yaml @@ -38,3 +38,28 @@ jobs: - name: Formatting (rustfmt) run: cargo fmt -- --check + + lint: + name: Lint (clippy) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + platform: + - target: x86_64-unknown-linux-gnu + + steps: + - name: Code checkout + uses: actions/checkout@v4 + + - name: Install Rust toolchain (stable) + uses: dtolnay/rust-toolchain@stable + with: + target: ${{ matrix.platform.target }} + components: clippy + + - name: Clippy (all crates) + run: cargo clippy --locked --target=${{ matrix.platform.target }} --workspace --all-targets -- -D warnings + + - name: Check build did not modify any files + run: test -z "$(git status --porcelain)" From e4fe3c3edd3ea20328d39fbfcffa2253be84cbd5 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Tue, 22 Oct 2024 11:18:25 -0400 Subject: [PATCH 012/131] Fixed docker issues --- Dockerfile | 29 +++++++++++++++++++---------- src/main.rs | 14 ++++++++++++++ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index a83e671fd..60416e485 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,32 +1,41 @@ FROM ubuntu:24.04 +ARG BINWALK_INSTALL_DIR="/tmp/binwalk" +ARG DEFAULT_WORKING_DIR="/analysis" + WORKDIR /tmp -# Update apt and install git -RUN apt-get update && apt-get upgrade -y && apt-get install -y git +# Update apt +RUN apt-get update && apt-get upgrade -y -# Pull down latest Binwalk code -RUN git clone https://github.com/ReFirmLabs/binwalk.git +# Copy over the Binwalk build directory +RUN mkdir -p ${BINWALK_INSTALL_DIR} +COPY . ${BINWALK_INSTALL_DIR} # Allow pip to install packages system-wide RUN mkdir -p $HOME/.config/pip && echo "[global]" > $HOME/.config/pip/pip.conf && echo "break-system-packages = true" >> $HOME/.config/pip/pip.conf # Install all system dependencies -RUN /tmp/binwalk/dependencies/ubuntu.sh +RUN ${BINWALK_INSTALL_DIR}/dependencies/ubuntu.sh # Install Rust RUN curl https://sh.rustup.rs -sSf | sh -s -- -y # Build and install Binwalk -RUN cd /tmp/binwalk && /root/.cargo/bin/cargo build --release && cp ./target/release/binwalk /usr/local/bin/binwalk +RUN cd ${BINWALK_INSTALL_DIR} && /root/.cargo/bin/cargo build --release && cp ./target/release/binwalk /usr/local/bin/binwalk # Clean up binwalk build directory -RUN rm -rf /tmp/binwalk +RUN rm -rf ${BINWALK_INSTALL_DIR} -RUN useradd -m -u 1337 -s /sbin/nologin appuser +# Create the working directory +RUN mkdir -p ${DEFAULT_WORKING_DIR} && chmod 777 ${DEFAULT_WORKING_DIR} +WORKDIR ${DEFAULT_WORKING_DIR} -WORKDIR /home/appuser +# Run as the default ubuntu user +USER ubuntu -USER appuser +# Enable this environment variable to remove extractor top-level symlink, +# as the symlink target path in the docker environment will not match that of the host. +ENV BINWALK_RM_EXTRACTION_SYMLINK=1 ENTRYPOINT [ "binwalk" ] diff --git a/src/main.rs b/src/main.rs index d6cc06fa4..65db04e52 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,6 +26,10 @@ fn main() { // Number of seconds to wait before printing debug progress info const PROGRESS_INTERVAL: u64 = 30; + // If this env var is set during extraction, the Binwalk.base_target_file symlink will + // be deleted at the end of extraction. + const BINWALK_RM_SYMLINK: &str = "BINWALK_RM_EXTRACTION_SYMLINK"; + // Output directory for extracted files let mut output_directory: Option = None; @@ -213,6 +217,16 @@ fn main() { } } + // If BINWALK_RM_SYMLINK env var was set, delete the base_target_file symlink + if cliargs.extract && std::env::var(BINWALK_RM_SYMLINK).is_ok() { + if let Err(e) = std::fs::remove_file(&binwalker.base_target_file) { + error!( + "Request to remove extraction symlink file {} failed: {}", + binwalker.base_target_file, e + ); + } + } + // All done, show some basic statistics display::print_stats( cliargs.quiet, From 9cc991997493f54a2a60b738036fb53076613631 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Tue, 22 Oct 2024 14:16:59 -0400 Subject: [PATCH 013/131] Fixed symlink target paths to be relative, rather than absolute --- src/extractors/common.rs | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/extractors/common.rs b/src/extractors/common.rs index 6c1666b8a..e4fea72a3 100644 --- a/src/extractors/common.rs +++ b/src/extractors/common.rs @@ -543,8 +543,7 @@ impl Chroot { /// Creates a symbolic link in the chroot directory, named `symlink_path`, which points to `target_path`. /// /// Note that both the symlink and target paths will be sanitized to stay in the chroot directory. - /// Both the symlink and target paths will be *absolute*, meaning that symlinks will break if the - /// symlink is later moved to a different absolute directory. + /// Both the target path will be converted into a path relative to the symlink file path. /// /// ## Example /// @@ -565,9 +564,6 @@ impl Chroot { symlink_path: impl Into, target_path: impl Into, ) -> bool { - let safe_target: String; - let safe_target_path: &path::Path; - let target = target_path.into(); let symlink = symlink_path.into(); @@ -575,10 +571,10 @@ impl Chroot { let safe_symlink = self.chrooted_path(&symlink); let safe_symlink_path = path::Path::new(&safe_symlink); - if target.starts_with(path::MAIN_SEPARATOR) { + // Normalize the symlink target path to a chrooted absolute path + let safe_target = if target.starts_with(path::MAIN_SEPARATOR) { // If the target path is absolute, just chroot it inside the chroot directory - safe_target = self.chrooted_path(&target); - safe_target_path = path::Path::new(&safe_target); + self.chrooted_path(&target) } else { // Get the symlink file's parent directory path let relative_dir: String = match safe_symlink_path.parent() { @@ -594,10 +590,33 @@ impl Chroot { // Join the target path with its relative directory, ensuring it does not traverse outside // the specified chroot directory - safe_target = self.safe_path_join(&relative_dir, &target); - safe_target_path = path::Path::new(&safe_target); + self.safe_path_join(&relative_dir, &target) + }; + + // Remove the chroot directory from the target and symlink paths. + // This results in each being an absolute path that is relative to the chroot directory, + // e.g., '/my_chroot_dir/bin/busybox' -> '/bin/busybox'. + let mut safe_target_rel_path = safe_target.replacen(&self.chroot_directory, "", 1); + let safe_symlink_rel_path = safe_symlink.replacen(&self.chroot_directory, "", 1); + + // Count the number of path separators (minus the leading one) and an '../' to the target + // path for each; e.g., '/bin/busybox' -> '..//bin/busybox'. + for _i in 0..safe_symlink_rel_path.matches(path::MAIN_SEPARATOR).count() - 1 { + safe_target_rel_path = format!("..{}{}", path::MAIN_SEPARATOR, safe_target_rel_path); } + // Add a './' at the beginning of the target path and remove any double slashes; + // e.g., '..//bin/busybox' -> './../bin/busybox'. + safe_target_rel_path = format!(".{}{}", path::MAIN_SEPARATOR, safe_target_rel_path); + safe_target_rel_path = self.strip_double_slash(&safe_target_rel_path); + + // The target path is now a safely chrooted path that is relative to the symlink file path. + // Ex: + // + // Original symlink: "/my_chroot_dir/usr/sbin/ls" is a symlink to "/bin/busybox" + // Safe relative symlink: "/my_chroot_dir/usr/sbin/ls" is a symlink to "./../../bin/busybox" + let safe_target_path = path::Path::new(&safe_target_rel_path); + #[cfg(unix)] { match unix::fs::symlink(safe_target_path, safe_symlink_path) { From 362922f2dca7d90980566be2420d694e682f2597 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Tue, 22 Oct 2024 17:22:31 -0400 Subject: [PATCH 014/131] Remove unecessary leading './' in some symlink paths --- src/extractors/common.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/extractors/common.rs b/src/extractors/common.rs index e4fea72a3..0e6b1e96c 100644 --- a/src/extractors/common.rs +++ b/src/extractors/common.rs @@ -605,9 +605,12 @@ impl Chroot { safe_target_rel_path = format!("..{}{}", path::MAIN_SEPARATOR, safe_target_rel_path); } - // Add a './' at the beginning of the target path and remove any double slashes; - // e.g., '..//bin/busybox' -> './../bin/busybox'. - safe_target_rel_path = format!(".{}{}", path::MAIN_SEPARATOR, safe_target_rel_path); + // Add a '.' at the beginning of any paths that start with '/', e.g., '/tmp' -> './tmp'. + if safe_target_rel_path.starts_with(path::MAIN_SEPARATOR) { + safe_target_rel_path = format!(".{}", safe_target_rel_path); + } + + // Replace any instances of '//' with '/' safe_target_rel_path = self.strip_double_slash(&safe_target_rel_path); // The target path is now a safely chrooted path that is relative to the symlink file path. From 24a2a96aeade0639ee170fbb5e588d4566b8ea34 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Tue, 22 Oct 2024 17:45:58 -0400 Subject: [PATCH 015/131] Fixed bug in create_symlink if chroot directory is '/' --- src/extractors/common.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/extractors/common.rs b/src/extractors/common.rs index 0e6b1e96c..d0dddeb64 100644 --- a/src/extractors/common.rs +++ b/src/extractors/common.rs @@ -596,8 +596,20 @@ impl Chroot { // Remove the chroot directory from the target and symlink paths. // This results in each being an absolute path that is relative to the chroot directory, // e.g., '/my_chroot_dir/bin/busybox' -> '/bin/busybox'. - let mut safe_target_rel_path = safe_target.replacen(&self.chroot_directory, "", 1); - let safe_symlink_rel_path = safe_symlink.replacen(&self.chroot_directory, "", 1); + // + // Note: need at least one leading '/', so if the chroot directory is just '/', just use the string as-is. + let mut safe_target_rel_path = if self.chroot_directory == path::MAIN_SEPARATOR.to_string() + { + safe_target.clone() + } else { + safe_target.replacen(&self.chroot_directory, "", 1) + }; + + let safe_symlink_rel_path = if self.chroot_directory == path::MAIN_SEPARATOR.to_string() { + safe_symlink.clone() + } else { + safe_symlink.replacen(&self.chroot_directory, "", 1) + }; // Count the number of path separators (minus the leading one) and an '../' to the target // path for each; e.g., '/bin/busybox' -> '..//bin/busybox'. From 0eb397baf4c960c021cc168687d852bc22a7ca12 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 23 Oct 2024 10:43:13 -0400 Subject: [PATCH 016/131] Added TP-Link RTOS firmware header signature --- src/magic.rs | 11 +++++++++++ src/signatures/tplink.rs | 36 ++++++++++++++++++++++++++++++++++- src/structures/tplink.rs | 41 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/magic.rs b/src/magic.rs index a11c03300..c5dc64167 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -866,6 +866,17 @@ pub fn patterns() -> Vec { description: signatures::luks::DESCRIPTION.to_string(), extractor: None, }, + // TP-Link RTOS + signatures::common::Signature { + name: "tplink_rtos".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::tplink::tplink_rtos_magic(), + parser: signatures::tplink::tplink_rtos_parser, + description: signatures::tplink::RTOS_DESCRIPTION.to_string(), + extractor: None, + }, ]; binary_signatures diff --git a/src/signatures/tplink.rs b/src/signatures/tplink.rs index 198cf9289..2b5e2bb9a 100644 --- a/src/signatures/tplink.rs +++ b/src/signatures/tplink.rs @@ -1,5 +1,5 @@ use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; -use crate::structures::tplink::parse_tplink_header; +use crate::structures::tplink::{parse_tplink_header, parse_tplink_rtos_header}; /// Human readable description pub const DESCRIPTION: &str = "TP-Link firmware header"; @@ -36,3 +36,37 @@ pub fn tplink_parser(file_data: &[u8], offset: usize) -> Result Vec> { + vec![b"\x00\x14\x2F\xC0".to_vec()] +} + +/// Parse and validate TP-Link RTOS firmware header +pub fn tplink_rtos_parser( + file_data: &[u8], + offset: usize, +) -> Result { + let mut result = SignatureResult { + offset, + description: RTOS_DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + if let Ok(fw_header) = parse_tplink_rtos_header(&file_data[offset..]) { + result.description = format!("{}, model number: {:X}, hardware version: {:X}, header size: {} bytes, total size: {} bytes", + result.description, + fw_header.model_number, + fw_header.hardware_revision, + fw_header.header_size, + fw_header.total_size, + ); + return Ok(result); + } + + Err(SignatureError) +} diff --git a/src/structures/tplink.rs b/src/structures/tplink.rs index fceb5e45b..857373a03 100644 --- a/src/structures/tplink.rs +++ b/src/structures/tplink.rs @@ -69,3 +69,44 @@ pub fn parse_tplink_header(tplink_data: &[u8]) -> Result Result { + const HEADER_SIZE: usize = 0x94; + const MAGIC2_VALUE: usize = 0x494D4730; + const TOTAL_SIZE_OFFSET: usize = 20; + + let tplink_rtos_structure = vec![ + ("magic1", "u32"), + ("unknown1", "u64"), + ("unknown2", "u64"), + ("magic2", "u32"), + ("data_size", "u32"), + ("model_number", "u16"), + ("hardware_revision", "u8"), + ]; + + if let Ok(header) = common::parse(tplink_data, &tplink_rtos_structure, "big") { + if header["magic2"] == MAGIC2_VALUE { + return Ok(TPLinkRTOSFirmwareHeader { + header_size: HEADER_SIZE, + total_size: header["data_size"] + TOTAL_SIZE_OFFSET, + model_number: header["model_number"], + hardware_revision: header["hardware_revision"], + }); + } + } + + Err(StructureError) +} From 8cf3dced96ae1234cb59fefc48085e6ed6440b76 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 23 Oct 2024 10:44:56 -0400 Subject: [PATCH 017/131] Fixed how LZMA uncompressed size field is displayed --- src/signatures/lzma.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/signatures/lzma.rs b/src/signatures/lzma.rs index 75856a861..c84b266ce 100644 --- a/src/signatures/lzma.rs +++ b/src/signatures/lzma.rs @@ -73,7 +73,7 @@ pub fn lzma_parser(file_data: &[u8], offset: usize) -> Result Date: Wed, 23 Oct 2024 10:51:30 -0400 Subject: [PATCH 018/131] Added major/minor hardware rev to TPLink RTOS signature --- src/signatures/tplink.rs | 5 +++-- src/structures/tplink.rs | 9 ++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/signatures/tplink.rs b/src/signatures/tplink.rs index 2b5e2bb9a..3325dcc28 100644 --- a/src/signatures/tplink.rs +++ b/src/signatures/tplink.rs @@ -58,10 +58,11 @@ pub fn tplink_rtos_parser( }; if let Ok(fw_header) = parse_tplink_rtos_header(&file_data[offset..]) { - result.description = format!("{}, model number: {:X}, hardware version: {:X}, header size: {} bytes, total size: {} bytes", + result.description = format!("{}, model number: {:X}, hardware version: {:X}.{:X}, header size: {} bytes, total size: {} bytes", result.description, fw_header.model_number, - fw_header.hardware_revision, + fw_header.hardware_rev_major, + fw_header.hardware_rev_minor, fw_header.header_size, fw_header.total_size, ); diff --git a/src/structures/tplink.rs b/src/structures/tplink.rs index 857373a03..8b8a2c753 100644 --- a/src/structures/tplink.rs +++ b/src/structures/tplink.rs @@ -76,7 +76,8 @@ pub struct TPLinkRTOSFirmwareHeader { pub header_size: usize, pub total_size: usize, pub model_number: usize, - pub hardware_revision: usize, + pub hardware_rev_major: usize, + pub hardware_rev_minor: usize, } /// Parse a TP-Link RTOS firmware header @@ -94,7 +95,8 @@ pub fn parse_tplink_rtos_header( ("magic2", "u32"), ("data_size", "u32"), ("model_number", "u16"), - ("hardware_revision", "u8"), + ("hardware_revision_major", "u8"), + ("hardware_revision_minor", "u8"), ]; if let Ok(header) = common::parse(tplink_data, &tplink_rtos_structure, "big") { @@ -103,7 +105,8 @@ pub fn parse_tplink_rtos_header( header_size: HEADER_SIZE, total_size: header["data_size"] + TOTAL_SIZE_OFFSET, model_number: header["model_number"], - hardware_revision: header["hardware_revision"], + hardware_rev_major: header["hardware_revision_major"], + hardware_rev_minor: header["hardware_revision_minor"], }); } } From 81a4755500dcccb10913a00d37464948d1c29801 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 23 Oct 2024 11:39:49 -0400 Subject: [PATCH 019/131] Added BIN firmware header signature --- src/magic.rs | 11 ++++++++ src/signatures.rs | 1 + src/signatures/binhdr.rs | 41 +++++++++++++++++++++++++++ src/structures.rs | 1 + src/structures/binhdr.rs | 60 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+) create mode 100644 src/signatures/binhdr.rs create mode 100644 src/structures/binhdr.rs diff --git a/src/magic.rs b/src/magic.rs index c5dc64167..1742f68b6 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -877,6 +877,17 @@ pub fn patterns() -> Vec { description: signatures::tplink::RTOS_DESCRIPTION.to_string(), extractor: None, }, + // BIN firmware header + signatures::common::Signature { + name: "binhdr".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::binhdr::bin_hdr_magic(), + parser: signatures::binhdr::bin_hdr_parser, + description: signatures::binhdr::DESCRIPTION.to_string(), + extractor: None, + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index f87ae31eb..3c5b09adb 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -108,6 +108,7 @@ pub mod aes; pub mod androidsparse; pub mod arcadyan; +pub mod binhdr; pub mod bzip2; pub mod cab; pub mod cfe; diff --git a/src/signatures/binhdr.rs b/src/signatures/binhdr.rs new file mode 100644 index 000000000..89a217130 --- /dev/null +++ b/src/signatures/binhdr.rs @@ -0,0 +1,41 @@ +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use crate::structures::binhdr::parse_bin_header; + +/// Human readable description +pub const DESCRIPTION: &str = "BIN firmware header"; + +/// BIN header magic bytes +pub fn bin_hdr_magic() -> Vec> { + vec![b"U2ND".to_vec()] +} + +/// Validates the BIN header +pub fn bin_hdr_parser(file_data: &[u8], offset: usize) -> Result { + const MAGIC_OFFSET: usize = 14; + + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + if offset >= MAGIC_OFFSET { + result.offset = offset - MAGIC_OFFSET; + + if let Ok(bin_header) = parse_bin_header(&file_data[result.offset..]) { + result.description = format!( + "{}, board ID: {}, hardware revision: {}, firmware version: {}.{}", + result.description, + bin_header.board_id, + bin_header.hardware_revision, + bin_header.firmware_version_major, + bin_header.firmware_version_minor, + ); + return Ok(result); + } + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index 6c3de9372..8f264d3d6 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -97,6 +97,7 @@ //! ``` pub mod androidsparse; +pub mod binhdr; pub mod cab; pub mod chk; pub mod common; diff --git a/src/structures/binhdr.rs b/src/structures/binhdr.rs new file mode 100644 index 000000000..e6ff9990a --- /dev/null +++ b/src/structures/binhdr.rs @@ -0,0 +1,60 @@ +use crate::common::get_cstring; +use crate::structures::common::{self, StructureError}; +use std::collections::HashMap; + +/// Struct to store BIN header info +pub struct BINHeader { + pub board_id: String, + pub hardware_revision: String, + pub firmware_version_major: usize, + pub firmware_version_minor: usize, +} + +/// Parses a BIN header +pub fn parse_bin_header(bin_hdr_data: &[u8]) -> Result { + // The data strcuture is preceeded by a 4-byte board ID string + const STRUCTURE_OFFSET: usize = 4; + + let bin_hdr_structure = vec![ + ("reserved1", "u32"), + ("build_date", "u32"), + ("firmware_version_major", "u8"), + ("firmware_version_minor", "u8"), + ("magic", "u32"), + ("hardware_id", "u8"), + ("reserved2", "u24"), + ("reserved3", "u64"), + ]; + + let known_hardware_ids: HashMap = + HashMap::from([(0, "4702"), (1, "4712"), (2, "4712L"), (3, "4704")]); + + // Parse the header + if let Some(structure_data) = bin_hdr_data.get(STRUCTURE_OFFSET..) { + if let Ok(header) = common::parse(structure_data, &bin_hdr_structure, "little") { + // Make sure the reserved fields are NULL + if header["reserved1"] == 0 && header["reserved2"] == 0 && header["reserved3"] == 0 { + // Make sure the reported hardware ID is valid + if known_hardware_ids.contains_key(&header["hardware_id"]) { + // Get the board ID string, which immediately preceeds the data structure + if let Some(board_id_bytes) = bin_hdr_data.get(0..STRUCTURE_OFFSET) { + let board_id = get_cstring(board_id_bytes); + + // The board ID string should be 4 bytes in length + if board_id.len() == STRUCTURE_OFFSET { + return Ok(BINHeader { + board_id, + hardware_revision: known_hardware_ids[&header["hardware_id"]] + .to_string(), + firmware_version_major: header["firmware_version_major"], + firmware_version_minor: header["firmware_version_minor"], + }); + } + } + } + } + } + } + + Err(StructureError) +} From 3d67da70f8b1b2d8f63a31364f0b5ccd839bc5ed Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 23 Oct 2024 11:49:04 -0400 Subject: [PATCH 020/131] Updated arcadyan obfuscation confidence --- src/signatures/arcadyan.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/signatures/arcadyan.rs b/src/signatures/arcadyan.rs index fff70f4ea..43a2a180d 100644 --- a/src/signatures/arcadyan.rs +++ b/src/signatures/arcadyan.rs @@ -1,5 +1,5 @@ use crate::extractors::arcadyan::extract_obfuscated_lzma; -use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; /// Human readable description pub const DESCRIPTION: &str = "Arcadyan obfuscated LZMA"; @@ -20,7 +20,7 @@ pub fn obfuscated_lzma_parser( // Success return value let mut result = SignatureResult { description: DESCRIPTION.to_string(), - confidence: CONFIDENCE_MEDIUM, + confidence: CONFIDENCE_HIGH, ..Default::default() }; From 6c804738cfeeb3e559817fccc247370a21543f12 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Thu, 24 Oct 2024 11:44:54 -0400 Subject: [PATCH 021/131] Removed unwrap() from code examples --- src/binwalk.rs | 28 +++++++++++++++++++++++++--- src/common.rs | 6 ++++-- src/extractors/common.rs | 40 ++++++++++++++++++++++++++++++++-------- src/lib.rs | 2 +- src/structures/common.rs | 5 ++++- 5 files changed, 66 insertions(+), 15 deletions(-) diff --git a/src/binwalk.rs b/src/binwalk.rs index d86e59836..ee0053698 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -19,6 +19,7 @@ use crate::extractors; use crate::magic; use crate::signatures; +/// Returned on initialization error #[derive(Debug, Default, Clone)] pub struct BinwalkError; @@ -100,12 +101,19 @@ impl Binwalk { /// ## Example /// /// ``` + /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_binwalk_rs_102_0() -> Result { /// use binwalk::Binwalk; /// /// // Don't scan for these file signatures /// let exclude_filters: Vec = vec!["jpeg".to_string(), "png".to_string()]; /// - /// let binwalker = Binwalk::configure(None, None, None, Some(exclude_filters), None).unwrap(); + /// let binwalker = Binwalk::configure(None, + /// None, + /// None, + /// Some(exclude_filters), + /// None)?; + /// # Ok(binwalker) + /// # } _doctest_main_src_binwalk_rs_102_0(); } /// ``` pub fn configure( target_file_name: Option, @@ -525,13 +533,18 @@ impl Binwalk { /// ## Example /// /// ``` + /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_binwalk_rs_529_0() -> Result { /// use binwalk::Binwalk; /// /// # std::fs::remove_dir_all("/tmp/foobar"); /// let target_path = "/usr/share/man/man2/accept.2.gz".to_string(); /// let extraction_directory = "/tmp/foobar/extractions".to_string(); /// - /// let binwalker = Binwalk::configure(Some(target_path), Some(extraction_directory), None, None, None).unwrap(); + /// let binwalker = Binwalk::configure(Some(target_path), + /// Some(extraction_directory), + /// None, + /// None, + /// None)?; /// /// let file_data = std::fs::read(&binwalker.base_target_file).expect("Unable to read file"); /// @@ -542,6 +555,8 @@ impl Binwalk { /// assert_eq!(extraction_results.len(), 1); /// assert_eq!(std::path::Path::new("/tmp/foobar/extractions/accept.2.gz.extracted/0/decompressed.bin").exists(), true); /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # Ok(binwalker) + /// # } _doctest_main_src_binwalk_rs_529_0(); } /// ``` pub fn extract( &self, @@ -619,13 +634,18 @@ impl Binwalk { /// ## Example /// /// ``` + /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_binwalk_rs_624_0() -> Result { /// use binwalk::Binwalk; /// /// # std::fs::remove_dir_all("/tmp/foobar"); /// let target_path = "/usr/share/man/man2/accept.2.gz".to_string(); /// let extraction_directory = "/tmp/foobar/extractions".to_string(); /// - /// let binwalker = Binwalk::configure(Some(target_path), Some(extraction_directory), None, None, None).unwrap(); + /// let binwalker = Binwalk::configure(Some(target_path), + /// Some(extraction_directory), + /// None, + /// None, + /// None)?; /// /// let analysis_results = binwalker.analyze(&binwalker.base_target_file, true); /// @@ -633,6 +653,8 @@ impl Binwalk { /// assert_eq!(analysis_results.extractions.len(), 1); /// assert_eq!(std::path::Path::new("/tmp/foobar/extractions/accept.2.gz.extracted/0/decompressed.bin").exists(), true); /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # Ok(binwalker) + /// # } _doctest_main_src_binwalk_rs_624_0(); } /// ``` pub fn analyze(&self, target_file: &String, do_extraction: bool) -> AnalysisResults { // Return value diff --git a/src/common.rs b/src/common.rs index aae12b280..cb1276a4c 100644 --- a/src/common.rs +++ b/src/common.rs @@ -9,11 +9,13 @@ use std::io::Read; /// ## Example /// /// ``` +/// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_common_rs_11_0() -> Result<(), Box> { /// use binwalk::common::read_file; /// -/// let file_data = read_file("/etc/passwd").unwrap(); -/// +/// let file_data = read_file("/etc/passwd")?; /// assert!(file_data.len() > 0); +/// # Ok(()) +/// # } _doctest_main_src_common_rs_11_0(); } /// ``` pub fn read_file(file: impl Into) -> Result, std::io::Error> { let mut file_data = Vec::new(); diff --git a/src/extractors/common.rs b/src/extractors/common.rs index d0dddeb64..9082d20ff 100644 --- a/src/extractors/common.rs +++ b/src/extractors/common.rs @@ -211,6 +211,7 @@ impl Chroot { /// ## Example /// /// ``` + /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_213_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// /// let chroot_dir = "/tmp/foobar".to_string(); @@ -220,8 +221,10 @@ impl Chroot { /// let chroot = Chroot::new(Some(&chroot_dir)); /// /// assert_eq!(chroot.create_file("created_file.txt", file_data), true); - /// assert_eq!(std::fs::read_to_string("/tmp/foobar/created_file.txt").unwrap(), "foobar"); + /// assert_eq!(std::fs::read_to_string("/tmp/foobar/created_file.txt")?, "foobar"); /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # Ok(()) + /// # } _doctest_main_src_extractors_common_rs_213_0(); } /// ``` pub fn create_file(&self, file_path: impl Into, file_data: &[u8]) -> bool { let safe_file_path: String = self.chrooted_path(file_path); @@ -250,6 +253,7 @@ impl Chroot { /// ## Example /// /// ``` + /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_255_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// /// let chroot_dir = "/tmp/foobar".to_string(); @@ -259,8 +263,10 @@ impl Chroot { /// let chroot = Chroot::new(Some(&chroot_dir)); /// /// assert_eq!(chroot.carve_file("carved_file.txt", file_data_with_trailing_junk, 0, 6), true); - /// assert_eq!(std::fs::read_to_string("/tmp/foobar/carved_file.txt").unwrap(), "foobar"); + /// assert_eq!(std::fs::read_to_string("/tmp/foobar/carved_file.txt")?, "foobar"); /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # Ok(()) + /// } _doctest_main_src_extractors_common_rs_255_0(); } /// ``` pub fn carve_file( &self, @@ -304,6 +310,7 @@ impl Chroot { /// ## Example /// /// ``` + /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_312_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// /// let chroot_dir = "/tmp/foobar".to_string(); @@ -314,8 +321,10 @@ impl Chroot { /// let chroot = Chroot::new(Some(&chroot_dir)); /// /// assert_eq!(chroot.create_character_device("char_device", dev_major, dev_minor), true); - /// assert_eq!(std::fs::read_to_string("/tmp/foobar/char_device").unwrap(), "c 1 2"); + /// assert_eq!(std::fs::read_to_string("/tmp/foobar/char_device")?, "c 1 2"); /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # Ok(()) + /// # } _doctest_main_src_extractors_common_rs_312_0(); } /// ``` pub fn create_character_device( &self, @@ -333,6 +342,7 @@ impl Chroot { /// ## Example /// /// ``` + /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_345_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// /// let chroot_dir = "/tmp/foobar".to_string(); @@ -343,8 +353,10 @@ impl Chroot { /// let chroot = Chroot::new(Some(&chroot_dir)); /// /// assert_eq!(chroot.create_block_device("block_device", dev_major, dev_minor), true); - /// assert_eq!(std::fs::read_to_string("/tmp/foobar/block_device").unwrap(), "b 1 2"); + /// assert_eq!(std::fs::read_to_string("/tmp/foobar/block_device")?, "b 1 2"); /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # Ok(()) + /// # } _doctest_main_src_extractors_common_rs_345_0(); } /// ``` pub fn create_block_device( &self, @@ -362,6 +374,7 @@ impl Chroot { /// ## Example /// /// ``` + /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_377_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// /// let chroot_dir = "/tmp/foobar".to_string(); @@ -370,8 +383,10 @@ impl Chroot { /// let chroot = Chroot::new(Some(&chroot_dir)); /// /// assert_eq!(chroot.create_fifo("fifo_file"), true); - /// assert_eq!(std::fs::read_to_string("/tmp/foobar/fifo_file").unwrap(), "fifo"); + /// assert_eq!(std::fs::read_to_string("/tmp/foobar/fifo_file")?, "fifo"); /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # Ok(()) + /// # } _doctest_main_src_extractors_common_rs_377_0(); } /// ``` pub fn create_fifo(&self, file_path: impl Into) -> bool { self.create_file(file_path, b"fifo") @@ -384,6 +399,7 @@ impl Chroot { /// ## Example /// /// ``` + /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_401_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// /// let chroot_dir = "/tmp/foobar".to_string(); @@ -392,8 +408,10 @@ impl Chroot { /// let chroot = Chroot::new(Some(&chroot_dir)); /// /// assert_eq!(chroot.create_socket("socket_file"), true); - /// assert_eq!(std::fs::read_to_string("/tmp/foobar/socket_file").unwrap(), "socket"); + /// assert_eq!(std::fs::read_to_string("/tmp/foobar/socket_file")?, "socket"); /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # Ok(()) + /// # } _doctest_main_src_extractors_common_rs_401_0(); } /// ``` pub fn create_socket(&self, file_path: impl Into) -> bool { self.create_file(file_path, b"socket") @@ -406,6 +424,7 @@ impl Chroot { /// ## Example /// /// ``` + /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_426_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// /// let chroot_dir = "/tmp/foobar".to_string(); @@ -415,8 +434,10 @@ impl Chroot { /// let chroot = Chroot::new(Some(&chroot_dir)); /// /// assert_eq!(chroot.append_to_file("append.txt", my_file_data), true); - /// assert_eq!(std::fs::read_to_string("/tmp/foobar/append.txt").unwrap(), "foobar"); + /// assert_eq!(std::fs::read_to_string("/tmp/foobar/append.txt")?, "foobar"); /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # Ok(()) + /// # } _doctest_main_src_extractors_common_rs_426_0(); } /// ``` pub fn append_to_file(&self, file_path: impl Into, data: &[u8]) -> bool { let safe_file_path: String = self.chrooted_path(file_path); @@ -548,6 +569,7 @@ impl Chroot { /// ## Example /// /// ``` + /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_571_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// /// let chroot_dir = "/tmp/foobar".to_string(); @@ -556,8 +578,10 @@ impl Chroot { /// let chroot = Chroot::new(Some(&chroot_dir)); /// /// assert_eq!(chroot.create_symlink("symlink", "/"), true); - /// assert_eq!(std::fs::canonicalize("/tmp/foobar/symlink").unwrap().to_str(), Some("/tmp/foobar")); + /// assert_eq!(std::fs::canonicalize("/tmp/foobar/symlink")?.to_str(), Some("/tmp/foobar")); /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # Ok(()) + /// # } _doctest_main_src_extractors_common_rs_571_0(); } /// ``` pub fn create_symlink( &self, diff --git a/src/lib.rs b/src/lib.rs index 0f4239c03..c5151dd78 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,4 +22,4 @@ pub mod extractors; mod magic; pub mod signatures; pub mod structures; -pub use binwalk::{AnalysisResults, Binwalk}; +pub use binwalk::{AnalysisResults, Binwalk, BinwalkError}; diff --git a/src/structures/common.rs b/src/structures/common.rs index dd0c29f55..3bfcaf261 100644 --- a/src/structures/common.rs +++ b/src/structures/common.rs @@ -32,6 +32,7 @@ pub struct StructureError; /// ## Example: /// /// ``` +/// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_structures_common_rs_34_0() -> Result { /// use binwalk::structures; /// /// let my_structure = vec![ @@ -43,10 +44,12 @@ pub struct StructureError; /// ]; /// /// let some_data = b"AAAA\x01\x00\x00\x00\x00\x00\x00\x00\x08\x0A\x0B\x0C\x01\x02"; -/// let header = structures::common::parse(some_data, &my_structure, "little").unwrap(); +/// let header = structures::common::parse(some_data, &my_structure, "little")?; /// /// assert_eq!(header["magic"], 0x41414141); /// assert_eq!(header["checksum"], 0x0201); +/// # Ok(true) +/// # } _doctest_main_src_structures_common_rs_34_0(); } /// ``` pub fn parse( data: &[u8], From 909df572a5983be03bec79200c66698b9e514f9b Mon Sep 17 00:00:00 2001 From: devttys0 Date: Thu, 24 Oct 2024 11:53:21 -0400 Subject: [PATCH 022/131] Updated Cargo.toml metadata --- Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 42d17dcd8..091cebf9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,10 @@ name = "binwalk" version = "3.1.0" edition = "2021" authors = ["Craig Heffner "] +license = "MIT" +repository = "https://github.com/ReFirmLabs/binwalk" +description = "Analyzes data for embedded file types" +keywords = ["binwalk", "firmware", "analysis"] [dependencies] log = "0.4.22" From bcb147519731722d677730a93738628184bfd239 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 25 Oct 2024 11:13:28 -0400 Subject: [PATCH 023/131] Added support for Autel encoded firmware --- src/extractors.rs | 1 + src/extractors/autel.rs | 340 ++++++++++++++++++++++++++++++++++++++++ src/magic.rs | 11 ++ src/signatures.rs | 1 + src/signatures/autel.rs | 32 ++++ src/structures.rs | 1 + src/structures/autel.rs | 47 ++++++ src/structures/dlob.rs | 1 + 8 files changed, 434 insertions(+) create mode 100644 src/extractors/autel.rs create mode 100644 src/signatures/autel.rs create mode 100644 src/structures/autel.rs diff --git a/src/extractors.rs b/src/extractors.rs index ee4161613..f9663ccd5 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -141,6 +141,7 @@ pub mod androidsparse; pub mod arcadyan; +pub mod autel; pub mod bzip2; pub mod cab; pub mod common; diff --git a/src/extractors/autel.rs b/src/extractors/autel.rs new file mode 100644 index 000000000..f18e34f67 --- /dev/null +++ b/src/extractors/autel.rs @@ -0,0 +1,340 @@ +use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; +use crate::structures::autel::parse_autel_header; + +const BLOCK_SIZE: usize = 256; + +/// Defines the internal extractor function for deobfuscating Autel firmware +pub fn autel_extractor() -> Extractor { + Extractor { + utility: ExtractorType::Internal(autel_deobfuscate), + ..Default::default() + } +} + +/// Internal extractor for obfuscated Autel firmware +/// https://gist.github.com/sector7-nl/3fc815cd2497817ad461bfbd393294cb +pub fn autel_deobfuscate( + file_data: &[u8], + offset: usize, + output_directory: Option<&String>, +) -> ExtractionResult { + const OUTPUT_FILE_NAME: &str = "autel.decoded"; + + let mut result = ExtractionResult { + ..Default::default() + }; + + // Parse and validate the header + if let Ok(autel_header) = parse_autel_header(&file_data[offset..]) { + // Get the start and end offsets of the actual encoded data + let data_start = offset + autel_header.header_size; + let data_end = data_start + autel_header.data_size; + + // Get the encoded data + if let Some(autel_data) = file_data.get(data_start..data_end) { + // Interate through each block of the encoded data + let mut block_iter = autel_data.chunks(BLOCK_SIZE); + + loop { + match block_iter.next() { + None => { + // EOF + result.size = Some(autel_header.data_size); + result.success = true; + break; + } + Some(block_bytes) => { + // Decode the data block + let decoded_block = decode_autel_block(block_bytes); + + // Write to file, if requested + if output_directory.is_some() { + let chroot = Chroot::new(output_directory); + if !chroot.append_to_file(OUTPUT_FILE_NAME, &decoded_block) { + break; + } + } + } + } + } + } + } + + result +} + +/// Block decoder for autel encoded firmware. +/// block_data *must* be 256 bytes in size, or less. +fn decode_autel_block(block_data: &[u8]) -> Vec { + // Lookup table for encoding/decoding bytes + let encoding_table: Vec<(usize, usize)> = vec![ + (54, 147), + (96, 129), + (59, 193), + (191, 0), + (45, 130), + (96, 144), + (27, 129), + (152, 0), + (44, 180), + (118, 141), + (115, 129), + (210, 0), + (13, 164), + (27, 133), + (20, 192), + (139, 0), + (28, 166), + (17, 133), + (19, 193), + (224, 0), + (20, 161), + (145, 0), + (14, 193), + (12, 132), + (18, 161), + (17, 140), + (29, 192), + (246, 0), + (115, 178), + (28, 132), + (155, 0), + (12, 132), + (31, 165), + (20, 136), + (27, 193), + (142, 0), + (96, 164), + (18, 133), + (145, 0), + (23, 132), + (13, 165), + (13, 148), + (23, 193), + (19, 132), + (27, 178), + (83, 137), + (146, 0), + (145, 0), + (18, 166), + (96, 148), + (13, 193), + (159, 0), + (96, 166), + (20, 129), + (20, 193), + (27, 132), + (9, 160), + (96, 148), + (13, 192), + (159, 0), + (96, 180), + (142, 0), + (31, 193), + (155, 0), + (7, 166), + (224, 0), + (20, 192), + (27, 132), + (28, 160), + (17, 149), + (19, 193), + (96, 132), + (76, 164), + (208, 0), + (80, 192), + (78, 132), + (96, 160), + (27, 144), + (24, 193), + (140, 0), + (96, 178), + (17, 141), + (12, 193), + (224, 0), + (14, 161), + (17, 141), + (151, 0), + (14, 132), + (16, 165), + (96, 137), + (13, 193), + (155, 0), + (20, 161), + (29, 141), + (23, 192), + (24, 132), + (27, 178), + (10, 133), + (96, 192), + (140, 0), + (14, 180), + (17, 133), + (16, 192), + (144, 0), + (11, 163), + (13, 141), + (96, 192), + (17, 132), + (12, 178), + (96, 141), + (28, 192), + (27, 132), + (27, 130), + (18, 141), + (96, 193), + (31, 132), + (96, 181), + (13, 140), + (23, 193), + (224, 0), + (27, 166), + (142, 0), + (27, 192), + (24, 132), + (12, 183), + (96, 133), + (84, 192), + (14, 132), + (27, 178), + (10, 140), + (155, 0), + (9, 132), + (17, 160), + (56, 133), + (96, 192), + (82, 132), + (13, 160), + (27, 137), + (20, 193), + (139, 0), + (28, 161), + (145, 0), + (19, 192), + (118, 132), + (115, 165), + (20, 132), + (145, 0), + (14, 132), + (12, 167), + (146, 0), + (17, 193), + (29, 132), + (96, 176), + (28, 144), + (27, 193), + (140, 0), + (31, 180), + (148, 0), + (27, 192), + (14, 132), + (83, 160), + (18, 137), + (17, 193), + (23, 132), + (13, 165), + (13, 145), + (151, 0), + (147, 0), + (27, 178), + (96, 137), + (19, 193), + (159, 0), + (14, 160), + (25, 148), + (17, 193), + (142, 0), + (16, 180), + (27, 136), + (14, 193), + (224, 0), + (17, 178), + (12, 144), + (224, 0), + (28, 132), + (27, 160), + (13, 141), + (11, 193), + (96, 132), + (27, 165), + (30, 140), + (224, 0), + (146, 0), + (31, 165), + (29, 129), + (96, 192), + (140, 0), + (31, 161), + (24, 145), + (140, 0), + (96, 132), + (27, 165), + (29, 140), + (31, 192), + (154, 0), + (14, 161), + (27, 145), + (140, 0), + (18, 132), + (23, 167), + (96, 140), + (21, 129), + (14, 132), + (17, 165), + (9, 137), + (12, 193), + (155, 0), + (18, 161), + (96, 141), + (27, 192), + (148, 0), + (29, 178), + (23, 133), + (24, 192), + (155, 0), + (10, 180), + (96, 133), + (28, 192), + (14, 132), + (31, 130), + (28, 129), + (18, 193), + (31, 132), + (12, 180), + (13, 144), + (96, 193), + (31, 132), + (96, 160), + (13, 141), + (27, 193), + (18, 132), + (23, 181), + (26, 140), + (27, 193), + (156, 0), + (96, 166), + (79, 141), + (211, 0), + (76, 132), + (77, 160), + (75, 133), + (206, 0), + (182, 0), + (96, 129), + (59, 133), + (191, 0), + (173, 0), + ]; + + assert!(block_data.len() <= BLOCK_SIZE); + + let mut decoded_block: Vec = vec![]; + + for (i, byte) in block_data.iter().enumerate() { + let encoding = encoding_table[i]; + + decoded_block.push(((((*byte as usize) + encoding.0) ^ encoding.1) % 256) as u8); + } + + decoded_block +} diff --git a/src/magic.rs b/src/magic.rs index 1742f68b6..7e6113925 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -888,6 +888,17 @@ pub fn patterns() -> Vec { description: signatures::binhdr::DESCRIPTION.to_string(), extractor: None, }, + // Autel obfuscated firmware + signatures::common::Signature { + name: "autel".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::autel::autel_magic(), + parser: signatures::autel::autel_parser, + description: signatures::autel::DESCRIPTION.to_string(), + extractor: Some(extractors::autel::autel_extractor()), + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index 3c5b09adb..113711ead 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -108,6 +108,7 @@ pub mod aes; pub mod androidsparse; pub mod arcadyan; +pub mod autel; pub mod binhdr; pub mod bzip2; pub mod cab; diff --git a/src/signatures/autel.rs b/src/signatures/autel.rs new file mode 100644 index 000000000..e1c012cd0 --- /dev/null +++ b/src/signatures/autel.rs @@ -0,0 +1,32 @@ +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use crate::structures::autel::parse_autel_header; + +/// Human readable description +pub const DESCRIPTION: &str = "Autel obfuscated firmware"; + +/// Autel magic bytes +pub fn autel_magic() -> Vec> { + vec![b"ECC0101\x00".to_vec()] +} + +/// Validates the Autel header +pub fn autel_parser(file_data: &[u8], offset: usize) -> Result { + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + if let Ok(autel_header) = parse_autel_header(&file_data[offset..]) { + result.size = autel_header.header_size + autel_header.data_size; + result.description = format!( + "{}, header size: {} bytes, data size: {}, total size: {}", + result.description, autel_header.header_size, autel_header.data_size, result.size + ); + return Ok(result); + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index 8f264d3d6..8455b32af 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -97,6 +97,7 @@ //! ``` pub mod androidsparse; +pub mod autel; pub mod binhdr; pub mod cab; pub mod chk; diff --git a/src/structures/autel.rs b/src/structures/autel.rs new file mode 100644 index 000000000..acd97a484 --- /dev/null +++ b/src/structures/autel.rs @@ -0,0 +1,47 @@ +use crate::common::get_cstring; +use crate::structures::common::{self, StructureError}; + +/// Struct to store Autel ECC header info +#[derive(Debug, Default, Clone)] +pub struct AutelECCHeader { + pub data_size: usize, + pub header_size: usize, +} + +/// Parses an Autel header +pub fn parse_autel_header(autel_data: &[u8]) -> Result { + const EXPECTED_HEADER_SIZE: usize = 0x20; + const COPYRIGHT_SIZE: usize = 16; + const EXPECTED_COPYRIGHT_STRING: &str = "Copyright Autel"; + + let autel_ecc_structure = vec![ + ("magic", "u64"), + ("data_size", "u32"), + ("header_size", "u32"), + // Followed by 16-byte copyright string + ]; + + // Parse the header + if let Ok(autel_header) = common::parse(autel_data, &autel_ecc_structure, "little") { + // Sanity check the reported header size + if autel_header["header_size"] == EXPECTED_HEADER_SIZE { + let copyright_start = common::size(&autel_ecc_structure); + let copyright_end = copyright_start + COPYRIGHT_SIZE; + + // Get the copyright string contained in the header + if let Some(copyright_bytes) = autel_data.get(copyright_start..copyright_end) { + let copyright_string = get_cstring(copyright_bytes); + + // Sanity check the copyright string value + if copyright_string == EXPECTED_COPYRIGHT_STRING { + return Ok(AutelECCHeader { + data_size: autel_header["data_size"], + header_size: autel_header["header_size"], + }); + } + } + } + } + + Err(StructureError) +} diff --git a/src/structures/dlob.rs b/src/structures/dlob.rs index 6d0ce9aeb..d8069491f 100644 --- a/src/structures/dlob.rs +++ b/src/structures/dlob.rs @@ -1,6 +1,7 @@ use crate::structures::common::{self, StructureError}; /// Struct to store DLOB header info +#[derive(Debug, Default, Clone)] pub struct DlobHeader { pub data_size: usize, pub header_size: usize, From 5aa5b3e747997056106d9bdb75640d840cbbd616 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 26 Oct 2024 16:17:10 -0400 Subject: [PATCH 024/131] Added os type 7 to MBR signature --- src/structures/mbr.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/structures/mbr.rs b/src/structures/mbr.rs index 4bdf50c01..73a57129a 100644 --- a/src/structures/mbr.rs +++ b/src/structures/mbr.rs @@ -34,6 +34,7 @@ pub fn parse_mbr_image(mbr_data: &[u8]) -> Result { ]; let known_os_types = HashMap::from([ + (0x07, "NTFS_IFS_HPFS_exFAT"), (0x0B, "FAT32"), (0x0C, "FAT32"), (0x43, "Linux"), From 4a3957282d43794c94c53c0aba8b940b7f0e62c8 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 26 Oct 2024 16:59:27 -0400 Subject: [PATCH 025/131] Added NTFS support --- src/magic.rs | 11 ++++++++++ src/signatures.rs | 1 + src/signatures/ntfs.rs | 37 ++++++++++++++++++++++++++++++++ src/structures.rs | 1 + src/structures/ntfs.rs | 48 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+) create mode 100644 src/signatures/ntfs.rs create mode 100644 src/structures/ntfs.rs diff --git a/src/magic.rs b/src/magic.rs index 7e6113925..a728ce7b5 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -899,6 +899,17 @@ pub fn patterns() -> Vec { description: signatures::autel::DESCRIPTION.to_string(), extractor: Some(extractors::autel::autel_extractor()), }, + // NTFS + signatures::common::Signature { + name: "ntfs".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::ntfs::ntfs_magic(), + parser: signatures::ntfs::ntfs_parser, + description: signatures::ntfs::DESCRIPTION.to_string(), + extractor: Some(extractors::tsk::tsk_extractor()), + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index 113711ead..3758e2318 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -143,6 +143,7 @@ pub mod lzfse; pub mod lzma; pub mod lzop; pub mod mbr; +pub mod ntfs; pub mod openssl; pub mod packimg; pub mod pcap; diff --git a/src/signatures/ntfs.rs b/src/signatures/ntfs.rs new file mode 100644 index 000000000..6766bd212 --- /dev/null +++ b/src/signatures/ntfs.rs @@ -0,0 +1,37 @@ +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use crate::structures::ntfs::parse_ntfs_header; + +/// Human readable description +pub const DESCRIPTION: &str = "NTFS partition"; + +/// NTFS partitions start with these bytes +pub fn ntfs_magic() -> Vec> { + vec![b"\xEb\x52\x90NTFS\x20\x20\x20\x20".to_vec()] +} + +/// Validates the NTFS header +pub fn ntfs_parser(file_data: &[u8], offset: usize) -> Result { + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + if let Ok(ntfs_header) = parse_ntfs_header(&file_data[offset..]) { + // The reported sector count does not include the NTFS boot sector itself + result.size = ntfs_header.sector_size * (ntfs_header.sector_count + 1); + + // Simple sanity check on the reported total size + if result.size > ntfs_header.sector_size { + result.description = format!( + "{}, number of sectors: {}, bytes per sector: {}, total size: {} bytes", + result.description, ntfs_header.sector_count, ntfs_header.sector_size, result.size + ); + return Ok(result); + } + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index 8455b32af..e5c55e9b4 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -124,6 +124,7 @@ pub mod lzfse; pub mod lzma; pub mod lzop; pub mod mbr; +pub mod ntfs; pub mod openssl; pub mod packimg; pub mod pcap; diff --git a/src/structures/ntfs.rs b/src/structures/ntfs.rs new file mode 100644 index 000000000..7da77c00b --- /dev/null +++ b/src/structures/ntfs.rs @@ -0,0 +1,48 @@ +use crate::structures::common::{self, StructureError}; + +/// Struct to store NTFS info +#[derive(Debug, Default, Clone)] +pub struct NTFSPartition { + pub sector_size: usize, + pub sector_count: usize, +} + +/// Parses an NTFS partition header +pub fn parse_ntfs_header(ntfs_data: &[u8]) -> Result { + // https://en.wikipedia.org/wiki/NTFS + let ntfs_structure = vec![ + ("opcodes", "u24"), + ("magic", "u64"), + ("bytes_per_sector", "u16"), + ("sectors_per_cluster", "u8"), + ("unused1", "u16"), + ("unused2", "u24"), + ("unused3", "u16"), + ("media_type", "u8"), + ("unused4", "u16"), + ("sectors_per_track", "u16"), + ("head_count", "u16"), + ("hidden_sector_count", "u32"), + ("unused5", "u32"), + ("unknown", "u32"), + ("sector_count", "u64"), + ]; + + // Parse the NTFS partition header + if let Ok(ntfs_header) = common::parse(ntfs_data, &ntfs_structure, "little") { + // Sanity check to make sure the unused fields are not used + if ntfs_header["unused1"] == 0 + && ntfs_header["unused2"] == 0 + && ntfs_header["unused3"] == 0 + && ntfs_header["unused4"] == 0 + && ntfs_header["unused5"] == 0 + { + return Ok(NTFSPartition { + sector_count: ntfs_header["sector_count"], + sector_size: ntfs_header["bytes_per_sector"], + }); + } + } + + Err(StructureError) +} From 42f1ece86cb1a65cdffa65691fd70d27db2e0845 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 26 Oct 2024 18:30:03 -0400 Subject: [PATCH 026/131] Added initial APFS signature (extraction not functional) --- src/magic.rs | 11 +++++++++++ src/signatures.rs | 1 + src/signatures/apfs.rs | 35 +++++++++++++++++++++++++++++++++++ src/structures.rs | 1 + src/structures/apfs.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 src/signatures/apfs.rs create mode 100644 src/structures/apfs.rs diff --git a/src/magic.rs b/src/magic.rs index a728ce7b5..1cedb28f5 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -910,6 +910,17 @@ pub fn patterns() -> Vec { description: signatures::ntfs::DESCRIPTION.to_string(), extractor: Some(extractors::tsk::tsk_extractor()), }, + // APFS + signatures::common::Signature { + name: "apfs".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::apfs::apfs_magic(), + parser: signatures::apfs::apfs_parser, + description: signatures::apfs::DESCRIPTION.to_string(), + extractor: Some(extractors::tsk::tsk_extractor()), + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index 3758e2318..f6395cc34 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -107,6 +107,7 @@ //! ``` pub mod aes; pub mod androidsparse; +pub mod apfs; pub mod arcadyan; pub mod autel; pub mod binhdr; diff --git a/src/signatures/apfs.rs b/src/signatures/apfs.rs new file mode 100644 index 000000000..f8972c51e --- /dev/null +++ b/src/signatures/apfs.rs @@ -0,0 +1,35 @@ +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_LOW}; +use crate::structures::apfs::{parse_apfs_header, MAGIC_OFFSET}; + +/// Human readable description +pub const DESCRIPTION: &str = "ApPle File System"; + +/// APFS magic bytes +pub fn apfs_magic() -> Vec> { + vec![b"NXSB".to_vec()] +} + +/// Validates the APFS header +pub fn apfs_parser(file_data: &[u8], offset: usize) -> Result { + // Successful return value + let mut result = SignatureResult { + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_LOW, + ..Default::default() + }; + + if offset >= MAGIC_OFFSET { + result.offset = offset - MAGIC_OFFSET; + + if let Ok(apfs_header) = parse_apfs_header(&file_data[result.offset..]) { + result.size = apfs_header.block_count * apfs_header.block_size; + result.description = format!( + "{}, block size: {} bytes, block count: {}, total size: {} bytes", + result.description, apfs_header.block_size, apfs_header.block_count, result.size + ); + return Ok(result); + } + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index e5c55e9b4..f5e2ab764 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -97,6 +97,7 @@ //! ``` pub mod androidsparse; +pub mod apfs; pub mod autel; pub mod binhdr; pub mod cab; diff --git a/src/structures/apfs.rs b/src/structures/apfs.rs new file mode 100644 index 000000000..e74266e95 --- /dev/null +++ b/src/structures/apfs.rs @@ -0,0 +1,40 @@ +use crate::structures::common::{self, StructureError}; + +/// Offset of the APFS magic bytes from the start of the APFS image +pub const MAGIC_OFFSET: usize = 0x20; + +/// Struct to store APFS header info +#[derive(Debug, Default, Clone)] +pub struct APFSHeader { + pub block_size: usize, + pub block_count: usize, +} + +/// Parses an APFS header +pub fn parse_apfs_header(apfs_data: &[u8]) -> Result { + // Partial APFS header, just to figure out the size of the image. + // https://developer.apple.com/support/downloads/Apple-File-System-Reference.pdf + let apfs_structure = vec![ + ("magic", "u32"), + ("block_size", "u32"), + ("block_count", "u64"), + ]; + + let apfs_struct_start = MAGIC_OFFSET; + let apfs_struct_end = apfs_struct_start + common::size(&apfs_structure); + + // Parse the header + if let Some(apfs_structure_data) = apfs_data.get(apfs_struct_start..apfs_struct_end) { + if let Ok(apfs_header) = common::parse(apfs_structure_data, &apfs_structure, "little") { + // Simple sanity check on the reported block data + if apfs_header["block_size"] != 0 && apfs_header["block_count"] != 0 { + return Ok(APFSHeader { + block_size: apfs_header["block_size"], + block_count: apfs_header["block_count"], + }); + } + } + } + + Err(StructureError) +} From 528c21bba0aaec9f34571ac405420981b117cd40 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Mon, 28 Oct 2024 10:13:06 -0400 Subject: [PATCH 027/131] Fixed bug in binwalk::scan while processing short signatures --- src/binwalk.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/binwalk.rs b/src/binwalk.rs index ee0053698..3a32c388b 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -277,8 +277,8 @@ impl Binwalk { signature_result.name, FILE_START_OFFSET ); - // Only update the next_valid_offset if confidence is at least medium - if signature_result.confidence >= signatures::common::CONFIDENCE_MEDIUM { + // Only update the next_valid_offset if confidence is high; these are, after all, short signatures + if signature_result.confidence >= signatures::common::CONFIDENCE_HIGH { next_valid_offset = signature_result.offset + signature_result.size; } From 8581d786947cb928dbf0ddc0add959dd1b714127 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Mon, 28 Oct 2024 10:14:33 -0400 Subject: [PATCH 028/131] Fixed bug in binwalk::scan while processing short signatures --- src/signatures/apfs.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/signatures/apfs.rs b/src/signatures/apfs.rs index f8972c51e..21f4df51d 100644 --- a/src/signatures/apfs.rs +++ b/src/signatures/apfs.rs @@ -27,6 +27,7 @@ pub fn apfs_parser(file_data: &[u8], offset: usize) -> Result Date: Mon, 28 Oct 2024 11:08:01 -0400 Subject: [PATCH 029/131] Added better validation to APFS signatures --- src/signatures/apfs.rs | 32 +++++++++++++++++++----- src/structures/apfs.rs | 55 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 77 insertions(+), 10 deletions(-) diff --git a/src/signatures/apfs.rs b/src/signatures/apfs.rs index 21f4df51d..9ccef9b49 100644 --- a/src/signatures/apfs.rs +++ b/src/signatures/apfs.rs @@ -1,8 +1,8 @@ -use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_LOW}; +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; use crate::structures::apfs::{parse_apfs_header, MAGIC_OFFSET}; /// Human readable description -pub const DESCRIPTION: &str = "ApPle File System"; +pub const DESCRIPTION: &str = "APple File System"; /// APFS magic bytes pub fn apfs_magic() -> Vec> { @@ -11,23 +11,43 @@ pub fn apfs_magic() -> Vec> { /// Validates the APFS header pub fn apfs_parser(file_data: &[u8], offset: usize) -> Result { + const MBR_BLOCK_SIZE: usize = 512; + // Successful return value let mut result = SignatureResult { description: DESCRIPTION.to_string(), - confidence: CONFIDENCE_LOW, + confidence: CONFIDENCE_MEDIUM, ..Default::default() }; if offset >= MAGIC_OFFSET { result.offset = offset - MAGIC_OFFSET; + let available_data = file_data.len() - result.offset; if let Ok(apfs_header) = parse_apfs_header(&file_data[result.offset..]) { + let mut truncated_message = "".to_string(); result.size = apfs_header.block_count * apfs_header.block_size; + + // It is observed that an APFS contained in an EFIGPT with a protective MBR includes the MBR block in its size. + // If the APFS image is pulled out of the EFIGPT, the reported size will be 512 bytes too long, but otherwise valid. + if result.size > available_data { + let truncated_size = result.size - available_data; + + // If the calculated size is 512 bytes short, adjust the reported APFS size accordingly + if truncated_size == MBR_BLOCK_SIZE { + result.size -= truncated_size; + truncated_message = format!(" (truncated by {} bytes)", truncated_size); + } + } + result.description = format!( - "{}, block size: {} bytes, block count: {}, total size: {} bytes", - result.description, apfs_header.block_size, apfs_header.block_count, result.size + "{}, block size: {} bytes, block count: {}, total size: {} bytes{}", + result.description, + apfs_header.block_size, + apfs_header.block_count, + result.size, + truncated_message ); - result.size = 0; return Ok(result); } } diff --git a/src/structures/apfs.rs b/src/structures/apfs.rs index e74266e95..ea553924b 100644 --- a/src/structures/apfs.rs +++ b/src/structures/apfs.rs @@ -12,26 +12,73 @@ pub struct APFSHeader { /// Parses an APFS header pub fn parse_apfs_header(apfs_data: &[u8]) -> Result { + const MAX_FS_COUNT: usize = 100; + const FS_COUNT_BLOCK_SIZE: usize = 512; + // Partial APFS header, just to figure out the size of the image. // https://developer.apple.com/support/downloads/Apple-File-System-Reference.pdf let apfs_structure = vec![ ("magic", "u32"), ("block_size", "u32"), ("block_count", "u64"), + ("nx_features", "u64"), + ("nx_ro_compat_features", "u64"), + ("nx_incompat_features", "u64"), + ("nx_uuid_p1", "u64"), + ("nx_uuid_p2", "u64"), + ("nx_next_oid", "u64"), + ("nx_next_xid", "u64"), + ("nx_xp_desc_blocks", "u32"), + ("nx_xp_data_blocks", "u32"), + ("nx_xp_desc_base", "u64"), + ("nx_xp_data_base", "u64"), + ("nx_xp_desc_next", "u32"), + ("nx_xp_data_next", "u32"), + ("nx_xp_desc_index", "u32"), + ("nx_xp_desc_len", "u32"), + ("nx_xp_data_index", "u32"), + ("nx_xp_data_len", "u32"), + ("nx_spaceman_oid", "u64"), + ("nx_omap_oid", "u64"), + ("nx_reaper_oid", "u64"), + ("nx_xp_test_type", "u32"), + ("nx_xp_max_file_systems", "u32"), ]; + // Expected values of superblock flag fields + let allowed_feature_flags: Vec = vec![0, 1, 2, 3]; + let allowed_incompat_flags: Vec = vec![0, 1, 2, 3, 0x100, 0x101, 0x102, 0x103]; + let allowed_ro_compat_flags: Vec = vec![0]; + let apfs_struct_start = MAGIC_OFFSET; let apfs_struct_end = apfs_struct_start + common::size(&apfs_structure); // Parse the header if let Some(apfs_structure_data) = apfs_data.get(apfs_struct_start..apfs_struct_end) { if let Ok(apfs_header) = common::parse(apfs_structure_data, &apfs_structure, "little") { + println!("{:?}", apfs_header); + // Simple sanity check on the reported block data if apfs_header["block_size"] != 0 && apfs_header["block_count"] != 0 { - return Ok(APFSHeader { - block_size: apfs_header["block_size"], - block_count: apfs_header["block_count"], - }); + // Sanity check the feature flags + if allowed_feature_flags.contains(&apfs_header["nx_features"]) + && allowed_ro_compat_flags.contains(&apfs_header["nx_ro_compat_features"]) + && allowed_incompat_flags.contains(&apfs_header["nx_incompat_features"]) + { + // The test_type field *must* be NULL + if apfs_header["nx_xp_test_type"] == 0 { + // Make sure the FS count is sane; this is max_file_systems divided by 512, rounded up to nearest whole + let fs_count = ((apfs_header["nx_xp_max_file_systems"] as f32) + / (FS_COUNT_BLOCK_SIZE as f32)) + .ceil() as usize; + if fs_count > 0 && fs_count <= MAX_FS_COUNT { + return Ok(APFSHeader { + block_size: apfs_header["block_size"], + block_count: apfs_header["block_count"], + }); + } + } + } } } } From c3a38e643de7f90be65a1cc2f5c5ad27bf1fbad0 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Mon, 28 Oct 2024 12:02:47 -0400 Subject: [PATCH 030/131] APFS extraction working --- src/extractors.rs | 1 + src/extractors/apfs.rs | 18 ++++++++++++++++++ src/magic.rs | 2 +- src/structures/apfs.rs | 8 ++++---- 4 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 src/extractors/apfs.rs diff --git a/src/extractors.rs b/src/extractors.rs index f9663ccd5..87cf0104c 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -140,6 +140,7 @@ //! ``` pub mod androidsparse; +pub mod apfs; pub mod arcadyan; pub mod autel; pub mod bzip2; diff --git a/src/extractors/apfs.rs b/src/extractors/apfs.rs new file mode 100644 index 000000000..3445162e9 --- /dev/null +++ b/src/extractors/apfs.rs @@ -0,0 +1,18 @@ +use crate::extractors; + +/// Describes how to run the 7zzs utility to extract APFS images +pub fn apfs_extractor() -> extractors::common::Extractor { + extractors::common::Extractor { + utility: extractors::common::ExtractorType::External("7zzs".to_string()), + extension: "img".to_string(), + arguments: vec![ + "x".to_string(), // Perform extraction + "-y".to_string(), // Assume Yes to all questions + "-o.".to_string(), // Output to current working directory + extractors::common::SOURCE_FILE_PLACEHOLDER.to_string(), + ], + // If there is trailing data after the compressed data, extraction will happen but exit code will be 2 + exit_codes: vec![0, 2], + ..Default::default() + } +} diff --git a/src/magic.rs b/src/magic.rs index 1cedb28f5..7a6b529f8 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -919,7 +919,7 @@ pub fn patterns() -> Vec { magic: signatures::apfs::apfs_magic(), parser: signatures::apfs::apfs_parser, description: signatures::apfs::DESCRIPTION.to_string(), - extractor: Some(extractors::tsk::tsk_extractor()), + extractor: Some(extractors::apfs::apfs_extractor()), }, ]; diff --git a/src/structures/apfs.rs b/src/structures/apfs.rs index ea553924b..f17c69b80 100644 --- a/src/structures/apfs.rs +++ b/src/structures/apfs.rs @@ -15,7 +15,7 @@ pub fn parse_apfs_header(apfs_data: &[u8]) -> Result const MAX_FS_COUNT: usize = 100; const FS_COUNT_BLOCK_SIZE: usize = 512; - // Partial APFS header, just to figure out the size of the image. + // Partial APFS header, just to figure out the size of the image and validate some fields // https://developer.apple.com/support/downloads/Apple-File-System-Reference.pdf let apfs_structure = vec![ ("magic", "u32"), @@ -56,8 +56,6 @@ pub fn parse_apfs_header(apfs_data: &[u8]) -> Result // Parse the header if let Some(apfs_structure_data) = apfs_data.get(apfs_struct_start..apfs_struct_end) { if let Ok(apfs_header) = common::parse(apfs_structure_data, &apfs_structure, "little") { - println!("{:?}", apfs_header); - // Simple sanity check on the reported block data if apfs_header["block_size"] != 0 && apfs_header["block_count"] != 0 { // Sanity check the feature flags @@ -67,10 +65,12 @@ pub fn parse_apfs_header(apfs_data: &[u8]) -> Result { // The test_type field *must* be NULL if apfs_header["nx_xp_test_type"] == 0 { - // Make sure the FS count is sane; this is max_file_systems divided by 512, rounded up to nearest whole + // Calculate the file system count; this is max_file_systems divided by 512, rounded up to nearest whole let fs_count = ((apfs_header["nx_xp_max_file_systems"] as f32) / (FS_COUNT_BLOCK_SIZE as f32)) .ceil() as usize; + + // Sanity check the file system count if fs_count > 0 && fs_count <= MAX_FS_COUNT { return Ok(APFSHeader { block_size: apfs_header["block_size"], From b624a5e5811bed5f26d03cefb589ed7c530103c2 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Mon, 28 Oct 2024 12:05:53 -0400 Subject: [PATCH 031/131] Added 7zzs dependency --- dependencies/src.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dependencies/src.sh b/dependencies/src.sh index 0353edf2b..a02cfb53e 100755 --- a/dependencies/src.sh +++ b/dependencies/src.sh @@ -39,3 +39,12 @@ make cp srec2bin /usr/local/bin/ cd /tmp rm -rf /tmp/srec + +# Install latest version of 7z (static) for APFS support +mkdir /tmp/7z +cd /tmp/7z +wget https://www.7-zip.org/a/7z2408-linux-x64.tar.xz +tar -xf 7z2408-linux-x64.tar.xz +cp 7zzs /usr/local/bin/ +cd /tmp +rm -rf /tmp/7z From 82f1b8f6320bdabce8de9266664bb688ef13f978 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Tue, 29 Oct 2024 11:02:53 -0400 Subject: [PATCH 032/131] BTRFS identification working --- Cargo.lock | 10 ++++++ Cargo.toml | 1 + src/magic.rs | 11 +++++++ src/signatures.rs | 1 + src/signatures/btrfs.rs | 39 +++++++++++++++++++++++ src/structures.rs | 1 + src/structures/btrfs.rs | 68 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 131 insertions(+) create mode 100644 src/signatures/btrfs.rs create mode 100644 src/structures/btrfs.rs diff --git a/Cargo.lock b/Cargo.lock index 4e1b98eeb..5c2bbb455 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -110,6 +110,7 @@ dependencies = [ "clap", "colored", "crc32-v2", + "crc32c", "entropy", "env_logger", "flate2", @@ -325,6 +326,15 @@ version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f546fcecc3490696c3bea070d8949208279bbc220a5a7738573a10f584cda51" +[[package]] +name = "crc32c" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a47af21622d091a8f0fb295b88bc886ac74efcc613efc19f5d0b21de5c89e47" +dependencies = [ + "rustc_version", +] + [[package]] name = "crc32fast" version = "1.4.2" diff --git a/Cargo.toml b/Cargo.toml index 091cebf9d..4a7bf7576 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ entropy = "0.4.2" colored = "2.1.0" termsize = "0.1" crc32-v2 = "0.0.4" +crc32c = "0.6.8" plotters = "0.3.6" xz2 = "0.1.7" bzip2 = "0.4.4" diff --git a/src/magic.rs b/src/magic.rs index 7a6b529f8..aa0a7b783 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -921,6 +921,17 @@ pub fn patterns() -> Vec { description: signatures::apfs::DESCRIPTION.to_string(), extractor: Some(extractors::apfs::apfs_extractor()), }, + // BTRFS + signatures::common::Signature { + name: "btrfs".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::btrfs::btrfs_magic(), + parser: signatures::btrfs::btrfs_parser, + description: signatures::btrfs::DESCRIPTION.to_string(), + extractor: None, + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index f6395cc34..6f71e2810 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -111,6 +111,7 @@ pub mod apfs; pub mod arcadyan; pub mod autel; pub mod binhdr; +pub mod btrfs; pub mod bzip2; pub mod cab; pub mod cfe; diff --git a/src/signatures/btrfs.rs b/src/signatures/btrfs.rs new file mode 100644 index 000000000..13e1d0e91 --- /dev/null +++ b/src/signatures/btrfs.rs @@ -0,0 +1,39 @@ +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use crate::structures::btrfs::parse_btrfs_header; + +/// Human readable description +pub const DESCRIPTION: &str = "BTRFS file system"; + +/// BTRFS magic bytes +pub fn btrfs_magic() -> Vec> { + vec![b"_BHRfS_M".to_vec()] +} + +/// Validates the BTRFS header +pub fn btrfs_parser(file_data: &[u8], offset: usize) -> Result { + const MAGIC_OFFSET: usize = 0x10040; + + // Successful return value + let mut result = SignatureResult { + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + // Sanity check the reported offset + if offset >= MAGIC_OFFSET { + result.offset = offset - MAGIC_OFFSET; + + // Parse the superblock header; this also validates the superblock CRC + if let Ok(btrfs_header) = parse_btrfs_header(&file_data[result.offset..]) { + result.size = btrfs_header.total_size; + result.description = format!( + "{}, node size: {}, sector size: {}, leaf size: {}, stripe size: {}, bytes used: {}, total size: {} bytes", + result.description, btrfs_header.node_size, btrfs_header.sector_size, btrfs_header.leaf_size, btrfs_header.stripe_size, btrfs_header.bytes_used, result.size + ); + return Ok(result); + } + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index f5e2ab764..fd11b48b9 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -100,6 +100,7 @@ pub mod androidsparse; pub mod apfs; pub mod autel; pub mod binhdr; +pub mod btrfs; pub mod cab; pub mod chk; pub mod common; diff --git a/src/structures/btrfs.rs b/src/structures/btrfs.rs new file mode 100644 index 000000000..fdfefc941 --- /dev/null +++ b/src/structures/btrfs.rs @@ -0,0 +1,68 @@ +use crate::structures::common::{self, StructureError}; +use crc32c::crc32c; + +/// Struct to store BTRFS header info +#[derive(Debug, Default, Clone)] +pub struct BTRFSHeader { + pub bytes_used: usize, + pub total_size: usize, + pub leaf_size: usize, + pub node_size: usize, + pub stripe_size: usize, + pub sector_size: usize, +} + +/// Parses a BTRFS header +pub fn parse_btrfs_header(btrfs_data: &[u8]) -> Result { + const SUPERBLOCK_OFFSET: usize = 0x10000; + const SUPERBLOCK_END: usize = SUPERBLOCK_OFFSET + 0x1000; + const CRC_START: usize = 0x20; + + // Partial BTRFS superblock structure for obtaining image size and CRC validation + // https://archive.kernel.org/oldwiki/btrfs.wiki.kernel.org/index.php/On-disk_Format.html#Superblock + let btrfs_structure = vec![ + ("header_checksum", "u32"), + ("unused1", "u32"), + ("unused2", "u64"), + ("unused3", "u64"), + ("unused4", "u64"), + ("uuid_p1", "u64"), + ("uuid_p2", "u64"), + ("block_phys_addr", "u64"), + ("flags", "u64"), + ("magic", "u64"), + ("generation", "u64"), + ("root_tree_address", "u64"), + ("chunk_tree_address", "u64"), + ("log_tree_address", "u64"), + ("log_root_transid", "u64"), + ("total_bytes", "u64"), + ("bytes_used", "u64"), + ("root_dir_objid", "u64"), + ("num_devices", "u64"), + ("sector_size", "u32"), + ("node_size", "u32"), + ("leaf_size", "u32"), + ("stripe_size", "u32"), + ]; + + // Parse the header + if let Some(btrfs_header_data) = btrfs_data.get(SUPERBLOCK_OFFSET..SUPERBLOCK_END) { + if let Ok(btrfs_header) = common::parse(btrfs_header_data, &btrfs_structure, "little") { + // Validate the superblock CRC + if btrfs_header["header_checksum"] == (crc32c(&btrfs_header_data[CRC_START..]) as usize) + { + return Ok(BTRFSHeader { + sector_size: btrfs_header["sector_size"], + node_size: btrfs_header["node_size"], + leaf_size: btrfs_header["leaf_size"], + stripe_size: btrfs_header["stripe_size"], + bytes_used: btrfs_header["bytes_used"], + total_size: btrfs_header["total_bytes"], + }); + } + } + } + + Err(StructureError) +} From 9391f8925d886144589c82314ef8d895a91e7689 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Tue, 29 Oct 2024 13:14:48 -0400 Subject: [PATCH 033/131] BTRFS signature tested --- src/magic.rs | 2 +- src/signatures/btrfs.rs | 2 ++ src/structures/btrfs.rs | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/magic.rs b/src/magic.rs index aa0a7b783..38e18fe36 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -926,7 +926,7 @@ pub fn patterns() -> Vec { name: "btrfs".to_string(), short: false, magic_offset: 0, - always_display: false, + always_display: true, magic: signatures::btrfs::btrfs_magic(), parser: signatures::btrfs::btrfs_parser, description: signatures::btrfs::DESCRIPTION.to_string(), diff --git a/src/signatures/btrfs.rs b/src/signatures/btrfs.rs index 13e1d0e91..d96a3f9d8 100644 --- a/src/signatures/btrfs.rs +++ b/src/signatures/btrfs.rs @@ -11,6 +11,7 @@ pub fn btrfs_magic() -> Vec> { /// Validates the BTRFS header pub fn btrfs_parser(file_data: &[u8], offset: usize) -> Result { + // Offset of the superblock magic bytes in a BTRFS image const MAGIC_OFFSET: usize = 0x10040; // Successful return value @@ -22,6 +23,7 @@ pub fn btrfs_parser(file_data: &[u8], offset: usize) -> Result= MAGIC_OFFSET { + // Actual offset is the location of the magic bytes minus the magic byte offset result.offset = offset - MAGIC_OFFSET; // Parse the superblock header; this also validates the superblock CRC diff --git a/src/structures/btrfs.rs b/src/structures/btrfs.rs index fdfefc941..5eaf7da45 100644 --- a/src/structures/btrfs.rs +++ b/src/structures/btrfs.rs @@ -1,7 +1,7 @@ use crate::structures::common::{self, StructureError}; use crc32c::crc32c; -/// Struct to store BTRFS header info +/// Struct to store BTRFS super block info #[derive(Debug, Default, Clone)] pub struct BTRFSHeader { pub bytes_used: usize, @@ -12,7 +12,7 @@ pub struct BTRFSHeader { pub sector_size: usize, } -/// Parses a BTRFS header +/// Parse and validate a BTRFS super block pub fn parse_btrfs_header(btrfs_data: &[u8]) -> Result { const SUPERBLOCK_OFFSET: usize = 0x10000; const SUPERBLOCK_END: usize = SUPERBLOCK_OFFSET + 0x1000; From e5218f450dc8bf6519167d550a81ef131a3d5d6c Mon Sep 17 00:00:00 2001 From: Mole Shang <135e2@135e2.dev> Date: Wed, 30 Oct 2024 01:27:48 +0800 Subject: [PATCH 034/131] extractors/common: support Chroot path on windows --- src/extractors/common.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/extractors/common.rs b/src/extractors/common.rs index 9082d20ff..e9fd85ac7 100644 --- a/src/extractors/common.rs +++ b/src/extractors/common.rs @@ -176,7 +176,10 @@ impl Chroot { // If the joined path does not start with the chroot directory, // prepend the chroot directory to the final joined path. - if !joined_path.starts_with(&self.chroot_directory) { + // on Windows: If no chroot directory is specified, skip the operation + if cfg!(windows) && self.chroot_directory == path::MAIN_SEPARATOR.to_string() { + // do nothing and skip + } else if !joined_path.starts_with(&self.chroot_directory) { joined_path = format!( "{}{}{}", self.chroot_directory, @@ -749,6 +752,14 @@ impl Chroot { // Concatenate each non-excluded part of the file path, with each part separated by '/' for (i, path_part) in path_parts.iter().enumerate() { if !exclude_indicies.contains(&i) { + #[cfg(windows)] + { + // on Windows: in the first loop run, we cannot really prepend a '\' to drive letters like 'C:' + if sanitized_path.is_empty() { + sanitized_path = path_part.to_string(); + continue; + } + } sanitized_path = format!("{}{}{}", sanitized_path, path::MAIN_SEPARATOR, path_part); } } From 00086318dfcf78394db2f28ebf9bf8fb7d5b438f Mon Sep 17 00:00:00 2001 From: devttys0 Date: Tue, 29 Oct 2024 22:51:17 -0400 Subject: [PATCH 035/131] Initial Windows CE signature and extractor functional --- src/extractors.rs | 1 + src/extractors/wince.rs | 107 ++++++++++++++++++++++++++++++++++++++++ src/magic.rs | 11 +++++ src/signatures.rs | 1 + src/signatures/wince.rs | 43 ++++++++++++++++ src/structures.rs | 1 + src/structures/wince.rs | 55 +++++++++++++++++++++ 7 files changed, 219 insertions(+) create mode 100644 src/extractors/wince.rs create mode 100644 src/signatures/wince.rs create mode 100644 src/structures/wince.rs diff --git a/src/extractors.rs b/src/extractors.rs index 87cf0104c..51e948c77 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -178,6 +178,7 @@ pub mod ubi; pub mod uefi; pub mod uimage; pub mod vxworks; +pub mod wince; pub mod yaffs2; pub mod zip; pub mod zlib; diff --git a/src/extractors/wince.rs b/src/extractors/wince.rs new file mode 100644 index 000000000..fcaf0e5aa --- /dev/null +++ b/src/extractors/wince.rs @@ -0,0 +1,107 @@ +use crate::common::is_offset_safe; +use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; +use crate::structures::wince::{parse_wince_block_header, parse_wince_header}; + +/// Defines the internal extractor function for extracting Windows CE images +pub fn wince_extractor() -> Extractor { + return Extractor { + utility: ExtractorType::Internal(wince_dump), + ..Default::default() + }; +} + +/// Internal extractor for extracting data blocks from Windows CE images +pub fn wince_dump( + file_data: &[u8], + offset: usize, + output_directory: Option<&String>, +) -> ExtractionResult { + let mut result = ExtractionResult { + ..Default::default() + }; + + if let Some(wince_data) = file_data.get(offset..) { + if let Ok(wince_header) = parse_wince_header(&file_data) { + if let Some(wince_block_data) = wince_data.get(wince_header.header_size..) { + if let Some(data_blocks) = process_wince_blocks(wince_block_data) { + result.success = true; + result.size = Some(wince_header.header_size + data_blocks.total_size); + + if output_directory.is_some() { + let chroot = Chroot::new(output_directory); + + for block in data_blocks.blocks { + let block_file_name = format!("{:X}.bin", block.address); + + if !chroot.carve_file( + block_file_name, + wince_block_data, + block.offset, + block.size, + ) { + result.success = false; + break; + } + } + } + } + } + } + } + + result +} + +#[derive(Debug, Default, Clone)] +struct BlockInfo { + pub address: usize, + pub offset: usize, + pub size: usize, +} + +#[derive(Debug, Default, Clone)] +struct BlockData { + pub total_size: usize, + pub blocks: Vec, +} + +fn process_wince_blocks(blocks_data: &[u8]) -> Option { + const MIN_BLOCK_COUNT: usize = 3; + + let mut blocks = BlockData { + ..Default::default() + }; + let mut next_offset: usize = 0; + let mut previous_offset = None; + let available_data = blocks_data.len(); + + while is_offset_safe(available_data, next_offset, previous_offset) { + match parse_wince_block_header(&blocks_data[next_offset..]) { + Err(_) => { + break; + } + Ok(block_header) => { + blocks.total_size += block_header.header_size; + + if block_header.address == 0 { + if blocks.blocks.len() > MIN_BLOCK_COUNT { + return Some(blocks); + } else { + break; + } + } else { + blocks.total_size += block_header.data_size; + blocks.blocks.push(BlockInfo { + address: block_header.address, + offset: next_offset + block_header.header_size, + size: block_header.data_size, + }); + previous_offset = Some(next_offset); + next_offset += block_header.header_size + block_header.data_size; + } + } + } + } + + None +} diff --git a/src/magic.rs b/src/magic.rs index 38e18fe36..46883390b 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -932,6 +932,17 @@ pub fn patterns() -> Vec { description: signatures::btrfs::DESCRIPTION.to_string(), extractor: None, }, + // WinCE + signatures::common::Signature { + name: "wince".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::wince::wince_magic(), + parser: signatures::wince::wince_parser, + description: signatures::wince::DESCRIPTION.to_string(), + extractor: Some(extractors::wince::wince_extractor()), + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index 6f71e2810..0fbc596e8 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -173,6 +173,7 @@ pub mod ubi; pub mod uefi; pub mod uimage; pub mod vxworks; +pub mod wince; pub mod xz; pub mod yaffs; pub mod zip; diff --git a/src/signatures/wince.rs b/src/signatures/wince.rs new file mode 100644 index 000000000..95549a7c9 --- /dev/null +++ b/src/signatures/wince.rs @@ -0,0 +1,43 @@ +use crate::extractors::wince::wince_dump; +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use crate::structures::wince::parse_wince_header; + +/// Human readable description +pub const DESCRIPTION: &str = "Windows CE binary image"; + +/// Windows CE magic bytes +pub fn wince_magic() -> Vec> { + vec![b"B000FF\n".to_vec()] +} + +/// Validates the Windows CE header +pub fn wince_parser(file_data: &[u8], offset: usize) -> Result { + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + let dry_run = wince_dump(file_data, offset, None); + + if dry_run.success { + if let Some(total_size) = dry_run.size { + result.size = total_size; + + if let Ok(wince_header) = parse_wince_header(&file_data[offset..]) { + result.description = format!( + "{}, base address: {:#X}, image size: {} bytes, file size: {} bytes", + result.description, + wince_header.base_address, + wince_header.image_size, + result.size + ); + return Ok(result); + } + } + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index fd11b48b9..7abec370b 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -148,6 +148,7 @@ pub mod ubi; pub mod uefi; pub mod uimage; pub mod vxworks; +pub mod wince; pub mod xz; pub mod yaffs; pub mod zip; diff --git a/src/structures/wince.rs b/src/structures/wince.rs new file mode 100644 index 000000000..570a9e797 --- /dev/null +++ b/src/structures/wince.rs @@ -0,0 +1,55 @@ +use crate::structures::common::{self, StructureError}; + +/// Struct to store WindowsCE header info +#[derive(Debug, Default, Clone)] +pub struct WinCEHeader { + pub base_address: usize, + pub image_size: usize, + pub header_size: usize, +} + +/// Parses a Windows CE header +pub fn parse_wince_header(wince_data: &[u8]) -> Result { + let wince_header_structure = vec![ + ("magic_p1", "u32"), + ("magic_p2", "u24"), + ("image_start", "u32"), + ("image_size", "u32"), + ]; + + // Parse the WinCE header + if let Ok(wince_header) = common::parse(wince_data, &wince_header_structure, "little") { + return Ok(WinCEHeader { + base_address: wince_header["image_start"], + image_size: wince_header["image_size"], + header_size: common::size(&wince_header_structure), + }); + } + + Err(StructureError) +} + +/// Struct to store WindowsCE block info +#[derive(Debug, Default, Clone)] +pub struct WinCEBlock { + pub address: usize, + pub data_size: usize, + pub header_size: usize, + pub checksum: usize, +} + +/// Parse a WindowsCE block header +pub fn parse_wince_block_header(block_data: &[u8]) -> Result { + let wince_block_structure = vec![("address", "u32"), ("size", "u32"), ("checksum", "u32")]; + + if let Ok(block_header) = common::parse(block_data, &wince_block_structure, "little") { + return Ok(WinCEBlock { + address: block_header["address"], + data_size: block_header["size"], + checksum: block_header["checksum"], + header_size: common::size(&wince_block_structure), + }); + } + + Err(StructureError) +} From cb2206ec1a07cbe35acca9b49d80378ce4863873 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Tue, 29 Oct 2024 23:15:54 -0400 Subject: [PATCH 036/131] Code cleanup, code comments --- src/extractors/wince.rs | 72 +++++++++++++++++++++++++++-------------- src/signatures/wince.rs | 6 ++-- src/structures/wince.rs | 2 -- 3 files changed, 52 insertions(+), 28 deletions(-) diff --git a/src/extractors/wince.rs b/src/extractors/wince.rs index fcaf0e5aa..243661409 100644 --- a/src/extractors/wince.rs +++ b/src/extractors/wince.rs @@ -4,10 +4,10 @@ use crate::structures::wince::{parse_wince_block_header, parse_wince_header}; /// Defines the internal extractor function for extracting Windows CE images pub fn wince_extractor() -> Extractor { - return Extractor { + Extractor { utility: ExtractorType::Internal(wince_dump), ..Default::default() - }; + } } /// Internal extractor for extracting data blocks from Windows CE images @@ -20,27 +20,36 @@ pub fn wince_dump( ..Default::default() }; + // Parse the file header if let Some(wince_data) = file_data.get(offset..) { - if let Ok(wince_header) = parse_wince_header(&file_data) { + if let Ok(wince_header) = parse_wince_header(wince_data) { + // Get the block data, immediately following the file header if let Some(wince_block_data) = wince_data.get(wince_header.header_size..) { + // Process all blocks in the block data if let Some(data_blocks) = process_wince_blocks(wince_block_data) { - result.success = true; - result.size = Some(wince_header.header_size + data_blocks.total_size); - - if output_directory.is_some() { - let chroot = Chroot::new(output_directory); - - for block in data_blocks.blocks { - let block_file_name = format!("{:X}.bin", block.address); - - if !chroot.carve_file( - block_file_name, - wince_block_data, - block.offset, - block.size, - ) { - result.success = false; - break; + // The first block entry's address should equal the WinCE header's base address + if data_blocks.entries[0].address == wince_header.base_address { + // Block processing was successful + result.success = true; + result.size = Some(wince_header.header_size + data_blocks.total_size); + + // If extraction was requested, extract each block to a file on disk + if output_directory.is_some() { + let chroot = Chroot::new(output_directory); + + for block in data_blocks.entries { + let block_file_name = format!("{:X}.bin", block.address); + + // If file carving fails, report a failure to extract + if !chroot.carve_file( + block_file_name, + wince_block_data, + block.offset, + block.size, + ) { + result.success = false; + break; + } } } } @@ -52,6 +61,7 @@ pub fn wince_dump( result } +/// Stores info about each WinCE block #[derive(Debug, Default, Clone)] struct BlockInfo { pub address: usize, @@ -59,43 +69,57 @@ struct BlockInfo { pub size: usize, } +/// Stores info about all WinCE blocks #[derive(Debug, Default, Clone)] struct BlockData { pub total_size: usize, - pub blocks: Vec, + pub entries: Vec, } +/// Process all WinCE blocks fn process_wince_blocks(blocks_data: &[u8]) -> Option { - const MIN_BLOCK_COUNT: usize = 3; + // Arbitrarily chosen, just to make sure more than one or two blocks were processed and sane + const MIN_ENTRIES_COUNT: usize = 5; let mut blocks = BlockData { ..Default::default() }; + let mut next_offset: usize = 0; let mut previous_offset = None; let available_data = blocks_data.len(); + // Process all blocks until the end block is reached, or an error is encountered while is_offset_safe(available_data, next_offset, previous_offset) { + // Parse this block's header match parse_wince_block_header(&blocks_data[next_offset..]) { Err(_) => { break; } Ok(block_header) => { + // Include the block header size in the total size of the block data blocks.total_size += block_header.header_size; + // A block header address of NULL indicates EOF if block_header.address == 0 { - if blocks.blocks.len() > MIN_BLOCK_COUNT { + // Sanity check the number of blocks processed + if blocks.entries.len() > MIN_ENTRIES_COUNT { return Some(blocks); } else { break; } } else { + // Include this block's size in the total size of the block data blocks.total_size += block_header.data_size; - blocks.blocks.push(BlockInfo { + + // Add this block to the list of block entries + blocks.entries.push(BlockInfo { address: block_header.address, offset: next_offset + block_header.header_size, size: block_header.data_size, }); + + // Update the offsets for the next loop iteration previous_offset = Some(next_offset); next_offset += block_header.header_size + block_header.data_size; } diff --git a/src/signatures/wince.rs b/src/signatures/wince.rs index 95549a7c9..64d52945c 100644 --- a/src/signatures/wince.rs +++ b/src/signatures/wince.rs @@ -1,5 +1,5 @@ use crate::extractors::wince::wince_dump; -use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; use crate::structures::wince::parse_wince_header; /// Human readable description @@ -16,16 +16,18 @@ pub fn wince_parser(file_data: &[u8], offset: usize) -> Result Result Date: Wed, 30 Oct 2024 10:00:19 -0400 Subject: [PATCH 037/131] Replaced unzip with 7z extractor --- dependencies/ubuntu.sh | 1 - src/extractors.rs | 1 - src/extractors/zip.rs | 18 ------------------ src/magic.rs | 2 +- 4 files changed, 1 insertion(+), 21 deletions(-) delete mode 100644 src/extractors/zip.rs diff --git a/dependencies/ubuntu.sh b/dependencies/ubuntu.sh index 26c301e12..594096832 100755 --- a/dependencies/ubuntu.sh +++ b/dependencies/ubuntu.sh @@ -7,7 +7,6 @@ SCRIPT_DIRECTORY=$(dirname -- "$( readlink -f -- "$0"; )") DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install \ p7zip-full \ zstd \ - unzip \ tar \ sleuthkit \ cabextract \ diff --git a/src/extractors.rs b/src/extractors.rs index 51e948c77..87b19ff52 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -180,6 +180,5 @@ pub mod uimage; pub mod vxworks; pub mod wince; pub mod yaffs2; -pub mod zip; pub mod zlib; pub mod zstd; diff --git a/src/extractors/zip.rs b/src/extractors/zip.rs deleted file mode 100644 index 5ba90ccfc..000000000 --- a/src/extractors/zip.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::extractors; - -/// Describes how to run the unzip utility to extract ZIP archives -pub fn zip_extractor() -> extractors::common::Extractor { - extractors::common::Extractor { - utility: extractors::common::ExtractorType::External("unzip".to_string()), - extension: "zip".to_string(), - arguments: vec![ - "-o".to_string(), // Overwrite files without prompting - "-P".to_string(), // Specify a password for encrypted ZIP files - "''".to_string(), // Just use a blank password - extractors::common::SOURCE_FILE_PLACEHOLDER.to_string(), - ], - // Exit code 2 occurs when a CRC fails; files are still extracted though - exit_codes: vec![0, 2], - ..Default::default() - } -} diff --git a/src/magic.rs b/src/magic.rs index 46883390b..a3336104c 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -212,7 +212,7 @@ pub fn patterns() -> Vec { magic: signatures::zip::zip_magic(), parser: signatures::zip::zip_parser, description: signatures::zip::DESCRIPTION.to_string(), - extractor: Some(extractors::zip::zip_extractor()), + extractor: Some(extractors::sevenzip::sevenzip_extractor()), }, // Intel PCH ROM signatures::common::Signature { From aff478191e2ffe691390b533aacc08415ece36b1 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 30 Oct 2024 10:22:10 -0400 Subject: [PATCH 038/131] Added --search-all option --- src/binwalk.rs | 10 ++++++---- src/cliparser.rs | 4 ++++ src/extractors/zlib.rs | 5 +++-- src/main.rs | 1 + src/signatures/compressd.rs | 13 +++++++------ src/signatures/fat.rs | 4 ++-- src/signatures/gpg.rs | 25 ++++++++++++++----------- src/signatures/zlib.rs | 21 +++++++++------------ 8 files changed, 46 insertions(+), 37 deletions(-) diff --git a/src/binwalk.rs b/src/binwalk.rs index 3a32c388b..e09bf4806 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -73,7 +73,7 @@ pub struct Binwalk { impl Binwalk { /// Create a new Binwalk instance with all default values. - /// Equivalent to `Binwalk::configure(None, None, None, None, None)`. + /// Equivalent to `Binwalk::configure(None, None, None, None, None, false)`. /// /// ## Example /// @@ -84,7 +84,7 @@ impl Binwalk { /// ``` #[allow(dead_code)] pub fn new() -> Binwalk { - Binwalk::configure(None, None, None, None, None).unwrap() + Binwalk::configure(None, None, None, None, None, false).unwrap() } /// Create a new Binwalk instance. @@ -111,7 +111,8 @@ impl Binwalk { /// None, /// None, /// Some(exclude_filters), - /// None)?; + /// None, + /// false)?; /// # Ok(binwalker) /// # } _doctest_main_src_binwalk_rs_102_0(); } /// ``` @@ -121,6 +122,7 @@ impl Binwalk { include: Option>, exclude: Option>, signatures: Option>, + full_search: bool, ) -> Result { let mut new_instance = Binwalk { ..Default::default() @@ -193,7 +195,7 @@ impl Binwalk { // Each signature may have multiple magic bytes associated with it for pattern in signature.magic.clone() { - if signature.short { + if signature.short && !full_search { // These are short patterns, and should only be searched for at the very beginning of a file new_instance.short_signatures.push(signature.clone()); } else { diff --git a/src/cliparser.rs b/src/cliparser.rs index ae8461e26..e2aad1130 100644 --- a/src/cliparser.rs +++ b/src/cliparser.rs @@ -23,6 +23,10 @@ pub struct CliArgs { #[arg(short = 'M', long)] pub matryoshka: bool, + /// Search for all signatures at all offsets + #[arg(short = 'a', long)] + pub search_all: bool, + /// Plot the entropy of the specified file #[arg(short = 'E', long, conflicts_with = "extract")] pub entropy: bool, diff --git a/src/extractors/zlib.rs b/src/extractors/zlib.rs index e0c5aed90..513ade44a 100644 --- a/src/extractors/zlib.rs +++ b/src/extractors/zlib.rs @@ -1,6 +1,9 @@ use crate::extractors::common::{ExtractionResult, Extractor, ExtractorType}; use crate::extractors::inflate; +/// Size of the checksum that follows the ZLIB deflate data stream +pub const CHECKSUM_SIZE: usize = 4; + /// Defines the internal extractor function for decompressing zlib data pub fn zlib_extractor() -> Extractor { Extractor { @@ -17,8 +20,6 @@ pub fn zlib_decompress( ) -> ExtractionResult { // Size of the zlib header const HEADER_SIZE: usize = 2; - // Size of the checksum that follows the deflate data stream - const CHECKSUM_SIZE: usize = 4; // Do the decompression, ignoring the ZLIB header let mut result = diff --git a/src/main.rs b/src/main.rs index 65db04e52..69d78d45a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -95,6 +95,7 @@ fn main() { cliargs.include, cliargs.exclude, None, + cliargs.search_all, ) .expect("Binwalk initialization failed"); diff --git a/src/signatures/compressd.rs b/src/signatures/compressd.rs index b3ca915ea..66e8ae003 100644 --- a/src/signatures/compressd.rs +++ b/src/signatures/compressd.rs @@ -1,4 +1,6 @@ -use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use crate::signatures::common::{ + SignatureError, SignatureResult, CONFIDENCE_LOW, CONFIDENCE_MEDIUM, +}; /// Human readable description pub const DESCRIPTION: &str = "compress'd data"; @@ -14,17 +16,16 @@ pub fn compressd_parser( offset: usize, ) -> Result { // Successful return value; confidence is medium since this only matches magic bytes at the beginning of a file - let result = SignatureResult { + let mut result = SignatureResult { offset, description: DESCRIPTION.to_string(), - confidence: CONFIDENCE_MEDIUM, + confidence: CONFIDENCE_LOW, ..Default::default() }; - // This is enforced in magic.rs so this check is superfluous if offset == 0 { - return Ok(result); + result.confidence = CONFIDENCE_MEDIUM; } - Err(SignatureError) + Ok(result) } diff --git a/src/signatures/fat.rs b/src/signatures/fat.rs index 4aa91ca66..2e77b8f92 100644 --- a/src/signatures/fat.rs +++ b/src/signatures/fat.rs @@ -21,8 +21,8 @@ pub fn fat_parser(file_data: &[u8], offset: usize) -> Result= MAGIC_OFFSET { // FAT actually starts this may bytes before the magic bytes result.offset = offset - MAGIC_OFFSET; diff --git a/src/signatures/gpg.rs b/src/signatures/gpg.rs index 223e6bda4..001044773 100644 --- a/src/signatures/gpg.rs +++ b/src/signatures/gpg.rs @@ -1,4 +1,4 @@ -use crate::extractors::zlib::zlib_decompress; +use crate::extractors::zlib::{zlib_decompress, CHECKSUM_SIZE}; use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; /// Human readable description @@ -15,23 +15,26 @@ pub fn gpg_signed_parser( offset: usize, ) -> Result { // Success result; confidence is high since this signature is only reported what it starts at the beginning of a file - let result = SignatureResult { + let mut result = SignatureResult { offset, confidence: CONFIDENCE_HIGH, description: GPG_SIGNED_DESCRIPTION.to_string(), ..Default::default() }; - // This is enforced in magic.rs so this check is supurfulous - if offset == 0 { - /* - * GPG signed files are just zlib compressed files with the zlib magic bytes replaced with the GPG magic bytes. - * Decompress the signed file; no output directory specified, dry run only. - */ - let decompression_dry_run = zlib_decompress(file_data, offset, None); + /* + * GPG signed files are just zlib compressed files with the zlib magic bytes replaced with the GPG magic bytes. + * Decompress the signed file; no output directory specified, dry run only. + */ + let decompression_dry_run = zlib_decompress(file_data, offset, None); - // If the decompression dry run was a success, this signature is almost certianly valid - if decompression_dry_run.success { + // If the decompression dry run was a success, this signature is almost certianly valid + if decompression_dry_run.success { + if let Some(total_size) = decompression_dry_run.size { + // GPG doesn't include the trailing checksum + result.size = total_size - CHECKSUM_SIZE; + result.description = + format!("{}, total size: {} bytes", result.description, result.size); return Ok(result); } } diff --git a/src/signatures/zlib.rs b/src/signatures/zlib.rs index 171fb74cc..294d6532b 100644 --- a/src/signatures/zlib.rs +++ b/src/signatures/zlib.rs @@ -22,19 +22,16 @@ pub fn zlib_parser(file_data: &[u8], offset: usize) -> Result Date: Wed, 30 Oct 2024 10:23:31 -0400 Subject: [PATCH 039/131] Updated doc tests --- src/binwalk.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/binwalk.rs b/src/binwalk.rs index e09bf4806..678df9575 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -546,7 +546,8 @@ impl Binwalk { /// Some(extraction_directory), /// None, /// None, - /// None)?; + /// None, + /// false)?; /// /// let file_data = std::fs::read(&binwalker.base_target_file).expect("Unable to read file"); /// @@ -647,7 +648,8 @@ impl Binwalk { /// Some(extraction_directory), /// None, /// None, - /// None)?; + /// None, + /// false)?; /// /// let analysis_results = binwalker.analyze(&binwalker.base_target_file, true); /// From 912ce857c1aa53765d9d198bdd789f60fa086a09 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 30 Oct 2024 11:08:55 -0400 Subject: [PATCH 040/131] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 27358077a..2587d7f4c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # Binwalk v3 -This is an updated version of the Binwalk firmware analysis tool. - -It has been re-written in Rust, and is currently in the beta testing phase. +This is an updated version of the Binwalk firmware analysis tool, re-written in Rust for speed and accuracy. ![binwalk v3](images/binwalk_animated.svg) From 5f41f8d2f34eca8115f6452caa265549892eb976 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Thu, 31 Oct 2024 10:32:21 -0400 Subject: [PATCH 041/131] Fixed dependency issue; added README for crates.io --- CARGO_README.md | 28 ++++++++++++++++++++++++++++ Cargo.toml | 1 + dependencies/ubuntu.sh | 1 + fuzzing/Cargo.lock | 10 ++++++++++ 4 files changed, 40 insertions(+) create mode 100644 CARGO_README.md diff --git a/CARGO_README.md b/CARGO_README.md new file mode 100644 index 000000000..3ca954b25 --- /dev/null +++ b/CARGO_README.md @@ -0,0 +1,28 @@ +## binwalk + +A Rust implementation of the Binwalk firmware analysis tool. + +## System Requirements + +Building requires the following system packages: + +``` +build-essential libfontconfig1-dev liblzma-dev +``` + +## Example + +``` +use binwalk::Binwalk; + +// Create a new Binwalk instance +let binwalker = Binwalk::new(); + +// Read in the data to analyze +let file_data = std::fs::read("/tmp/firmware.bin").expect("Failed to read from file"); + +// Scan the file data and print the results +for result in binwalker.scan(&file_data) { + println!("{:#?}", result); +} +``` diff --git a/Cargo.toml b/Cargo.toml index 4a7bf7576..3d0e6b7ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ version = "3.1.0" edition = "2021" authors = ["Craig Heffner "] license = "MIT" +readme = "CARGO_README.md" repository = "https://github.com/ReFirmLabs/binwalk" description = "Analyzes data for embedded file types" keywords = ["binwalk", "firmware", "analysis"] diff --git a/dependencies/ubuntu.sh b/dependencies/ubuntu.sh index 594096832..e67c6a6c4 100755 --- a/dependencies/ubuntu.sh +++ b/dependencies/ubuntu.sh @@ -8,6 +8,7 @@ DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install \ p7zip-full \ zstd \ tar \ + unzip \ sleuthkit \ cabextract \ curl \ diff --git a/fuzzing/Cargo.lock b/fuzzing/Cargo.lock index 42ebaaef2..a93b56ef2 100644 --- a/fuzzing/Cargo.lock +++ b/fuzzing/Cargo.lock @@ -116,6 +116,7 @@ dependencies = [ "clap", "colored", "crc32-v2", + "crc32c", "entropy", "env_logger", "flate2", @@ -331,6 +332,15 @@ version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f546fcecc3490696c3bea070d8949208279bbc220a5a7738573a10f584cda51" +[[package]] +name = "crc32c" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a47af21622d091a8f0fb295b88bc886ac74efcc613efc19f5d0b21de5c89e47" +dependencies = [ + "rustc_version", +] + [[package]] name = "crc32fast" version = "1.4.2" From 4fdab3d464d97b68e0af9088df3f9e2e1545b21c Mon Sep 17 00:00:00 2001 From: devttys0 Date: Thu, 31 Oct 2024 10:33:41 -0400 Subject: [PATCH 042/131] Minor cargo readme change --- CARGO_README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CARGO_README.md b/CARGO_README.md index 3ca954b25..d6da9a2da 100644 --- a/CARGO_README.md +++ b/CARGO_README.md @@ -1,4 +1,4 @@ -## binwalk +# binwalk A Rust implementation of the Binwalk firmware analysis tool. From e0a4434159f22ff926c1baa3872d93a5f8dbf87e Mon Sep 17 00:00:00 2001 From: devttys0 Date: Thu, 31 Oct 2024 11:10:42 -0400 Subject: [PATCH 043/131] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2587d7f4c..fb517d90d 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ Binwalk can be customized and [integrated](https://github.com/ReFirmLabs/binwalk The easiest way to install Binwalk and all dependencies is to [build a Docker image](https://github.com/ReFirmLabs/binwalk/wiki/Building-A-Binwalk-Docker-Image). +Binwalk can also be [installed](https://github.com/ReFirmLabs/binwalk/wiki/Cargo-Installation) via the Rust package manager. + Or, you can [compile from source](https://github.com/ReFirmLabs/binwalk/wiki/Compile-From-Source)! ## How do I use it? From 40111215a8adc39f2018a832a91d3ba6e5b9c491 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 1 Nov 2024 10:10:46 -0400 Subject: [PATCH 044/131] Added extraction utility existence tests for extractors a-c --- src/extractors/androidsparse.rs | 23 ++++++++++++++++++++++- src/extractors/apfs.rs | 21 +++++++++++++++++++++ src/extractors/arcadyan.rs | 21 +++++++++++++++++++++ src/extractors/autel.rs | 21 +++++++++++++++++++++ src/extractors/bzip2.rs | 21 +++++++++++++++++++++ src/extractors/cab.rs | 21 +++++++++++++++++++++ src/extractors/dtb.rs | 21 +++++++++++++++++++++ 7 files changed, 148 insertions(+), 1 deletion(-) diff --git a/src/extractors/androidsparse.rs b/src/extractors/androidsparse.rs index cd98e189f..755ccceb8 100644 --- a/src/extractors/androidsparse.rs +++ b/src/extractors/androidsparse.rs @@ -2,7 +2,28 @@ use crate::common::is_offset_safe; use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; use crate::structures::androidsparse; -/// Defines the internal extractor function for decompressing zlib data +/// Defines the internal extractor function for extracting Android Sparse files +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::androidsparse::android_sparse_extractor; +/// +/// match android_sparse_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn android_sparse_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(extract_android_sparse), diff --git a/src/extractors/apfs.rs b/src/extractors/apfs.rs index 3445162e9..cc6b2771a 100644 --- a/src/extractors/apfs.rs +++ b/src/extractors/apfs.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the 7zzs utility to extract APFS images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::apfs::apfs_extractor; +/// +/// match apfs_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn apfs_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("7zzs".to_string()), diff --git a/src/extractors/arcadyan.rs b/src/extractors/arcadyan.rs index 456616030..dec1f7474 100644 --- a/src/extractors/arcadyan.rs +++ b/src/extractors/arcadyan.rs @@ -2,6 +2,27 @@ use crate::extractors::common::{ExtractionResult, Extractor, ExtractorType}; use crate::extractors::lzma::lzma_decompress; /// Defines the internal extractor for Arcadyn Obfuscated LZMA +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::arcadyan::obfuscated_lzma_extractor; +/// +/// match obfuscated_lzma_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn obfuscated_lzma_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(extract_obfuscated_lzma), diff --git a/src/extractors/autel.rs b/src/extractors/autel.rs index f18e34f67..05f681a56 100644 --- a/src/extractors/autel.rs +++ b/src/extractors/autel.rs @@ -4,6 +4,27 @@ use crate::structures::autel::parse_autel_header; const BLOCK_SIZE: usize = 256; /// Defines the internal extractor function for deobfuscating Autel firmware +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::autel::autel_extractor; +/// +/// match autel_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn autel_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(autel_deobfuscate), diff --git a/src/extractors/bzip2.rs b/src/extractors/bzip2.rs index 1aa861c47..15b68856e 100644 --- a/src/extractors/bzip2.rs +++ b/src/extractors/bzip2.rs @@ -2,6 +2,27 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use bzip2::{Decompress, Status}; /// Defines the internal extractor function for decompressing BZIP2 files +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::bzip2::bzip2_extractor; +/// +/// match bzip2_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn bzip2_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(bzip2_decompressor), diff --git a/src/extractors/cab.rs b/src/extractors/cab.rs index 4e800dcf2..bdddda932 100644 --- a/src/extractors/cab.rs +++ b/src/extractors/cab.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the cabextract utility to extract MS CAB archives +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::cab::cab_extractor; +/// +/// match cab_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn cab_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("cabextract".to_string()), diff --git a/src/extractors/dtb.rs b/src/extractors/dtb.rs index 364ff5287..1753ca0ab 100644 --- a/src/extractors/dtb.rs +++ b/src/extractors/dtb.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the dtc utility to extract DTB files +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::dtb::dtb_extractor; +/// +/// match dtb_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn dtb_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("dtc".to_string()), From 92f7a13590760702168a0989d8aa8f7b348ffdd7 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 1 Nov 2024 10:20:07 -0400 Subject: [PATCH 045/131] Added extractor definition tests for d-j --- src/extractors/dmg.rs | 21 +++++++++++++++++++++ src/extractors/dumpifs.rs | 21 +++++++++++++++++++++ src/extractors/gif.rs | 21 +++++++++++++++++++++ src/extractors/gzip.rs | 21 +++++++++++++++++++++ src/extractors/jboot.rs | 21 +++++++++++++++++++++ src/extractors/jffs2.rs | 21 +++++++++++++++++++++ src/extractors/jpeg.rs | 21 +++++++++++++++++++++ 7 files changed, 147 insertions(+) diff --git a/src/extractors/dmg.rs b/src/extractors/dmg.rs index d75e091c0..c1bf54614 100644 --- a/src/extractors/dmg.rs +++ b/src/extractors/dmg.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the dmg2img utility to convert DMG images to MBR +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::dmg::dmg_extractor; +/// +/// match dmg_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn dmg_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("dmg2img".to_string()), diff --git a/src/extractors/dumpifs.rs b/src/extractors/dumpifs.rs index 9f6de0c19..90df3f457 100644 --- a/src/extractors/dumpifs.rs +++ b/src/extractors/dumpifs.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the dumpifs utility to extract QNX IFS images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::dumpifs::dumpifs_extractor; +/// +/// match dumpifs_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn dumpifs_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("dumpifs".to_string()), diff --git a/src/extractors/gif.rs b/src/extractors/gif.rs index d9a0253ec..0ec4beaa8 100644 --- a/src/extractors/gif.rs +++ b/src/extractors/gif.rs @@ -4,6 +4,27 @@ use crate::structures::common::StructureError; use crate::structures::gif::{parse_gif_extension, parse_gif_header, parse_gif_image_descriptor}; /// Defines the internal extractor function for carving out JPEG images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::gif::gif_extractor; +/// +/// match gif_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn gif_extractor() -> Extractor { Extractor { do_not_recurse: true, diff --git a/src/extractors/gzip.rs b/src/extractors/gzip.rs index 4ec01ecf5..b7a3004c0 100644 --- a/src/extractors/gzip.rs +++ b/src/extractors/gzip.rs @@ -3,6 +3,27 @@ use crate::extractors::inflate; use crate::structures::gzip::parse_gzip_header; /// Defines the internal extractor function for decompressing gzip data +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::gzip::gzip_extractor; +/// +/// match gzip_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn gzip_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(gzip_decompress), diff --git a/src/extractors/jboot.rs b/src/extractors/jboot.rs index 148188ade..77a6ed154 100644 --- a/src/extractors/jboot.rs +++ b/src/extractors/jboot.rs @@ -3,6 +3,27 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use crate::structures::jboot::parse_jboot_sch2_header; /// Defines the internal extractor function for carving out JBOOT SCH2 kernels +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::jboot::sch2_extractor; +/// +/// match sch2_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn sch2_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(extract_jboot_sch2_kernel), diff --git a/src/extractors/jffs2.rs b/src/extractors/jffs2.rs index 9c8185e97..e0875fe5b 100644 --- a/src/extractors/jffs2.rs +++ b/src/extractors/jffs2.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the jefferson utility to extract JFFS file systems +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::jffs2::jffs2_extractor; +/// +/// match jffs2_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn jffs2_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("jefferson".to_string()), diff --git a/src/extractors/jpeg.rs b/src/extractors/jpeg.rs index 6458d7406..99c5d6e0c 100644 --- a/src/extractors/jpeg.rs +++ b/src/extractors/jpeg.rs @@ -2,6 +2,27 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use aho_corasick::AhoCorasick; /// Defines the internal extractor function for carving out JPEG images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::jpeg::jpeg_extractor; +/// +/// match jpeg_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn jpeg_extractor() -> Extractor { Extractor { do_not_recurse: true, From eaf87808d42acb3fbad897eda8d6a2e257687484 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 1 Nov 2024 10:35:38 -0400 Subject: [PATCH 046/131] Added extractor definition tests for l-s --- src/extractors/linux.rs | 21 +++++++++++++++++++ src/extractors/lz4.rs | 21 +++++++++++++++++++ src/extractors/lzfse.rs | 21 +++++++++++++++++++ src/extractors/lzma.rs | 21 +++++++++++++++++++ src/extractors/lzop.rs | 21 +++++++++++++++++++ src/extractors/mbr.rs | 21 +++++++++++++++++++ src/extractors/pcap.rs | 21 +++++++++++++++++++ src/extractors/pem.rs | 42 ++++++++++++++++++++++++++++++++++++++ src/extractors/png.rs | 21 +++++++++++++++++++ src/extractors/rar.rs | 21 +++++++++++++++++++ src/extractors/riff.rs | 21 +++++++++++++++++++ src/extractors/romfs.rs | 21 +++++++++++++++++++ src/extractors/sevenzip.rs | 21 +++++++++++++++++++ src/extractors/squashfs.rs | 42 ++++++++++++++++++++++++++++++++++++++ src/extractors/srec.rs | 21 +++++++++++++++++++ src/extractors/svg.rs | 21 +++++++++++++++++++ 16 files changed, 378 insertions(+) diff --git a/src/extractors/linux.rs b/src/extractors/linux.rs index c939fb6b0..bf6020fe6 100644 --- a/src/extractors/linux.rs +++ b/src/extractors/linux.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the vmlinux-to-elf utility to convert raw kernel images to ELF files +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::linux::linux_kernel_extractor; +/// +/// match linux_kernel_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn linux_kernel_extractor() -> extractors::common::Extractor { extractors::common::Extractor { do_not_recurse: true, diff --git a/src/extractors/lz4.rs b/src/extractors/lz4.rs index 8d6992982..f45aaacd2 100644 --- a/src/extractors/lz4.rs +++ b/src/extractors/lz4.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the lz4 utility to extract LZ4 compressed files +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::lz4::lz4_extractor; +/// +/// match lz4_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn lz4_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("lz4".to_string()), diff --git a/src/extractors/lzfse.rs b/src/extractors/lzfse.rs index ca553aba0..2eb2d4b7c 100644 --- a/src/extractors/lzfse.rs +++ b/src/extractors/lzfse.rs @@ -1,6 +1,27 @@ use crate::extractors::common::{Extractor, ExtractorType, SOURCE_FILE_PLACEHOLDER}; /// Describes how to run the lzfse utility to decompress LZFSE files +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::lzfse::lzfse_extractor; +/// +/// match lzfse_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn lzfse_extractor() -> Extractor { const OUTPUT_FILE_NAME: &str = "decompressed.bin"; diff --git a/src/extractors/lzma.rs b/src/extractors/lzma.rs index d19531e35..3796bd559 100644 --- a/src/extractors/lzma.rs +++ b/src/extractors/lzma.rs @@ -2,6 +2,27 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use xz2::stream::{Action, Status, Stream}; /// Defines the internal extractor function for decompressing LZMA/XZ data +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::lzma::lzma_extractor; +/// +/// match lzma_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn lzma_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(lzma_decompress), diff --git a/src/extractors/lzop.rs b/src/extractors/lzop.rs index 6fd0487e5..b5cb6b788 100644 --- a/src/extractors/lzop.rs +++ b/src/extractors/lzop.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the lzop utility to extract LZO compressed files +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::lzop::lzop_extractor; +/// +/// match lzop_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn lzop_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("lzop".to_string()), diff --git a/src/extractors/mbr.rs b/src/extractors/mbr.rs index 6d47086da..99527a7c9 100644 --- a/src/extractors/mbr.rs +++ b/src/extractors/mbr.rs @@ -2,6 +2,27 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use crate::structures::mbr::parse_mbr_image; /// Defines the internal extractor function for MBR partitions +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::mbr::mbr_extractor; +/// +/// match mbr_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn mbr_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(extract_mbr_partitions), diff --git a/src/extractors/pcap.rs b/src/extractors/pcap.rs index c0c899db9..01a9eb954 100644 --- a/src/extractors/pcap.rs +++ b/src/extractors/pcap.rs @@ -3,6 +3,27 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use crate::structures::pcap::{parse_pcapng_block, parse_pcapng_section_block}; /// Defines the internal extractor function for extracting pcap-ng files +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::pcap::pcapng_extractor; +/// +/// match pcapng_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn pcapng_extractor() -> Extractor { Extractor { do_not_recurse: true, diff --git a/src/extractors/pem.rs b/src/extractors/pem.rs index 7857bd24d..e58ad70bc 100644 --- a/src/extractors/pem.rs +++ b/src/extractors/pem.rs @@ -2,6 +2,27 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use aho_corasick::AhoCorasick; /// Defines the internal extractor function for carving out PEM keys +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::pem::pem_key_extractor; +/// +/// match pem_key_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn pem_key_extractor() -> Extractor { Extractor { do_not_recurse: true, @@ -11,6 +32,27 @@ pub fn pem_key_extractor() -> Extractor { } /// Internal extractor function for carving out PEM certs +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::pem::pem_certificate_extractor; +/// +/// match pem_certificate_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn pem_certificate_extractor() -> Extractor { Extractor { do_not_recurse: true, diff --git a/src/extractors/png.rs b/src/extractors/png.rs index 06e5531ea..5f7a3fc6b 100644 --- a/src/extractors/png.rs +++ b/src/extractors/png.rs @@ -3,6 +3,27 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use crate::structures::png::parse_png_chunk_header; /// Defines the internal extractor function for carving out PNG images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::png::png_extractor; +/// +/// match png_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn png_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(extract_png_image), diff --git a/src/extractors/rar.rs b/src/extractors/rar.rs index 8441807c7..a2bd47d78 100644 --- a/src/extractors/rar.rs +++ b/src/extractors/rar.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the unrar utility to extract RAR archives +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::rar::rar_extractor; +/// +/// match rar_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn rar_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("unrar".to_string()), diff --git a/src/extractors/riff.rs b/src/extractors/riff.rs index 0fe6be828..52ecee5c5 100644 --- a/src/extractors/riff.rs +++ b/src/extractors/riff.rs @@ -2,6 +2,27 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use crate::structures::riff::parse_riff_header; /// Describes the internal RIFF image extactor +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::riff::riff_extractor; +/// +/// match riff_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn riff_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(extract_riff_image), diff --git a/src/extractors/romfs.rs b/src/extractors/romfs.rs index 58e879fa1..a7a9116b5 100644 --- a/src/extractors/romfs.rs +++ b/src/extractors/romfs.rs @@ -27,6 +27,27 @@ struct RomFSEntry { } /// Defines the internal extractor function for extracting RomFS file systems */ +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::romfs::romfs_extractor; +/// +/// match romfs_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn romfs_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(extract_romfs), diff --git a/src/extractors/sevenzip.rs b/src/extractors/sevenzip.rs index 3de64dccd..a67509eeb 100644 --- a/src/extractors/sevenzip.rs +++ b/src/extractors/sevenzip.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the 7z utility, supports multiple file formats +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::sevenzip::sevenzip_extractor; +/// +/// match sevenzip_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn sevenzip_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("7z".to_string()), diff --git a/src/extractors/squashfs.rs b/src/extractors/squashfs.rs index 4f8c871a6..4747d541f 100644 --- a/src/extractors/squashfs.rs +++ b/src/extractors/squashfs.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the sasquatch utility to extract SquashFS images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::squashfs::squashfs_extractor; +/// +/// match squashfs_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn squashfs_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("sasquatch".to_string()), @@ -13,6 +34,27 @@ pub fn squashfs_extractor() -> extractors::common::Extractor { } /// Describes how to run the sasquatch-v4be utility to extract big endian SquashFSv4 images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::squashfs::squashfs_v4_be_extractor; +/// +/// match squashfs_v4_be_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn squashfs_v4_be_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("sasquatch-v4be".to_string()), diff --git a/src/extractors/srec.rs b/src/extractors/srec.rs index 0bc049d30..392833c0d 100644 --- a/src/extractors/srec.rs +++ b/src/extractors/srec.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the srec2bin utility to convert Motorola S-records to binary +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::srec::srec_extractor; +/// +/// match srec_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn srec_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("srec2bin".to_string()), diff --git a/src/extractors/svg.rs b/src/extractors/svg.rs index d7846e2a5..287788d83 100644 --- a/src/extractors/svg.rs +++ b/src/extractors/svg.rs @@ -2,6 +2,27 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use crate::structures::svg::parse_svg_image; /// Defines the internal extractor function for carving out SVG images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::svg::svg_extractor; +/// +/// match svg_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn svg_extractor() -> Extractor { Extractor { do_not_recurse: true, From 4b4458797d79ba8a6c05c38bd395f7072fd5cee8 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 1 Nov 2024 10:39:58 -0400 Subject: [PATCH 047/131] Added extractor definition tests for m-z --- src/extractors/tarball.rs | 21 +++++++++++++++++++++ src/extractors/trx.rs | 21 +++++++++++++++++++++ src/extractors/ubi.rs | 21 +++++++++++++++++++++ src/extractors/uefi.rs | 23 ++++++++++++++++++++++- src/extractors/uimage.rs | 22 ++++++++++++++++++++++ src/extractors/vxworks.rs | 21 +++++++++++++++++++++ src/extractors/wince.rs | 21 +++++++++++++++++++++ src/extractors/yaffs2.rs | 21 +++++++++++++++++++++ src/extractors/zlib.rs | 21 +++++++++++++++++++++ src/extractors/zstd.rs | 21 +++++++++++++++++++++ 10 files changed, 212 insertions(+), 1 deletion(-) diff --git a/src/extractors/tarball.rs b/src/extractors/tarball.rs index 96ae07fba..f482b77de 100644 --- a/src/extractors/tarball.rs +++ b/src/extractors/tarball.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the tar utility to extract tarball archives +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::tarball::tarball_extractor; +/// +/// match tarball_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn tarball_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("tar".to_string()), diff --git a/src/extractors/trx.rs b/src/extractors/trx.rs index 36bb89b0e..11d627824 100644 --- a/src/extractors/trx.rs +++ b/src/extractors/trx.rs @@ -3,6 +3,27 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use crate::structures::trx::parse_trx_header; /// Defines the internal TRX extractor +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::trx::trx_extractor; +/// +/// match trx_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn trx_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(extract_trx_partitions), diff --git a/src/extractors/ubi.rs b/src/extractors/ubi.rs index 7aa7893f1..fcad0861d 100644 --- a/src/extractors/ubi.rs +++ b/src/extractors/ubi.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the ubireader_extract_images utility to extract UBI images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::ubi::ubi_extractor; +/// +/// match ubi_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn ubi_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External( diff --git a/src/extractors/uefi.rs b/src/extractors/uefi.rs index 0c901a8e3..90c517653 100644 --- a/src/extractors/uefi.rs +++ b/src/extractors/uefi.rs @@ -1,6 +1,27 @@ use crate::extractors; -/* Describes how to run the uefi-firmware-parser utility to extract UEFI images */ +/// Describes how to run the uefi-firmware-parser utility to extract UEFI images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::uefi::uefi_extractor; +/// +/// match uefi_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn uefi_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("uefi-firmware-parser".to_string()), diff --git a/src/extractors/uimage.rs b/src/extractors/uimage.rs index 35a1195ed..56e54680b 100644 --- a/src/extractors/uimage.rs +++ b/src/extractors/uimage.rs @@ -2,6 +2,28 @@ use crate::common::crc32; use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; use crate::structures::uimage::parse_uimage_header; +/// Describes the internal extractor for carving uImage files to disk +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::uimage::uimage_extractor; +/// +/// match uimage_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn uimage_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(extract_uimage), diff --git a/src/extractors/vxworks.rs b/src/extractors/vxworks.rs index 072714504..6b8dbe9b6 100644 --- a/src/extractors/vxworks.rs +++ b/src/extractors/vxworks.rs @@ -6,6 +6,27 @@ use crate::structures::vxworks::{ use serde_json; /// Describes the VxWorks symbol table extractor +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::vxworks::vxworks_symtab_extractor; +/// +/// match vxworks_symtab_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn vxworks_symtab_extractor() -> Extractor { Extractor { do_not_recurse: true, diff --git a/src/extractors/wince.rs b/src/extractors/wince.rs index 243661409..509db92bf 100644 --- a/src/extractors/wince.rs +++ b/src/extractors/wince.rs @@ -3,6 +3,27 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use crate::structures::wince::{parse_wince_block_header, parse_wince_header}; /// Defines the internal extractor function for extracting Windows CE images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::wince::wince_extractor; +/// +/// match wince_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn wince_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(wince_dump), diff --git a/src/extractors/yaffs2.rs b/src/extractors/yaffs2.rs index 4e514fbae..d8b1f6316 100644 --- a/src/extractors/yaffs2.rs +++ b/src/extractors/yaffs2.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the unyaffs utility to extract YAFFS2 file systems +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::yaffs2::yaffs2_extractor; +/// +/// match yaffs2_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn yaffs2_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("unyaffs".to_string()), diff --git a/src/extractors/zlib.rs b/src/extractors/zlib.rs index 513ade44a..e6d99bd95 100644 --- a/src/extractors/zlib.rs +++ b/src/extractors/zlib.rs @@ -5,6 +5,27 @@ use crate::extractors::inflate; pub const CHECKSUM_SIZE: usize = 4; /// Defines the internal extractor function for decompressing zlib data +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::zlib::zlib_extractor; +/// +/// match zlib_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn zlib_extractor() -> Extractor { Extractor { utility: ExtractorType::Internal(zlib_decompress), diff --git a/src/extractors/zstd.rs b/src/extractors/zstd.rs index c7632a617..8cf1fec9f 100644 --- a/src/extractors/zstd.rs +++ b/src/extractors/zstd.rs @@ -1,6 +1,27 @@ use crate::extractors; /// Describes how to run the zstd utility to extract ZSTD compressed files +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::zstd::zstd_extractor; +/// +/// match zstd_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn zstd_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("zstd".to_string()), From 88051e420513ec8fbf55688c74981cea196346c9 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 1 Nov 2024 11:54:36 -0400 Subject: [PATCH 048/131] Added initial integration testing --- .gitattributes | 3 ++- src/binwalk.rs | 4 ++-- tests/arcadyan.rs | 8 +++++++ tests/common/mod.rs | 48 ++++++++++++++++++++++++++++++++++++++ tests/gzip.rs | 8 +++++++ tests/inputs/arcadyan.bin | Bin 0 -> 734208 bytes tests/inputs/gzip.bin | Bin 0 -> 109 bytes tests/inputs/pdf.bin | Bin 0 -> 245715 bytes tests/pdf.rs | 8 +++++++ 9 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 tests/arcadyan.rs create mode 100644 tests/common/mod.rs create mode 100644 tests/gzip.rs create mode 100644 tests/inputs/arcadyan.bin create mode 100644 tests/inputs/gzip.bin create mode 100644 tests/inputs/pdf.bin create mode 100644 tests/pdf.rs diff --git a/.gitattributes b/.gitattributes index dd97f3b97..2d4aa6d37 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ * text eol=lf *.md text eol=lf -*.png binary \ No newline at end of file +*.png binary +*.bin binary diff --git a/src/binwalk.rs b/src/binwalk.rs index 678df9575..ea55b13af 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -534,7 +534,7 @@ impl Binwalk { /// /// ## Example /// - /// ``` + /// ```no_run /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_binwalk_rs_529_0() -> Result { /// use binwalk::Binwalk; /// @@ -636,7 +636,7 @@ impl Binwalk { /// /// ## Example /// - /// ``` + /// ```no_run /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_binwalk_rs_624_0() -> Result { /// use binwalk::Binwalk; /// diff --git a/tests/arcadyan.rs b/tests/arcadyan.rs new file mode 100644 index 000000000..9b733713a --- /dev/null +++ b/tests/arcadyan.rs @@ -0,0 +1,8 @@ +mod common; + +#[test] +fn pdf_integration() { + const SIGNATURE_TYPE: &str = "arcadyan"; + const INPUT_FILE_NAME: &str = "arcadyan.bin"; + let _ = common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); +} diff --git a/tests/common/mod.rs b/tests/common/mod.rs new file mode 100644 index 000000000..5e57409e0 --- /dev/null +++ b/tests/common/mod.rs @@ -0,0 +1,48 @@ +use binwalk::{AnalysisResults, Binwalk}; + +pub fn integration_test(signature_filter: &str, file_name: &str) -> AnalysisResults { + // Build the path to the input file + let file_path = std::path::Path::new("tests") + .join("inputs") + .join(file_name) + .display() + .to_string(); + + // Build the path to the output directory + let output_directory = std::path::Path::new(&std::env::temp_dir().display().to_string()) + .join("binwalk_integration_test_extractions") + .display() + .to_string(); + + // Delete the output directory, if it exists + let _ = std::fs::remove_dir_all(&output_directory); + + // Configure binwalk + let binwalker = Binwalk::configure( + Some(file_path), + Some(output_directory.clone()), + Some(vec![signature_filter.to_string()]), + None, + None, + false, + ) + .expect("Binwalk initialization failed"); + + // Run analysis + let results = binwalker.analyze(&binwalker.base_target_file, true); + + // Each test is expected to have a single result at offset 0 in the file + assert!(results.file_map.len() == 1); + assert!(results.file_map[0].offset == 0); + + // Tests which support extraction are expected to have a single successful extraction + if !results.extractions.is_empty() { + assert!(results.extractions.len() == 1); + assert!(results.extractions[&results.file_map[0].id].success); + } + + // Clean up the output directory + let _ = std::fs::remove_dir_all(output_directory); + + results +} diff --git a/tests/gzip.rs b/tests/gzip.rs new file mode 100644 index 000000000..b8abbc9ab --- /dev/null +++ b/tests/gzip.rs @@ -0,0 +1,8 @@ +mod common; + +#[test] +fn gzip_integration() { + const SIGNATURE_TYPE: &str = "gzip"; + const INPUT_FILE_NAME: &str = "gzip.bin"; + let _ = common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); +} diff --git a/tests/inputs/arcadyan.bin b/tests/inputs/arcadyan.bin new file mode 100644 index 0000000000000000000000000000000000000000..d23b442d44cfa9443dd1416ff21b283d0ba58bda GIT binary patch literal 734208 zcmV(pK=8jX1rZ?oACM7-d=BU{#Pq&wX2rtWy}Ept&6=8;_Z8*bH6P67fM11Zpv8Um zm1D#*ARD?jeo^nQ&Vwc~(`L>jDLl_F06MF;Ny;f;&??`ogKyKa4TmVOk{ZUg#Q>qO z9s@Y6ZPSAQ)d&DY0HWRi000000FeOg5JZ8s@crP|t#Xu#B5^;RsJ}hdeok4K8)HeO zls(vB*UGM_w!yR#CPX0pSam^qbNgzfSNd1&Iz6XWRZN1dwi0@~(maIjq$U>S$emPQ znk_8yPT|kAsx#Hk$8sgfh8%tjL-Q6`K#a>#F?KF)-#Z1Vx5`~7$3pQH-8*O8#UtEv z5~ZhrVX}Cr%-vd+iFKev)T<7FXXQ}P>DoaP?!;;?9*ObY!QbF&&Sya`(Z{XdlDFO( z=7vnGT5%z5+19Ih6`~N{!6Le4d=l0waxx(AAPz+|1}B&^Op?i~T{yE)W`KK$gQvUD zf@PZ3W$I(^Tv7(Dh_YJG;W3gN-IwB@(AakVC4dDv_D{TUhM-2PmF0OCyEwbV>p}8U zZ$S=uuk41LFZ(NEqA$#4rX@~0uN|<`L{SHbTc)DlEU*9IaE4|_-(17TLzNX6~=DH4t za8~PQ3E5Sh?qxXNW13&uuAOdGS{PCl|Gz(z_w0i<30bMA|e-{btx7vAQmh?AioPIu@J#Ozm7>t`4}_I(8Ua z%&!qoj(g3`M-&5`sZVN0wm0U!EhKP9^unR-d!P>KI+YVDI~;&A;#wg2IczxowOhg( zm(C6-uE6|6?+iXIf;x?s#{+z{#yLwc-=r(9Ls2fSX6D5L$RuROtC4{rV6&6jj7M;L zd$*bcrUm;{VEMw*QDM9QxY&<*!<*p;9eiK=n8RV<>*_b}^5aF=zK3)z3mfEqUuBX* zO^__C(T&~BR7~r3b>Q(Z2Z`_0^EIw-&WG#KOn*w=_FkUrY7f?dDy(eB{`rY#vdqG;UPN_j-Z8#3Z3=X0i6L&V^-A;O1AI68@6`v=B#z?zQK= z6*~zw2SrUINXXd_1;{ST#M8*(ap_j0--{kfte6#=pwk2GBFDW}8t>3Q7HCgcrB(E( z-#dZO-LLB$jxVyrOYOf4TZea;c8{>VpD*+(3TKSIULssR*lFe495Y`O&4;eRLDc$F z_Ie2$*Z9fT0XZmWLu_crvvIdG(*=cUnd_T`z3Yl3_60+V5CWuDW$Rd)6uEybf{P2( z-{xCmb9d?W7^M-vU|eZscaHAGHRvawNg#}fXBh1y#q5ruRyf!K)iEqbM&9U(Z6BA- zSL|XrOqsoE0&pTdiOF_84$}V=89r`l7$c6Tp|ZwvQGgvA+y{Q*dC|E%_jeUnq8M@9 zM5DRqJD~ci4`*z4x4P{u?Tc-C@FiPQoq_YNxrv)*c%Xr3@z+`e(Gq~Jqm7EvpdTWc zz)E$az%5HxrJhezo$^6t

E|uxt8+E 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


D;u6*+5W( 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 z z6mee^N2XKd#zjp%ZgL$7}$C4IUI!FXxT9QR) zHaZv-NG58}$;KQTM5)LE#{#4vIoh@yZY|lo+mOW(+$OlvM>sNC0h74kJQg01&Gy+F zb14WFg(D-+ewbmAsw`oTaV6rVwj~QBetH5WBWARC78OAz`?|l}ES$Xm-pT;n#*0t^2 z9Z6Q^?)xxHLc#=9Mj)sJt5Q?26y$hRufGsE>sv_z^$KMuE3l9~tIjZCa+dWLgxn%*_G)P6C}Ixr|cK91KpQULcc)%TUl0R@FKWbf z8Kq4<@}`UllghPXHC&}c3avLoP$bdieF)TB;b{AgIREH6_hC>g z_6g;~&WpRrRz@}D&c;7!v`TPwv??gD(|>aOrk0Y%qSy!wtQh8sP|8sx92Au-0xl!V zqOfmhTB(NRohk*wG;UouSX6#y)WAcc-GvIxPpv{lLTbU}AC0L{jJc~sdR!ww9sq-( zVa*&n2W@xB#TK`NC}jq3)>Z^5h^-zbjNGm8XMsr2kI+>xH%j>lsBU}7PvsvT04qab zv|fA~yHuSUIaRO7@nHu*CeE>xF~Xh#GPTRikdhP09{~8d=c~q!F}rYK7$NlZD*F?A z`I_YXB)UU)`hmcwRV9Rbg@H3;dW43M;YiJO!0aDnnCfF3m}U@Ox&Lz){M{3roYViT zUSg2LpjsN`Y=7# z_65Ny3zxSoiCxw}obRYMMQK7%xl{x?_y0=pz=0X4adg_fbwg>Stwzo>&pcbA>=Bpr zw=U@B|GhombtP{lEwQ}tXKnPTd}jw>$^qiIWlsqhfovp$KC83eI2CAU2xG87x;q6) zLlcG)?3R4pub1w~#_2Ym>Gi(OSxP_&c65~r?A=9(fxCvN*(I{R#AD_N0JRm}be1!zU3DlGpDU}qJof*I= zP`UNtC=CDHMm*SLc@VIr%}Td-@4VS=h~|AR>|wET+JkL4UIK6w>~Vk>mK2}4g9nW9 z%N=QcdIU2C8{K9m%@~RAadH%yQx|}}Ws|#A%-w-PTxVA0 z?D=zadjt9NMx14Su99V5q75u*cV41}7^6PRx{x->UP~r+&EwtUiAVRj^Muf<@&3dx zN>}}E-&&f;6U)Cg+wg1$`5X6jWyPRwVb@hM;Dpo{049If1 zv3XlfDshj;tTTz~T#NXFVObM+aTMW2N$wDZJD%%nY8-aWH&)|TB-tTe)=6>!|OIfob%g@&1$$nV*Bi$mO6btcq|0sS2CT8z)%cxa8~BW zlxTK=Tk1=bN)jm$m>wkV^b)u_f1r0rC3-DUZh#6D42uT+s3vdUv3zAikRWd$JgzG9 zb{aKdB#vu|Mv)}d;KEpfDWmaXkVDQ9>(D_y7az0rF!XDbxtCTOECm3XUJrY2foBHuFusw4)jd@j-e=x=5O{8)&Atm8! zH#L#z0N(v+FKtqY1K#(&ukoRY^$l%g*&W8MizxLsXq`>He<$nv!;b;$a{qe4gA2dY zcW?qkICEX|$7ps;JB9D_~fU}&QaA;UVRH9qEKH!tR3*VPP(e99LKB*_m7?))OcIepl(;4_kWa|6UVnMifA z!^^zhO!S=m$~bnyfd?tjC^(Sz+vV1GlPQQIv)FlMu2`)fxKVx$Apzwy z2M^__>wf39hrKJlJtYzo%lC2D!9zK2)!CQAw91D7IarIqwF#!R=q+d>3LEx|7QfPi z6CB3_*&Mr_l`Wma4qMR$#3PwiieE_@L?Inv)_e$2f2Itd6$65u8zUx;TVj$M5bmN~P z((_*;;IukJ*QfC^MqqVaFd}DQ6-)NrB5BGr+oBh{ie}KZ(AF0=@b)()^4cdHlt~_BJ zaZvbXfrD(HD`fOW&x!?o*++evdIX>1&Jm#xVF)-i;=cixO3sho#gXB|LBS{{HH9RO zl^Zxh0A&Z)Q+!;8_JVyFn+|I9`P#T@vlIt)3z)gM!XQwX7*aCpNldOKio|IpbW?gR@ELQVAR&rTu)NF+rn_rzH1f z)JMA>9b>l%q!pKjm6hbIis02aTDmw*kfA(|Zjy=)Xj%Cf=7IrV2>t4@FA$%YQNK<5 z4f{^Yv#J_}RIo zbBCQxqYTWhX=zRh&_lBnBt^qvjy$`vG?D~ObTwRYHnftdcfj0&NsTZ;%xf*>qx}E` z1nf|PH3p`E3D~s`&Z9(JG|19t!SbOrHktuPJAh|>Tk$zVu!rdN?f3;QaK}y>YsTSg z;Of0WyF6O704W96oVcz=p1Hzuk04DQVeEP&nLt4mGq|HK5J@Zu@w}jA=J%FP+{?-j zOEYdcq~DhCbupj6{&-!dIuymI;B2(teLJ1ZM32Dv_*xYYjIZmJuuLZWe1~-B@9THf zkVc#ruuksW$QzihZ^9;M;J|92n>SF--6(&=2`ecdI_yKgh|->W_OnyY_^TNf^ocLQ zvYTrT`GcU-Fg>$++$WEVd4bIKB^jtH6{f^CO}$-+nG8{m9q$cidHSLfi@7 zJ5WCB(C?L)pRo1H(gzzO`85>_b>KUMXe!+Yz_i`2+3DWo3Vd z807RC8RUhI9n&TFV>tuQX*9Y>uE=roV{i8L_sxqIF{!L6;Qf zjE*|C)-DHR=)OT)`%mAdeRG_1aomgzYVKq3Byc+pOM@ClX3<`-Mj4fdr3=%)1%F~9 z?8@*tAeniHn66ME>W;{SFjO>qaJuNd3vRf}r8A_RAhS-va9P}12-5TJTE01%tgABT zh{DdKVWISWEsF2h@J2&rdEOBHqK4HIjz{kB;+4Z?LSl=w51z!3Z;5mzFy{1-tITbf3wc>|7WLiHu8OZj(@yjmoe& zeB_>mL{b3K6Azs;)lU{t{D0@CYXdThNv<~m%d{8D zrBxTP#(X&QtZ@1zvs7--cHn+JvrfgsD`YH(9?dnLA!-8q458l(rvt@Hc&QwZoofj9 zl3cCLAycnJR7>3h+`fKXXq*$nC*lcM3Z;GLQ$j6tCXhb=| z5IWsA<=MmIw{{g^(bQ9A>MUu8?GULv5OA_*95ZJ3Sx*Rmq>vQm=cJmAxjd);g?lZQ z&z4G{j@#KYi1{sHgKmx%UXH&+RYeav6^%NCBQY}PQUeNvuUCQt;m4HxBR&<%XT6#N zyE;ike5`Cm57ndIqtO6yBqag)1JMN?wv!>3d~uApmQR-*1~jw3rl1UXa?^e|B!NP;lJto75<5dUhq%(&EAx%dm>3v>PD|FCG2 z?!ADC^qr@(j${%f;7EG!F{rm;082o$zupixc7Y%Tn4dzg3VfjO6nvvHgR~rG`TArY z;qSYnU{@ZlRGt6)PeMfnj~O#HWJ3H*m~JEC(-Z)giAnE>6^O;8n)Z`MSMQS`=xlO* zwXo;*L=GovKp(&*(coGcR*Se6*UG=WY4pWyb^r@#Ui^+bspsVrLhs=;1E(){0*Nsq zlXwGEW?bnOBjA*Q7wc{U^;1*z444ail|qkkp&3&G3)uA(pU%gvaUqmf;*^0WUWC%Y zY}LE(`JbzNsow8UdhZQ~IKPyyN}NpZ48B3*=LSQi1vgBdsCR;<-6KkWkuKiC^hNgyU4G! zT~V;)GVDCspDt(C7Djoc8i!1%WX)ydJX3*6>>3qB4tcON{~~zmVA|P3h@#}l>A`oL z!R(-~ZomR)h53?atpd=(V5;?F`m1BrJH;kHM-Idn5{}fdA*GdUG?pTw-A?Nan)gMP zj2aU5eWrf4pX8zD>8w|C_s}_$`wOXxUEyrOd&=&I9Q8RnCg3$@vvl*R$bU69g-liWxjw9p2N3){779_Y0ew)2)R{Euh1FMFPlATa*LkD;DWenj2Zi-IO@oywY^>oP6 z%}-cAYZf<1HmD7H6WsVjur_!7Q@+~f$_Ecgz_yHDhSrinX+_Uw17@^}qN1=5u>HhK zmijB^Kyn^1j^;5Ud80n`x@S}J3YqXsH}v3^hKq(CfD{A3bJ?-+x3?={j662{EB(N5 z$BiuJs0yc&$y%wBWhii4urcnUh;9! zKe;}Oec9_UMe7t6@^jVn5syUZ$vVqcgsq<9$@FWiv=MA;$W6MC|8-_Qkp8nz>yodl zUm!#q_8u^VRtU^^OvM#pdo!~xV;FRET9-;dV~S*PjjZjMuOuIv(PLO?-eTLPr{xCi;d~>X=$FiCtw1}lLc9e9VKxms zGu_Uh8W3ZgkAf5!&jt#G_AySFkJmxQ;ylqs)??+_IcVUm!37L)&1iRg2G&@`Fy?dL zd#u=D5#ow~0F4UXUf9C1@QkpTe0sO-{Yq{Dk*T3!+F@&I)tVQncl&O03U;5qJ4cTe zsnh4j0FIoH6^$dndqxV)Ra_6LdVQj$b--jSK)`i(TU~)mwDa}u{~_fnNs&gk%mfF4 z_r#3XGh@7El{1-t#ylgi79Lc?zIZr=&eA|YVSkaRl%DwR2fiQj5lu{l?^JsB!PE-I zdBD`l8(rzyIV>eR@I7!L4dnjU!I|ip3mlD2PwcFpu1fBMW?y&zC(eo3;W=Pbt8j@x zId%GT5{yRFdZJp1TUcX=l!SC3yxnmagBW4BFz$kKgz9?N`~J}KHXx-{&;!!SHE%RE z_$Vg!JKJ6?h@eQ(Y!D$B`*Z}9tbW9F)YT(;Wt!u;R|Ptg(w7X1^Rhsrrcc*Lt)n71 zu^f2(N1hBdpqL}=zD8FrcdMvU@*=7}VtWlHzz|YFSmt=_6a)Q3Kj-sUtRaoc$&LRA z2m{8wtU@$E(k1gfKw~9@CG)6nM0&!Td5xY(D@<~DVxzAciYv(iYjtpx=%Vw10YAGkis4W7kJOB3(ALB(7Dg4f7;qS2m4wJ%W0AdGKKF&P z5@eNBej0RH5yjwC@9OeVKuN0({~7(GF0TB%O84nHc6mVavGbnYBJP_;0nLk^J$V1suOfY3qy_7sx0ia@IX8f|@zlA3|Ql zpBIy=Yy`M^DB3#fHZxUR1*#i3YE0fQtC*fkj11ou&EkZR0%@u)@H~KM7q$w1gGnp3~jAvb)bg96fBGvH8p-7KVKC;#*41>K)LN zZ8+~>Ix~e_t85O>H&b;m(tknb3z)D4v{uOxNs=}d=-}3UeG&wt7jEn%@Dg{0opR|< z`MVRkhQV{2qbAXUm*dkIjuxyj(-U}Il!lDudr9#8fNSd(hO{G@B(hhOf)fn6R{Qz5 zXD_8>xyCpNnU)A4>4xCJPC#}l{n?K)6;#VN1s7BsVpOaG2ayl&*x_i9S3>7g@c!S$R8 zKgvx!Z>;sm(vcbQ263$3z55Q6fvK^nYOJi@1Z$;Xx7jTF;@uPDI|hmdd?*V{JsV>Q zT6W9J*85l2u_pt2vc|${2`)`t1|GKnwJGHl_o>a`knF$L1YqACDVZ)Yf8RS6hGp>y z@tU)PLZ3j$JQHddMRA`Jv*3bP=xcXaea*4{V;U(bWsITUJa9j<^*5ks8S@zQLP&)ktiOfI)vMh#97|f zuIphoaXIxIXe6p`*g7Um;&7P?mT+Cu&i`1ex|M$cv8jfK>GEGgaVyLiCA(l?9nZE2 z;?5v<_6T)t2cAAXXblnFZZN^Fx!GKKVoIonr)^jJ5^FTB6Ozx45i*ReT;M{4^L73@ zY?iwS?8Y*Ja!boc1OD`lE|&v5){G;F6FHBJpxdWuXRtS$O#ilW)pSl9aiF_QDC<6z zs4i?hwPD(n&rEioCT_zMivRC1)EQ8$M{y!`Wc3bx=oS1JR=Fw5#?TT*BiXCE#=O9C z#jH?6!Gl@*LnTXoD0#eJx9a*h6i?CSlk4D-1wjD{(hciO{s?I{M+T9!v$YKPw1WV#gFi%Y;rO+fx-n5oRsNY31N0h$jdtTa8F=tkOY<$+O#5*#Ugf7_i_{ zJedOkak_U>zhMj<4N z8{m(l$YhnJ%I#(IL`toR)Cf0&3(^qX5kmP(kxeVuf2=1Y7|##dj{mfXPmo=pu7q*B z0=9N*?x^QJ-PW!P1~DKap5 zvY+e+W9)j}5m1!2rQmho{e+klC0x>tU5C}lCUZySkH(m;ZScRK|99BQOyh~BTP@M^ z*my#ej^+Ot@WMu*v1*dJBL?XGg%>i|Ug0UP%j9OF#{+zQaU|%DH#e61oDTa&45i-R z20)FKX7b2~%)hrCe=uKYrBqb^c{c*Di-O&fUR6sNqdwPn!te252=)-qIPa3<9ayis zP=rerg2R)GwK{3Ulxee@@iMJN)>bC}QFm&$ZFjp?o-D@JOLB~zzF{}Vd-IUgc{56C z7&n}GAhd`M4oc8UWifiKQNu0uT!@eFcArmLj9%roo9d>my!-_1wYh~@07~x*l}N@( zUT9P1g~!lSe?zf__x)<>2aS%ZYw)S!7tinm!_#l%GBA0PX|Sc8F8RTlT?ssyXc({|w|!I90qV$`GQ&w&jXGHz={ zbg&p$S`P=1QZ;%&WE=}6oscOAm8}Jt2mx@niaMGHQ;?^y7ntNky9kb-Wn++wGPm7T z%25L25rLN|n$Wp-z9v%yW(b;TNU#5&xnCgrvUC_KJPIZ*VFcz22%+58u+Hb~;5z=B-|E66sW6bU$?c7;D=CU|Puc5soa;6xljg zI9m&L^|!1PFVV+Hx}zsFr%#>>S)_aaE;w>%Bhy(x06$22 z$a8@4pa!`M=OPSKJo+b5oU$DO@KI19H%<(BG?nyL%B*)< z$jU=sNn8lT!1Fat_rS>1_5gu7`o9A>Td8W^yN3__<%uY1{E=nKb%7 zXO@TB)Otq`7oz7QTi2PR<>hJDThwWly%>i78ezZ$^bw{>BKMZzi$)2w-(6#${)qk^ z6`UzY?wiggJejUMC|)?S@7{sZCo2REm$2+Yugwfdyw8|cj7i`SiT4(J13j&yr@@Od zsy&p7ETi0$qbm5kiOJ|+j>JH){=#MqUC8A4tS9s^YKRU9_ACi*cYovbM)b^C@Gb<91y>S_;izsQ1`Lz2wTvt77RCZ8*}|gD z(Z6{Ab&z+&<{f(sAfBX(cnmt{T-g=v**<~iL+XM0eAH4=PWoFKOY}@iB;hX?hTFq% z#{^dwSIDmSIFY|gL2~~)xZ#(7o3+(?_D;=V6y6iOht8^0iO%bSwgaR!9|w~o&s1~j z{NwslT&zy8d+^Z+l)SPD;9Zg_ug@@4q~;|sQH7&Pb$C1i4Z#A9_1%S}O7fh2w`~o#Nq0;opwLPP%qG zGkF92PPs4r)_jGGsH5B`7|9$GXmAet39r2UaO-5pRMke*c@cx=JYU5=&=3l zMy(T##-7x~0570!o}_(i|Gm~lHT5j4)*mb8IMWJ+O%N(njQaFac`BqM#+@`?Kd2!D9B~z7ZRR+X)&~g~UH3OFQp0=pr?f1hnpvJ$m zi#Ev(ub-eC($2{G&tq*Il57hAv~^GQ`4p;R!`*7n)iE0?l?;3Xv7A#(?!+4rH%*~a8T2^?#ObGWV;2(;q71lC(2FJg#bhR{|7rgaZOLo0->YlyD6pEXUyc)Sx>55@yGHYGKb zbYx(43aF6R3o<6VL=eEcE&QRJSP=_v66&X`hE6@^oKlY@4$ZfvJCF_BTLy z1}3wvzxm+^q=IAXf)YhBFLG-ayQwPZN?Kyc+wmJ#EQ! zQmO^Ksx#PP#idO85LwqA@7{L*|2|erlg`bmioR}jbobTf5z@ZduCaakZRc3O)SSeq za1jg?(db+Q#m4vpUu;2r5)NP)eV*X&gBn2+%j`AGB!wfcU?^Bb{)^AKg#6lH&CYj> z0VTnW*U0X2)B~`$K8M&DLRHiXcf<7GvPo=fMIMIl>JfEt2vb?2gJ=_Yw@|>?F|`Av zKcT6uX^k4v(%AI2py*t|TkQOxfvxL{lo?WwHVL{d=8j$-9Hnu=$o$Eu*kTECJiGY9~#=vo5(lmFO5WvYF?No#r=Bvk~d* zl4;5E%cWbf+!F4*qYD|aBAY(0;Uqqi3InbgUVnaQlzsZk(t^wl&!Pkt&rISGs}!^z z9;szV0gaO;nM3&^u>sMcL@6)Y4~e>GRq13M5_4%%sqnc)5a66e53bGDs)-cMgTnE;GqB6vQJT_kT(QK0h( z4l?Hf&=f(*mf6-nO^g{SJmzz&S~@YEy(oMN1o~ZNK-#XFOcyToo`)^fhu?uTd6%*! zw;o8;SGEhst^^pcMD!Cd{`&_zpEat^S%aqSe9<_UOuEFrx*MjsU+&wQaHo2y-$LVpVt5dEl16^PH=DV}L zPSNh9Q?AWpORhp6))3pjv_n%+NZ}5+OP>V!=vghu4Wk{UPi-bmBxJv^JaF%%7#fy< z{!o1{x5L!4QYS>g){DyiBO311KA02Ao_}NdG~jyaAA!rQC9YfY^)L*%TDn|oCvX2f zpQfU27XG;g@)8-miB`4r*0z zPx!fUjX9znqo-x+B`j+i{H*Z_lmn*y0wX)9CTw!eI*>Zb!3uF!OlBs(He+$;!12R( zQnE&^TU06|9v5KdZHe*cFsjLy2-Xte9PR7l5=5Zzn^uUuk;h#Q^-zDi73&Jg76w^g z`ntN+LyhuFXn&V$m$bb;r$JKTk3cu6yfeyR;+fY2Mnv`3;m?)9zC;>Rl=$ zvKGaO*k#F#JeFNav7nbv6WFJ6B~?4_OjF zn6pq+p1bTMd^zWqGVq#&xD#ZbuDa(fG8osC1$al|NgXMiVYL*P_seKTp=+o&Ftn^l zk|~F>1T{6avDqhvYb5OxpLRA9^QzpprW;dbL=r@{@FGuu9K83XIdRDKp zu4X6nxPUIA$$##p&=o*E7+$7Bq#J7+%d2S|(uFlFJQfTU%u+r5#tt>ZG0axzTN4`k%<s}<(YZ`{GKEu?#%B54-?FFD4Z{HMVe@yroN4UriYdsphHkoZC#>~hh2kDizJxe`W-QT z)$5>xqv*+IEMF*2(8%Sh2s6AH!%ss}PNh--25-6d!l-jf`|8}PR7^ndxSTB{Uq+l2XG#iFkV3(H{Rjw2f>|67QPnAoSbyk6K`}9$St^{B z=`Br1V`U;#N(<7->s4v#vypV{R)4ctTO+HqndD_AVDm>h8iuoyGl*>ENnG~@)@Iu; zMRxkYpxeDCWfSyg`Z$2Y^Fm8Jm90aShBbBGgZi{Rv@6XNAy6Cd<*m*CQz zitO1bU@I0JyRd_-r=X_`4h16lPl+Y~Ljpm@K==N^p4kTR#1}3Y6$UR$n&lxg{EXq0 zf!8#(nKn#Y%(ck6HLYOQ=-K9l7Pj+KfpmpT-bIyAbF%0#Gr|)|Ks{Xp&W~@`j^U){ zm)G36q|Wiq{wi%NgyUcBWQ!U3`ZvA{sFPiU)VScUT|5{6l;ZVz@;um-LpHG~Upw!r z>`$L9969qYacFH{xrvV*u^2RmiQVfEkgz&oa}{y^-L6W;eWKp%WNrCszsgiiwK9bX zrw+%pMnA}0p8&L?H}00iv7?~*D%T-!)Wq&kQxOexH%&j$9xntJWftU1o{Ql%3Kge?G$RlTm|D601^AUb12wCK>gJnD& zhet!sj998-plGi3i*CNL*|mE{GK{a`bPrP9A;@+D(WS%?ZvXcBIX~2j0vv;gzK(T2 z==w$nVUG5IRBGNCf~)k*CSRQQZ&e#nyTQMKnPE0L9f4qA-!PsC8$?%dj=XadKR_R# zb1tFm^Q9m5F1nX{KQ++4qfD^AX@dN5irMi4mx?;YR{;+(rz~cp{nAsrpw)+geRpH(rZwh_F!!Xv=mo5wufg@d+t@l!APo9#%(Fh zVhRgZjqTB&C8XEF`I4n!_S+A0TEwrAsY`Z*wY@Czn)2ah(jR;Z&=#BYaG!62aC6bk zPMn9)M;EC410zE6oNv1Uc5~RGU;&!tiu1D&5ITw=XCorB!Tm4JtVwMVv|%qQ!^sr3 zZx;i6nAEDD*4*-Jgr$2z+B4(qr9J1A#M?O=BwNHKj4MTXtwYVQLCD!q$xen2U|WLt zQRk%H`(!kS?ybfe+<@H%37EA;mvcb@A z5Zn%ii%`%OCoz0MhArBi*TtPK(v`6x(~}#7#+D3H$O5B>Joe}^#^3hjKB_7Jxam@q z*dGIp%D4Veir!IyPGl}kJ_@!K?X><+6D@x1l#UVAdt!#pWFI(p&yw**$ViW0uQ z(jhbuOdWpypBX_jJNkL2fdHyFlzDw?NU@0^qB|^^TART)L6k1JypK_f)m|)w!x8!R zH<^3RB=(@3615mQ)RS9abl8zgWGelFX@0b;l=%z|fjgC!W%)VgAs8bWLA7ogessfcg&K0Le~3YO zlzj}j&ec%=u}$D_Kjkz5O4|YRwC8u%`P0#ByA6n)A`qXios;9sqPZH;!S=k#Jqr^q zKS1vpEomfxoKry^b+*N(_1CAISUHLK-js>he^zcsz&DLESM`_?*bk=#+Sd~^&iTf# z%fqGuG`2w2QCjaOfL&BwfKOEa`eutKyhmi+}Q>KK&oMXO^EG z?)aB&5$RQ7!M#MT*#!S)Lc!~-cNknA5TA*Fs|gPv1U5WI9K=6Dw&dQWtWu+EsdEy) z-?okp4Gw=W-4`Cb)I#SKuSSaBw)Mk=shSlALQcB`{IC z3(5n@h=|njZu7pDlbzw@IR8YsaQ>RW=dY--{syN0lQx9ln)g10nm1g~&Q}InQC%dn z`X(XE(+KT>w(0VI5cv2Z?{xQBVE?b4Mz@YBrf&CMvZw7rMLmrRnIwt|j3^{bTthE; z=s%GOK+Bj5m1alv<1OFJpH|)z@pieRR(XeG^u--z*+{IdV6`Tr`%I@iCZfdFOXa6D z6eW~lov&@W_J+&t{`8bxZwP8VpY@3p0?=|&yqdfhxvJsdR;O+pYoc=;JP1VK_YMHbN`)FVz>peKs%o8->0_JS z*YpDMY-WK}H3H1Zv|8E}l$Q2C5>hQq^pu!KUv+kGVqanB+)&LY_?m6Jifr6bC*tB} zW?W_ReOTHBmSdbi$!7DCHw9YNNI63b$z6RMx`*jAU5Xyz#b$T!X)(eg9c|qq^WO40 z431PStkpxSv-2P5@14?B=LEg0Jo`d_US^n6D1?IiE&8W zT@5c|Tn|Xe86PZGdB%LZW;Q((#)cU?>wFHuRTQT((QO-wErXOERoDLyw+0$+5`92fwz>NC41l236A zzJGdir%kn-Kjuo2&}k4h4Lw%M7gK;w^2@vzCk!NFt1;JQkWwDe9Xxf)^d2RtS43z` zjL8_Jg~z=-Nxynfn^fBu(uFrjSRTN9ycm6X24yohzTyeKtvD$taJAWmRRbZ){oD-) zc5G>nRme$h?CZ+0aVFnu#fp;fCy@r1^J_w#ESR^oxSizX=oA|ym**QqULqbR^C$Kv z#NzM^bPEhDl+jP*V6!O4toQ|k<2EYKY`V-1v63%xHd}G%qA$5xa$*b|J`Y6^bqG)7 z|JuKGO#R&Ww9pg%U96bMZ`y`ItErp_3= zRj2TOzifLIXKN*3noN5IvQ-4kBDwJE-qSU6I?zJEA^=wC2sjP6I4wY^n%}Foc5TQ4 zJm=BFz~$q#1FLImf$PXl;8{IzF*GcXr8J5-j~zwLV=co5C4%ab&=;uxVyG6hhi_%_ zGKH%LPK~{87X*WHzz>gwec77{-$KV`bUqi@$Wd}rize@E@@05pyApNcvQKjWOAbW) zxlKVQItiwA@zvNay3QHw-7)C244^`~^v?^cBa{3NLc9yQY8AoVMr^FuEWD$8yhobZ zJP}oHXo@+>sHd^eEXMPhFj*@|L@=|4_L}WD6SZD%1h&*=Gr0{HQaD2R?rkdYFt|<_ zEbTNLtIixycN)kULrb-Bfdy&O&41F2AQAO7@Mh!CQa~5nXgb^0Z_FjH&C+g|ANY#* zWV1o5f~~)1*!7KK5k3G|uNW60xt0j7En2)c&tCfC&uE?eH5aptUVlX)2NtjTSE^2M zQK^I2FOq?akEHNH*=nu`k`MQ@hD9qp4~%>vhyjd2+N0oV{CKz_WO=gBp83a4Q_*Of zNje%w{p)AxNNgUYt}NpDe>5&t0ftYrJ={0e7Sc;DvX^k_eGp5Ak*#=3+<)c(S%M~qej$fW+ zL=`E>T_qeu#rhx@fI0&kLbYLrNM$(Y_=9clK-I_;Oxc@beWnu!Zl~BPbWh1y3g{Xl z;gTYYD^tn{5uv-!t)%D(Yf8WD1MdFLI?!O0${BQn6_@KhJOWnvhyomg#1mOqVv zsgDUpB>-3p6nk6fIvy6;Ng}3Mp+5A>BznqVAu*4{tS%AytIIHq`MBiVo{|C^E-E#; zMl2YJ*?Ts4NEq@5Z}hNR_~E0XFz(vQn6#lXmDBo^*>?YUR?Qjiqh0Gv?y)S;rv@Pk zIIj^UeEO82R%h;Vl*usqfyxZ+B^WmYsoQ9Q{WWIH7x$RwF^LRmSxD`op(UNmYSl9= zvu}zcKZJJSC?8_ma@R@d^;gO_238U3)}XHuX5FymwC(JB!jLZj&rt&JzB6PSJjU_3 z=38$|gn*rj<&fS*^*z?Lw4T8N&qi!#J_-{6DCja0z0S5J-fRJbtnTRva-Bzxh#ni` zIC`eDMlo9RYb1g8e7|YE75ohV8hsbqf6ypD(Z9t$8tMaAKtmXGGOrenLoBv)4ZeVzvbhgU+(+*s@vI?;!7&2)wl{y75r}vUYZ({ z?^i*zF4BZeaH?w7jFljlGQ;2tAt0D(e_u0Q*m@vQvwss|R$1-~AU)jikhOz7}6sB3$_mEsq{ zw|yiZ+yo3T$XU>vAEq)%+-Qm;1gh+~ioWYV=o(S+4<8t%g(Ci!GX>KDp00+|y46+dzi`r_+V@KQ4vl zk_B7Ib~x)}ADDw=gNj3PwGl8sB6zk@k!(}mpyP#(;isec&6J@Jslb@5*t-CQ+7t03 zx9Z{wdJ~9-;iJ>o;cETe$22_3h?K}2y8nfG*S%Hv>aD zUXhvmm=^S{hAVsWNj*PnUdcD5@d1UWx@KsbLz}Ed$`j+i#J`mFhUQFJ%(VInHL5BV zCeOi=mZ=8XzSPH6>(^-;7yJa#&2sR(R!*C=Kt|XcP;04Ra_Ud68m>P4(jJ(^cJul; zj}07Ookt#>*ECu$KADF8VOY2rSMb6jL8qVj@#|UUCB>|jA$~lDk+uJ^iAOmH?P6G6 zbjgpA0kZz&Bzo`B(MQpM$WMzI$0=E(oi7y+P$5A_#Pg8%B(Mqg#r6x_UP6=F!%o!2;Mfx5h(HKs z+DU}`b2~yVcv-CM375nu-v1pahf6`LC_Nw{>y;X_P@B(hJ2bs_w|%$EjkPleeMtIn z4_g62h5O$$@llx_G7!$v`#YaA(e~Wlz`FzL1s|qul<={I0$f(RA@ak_Y4=rkkTGa% zfYpI3P`qDgyhJ6g^#(D1t5Ffhs@||n76MiA`kY;kYGvsQ=6`gO!_#u;Fo2JJ%-LR4 zf8jA#Q)b)##+v1o8B4`%MD~CnHY}sh7o`GK+SVNh_2&{SunaGhi=J=2rp$h(%K3ES zsl@8S{wRg@KW0eXHml$0?jg}vSI0pglmklkI+_LQ5r&Q#pVg zE02IarK61G;pv8He;LR3FKNCuSjZs^qXEUgt<89MJd37W1=*wvNzrr7%XRhw19fuB z;z>ImJ97G7=QF;0W&r@n;z1XCS;6RGB|TsJGc%Uo4M2_$`I(fHc4@9sQkJa<(ee? zYhV1^Ok2aH*K?b7b-Ca9(K&_!Xpw_Kf7)d*{Cgf`-_7jJl4S^hk_|4;Wz!2P*EhWs z#V>Mit!f|^e0WCd>Dm1{r)xhVp05JPr1f;;*umWaZ32)vNHOaxo}w1f2E~3>wMl3@ zt&pEoI#&n8!);Gsi97kbPOfR?5gw`SWLF~V>e7CVIvPv_Zc7724cEBx-Z4?H)p=yu zVp^nnMv@2?s)3JD_gW*{u!tlMe^JN8beF2L7UpggeK{m}khP9ITI-?|baD_JPGMnx zOTiuu`m$kq)Wvn;->5A)>RpO7S;MzIsPeWQ*cB#V5eI7{Ih4(h6=*HJ9I0nIU-qjw zxMGbrQ-fjOr1U)L$@&?SSsi`#(xubl4O7KrE;&HAA zJb8M~ClQ4Lh=E8IUolP;Jpuz7*J8JXskV-f5)3kleK4$35QfC)vAa3>g}*Kqxc* zkB#6rlRb!Q9&iC#XZ{!OV5;2#WKOS!a&7O$}By`26rg=6B)j zm}N@m`;4UjCBrU3vlXvAKEl!j#eB38$sHxe^i5)fm<;1=_-9Jme>N>oafEN{;F^Q& zv!j+D(MZD~!L`57oseU~D?4|DhJtX`O4P$X^-=rP!P>ln{(l&Yq>i6RS$M6j6g`%g z*TQcrmC$stLCw4yHzV`Nrg?H<%ECFROCN!(VxP9yucSy4_t=7~VKN3q=|-y+eJ(CLdVUzj(~~gbpS;?;tbxQJp}+c9(JM zTQ8m1+r~N3i6?(;dGW2C)wjV{*idk-O#m&R(}|?dQ=I)Hc`h0HbMfwtfffhK4`Q_H zc6v_Wy`<;+a>Ub_PkXX%FVIo;pUO+ed>UdjsrO+%@Y^{S&tf%||1+?H0k0o8uaU8b zh6Vc`zsLYfHOc{ko}l2*NgsL?iL++~4KV~0w5mmFnJkg#4x3JR%#+t{rfQPic>axp zRg2dK+r;Ia7z-yUItZxmKYz&Kiy#3ddm(&|_y?<*Tfm}!#DMPD&mu>tpedUOpO;Eh z6nXCt);mdle-Eyx?9t|HvK^dgf}Pc2CJ?Dqw|GQO516nd48DW!qSTE8_xxcGn*2OxDXFM)7&{HF}P2Amt7P{Gd|^AhX~0hDx~=Y+qt6@-lF70 zq4XeQn%fZAyIL*S>BjVD8Hb6%xO?u53oIWugDyU9>j?*!!m_zyio3}Th(Y#OemxZgmsboht6jZ2T(Z@vUWKbao7L^KAt1dEwW>qbt*{hKEts3hEpU&H2Hx zTQ-R}|M!ec0gB*wq(R71Ni|gO3xs^Y6739K;4w(3rBgY7!q<+Zm`d$nZDioKp`v>H zCnDsM^N^HOVQtD+bRz~H7=QRK+TThKtKcoRDJ3oH2xi=ljfCh_Mr!}unJns1z)>a;h23 zc^j!*^Hu9>y(0aG+eJ`+hfW5f>i~rW$=RC~Z&B;BlOa z{b}ZAAE$3kLS||%WKtkJaL?o2JWxAU9>tX2#>x`P(0cZwPPum|z4C%!YNj-fE*HX9KZJJyZ1 zu|RzP{@zQJ(}rAkCBsqbaLgOoe~42^k8&odxD=*rrE;*K_sff+AfLJD=%;e4BS;%- zfblTEx8Ca5js@L6_@{#N*!`K|%qb0LxwzQVvon5yn~>*-;d{j-XR$wHj#Q1X!)R>~ zsP>Gu6Y{qOhw!JIYo=|X5?U|(??t27L;szXreOJ4XQ5gY*{*M)3L{%L%^!7(4t%ea zr-0a)nS&4Bq={QU}~iY@Fw^3=%})S=Lo z9Q@5y2Fl=ylXC~vlL>d12M)prCKF-dHhHAilYxE}`I6!kS}@_!Px0Bf-}rP6RcPD9 z;{##DO0nZFrrKu?k6I$wlc`F?GjQBRuuvqLbKCRq9uxb`0o2H8BZ*CSzFG8_W^u&a zB@#FO91BLe*e80}V5$~U2Su2qQvYOXj3a}()XUP^Kvn#%~#yVhjAT$*_C$2EJ94Bl~ zCbtA%E{Yxad{`%RaBh^o`LRDQJEuIPkiU{OoYafIRK3w^_z>uV#de1(>4Y>k{>%yF zhPo#OTXfvvzHbac0x#xZy+#veaZ2#KViEj7V1nj_K|ZhU1knhs@*6aZKL+@B6}puI zCw+%2ea&E3kTAokE_M997Pgp${i}>XS7&L6!4o%c+yvZ?KT!!|PXFdh?Ted_T$#<} zm`S3mS@eErFh-LA<3MqVR_?*9wZrRKFS89?qmbE04LUy;M>03eXK~c)*{l2$y8Xm8< z%Jg4cvQPuFsYAkgd*nMLmklYCs#GJZ6%(xnwZHw&$Jkyc(9$~88}@iOUI9p7U)=0{ z%<)zM%3z;D%eYqr7TN?jcPJ2+EMzLbqu=<(t3LNi-*P|Ua@1Kgeup(VnM>HoyIw1e z!jyvV*+T#%N9t&kWn_%S#eyikPOi$2ipopQn6@OC*q;Swb*yF7VFRv7?Z94st@F_3 zIldZ@&&1*J{+jc~4S^qW;D&9}=RVN>uvPYo1KEY2hj&y@hZ0v=i)pFl)QIm{2-?!V z$kicx4LHdjZE{yiWT{34bdW?Vll0zEUqi{N$@F{X)*IV^CUqE%dlrrG%B0iwpdZ=~ zw+Vud!I)Vt?k8D9`=_PL^ByMS(Ge({5JxQ7IVILr8;+hH>;Hde|SR_*ji6CoT-H!Nr;{`yq)Lg^umHfud>?I8q`1E%(zPau3*!LhWy*t1Kfa7Bx z|MgCd)U9=8)ak~cTNM?tenTt43#-?&dLKxiH$ri3b%8?bS-OKypY@zt9D)9i(tNH~bA^)q=|QDT z06Rd$zXI#xdpKiU5p4yS> z9Xol;Wyrto2-k+`pDf2H$i*tJ?BIFB4~j|*$`+A7Iy*x{Fsk{+4Fr3HQie=-CH5&B zPNZRp_N|+)j>=6wV$_Pj$ETAhbxH-Nd>%`&edvW+^rR3#X2$}22CEPTcUfoA@~qO_4${j4N!7#KZ9$Ie>VW?t^iKPGMr>`2VWLU486 zBGqz>JyOiG$?22na)lLOdJj|;L1GW-jZ0w1RwvH-eZ#|$lOZt_IfAqxP61<#mRNmA z+K@5n`PYzmBVVaTX{T|N(xYD~@LSuGy_3GUZZ;ckeJWr8z>ggOReWMlFC1Sg6;+1F zcUA*q;10Zh7zeU)X_&f%a1I`3e4|`sN6TDaw{PhkMA%dqqte+EBBr(i_$UJ@h+C5h z>4Ooku2Oi@n|7#!vT3n5n4_Ofo`+x>s zILa783h-iG#+~aA;=2#_51o|;BqI%xqx{D;ZQ-s;$1p_wYjW@$SsDxWr^o`PXCaLR2)u?QuZ6PALVwm5oirL3}o~JKAM1FS6SDS%z{A=?eTRy^yr! zIR5?P$Ca91Ly8}+SQIIl_Z?%#QpP#QgTm&~EC$tto+DZ>hV5Z~b5Xp|M!Km#fZVcF z)un62&0>Pk9{In_L=0%$+I)(2?e5+OFa<|@{$XmGM?->{7(WjG#_8>?t=T+qWPGdt zz1KyD&V`Ci$|x!kD5r)vw#orB+S1)Fps??Kz=qw}CE3v2yt}8hX;S9xH6Bkz5Q!%o z&QM&1HcUpo z=yz7r%9zW;r_d&jwb)?@e$9qk%=xfUZ8?aH;ZdF}_XltvQ5ngTDw$|gfq~|NNm45i zpV<}F5;c42%1o@?mi&80H3!If)Wi~Z7z2U5ZbG1gdz#t8n1ZTzEp~~!yLYdBbU>tA z)?F{P6i5|~X~*hhax^U^Xk9|EOZJp~F$cnpQ1bB8ASo1wfT?P$V%A7s`5MFsaqi4XicU)6vg5P0}+7DA7#iO#tB&vU6qm2aOpP-15g_$rI2LXQq?9y!+NP zoDA=XvD7thCC@(r)Xx6YnD}{ESpAc{_K*NPo|vu)%K8O<^;!6z&0rN zBWroiJhCi2gO~+bz8l@v+VLl7v`7+W^vcWRMYwg%0&qMENnW;1fMsZj)7Pm|CkFE% zUQ;WN9$@V8zEdYaCgLsvRw3`}wEGgOF32m_m8w$kxYhp4_twkLqxIJJX=2gn5%_ON zw;(dzF2+XJE}#xDVLqCt-m+_E477@U7ePY@(pawwIT#qQ;>pkMyRsa zlWF}AAnp~YfThJ)JKU!&;y`&(^_emF<-1CbO$hqQ1;T0G9TjFxoUbgTp@!`z3nMr)h zGi`JsS`f-wfT<+8ci+!^II|&r?+Mpp0KY(5^~}X8F-PiD4>&&avTL&kc^a)e3f>i4WyeR2?kE7Z!*Z6N)lO(j4Vkx?(KW zO(#QqSpMY{FmLKQY&lL~gt4GIM!MHOfdJO0`hAuHM}p ze=Ppo95jg0ffZj*VJyEsM3U9*yiAXJE1`oC5Pz}8&RgttJL9TEErRV@ChtPG7;im; zVM=qR!L{uD4NF@{Z5Vp@c2O~(Xb%z}qWp`h_y1qZ+og$SrULaGd#Z zsT5xg$(`qu;tQBo+NWIg& z^%?X98qUZ1TWenG(pC_HkTFmhT38DBYi z{3;4A7^+M}G7SYSCJm0gziw736I<4&fiICo+r#p}IC6Eu3;b^;Q#rO?v@dM#vdoCY18h#)qZ0{ZC7NVM(Ybqfnp2KZxJl5G%B4*)(rH#C<|CqI!06Taa} z4|kzQKB0Wl3hyWBXgWe}^6N+$>3Zex5`u1`-g4SvmTkB~@mxEfb|I&0Aq6g2Z>b4W zB=okhZP<@PD085e|4XC&Ep}`9ke@riM3UU;<_C@>vb587055>70GvbDqx+w?-ljU+ zeo#y=$TO5JIt;`xZcS00oJ55oiGB=f<@>vhI*}oQAnP>Ej!o#9Tq<+}0-qlt zL{RI=mr=sGYRG#${-uw7!b$@oCS5hEP(#j#_tXMD0gSjX3812kBwNfCAV|fic8gr| zze#$5I!hqJY>@I`Je5d);KRmh^yG!AO9kb19rvEGz>7T|w6S-_FG( z>Rw9vin~^YxbwxSGi8>K0ZpJYJ5cCBvzVInGm3NrZ6``?!l*YRnd+s@XR-ztaPjR7 z7D6*ZJRX?cv7ewM{M267pk+PbH333nGHumz;zJc~vov;aaPkH*>jD@5NEK7z~U?No`5Iu#R|hOXc+Y#f(kv07X-LD_}69v8(BV9HSy*?9^VfAqr%u zVVR(9oa4IXEm(BdplDwXe? zQ<4X-au%jIRa&YYc=fdeB{Vx_iFTBfS+*19_1YauQL!52osN^Wn}x`Lge>VRmb!TP zJ-(3JEaHXh(?Z9-zCOk9@E!4c-`V1K5zih5=MCAx{{Fxp{1Z;Vc&m(O0N|xVs#~dr zH4dacQTskmAAEdGh(DGlk0kaC+^XX9=9GiflgW-q6e!TKpcZfJ-{0Jge4{J7VBC=# z_RK#0N_%0x)412oXcrxiV~PXTV|uAJnFOov)XPT;?{khWFCV0a=S$GeZmQi=hYGi_81FR??4&z9i`r|sG! z#Lh%wUv!*=HZj@ge4ovXD|1hq2?GtI76@hEP&KE@NE&GJ3I74`95A<*dVjp`UIYBou&+!IYw*j8gwQy~a? z7w_@lw??+_KYmGr$eH_tUB8Viv-oDC!7U?1Gs@@^jn^5cP=O<#_?h(7APqk&`VuY} z)U?qq=}T96yq^c?bct9gT>O|spu7z%UI+vX_Bb#Qvp(&BqbL-XCUWiI!E7f~(_;FD z#XNS0w^jT4g63qQMxM>AWfmOt33U2D<$Q!K1YcooEx%1;t-m2-8G(#w3g#WG>6jkb z&(d|5vU7ZV-3_jfQZ7YKS}M`k3(20?O!6x4FyAE*QPX&@hCzHA7FQZvq5Hys66<=H z^PrF;quVN_2{xX6owmGP#I4cLMu!4EJ-drQL!MViJbO(lLI6crbd6x2-^6vArCL=3RLxC0KJbpNEuf>IL=;l?aSO z=kQb7n`4s0t@eGqwh{RExqXrwNDFouU6dukUavQ;im-l_fyx^RFrhE}F1{9YTBust zb%dN#gzY~A6RF_&pk6+)>KApf<=#rhL)yD@_M!);0!gO@HT{Km+jxy2$JU2H&O*)72O_12#G3fpN}C}izL%pD2HxlPj&0yd3pVtBA3)DU_AbS=@t7!#%% zE4I*<3M0AiXSVlk<+kD$^1CG1Cy^5?xs*(~hW2xX6~404!sF}P?dM7d1#6(Wz@tX^ z30{pr72%DTeF_k`c9L?b!1Bnk6F>=!rBVp4t3J#>W397Q!qJS_}CFIEmdLt<+jP;1cKH-0Hhix5MePpd6oKlUjkTi`YHeaJp0 zNTLzUUmsYtZMbJCt69A0=`b#F6%+fRq1otOP*~3r&{~J_{-ReIFzvS&9EDE$|hXhEQKK+vlp95Id){2~N~ZF9@?eEl8j#ENH2!lny< z<(m(;p>>`B{ikItuFVWn#U@V&6n~FIJWI%lhBk=M_L4f%)KynQLUr~B?Nhe`*1efe zNKv->vxr!ROL9obK#_2p-rrwIltFm8r}=bTL#3|CTr1-PXf3~yei$xkfGZ%e#|>}qpD)3(2#E!h&4Z}%S03zM%W13@KP+<sj1m5>E!kVAB|RMF%bCjMl^1<&vmzt!7XA^4Mwfl$0c z7KzpGNx?1Du#+f)YMq?t?i|wn?HhUeySCK`hww|#$|RzS^X;-hp7IHf?E1u@tl#ms<%Y&+ixil=R z9>(fixFMBPEBoDX_32C6SO1xy4=uUR=y9hURxMQWbKg7!4Bd`%3Ad;!P15;L4as$5 z1_KfMUALY7==(Yvntk5Rw=Y=-BO|ekuSv;T?(Q$B7H!lh@mt1;3f}xw;!(qM)iwk^ zj!J@_2H#WsPoQGDs5zg~em9^3NYM7{>48=%2$ICCN1bA}S9Uq(Q@@XXdzIO;<)Q&& z`X0BFMgO5j2Ri>lxG=iKu(R?bk(YcCJ+;x2n^x|T`cZZXt`clXu`+EwWX`5A5^W;7 zER|F_^oY~ampr<`Uo^cGYO{^zWPyC~F7{Hc(Iz}98698dd|YB`iu~?$wd?wAqP?9H zEv~znzm|(KRA=GKy2PL-=B~<{n4TA}+9mU6zF~XpBhD{tofA43p4968Z*l}Oy);8N zgFS*q&#cUIQ&T_7iO0H+yn79`HyrmvrxE2q11d3X!di&}OI)EpiUFwO7(KwTQx#ET zSo~27s9tYr^h8-8NRAp)faoah31!jVo<@eVvG zafVu5FQ$>-Xy+l)3xjgsO-{=WV=^9y2$Tkw(_5Z;8%;&fr#J?B^3pXsiUsWVva+I6 z=<3%#qGG`Emf=w(LE$$NF$I8C$6H+xY3}EIXD8fuCU3w~+v`y^?ML2Z3i!8EPuKiw z$1qUy`73uCwn6mV7O>w~5-z-7^v`+yXvXn8L;*%=0p1_2nh;*?431~uW?}wpI_^v> z91Wov4|M_G0Hjwz7q~km%j!z6NiqGA4dKrNbgy!@2=`_N;w+6e&TZ%qTF+7E*v%20 z+f^kXSDtJTPv?_5K*T+Zs2rJ*Hsu;n4G0nTO?I~YM5y$FXC{I=Bj+a%I};%HyoC(< z`VsVp?0^-;E89YXXmUYNcB|I%-r(lh|4_OSRT3kyJ(9s!ggq}(=C(7bN7Wb8Y$xDT z)Bi0GM6;N1zN;9gOJ+$MS_8@diLEf(dEI&qPL^Ot;!x@lU07ZLd69~tLtO3LnD!oe zLHxOZwhZVBw~hk?5byvBF0ika1sGKwsbnYZGLMp%4gx*u_H~U$6g{tL@`mg?(~78+ zXC)YjX4F}NNdT0T@`AJIIgEVp&oT9zUGWq?{=EP!6uDC+UVg(<+q~yg!hPZj%+x1#MIOjl|I6 zv1trtta{hbHp~tky3qbvW*uU4Y)$U+e(a6YRTx8G^_ES+3%jCl3g&g(!3h$2R6B%=*-sWohIPN9@#r=oJ`i# z4I2{7S^$qZ^sg(>Jm00}2Z(aXrAV+0MiK|)YraHd2uX=2By1p0Baz?u;)W=zArc*o z3kI@^Q>T-9XPab4LSYQ#>kXGkNegVPkx~j8k9cemTO*%xSZaPUK`z&~sY<$XqYy!$ zDY|L7>dt7QMkiSUSVc0jcv4Rj#BxtPa3mklgW8RTn$CP9s0%#JeKn;$6(`vJ3E)+q zXewzdSiJixWoiypUp8+HPiQSIaq(iQuKGWxsI~@m4yAj++1sQ8i061zb7+G161Cz4 zWTi54%VHGJ$*-v6)VaO(g0aR390La`=YK@{#9+>+XAG8(vc)*qfx`?FvcQ>4 z#hm`=5+-aX;?%tBN>FjF*GC!Dse4(%&iUy^m2@8GnskwLx!t$sieXV4+RQ20G^!Kj zr1l$ZOz=##PFW8QKb!~pd5x6#*_M37sfhJ8h=V`k^kX>2eiU$OK7L{3w{@4^Yig>YA%s!*^r>s-@+n z1*_&bf?>I{Oh_5p09E!r{=^5Yu-RF2DUog=x|nfyi3~e*13e&cR8YEE8CZq2atqDK zk{p`97M%Y9_K-izEI7+4K_&W33P?51%$-!aE5#g&XZYxeVX;i+CWAFyta+*D5zk1E z=S%@%@+D@f*&qkt+yUKP{Uz_Mf+t;XD${zNZU>5lnCy=6FW;T6pXm;Y9NR;qy-B$c zuh0bEBjIBZw7{;{hmE$8uF?}?4LgOKhO+ty#_&OioHDkP zatPq8UHaRp83hX#>qe&e;mC}oO}DTqTeWh23|tDe9pc`G%r-p+m7G*CyP1|l$bX7s zBK@y+5O)6YMF)_l(uh5`vR)rk018(gJ5QhmnoyysA4|K?0cM@!UrKg7)OV~%3}F}? zq6u5*6a(UZP`onSRq>QmSz{3!7gj#2Y2CdWbaSjgV}hVGxw~G%Bu2U50YpNM-cVgjk=BXpCvsgBZvm$Rw~-DpdSl$xC#dYO z9$-AG53+?2s@M?$tJtXmUc`^p)#kHG6)6>p`{_RIGSX3a2@UO5bK!Or5@ANL*c325 zVL~7y=|Vsv43|a&IV=qq)*A!au!T_w{#rpLlfTYGUedBTvF5rahB#dDSzVX(Mk(J(gZ z@$TuNO(D6;X9UOjV{*iG#jIrtYrXfND}<6+lRI2s8Z#QMo{p|l69r#cyihR5d0j13_2+{_s;y*Fm@z`}L%X+Z}YGj}c>%m=li2I(>mw>>+KJ z?iM&WobOOi{)lb;0FQeGh$uHtb{`y&gdvmUH4#JL|I%mFGNyE4d7vheuAXQW{5Upf zAz?T^)O5+xZCarNFc+D@@_v@IiiL{sY!V%g3MQhB zOH@9RjH-p48|0G3x$-*!pZ(tb%y07FmYHTxfbKchJFDjuQ^Xlk-?Gk$#9* zPp{gWZdOt2Kum6quse@-S@id-`kn`#LC{H5ob(hL#}?K7_w;Nk*6rP)_M!-Xem6kR z_pX!{hvIGHkbo-1qsa*?Xh8-RDkK^kY<8IC&6 z7X^|y4c?czjx-mjP}{y3*=Hh0Ff<+Iu{sWp3@EISq5{?s8L;?_`>QYMQK*yN)DH-b z!^;QS2>=8oQ0ZvW$g7?Ib=z0t+ugIkDm|}eE^&003WB=`Q4Hcin1FJg zO%r5OC{+r&{Oi>%3z3Bd503K)Np#scgavKAjI4o^nId`KVZcZ~A$|dG=hY5%c20e1 z=b`cP3K4T~a;W(r@2EYefZ`$1;H9py=!E92xHYh@&q7!|lqAerhYY%-iopozk) z36HsUyQ{+gC@q65yu~={4QWJFA|Jid;c>isn67SvWSJbV|40;D>tnYZyrX(rX!p5h zs##k=KCnl&I?mxqEM3F#K9&zaH5^T+xs2H&g$Pp#CQSM~`xGhEb6|i%eu-bM!KClo zl|q$#J@Nsa)qk>fFmnQDA9*|IeW3E2*S9kDQ}$)sw3z?lNzOIkxxwzx-Pc&%x!0Wt31?P`f5Wl|cfYG|%tT|WnQL5Uz67>wPo2C6; z#rzDC_ovkAv0P{CO@EyjC&}n9?>fhT0)*%BVUuV^5cFi&XI8~LK$Jh00_BS^w~@Vk zzJBOOe!~0s-M{7QB~#{h&4X?hHn!b~d)wq2&X5aJIqtVpvhaiEM*inWJEx zvA63|C|u2W6a;6OX61d9r@A4%GvZa0PSjT&GjLO*L`Q;K;_o99)IT#P+`Ox8sykZ{ zC5l)VepwU#!p_xKJ%OSydK>8`3`fVzK2Q;Lb6TryQDpzcZZ+5{Jm~<7)W~o=SWh#p zsIzA*8nVl$WxRq?X%8e4WtDcL0EF@8M)gMn(Jl{{Dmv?ohSl#jW!zgcN^RjX&eOYo z0WH~jH&;-{+!l2~jc5A^#4PTuV;sZ_J{V(6EaWHnQ8=i$_pWvT(W8@y7#KSQej|JsQE)sOLZk;7M} zjFXa6=HTRD9LAX#YX0XD#juO=U(Gi#iuHmx#4+xCfb1ZxoPxPxnbSAEpbki~#rh*6 zZj&kPSoXkD-~6$EMwKrd7sWadW8HNO&aWOoqdSCY8 zb8vL?3U3{i!U7CN{R+DQEwd=tu5U%g?!@qdDm-fb)y}j^;K~DVEH?6``2U6SeVfqE z3GPjSXGXBqKS6ysekvakTsSxz{BwIDkNI*7#Eqd9LP%7%eY69A%Jq#y9B%N>72H(_ zT}=Qj3->eZ!AM1~;`IFD#z9qQE99cfdg8Ixjzmcj71P^DszAKhdz^@Xu!BeG zwYL*T@N}^PtsUz4*)Ge6rI+k(3kz<9j32|U#6UCVQlMbtw;4BJ{)1(Wo}L693z=NC z@cuQZ@`2vnbRF4XqM66W_nxf(+sbS(hoP~_Cgy3YkQW`(>u7Zlq8Ob7oL zP)qGgG9-M+P9DvXsQgwrS-EWk(x+1w(f+hnog%d08x z9_uFD-WUNQ0o~oWhdkRjoOlIkY`>&Eh>(!&;GcNy0C^3FE`{}e2UBq^gt-DWRX+@9 z@b045dvJ_w&u8ga0k6fU9*9IZ$m-q9C1m~$XfLShcCWb#@qwwqUx+#m=b_gcXgW)0 ztmL7xmS`Og;COOcAvpmOAlE2^KuTSMLT(ed5yC0ud4hllX?EoSlkx^EfnSpTV5DHD%m%a*F>72^XHUHo`3Qet}AW5 z1-#NOhwO9L`(Sc%GhqR$HqnBz=AvX3rSRC&;Zg;o*JuUZmeb|*Hc~$i&k4=C6BeP+ zbpErA@_z(Fm4ZP%L|kX{XqxJa`XS_#GyPe{A;-IP|6C$gfj482g}zb4_aZi*wO<@h ze73Pmsoef>dvm07xKo8Rq)Gb`6R2_~*U@x1#lQr%B!+;6JA0G!gW+?JWL-}^0v02g?S6?Erz-HRHoFt7b5_qh04h9>Y@OG6>a}le3*NYZvM`T=l}ri!`~K zQJ-bQ=TmJjjT)+%rJ3)9Lp{X2uIkLadai9>e+#zF<7U~cg9?kdH9Qg23GLp^)7%;2jRV>QMJ_Q?<1ozrGR=iR(K^|!gBi6h6e zzE%(N?|7B^M|+hqu$YehS4vh0@8%0XlAV>-;IF;loLG~PepRGb^{RRQ9&(HiJl!@j zM(WmQ&+eqa(09&fwup_k?^?2OGRL1lbpV4F^RA`Ty=hm~Xb?+(ByF)&1F=q6bb9Zs`#n6G#K09wE$)dhanlVRxq!+&ssLSiE4A|E)G(l|W+Wt(zy+%dP& z71C>+?)%s+cJS$RRE#gw{L^DC$6Av`h3t=-V3d&+by++Is&y*v z8=RZ+%|p%Or%s_=VXS=7=AiHbhU@ggG-uqpA7ns@qk?jR_4SJMfIG7q4w6~7F7D1D z5T&T>f$y^NrN3ZuHvB5iplh7W5+^rXOpy%>0kV1- zQUT)g%>{er!8i&eUfA$B6XmJ3uy#Jrq`1KSYhxB|UT6TjwcN}T{Wb!7)3^`8=7x~0 zkdV#-lhtgwV(tI;sJ9crlowwsU#;T!R5Q^v&cVji3_n=h;k@>kW)5vWfrMN~)c zAG51kC{b9-iUUPIa9Ipy-x;Z&J^!^+q4o)Cv`*h4(|vpgkpaM%!b z*&8CN@Ac zYNXv4hO2od#n(%p?7}5m4&lDXmqHQ|*kyR)C8ht%_wmvBILe)z-n-NYdqGos=gPm^ zJJg-9T*cKN@@y~|1yv~;fR`v8)C?`3&x?s}b`MDI_;0Q)f1yNSl`6aegZ8oznk)MX z?R>_d^8xU@4O4z9^)kfKlhLxsn0(wj6sUf45f_%j0z~BNEkmV(zL|0`cDu(OrQKtV zPj74qB9-#qiuZx)h#?{Q&=tqwC!BLDiLDEF%8brhb4Dgp;u>loSgGT^4cRmke-ytK zhkJ+ke;k)JS|)tibCDM&@m%?6#j(P^CB$nH`!{|0N)3rlxq+jnS{X!+X-`1k?>O^lGLaH1!vaRd#O zA#eS7zr@A8(~@wr#b4f1AS$wFz?N)I&KFA9G(K2U6c$&A7-S+u-41oezIB6OkzLu$ zmHJX0H&y`l9m0d+%`;EopxL#EhsF zI-yy6z~FILg?wZk#mUuCz_yM+v&JXFeQKtMcUiCnm}zrvoJ?;lzVe+h{>i6H2JTmJ zYkJf%Vb)oOsi!-zlecUBJINtdyjWkZf+#h)L*^Ab*P9Xpfp4z^kADb=rOd0K&u_jU zGaZ8~AZ#Dz)A{mN>&r6Qel$xa4ka}{W~NO{S5C72=(aGtgiP}8k|~8ii7Ydcmpfj~ z^1~0|C6gUEW%e{v1#}^^Hr3i=oI=V=qn(Fu?|ZVTt5bm(8V3M z2OV4ipc|DdUr4^6EYIzNDryGMXyfce!emTakcyYQp_ZC5jKIGM(k=YvDoQN$@8Q?C z!Pnpt5_(`z>JL|QePytv?ko#OWj^S01g-1w(B*eioeEjZmh1mF8b4~<0BbK)5oK_S zKbsJ!6^<}2OvkDZF>I$oaQQJv6oNN4BNQF2@DO)S!m4{uDJmy2LhoLjP-5(Su{QV<3k0627(n`?jk|gf@1+1|a;O&05NmE(K3+ zk%9n$Qu3U3p7|gUEZy;c3}eV#^{G51l#Q&mUvqO04OjRL&L*boPUo0cV0`bqHuW}zgp(ZJ$FQSX&kd1J94*-xD&le7<4?r9!>bsE_1A(e zF%nULygldi;k6OVUgGKR%mPEdMu8ovzZj%YAr8Y1UceaRk$=pYnW0|w`KGTh!?amJ zb5>*D2ihz6f)S)TJQ6g(na)*hGf;?oyZVXs5GOqewrTIR%gJ4I4imouPS%?aont{> z>>13C*?7cJIf{>O3RJ;2mNAJ^KHX6IhZMbtsTs{kVl?xiukp`( zj3;iSdW|LQCPu0lE>LOGuCz|@dLTV$e}V`OTAT-@Z%X}8eZ9aflhxW(A1V`|Ph?0N zWcb#T*(!4r&e{u#H4}5PV%YCSa2Qy zLC%>K;+xM@78Ouqjqb8g3E!@{BSA~~$%4N5KXaX1&GUDzJ%sd z$bW0OVb5~QdKVZc9cxS^0>3EJtrt5+g2vZQN`et{hLUWZ=SU6%mjD#V zcICROKDhdGQsx#+q&;ytwr~!M(;$ix7_@Z&ebg6Q@h+^UjU0^ERo>Oh84v>eYsgH- zf+l5>cb#7N%BQ5|a0wek#Es&#Ucu)n=&9>NeaaPO-lo+?R>r+cLQaz58!89YZz}A< zfP?XZkOS#U5EWTKAdrG9u7nhA<1+#1p*3J0 zc4R^a5u?e!Krk(|N?d%lA5A~j~MJ)FP>Q@nl@rBQHUmTnPT%T=ycgpM9fQkvj69F_0{?^$G3~y z3ZiXgOoOH7I|Ubyp<_2-V&wW|SairH5}PU7dxMr5tP58#@ARO2mZnz$Rrw+%CuB-q zDT?J$2U$yfa*+f=FYX_OpFto+lt=hYA($7sC+6XJuNX3O7jY(mk8zt zkKhw_5+(l$+Ov2i4f@``ex?i_mrp}$-M>T5WIJGo;v5Jm%&;>IWxgq742`f9SNBri zS0RS9s(UbwJgO0BBMB|E^YBtYrM1)J&C1cL`dNo@2?)XJzV*^BYI8ZMlQM8WXf$m2hbqsgjkeoy#LhL`_aQT$Z zsN{L{s;)7--!|96bI$fdaa>yQPa{25q+PN@oynk3e#HXg8SH+=X=`6?A?+4S2jw+G zK12Xz%-)pu2zlfakqe#7{%JK=)A-!d-IvX?Z-0jVFly1(T|pJ$pP$3U30!mez+=Y< zCkK6-A5!>j$=o-@JWge&XRSW4NxyC77hBda%j`w&0pPY<^->(OmlWz`INT2L={c;s zw9zARW>Oq!nj%*az{K!d$w3MC{|5XY7}j-WMcZd&PrWYNg_@i4l5T$J8< zy;^FMd&nh+D*8-!gflxhWS&62CyXSm>IZ)D__^KZcZ8j@zqY1n8+5u)0>a+?vbE7k zJS?LRBhjeilNiQUSHF=)l4VkBgw;S|zbNLlLB?;WHRGLY#z&`VHFX`B99Lu>pL)Q8chaI^uX~2+C8*{%;O!(CaJ29RUaa|%!wwoQPGxGOHO)Bg zDi@>{7X;YPuc!}cu#-#9(>}g~8mEl72CKywyZJ~lO;SZ?|6XSw2r@DI*RA^ckYoGk zW*ZijS(E`u)eNAZ7kV~xeKMES?-P1(S5**T_bejCfn$4iBaptLikyRj??oz6?5313 zbyRM4O>m2xJ}MAf8p6HBuoJ?k8RcJUA=O<-Z7>juA*crCaKYGEbqx|l5;HT;nNyqk zauM>nKq;?Fh#Ui!Sac?|IVD)%8r8JSNSHH*5vN#Nue0vF$naK{$6pOx`xNveI}La|H0^()B0(#zyV*vy(C zA_9?M>q-3(7}#}@0DY>vbas;)Z51H*Ld%LuD0d0QYQMyfL&@rWT?wy^p%2Q2_8(P$1$aRxYa zf&Q}k-}B_Uat7)pFKM5mgGHJpR+*M7#}ULYH?X`PR;C=mYqac2;kNlr4<-jW5f-nn zrKzRoV_2JrWWihd@4Do$9VPny(jp~`3nf?_@>h8V5Ax~jy$>QBu!t!Bine=*pI|9j zrCCK6ToJVqK>M1WjvZjPz~J9D*|{$x&m_L%ox3#9qpXZb-yc6#g4f(elXe!68jmX& z2iteUhZFhbhxogLv_ZJ(4*@pGDNu(7AoKtU3?UO}ylqNOQQQJESaQ=k8`UtZiS%Hx zpRgpIHWC^0;%`Zb;BRS@YfFQpsmn^Pdk1bb?N6lj*MI#!xxX&*xN02MN!jZ~`$Dp~ zLn)u`_3T**Q}ZtoIp^F9k8{a^#+k9&sX5!QDch7xteX4k5*nRf20*V-wQ~V`3wNuU zQPV~}rLYl9a2s;&1$KW5m+G+tA=%G*^=qoqj$dpOb*cO{#PYEQQAT>q^M{U$S%t z6d79uIZ`imn;8dL9X}2W94s-iQ`WMWMM|pUvYEYG z+noOL@K|E^o{{T_5TP9Rs*1d_$25}QR!5R2MNg=_ez&^B+K&|`-f|f|-a2}I+znkP zbF@4dpUlFMbiYSD)P>>V7|mQyqgtcH`@sfc1NJ@GNuSP|wAz}xg&N0pxQc`9d{d9= zCbzA`jd+VC4nI&w1_O<^05w3$zZP)G1W!9$O|J@!DE#YQ&3PtY(GVhw$xZlt&+vu{ zjf2?-FIHIgeOdn!2x~bt&lr-(=&dnTo1c_rgNUw<*PCfUoS2@*HR2?Z1sf=ZfVvgE87jDNf z1)rz4*a&Q@<;t&RgmKaOG_$x7wrT% z5Fhg)6Ls|x-VC;=siAr6y6@G&OZ(xYR4lixsAkVM#SXwScxRr$O>FW6Nj&eK?p=|b zP(;Ha$?e=eE#0i6p6!{2mO*%pc}zyHjmV|QrxS*{j4x+Go`VZ*()}xsxTW2ABpwGd z4tGqZ#J#MOS6oqopw6_NH1X~zFrl3>=FK*_ji`gSe-d~#|M*@KP{Y#_|DEqjMM^lI zF`EcGa+ZFOn?fbe;)$qG>~aoKZDG|0exytj8d&&zlAe>$RTd(d@h-%yal7^@2^^sF zISC9T38HQ5WA4Y?6l#lz5T+gnm2M@dfT{0m>wI^C3|9g}V-sp7xN(83Uc=&d{Ty;b z()UuvSG69D$b!je9G+@|P4IC(xp-~Amh(wLpnAYkAH)b4QlY&$4&GSp-Tg-W?$c>e zjc5JjTJbUcH2_ACAwGWhy9e{0nht1OMAHO1*MdJY7X2Mp=SZ_kc4+M2HF-?r1!4$PeMW9NO!#R))6{xIvdvW@vgSyLt~|$a++}m^G0ooi(jS5$1tp*h zCSPe2{_SRHpVl}9$>Ik7XX0a%@&tqEPW3J|dlg(uRW)pST=AF^>#L*G<*UwB_F=M_ zyHfG143uY$5Nu^VJ>=co<%8aJGzlaB@0{4D`|ki~MHOR}sU2ByBer&&*cL>0A-yUT zKN)$xc+Cm!B-2CiqJJ5V^-F=|B5uALjEL271 z9s$XE;Yyx3oE?Ye@vs^g$TR|zg(BX#3+5*ohZy0t>D`Fy{!m!FThg_HL9St}-Ty$# zxB|d&!{!&LX~@5SEMY?NpJ7ovDH30EjFP{$1JYlzH7itTZbGdX!*Sw4qgv6nOzROL z$XsJ+p`TT!gGBBb+3eUZeWz^R)#R4meWUn2zl^-Hn}R0Jfe6N*ENQRKIWpM) zJg^}-S))oF#|I=ajqLU+Iu+eW0fz#q90(3OgksE}si(Kgg^Hq24=2hRrewq$1d(+WyfdI`O8L4@i)_jEcx2{Bp%L5e zJ&R~KKZ&BJoIx#Y0Qkv%R7!6h%lX7_v1D4>6#Y{sV!tGM-?Bk(V-Y!yv`a?9%B9IZF$6FxpUr zqDqPGcN)1F`VZwUwBg0F*Cg#v3B^8;9T^`te&WAqTFf2WLI{yuA3?###!7fKOvj*> zVX=DQs_C+8<_rrpaR;!(42!PmV({FP8~O@~Jsyg;HM}GAS&E1qlR;Z~z4Nkv9%85c zu@LcAi=~i}Xfq{pcmj+?ZSm4wN`?qyoyF|9wr=NT#6}Q}jS&7IPwh!Rn3@u}O*Ci` zkfgZSJsZcyztisR23tMOe=|ODw;4eY{SzTF4c<5)7e8BdtI>-Dh!1Q^hhVTqs!9{nT~n%Jxdv7KV}pH zY<31IyNTJj54(!9n-!H>n+BsHJg+9J3oeh+U~|$O{r+Bb&MCsE$hAV9JXUBNJ8lRN@ra|=fXK5+mfK1BFYhc~2^W1?vZ`8Lz2;8uk#l-S$dtyL~q!g1=ddQ{vJEv%R z?-u2hK+or%DZqx5FbL?!0n-UAdlJoYEN$-*dXk#0d$>m62Nhr*F37t1X)Vhm`F+6y z+t{-j%<~#Y6gKO=8L-td(E3O81On1r4RSvV znl?mLxcIEPT9Cr+qCBJ&@FO|>&bhl-h1@M{bID2*sqRAFpt>bilmr}1pEQe2j5u*a zK;YfO;Zy=XY`1gy9v(-Tv%498xel1a!)|4)?3r?9(XKKZuK3PenD90A-~3~NC;n;Q zkNolPWLix6sf*Go9C5E+uFIv;zS0i`iD9og!Dh#@)5%^-4F>&QZfm> zJBFApwZYA2zP4>+VZQ{dVen4qQsfs=D6rX%X9J33bumxJ$Cn+9M2oAoT|OGtMSLl* z-gYSL(Eo=}^U}3zjIt~xx2O8 zZ+t^_ydwTWeunNCm-pEFM7%z4xV)nh9i7wIBoKky)vw1un)Fv1CKU_ zmlBH&iE#0F2nzH*z>L<;)fYowwG3{XC3xl)lT*mB2Y=VTE%?JIS)q@8sT1agMQ5F% zLf)x9H-r$%vxvFyl|{%|6nR zh>@HJO2Pigb$x8N1qsiCA0!i@;bmS3%^2R$f&@U;+}OriRxQP@^l;Yt;Oai*Zn}EB zP3+fEm>CiSqXTim#OQRnof3`&9^WFZD!aWmQdk|$DLepJju%rTEjg&2f)&GX15W~P zQjXWn(E~x;``6M{g)-B)W=TkVLh0U+Fn~{u)aK)YDG1LE)5qz`p(gMA(L4W&I?Kki-IzK}mg_ zCiiL9UaD;+2w3clzvZNVbFVlZ;F~;TcpWTGOmcHNjYVP|l9)m8djo zoP*fJu3`hYnVX;HH!`EZ`5_q;84Rvk<)h3?WC!`Skvj7MrC58Ad4~2L z&W#@k|Agl>0q-{SgGDlSC4p(CK3T6F$gd!R;nENpo59HGk?Nwtk)vdfQZg=FCI z5~iEq1WcrecIc#{%PePs09G?b*~?iX0jaAp$z{V5wXDXB75v%v4x_56yok4!Ma8Vm z0lROJd*tx(KZlev7_#&G0EvSr0*5i!MhYB(i8373wRkmph6ii)r&TK(yIc1`ipE|c4x>8<(|_>Rd`+4iJX}HB;H}tu6i{&rV13B50T{fNx_M_P z^sbN6udLrwMFmJi&Yp+2aVw*6zI9;pHm11>;0ogfx5g7i^s*ikACP_)$G@jGwl0?DN{bZ-&t&3&{cvuLQa;pTPB+(>bQ*zJ>JvRk8z&ALs}IK3gz2n3h?jS%yXO! z0zqpEOPGabF%{@J+av>O&2oHWi|cu5HP1M|DX~as>k&tyaz!?aRi_p}J-#e&7Lb-0 zk1}>PURj+Y^xL~COFR*jasM7{A`F1iS_6Z4ir~YXVkJho-(Ipdq(I)FZYJ*SJQ?K7 zbOuS&8gh*s4T5;eU};6zsn9{Vx5+U#yK7yt>aK5)8@x-$43C55N~2)sW3 zS*^TKsL%rjH9#Klt^a0OVOskX*`Y(Mm}->a)3iFKs%h(gy-s2B#xXcy^-y`+3FC#s5vnE?kY}WG&+=K9{p)kPOajo* zaH;#9!I5JRb-#jha1yLm9z`!NX)uUtrPqksXvqNtRT<;YZ6RgC- zuztth>ISe#Lm+2~!1^6kyxGl9pR1Vg3nWm4NV^*jdLtrC~iM9gz&8|m$Asz3%1syGmZWR_ha(-aWp@5 znCw7i+!#-If5iWNWjZ0kfq%dd1||TEh(UKONn4rOhb2c~6i?*{*9Q_!90$KA2M|&` zMigfMELDwOz}GKaGMr#f!|upzJwLSl4V`Z!6e}0XaK#Q3ZBuB{YRFB7kT{S_=X$FG z=HX6>Yp0xf69d?x(H}SnqR$BDwE7!tRUNDgJ^%7@-$Up1T8#loBW1K0hCB92q8mFm z#JB}gU(n#_10OME{~nmBe6MM>*ow1c=)me(#@GYKIDqs5bMBWGR3 zpY@9>g;7AxFFW+WK9i%2_iUKU|1DypMhK_$^A!X-TA7nr!1(M32CtMzbkDEbUr>^n zp1U&1&$_fpu?GX63J<{}@gCr}h>HSv?=TPW6!d6r`Z{*vGwB=kIP+8KxzCN}xe!X? z8_mA)lD6QlWJD!%v^=?!J26_Qnep-G7i(kgcN3APjj#%tH5Zy@A(MX?Syze_j>9Pz zjd#z`k&s%HmZe3an%kTJUF%4wLHZ6ucQ;?&z~RozOy8-ezR<>`uvh}7F>jY6FA=gi z&q*$O5PbNs%i}OwH81`4%v9zu2SSpJ*)8#qfrHWgT&qRy++u8Wui|f|t7>vOSuJm~ zO`(nuY}(y<#t~yMC6ot0Rg_o+*>$-wx|yO_4B9<31xo~FPOA+0&*6MjS&}nTr+2N=V#gi=cxBmvAJT3%^bGgf5P;mG=`rlWe#x> zf8!0N7)p><-3Nzvm*LCJ8FrU)+Tnu;x&FO|H&>~BHlC8>7GaSgST+=&e{f z{{iw@+SxPhN_L;m)N~ICnJqzRT~&}e$)#giGF{^y?GAB2E#{u5ZRN4IMLo__E#a1M ztnb5!CSCHB9P?)S_7O2)>|qQ2RPOlg3rE8`d1I3ClCLTt-?FO8s_lMRMKN;csQS zF@XdN%{Az*vB^nY8hh9_+o+|ny19RS%I8%tG#mRg`_E|jE>#;sJx08>jJ(wGIN>kf zpmF0aN0qWZ2Z(AaycSaQ{YfM{G>S60`4=58ReQ(m_Q@pGPx?4%-~y62*Vtsi58Y0O zZ#V;l(7pKDUu*Z-&VqsN8Ke}GbcN>nFQ7(jMdgfQ!{fy{M+knUs?Zzqap)p^B8!$% zP$|lMHW&)zSd?;W-r0)HRp^|nd}QJBa~-gSXZ2v4YpqEUYWQi3rSB|l3I>kXv;1W5 zPn0RI`$a&4$wyXxKR_o~kMukfH&Y_48pkNBwx(|u&BkT4>k_QXu?Lf~q>7c>oRcTR%|qe;a~6k87NYuhlHDo&#g#p@lIQ=%8mSj8%7I+oH1)T1fy zVI$X)Yyf8fkncSdKf`rF6pEeSfQa6@urd1}!F)%cf0sI4$7>ZT!SOX}V8zRIR*Sy! zb?ts|XMzcqE6u2Onxz5_>gfQf5)>(@SOYlg#YxdN4y7;M^Qm8lAO(pa7eiydH3TT> zUo5(PDd1l4l~7Dkql$EHT0gDT=HQ7m#MN(7^ip1lR4#h6CJq0iv%$5)b%Ue4NZ@o^ zCUyzf)Iu@BZ%{q_`3y6M=UK0}L1{Mu6KM?SdV{j$$f^flkWy|%+iQ0Vv33~@66p}! zAb&f3O5)}Z^!j2d8oKhMWy|AaqU0gk9Rgx4_b-@qxG~zxjWM!YK-U>; zBg178+&gGYdphHsv7rM^_qsgsA*>!ERf+%e&lHVVBQ@pqwu!9AHvvp zGWRKx>cj}TRRDXAMw-j=^Za;V$;dcvx`k?@6e`6NnNnyiSkPT+D z1%ka+Z0!*!bKZK>XNsT3-lsF*TjDKxW=fA%^X}gC0ZlZ0_?}HRgoO&r0Wsr_6`5yp zG1ZqR$C!%Rpm-*qtvDtB<0@4bp^FS7jy+HAknFJYD-_#q5mKvi@$E$CAl!*R?B z7pqP@M|^895stxliQrbX!-iU0&gva!2Pk2bM>HyfPa&hHQ1EFmV1pheVMjwqUFTTR z7oAo{BG>cdzaNvY;iJv-xTd~b%7lqcudDA1T@bW8AaXEcU1}wQpBl)&m67jWW4*lB z)Vlt574jm{jj-1Lek}9~Fu*pEzF#>;-zGorMbahMELldR6m00`t#Wl>DX=-*> zY4%`ihm8#r3@v9hyoK0a+KU4{L)+`DQdV_FY;RZp(dXLUe~OYj{so5$E{3yq$wYf zQ913(tX~D4`PyyvGppmhYPg4BvJtnyKN9d|u^n0;m)0or;oGNJ@F+AlVYc44qS9tf zvM@h?tcgfEsVXpUHk`sX_-c?Wu#a?ZsI4R~~l0rgrm--!%Mugy$=<2FQXDQ~6 zZ!^39(T{#?%_Cg+6Vou9$`I}j8(vVS)mNcOV8A*+%1?u>77bA}I$q@F0SzKP{);(= z??QF!yY4b5YRamv%Uob9HHc9@ogcYrGPlZs?rK!0l)+9(NqUzGfc+%2lz5##hz*xxoc8+>kR3{2cGLh0nQCqFngoAZGSDxCcxaE5J}cdj9{$5YVF zlXN&WGt1zNZ=8St7bWi5Os?GwK|jNQ>7@q0)6*sGY4dnx==~`TdX^>pbf@h!x{4w< zyLHzUepE|~{PhW64Du9ptSj$F>G-o&w4!fzJJ!jliHSjn1FmF@6BX2$H-tcw4}znR8f)RD?5ZR+}gcomef zBu;~7)qj;&e^yCPm1xza$>sZ;|AQ5ychw_sjiE?Hft2$p(NmwPNq!kb&a)6#{fCCn zm=$Y;Xa&farC&nL?y?4sGIdN+5wUVaTB^s{Jb3i=0B1l&M)dwu{gj0;pp7zK#VpK7 zqWToFh+Nu03k!MLZh;9Ylr#`JmQ}U(ToZ0g)hU*2f3^5HJ;cZ^MlkGKml~SD3#&ke ziQ#0eVg+mtt?DjL3xH`GWRk>1ds|tgD(C85_HMK~(xCU?SIC?$U9$&qf5;hF6dP>R z63msGwSa9sA~^-bw01;uA+oB>Z3@zPEn}F)7*#A_%Nbc$_%^eub_bmDu03lEQ zXX$tSjFgmfaR#@P4KF+rVOR^x$=L0B94Y#yzG1L9m1K<8B@l&7xJvxKAMcGJEGL?0 zWRZu2s8`8LS9dJI5oQ}}h?{{_0WK98eDeoHFxAU5X@>FX6gJ(haSiEjB64%Zdi>Bl zLcgMT{Z$I|71WE8MzL_$DP%?jAGSCSh~&Re@X<_N=2=@ufO@&l<9EL5|37a9Is%r6 ztGz)wn#_RbiRc_%aPFhoR#?kS=k?eLO}`SX{B+pEpr6}O^yRG@1M0yxw!X``-6vlb z_p1ehyXgpKB1mY_iI<1w^(VVOk!59)KAKU`y|f~Az8fGNL_d?JBL6I+SLtXp*QEKa za#$oO*6UZG$&H4tW=X}1Q&yAfq0`xf2SCR9Hj~?Y#Z3|Li;tn`R=Xa5CY0o=n53%s z_`pT!4+(b2CWxankS^+ta_p+(W9ausvzsuIO)h+_TT(L^VTYU?5od^CfU*(95^S=F z=~ZEOA!jQ-XS6G)&*nj9@yvRz-$9^jGWa54B<dR@*h*MRQ52$p=O$1!QjV+#cfa*LAaCQ3foRN|a?Vr`9vrQRZDXMXfGtLs4OG|g<75(zHgcF$2n{7{9luK?ll z{RPP)$T(_+8yz)HkYByvcUgl36o%ebVZepDzc8De>$uBH?t$FF_In&1x7uj$wC`sC zf&IWA83upLP1iDx?Cy?rPU$rc&E&QxpM*f^b``mjn@>Hx;nz5L*kfP_Y8>8Ha7K}l zsE4_JaszUyHX~}&_8)1jFWC*wJ2_$2hI-T9lah=w)L`f{$8~kI5i}7puvJAC>*Guf zk?%eCvzfpQ?+kP1-G;7dJu@IX`kUWQR%!nbQYSLts^B3ELdT>5z2Y)@9$(e|K6mSk zEBe-B&UqCPd-AkFNISabM@OReY<+e`7oHMU1_oa5a^I`qsx{n91`42H(Ol4YA7ia? zxRd;Az$QIKdUU~pI^+|5I&PzkPP_Q`BnEn+b%j5fY6gG^+5x9-Z0t%@aG1;Hy00?z zq(hBXXuN_HJth)_mZQe%88>`|mKbBd8>`iMl`dVPHm_NzphkXK>U^7RmFU$Z&W(f8 z7t&cRtf$V3Lh2)FyCw6tQ}(amnO@O@dSbjn49}@poG|nA-~k_CRdeg3%;#9@A1hjx z$t%MwCkk{cpK!#cpWUrg-$vJ7)0&WChp!*{Z4{CbOQ`nFvQ?VG50>r9*@==@8h)b9gkdJcUfKX{r8~>jP1nDcu>de*`mL5lzgMHW7V= z+BZ7I=gcHj)64ICFVaE9d9o{e2C@wtbk0&gD2)G7$zxkkXZ>228+rk{j>{(`jy7Se z0)FQp>4(i@?8yBSE|TD5${ADn`B$-(N9*S^%(tj{W`L;8o7;~USdL)j0weY;<>A$` zZ@8{`!wslwQ1a7uhkOkl!%iG*C1ZRKj|IAtnQ@X5@MN>dlakn_*Ij$oAqF?=3TB7X zQT$<-irfrC4&QMVo%B=5HvFDy&;$#aklIb?%rjr%hYq03kS#APbMVN!>e$E~*eg)< zD0AWBxDhfrXvHDCFFt^N8Yo4z9FqRd%o zAFp62#gKE5B;%C}@91cW5-gb`kEVocJ(Fo)+?ZlFYCQ<0owti{84idTpq8CgSf$~Z z$C#IAnBFQ4@}l1yO#9{`s}#ad$3>f_K@3B?ok5Vx`cjg-Gb24~fK0Z|eOOVTCwt4E zYUEMc>3`|nRiP(b4Dg=<9JU+b7tTVGA(^4Qfd0GU?Lvv9d;F%5qvy@}KEQtj(JqTl zxz8K)(gKLo!^yg%;4t|?F>KzR`I#AioBQiOmma4S!Op(j0Hv?hG}%@5R-npuQFs@aRVTT`1#HqyFg$BDY8(9JKJJ$F z6KjqS#rR{57RGMiAZ!GhCY0v(cEmIf*%K51E+GmkCy*lKPtrdW1BSuvx({21^z_w( zOtVquCj5=fW!(UN1T6n}uce#Lbxqu6hy>%>7wEYGri8F=o%Cqdi{$lS3_v+uW{LHs zI875d_}_Z^P~zZf-vVZxneNm8gxS?@be$UiECa2Azq0L08spEv7x@Y=4V7KnjRNx~ ziv;{3WQBXni$*6xy=#1=HBzuLi;H8AjM0VDiz)|fTP07=o%ALyjM6(oFa*J4Mh4yG zGFD9UAdAY;)|_BJNDeC3K%Fq*lpqsbLdM}plGLJP)zY}R~j{17}uI! zeo~f*ltKepvaR#k$LBy3Tw6YW{$%2yRNRedo7cETob$>FN0>-dPW&*vxEwc=&fCcG zp>pFnj-7}Yhdkgz)8!2G7j=i|K-a~89~N2`!(l>p?y@#1ZV)IuuIBCBE~O@VgFNd( zd&hV_8%&9IWDPj*fH>;Dy(B%3ru)0Fkz^ru>-pf`A~~a4xKWPNH>Aod zFbA->-{HF!?o&zWth!}7>&$V3V736}eO!=kL0tOVbqeBG^*2+*TE(IZyhswNDVC(Fzi#dD2}@n$yY3>7s108$qiCkvL=x$pYp7Oz(gyB5cKZCnJ!XNS$YS z#UH+CSPTNRsRO`Kc({N!O^4OErV4?8^D?gd`mksM9=K$>6XQMi9NF<$aUw#K zZCuuWC%?Z&LLV_MVvf#!&z-rMyrv6$b0>}caiGgB`BQL|J=dv-QOhHd|tRYX+u zY$oAzx?&2Cmo3D*vKSr#h!lM9ls?OS@ za-fHFlOwU!C*r|3ZC>1+`;0PErH6qkner8}P>9EHEoY!M1r-sUpF4C>1$j7|=}QGt zVqyG5*Mdui@Xk;_umn)CKf0{v8ZWm%Z7%*HcjtD%gE1`~Wyob)%QE1JeB%Oune_kX z_NnYcq<@Y(+O%5ae#X(Y9Fm?$VT0J@!%#C5iAfqr!)2hwrbKZwyNvkD<7#}$FS%s=wBZH@ zcRmq|=`G59bmFHG8LK6~L2OQEu2vK?$!p}I`P$JZGcVI2Ki4W2s^0E%EohXyt zWV{>lD+?OXW&CI#OxezY+!)Sg9%;pV1gZyE?mA@${74Y}yv)^be5W0RwOqFxbfLpTyR`+i|{VhF`)&)PvlG4X=Z5D=V= zv3l2G+z&~s|F#ll*h#329pBO-jTveZwyhIxXI4agF& zAWrqOyXGs93TwO?_aA@TVnePMReMxKxuk68o3qQ!Nh-}|)QxOmVY;cy{Vu20oT~IG zf+uvpXrq&R*+ta9SFw*k6~5|mNWr;HiRaiDu6bI?fi>8;ESlAFODgALC1~k+-}OuQ z7GGoPPhl=owgUf?{_1S_1(b8K$~FQyljyL>fUX9`{`;Rb4X43&f%(R6rJ2d7ja>$v zCyzj_KcmU(Aawiztj4OODZ0j8qLLLg`1-14pN{1QQv9y*CzMRnLKL99Zl774;4Qnl z3CP8r{;yF1>O@pOL62ujO2y+HrfRHZa&xVZfg3_cL#kv*N3YKz3cg-xm5G67@lOwO z1uC%GEPaQghFNzXE@c}UUwshYKL2tdzgK$u!@2NePd2L|S(sKhdSZis+13_($&P;K z3O9H$55IbzzozSir)wuVsN=DCJ;v#hpjLaO@_$%sxr!L@U}As7s@2@AaCUe?F{-`R zbJRDTpnhR3q&-8QY7*XMc0{9Zc5#d3(T)vgZc8 z#u@=9h=p_#(lVf#6Iw1V4{pt(?C|qY;fhTbp+9tXdM{ zYBu5;Vm7LCZ0VS4n{B~}z0&(#o*P^4cr2X%)sS%~z8CLm#6!2yW8xr$*jIDjpu#FN zHMCrshPxW#`A^Xn1ossezN?7lM6xRL$E@F?1cgLOBaIcVu-Q!yo8yvm zC1n_byPZriz{)3^gI`HMZ&GsVTfFRXPVC!_>!Wv_~P#YPBi! zLQF`R0k#~w5CkN$JS+kk7oRA#CI*A= ztNwvk>kBso21)}iXw2fvA!^mMjF_R=LrLGZht^sD!Dpv}$7V;aZV|;K+4g~1H$Zfr zi0HOQN1Fp2_R&>Iu2a$|V->l`*>TOQ*$(JP*}p!;<35?RsUCB_#w2x%X4T^SlO$eV zAvnwBb`EIOi3o$6kdsWO*vZ7WYJZ7z_cEAQoqmy2!CKYE|cV{$Fl`kvj4$P?m+1?ap(lEjOFm`c4xhWqh<8m7kZN zxZ;@}b4eP!+Jk0039No00`9PwjV_@ZB+NJ=XVjtF=Zn`Pi}_cD6%+$G1KobHF$Qen z=woih4HaTeqR9~|rcb-wQ`d&um1S?(&?a2!MHhP;AaT}D<*o0xE{T%>7^;PYOl_75 z-K+%zm}$K3KQtxALQBysO&xr^bMVK|E~fqUs!>VRnGI=nSXwi&8}$7~E7$Y*vnO4o z+*P|;V%8w>F1!%a7zBLK+WU?6#+R==j#p4~AMuUBhRLmYusHQxOGrm-xwA8R(1Tady6bsWx{FXQHztnFztr4dIAn?Zzn^uiDxbOgcr z&Dqdm+?E`@Mtw+*%x&KO?I0wJ&0c_v+X5?64~Ud^sXLM^(&I;c8^sgUoPLzt)W+Xz ziCiB$TJwf_jirsuKME+yuUDyYX!lot=fnM@fXR%A6zO~^u8_1rrNqnoYbUSbp>*db z#_c#oNF)4USw)x4tKylVEdzm{;ICoyEKZAeQMHY$>5kGJ`&~{5)*bV}klqXVSH63` zKQ0>DeM&ZJ;R-~~@q^P*(3#frxr8X^B_Uf8(D)pgJo$~tE_$iZ9Cm;=m3AM2H-nQ4 zA4-C?Kgl&Byl;~wLXk=T*I!1*5<7NLb_SLN#HK+R~m=>}_zkgVIu3h~l~ z;{+RE)5w+3iU?HWN9vqb?upzft+R4;3th?DlJ2Om`Y3w?8S<$_xzs14QR5s}qT!|I zez9Xp1B_A30Z8h&49(|698kB2JrzcbmxUO+y_3}jP(zt!$f*+;Qzo0FSGs7Y`lfAs zD>y!Y3C&BRHx3X0Q5YbHs1_=3PwZ|#AWv*?UBI&?nJ&T+kk^Kt()ak;+o)t_TDwXD z<`jh=vSAi&aV&W@-Fyp&GmD!;^h}rC2zVUIwA1AdhJ(jYL3iOO%)hWxhn${`_i0{2 zpg*{g3`s2@1sVaJb4-2>U1HSkYK4<#1^ShS2_BetnbCd@B3siRhc`R_Yq|d)Tm}88 zIgHc3x28wa97*wZB*pmH%$RB2Kcl!Bb+~k#IQE6nMru)~Vtufb#Qt(xbU2)r34;2L zha^S4zTyOQ)yvqoiG^tRgS|$TJm`nf;H_e_&jij_7dFG$XO*4jd{a!gVY-(ZiDiUJ zfib;pwvFz#0mcSMK<(RNZ zh?vmz31Qwfr+?dg)ajvhlK@T&qAFgU*D$!Q@Y19P>Zg5;B^LZfu-uz%ZZApTDuAHt zUizTP%p{lRbMgT0BlZ_u$f3t7+n4TDlENB(QG}bi%U)8bumJ6)ctleZ$IOJU$5^&d zK)mDzt0HT!xC^mZTn9@4DW1ATCi^s)rJf5x#fwoRD)Q{~3hqbx0@;ktj-~)DLbOeX z0Q2LL8Sc2nS#*Kon_|ErF;i4WlklW{>ej_3jx62}Mz09{&W+xo`*8>PHagPQrPHkS za!YG(VBbxw!*`>YPP~rM$$`z-B08*8;Hs?K!?T?G0ycM0GelwG zg;vVA2X-`gcViU;$mF;=$-g!&FEn!QcGYvc8!{P$@UNi%R$O@XU1?_mBRf?Cn!B)K zl1ncjQ3)4c#bCBlvDG9>2cYxLOHE@q&L*CZq+N$)sTJjKqBWS4uQ3xW^fRRRmn3xf zs}$-SjmVlf1g1)=LoVBM2xddGq-;6?J+Ul(M1b> zAI@A~%qvJ+J;`LwaL@!5(Ty~(lzid`gpYx1D~!F;W+{m2(7-LRxVvLrLP7*e4u#5z zNn)ED5}0l!^iJPhepg|*j4LQKp85x~5z8GMHMlviktzKAK>iwj(;5c{J8l<B! z1&uj>v1~HPlU}q)Wf5lR$}yojAR%Y@AEJ{3OL$X|eO zswt;ZK6$xwl@e-fgsDFLQ?0NLsm&H9r1s^N8_jax-19JIwn%jZ zzX2%%!|jsoRZumpT1Y$T)KTu(ApNwy?~K)Uy8pSujh(j6^a$MPyLMu1C zz~OAGc_yhYi>#O90s;ImV;K%kG{r$dcqBQz53j9ef1|2Tg>|SX5iJch#ivaVzP{Yi zL6j4vs5UH@&IN8V4Zg? zlK8eC-7*E?NMngZihvMbQ92}9`&%<4)(qZ8vX8+QSTxOnH?Pb48ma-wZ{qTm-hzkK2|ob-vhuTB=YR5?lvRqQ8rhoXfZ!)(y9sAMKZXV$o{M&!nNFSPK{#hZ{soiQ@O(-3(wPq&35g zv-j#%^>%d7*5VH(_lHv%u{M8P1*Q8sd-t#D1y%n2afF2k*1yBGpPo& zbnbt^i6EUHjSiYPM{)l;{1}bit-((Borr`?C#yP4-tHdkSU9S98>l!otc-_V0{vwajm zcCeW54tmLeiw*z1!%7w1qj)=Q5i5wFQNr zzAudIFD*YhJAk?J_v3abfqLmhqs$Ig~L6AXZP&yr#pAum}dl@ zpSy#l4_5|LB;noDSbOF#9@GQZa&{$AY>5-=qcF~Mx#pH3CqidV*MM82^Ot2pekU%; zgD_z2_72u>JVEssC*F57jZ`C`>*-gz5X~FjB;n8$pZ)qb9!4=OqAKS zIrm+5H`O_v!&Sb{Uxt|#jUXWLOQGjZ!4d5W3oY4+%2i!SZ67oNja31UrInFJjH*;s zTEJ_gbIxo;B*|K{9zuo1y3t=$H&EgYRf4ka9JASER=pzG3k<0q*-zE|Z^RuBaH2%j z-LRb5jXHVQX3{6acdU00xXAu|>wx&U@`YojUVd0Y-P$B%^uu$gaGx8g=*dv-##R27 z(n+C5SppCMPqhqmzuDo!F**fTrn?Fk;PKA#VZ>+xaiILJs-J~?zj*evGY{2YeV9~5 zT+zV>N%P#dc{jS&nPP|tHItkP^%BWgppz*`#fZPjnp+gM3kUT%ScC4MPtr&57JFeH zv03@6#$VVusRZd`HbUT}P$yvPVYR=Lf}0OhtJ%dtH#BwH&Jby*^Xo`^L8f8UK9Rn= z7n*{!Uo5!!lslk#^>v!{ly-W1=lYb7FTYqXpTF>Uhi5Xd7e@ku56dlGXYt|=bvi{p zr-&{JDFG+RC9t!e#igyKUw-UVZe3h-ZsDQB2;UCkjgI+C6`h*KW&1bVtqbN(*xNNW zn=xBEv2W1$h{A6nGbR=on|0Iy-G>p(kLG7-XGBdR7U3$y@(ML~%12k4be&`y0Xw{E z^9x?LWIOu8#L@`&6eU9Jqkoe~ck1rz#?wl^mu^hlI{qJO%z40zE#cs2jk1m_@?#Ch zQ)w~{u6Y}-;+A)dYOOWrMB(L*=!!37nCIInXZH?L){)T<$c$nJe9 z%)xx>;k@xhW?UUNcPtXmecYe=R+8*SZvh&mEiur) zy3oJoqzKk>koSBu7KiIsLRsY@n&aWqMxFpYK*GO0^yd}YJY!!??Cj6@X0ywTi=ClN+^3^CHI2E$`qwgK z$=I}Rr^36$0X4G@eKju2wx&jZ@^_B{Rn0fV2ACkTXk^y82;{)534UB0xck~zPwULW za!WPBYE;mQ5b49?L?`kI)HOEL{c%s=%rm6xW#x~!IZd5%}0Anx-zxiq67cNO9S zpvJDvw0dZ+IXC&DDZXK?-YALQS3)qk|NK4X%9{T1E&!%rfkYZBqR?@2J7ghW`Sj7@ zT^5&G0hM#(Kj}?f^ur|}!XaIl)@clI2QG#!5a+rZlbMzk2|WH4jNNjVZWkBrJ$-i5 z+K>R$r_aknv0Y?Fj)q)nN;0;Uk znTF<`h+wuvz@|FOc^o1)+x^v?4d^?`MoSZS6HLdxH-VxYSZ-OUq5$J-;c3?i6Q?*^ z=jfx)`XMIYGnYf9;zy=3iO|pLShxPm#2$2sKu)bH6N6oE%4JtiSLIV%JqHl{Ldk~f z*Ak(+-c!j@I-oi02o>?LFX=%hoI|TBW@PGG#}89pHW zyK%7+^L9|j`p!|4e`jsD5Xn()H~Ps4{Z)-I&%<8VcNrScRJ&(=uoQ?T`!|t{zu#8+WuLv(Y zd`}it$COKIbn^YzUHJyNm_XtHNF3BG*;9K;!;iO3n-Va8GE&g17uN_}qpGbBHeu4d zsI1nK9giBygYOvOIHoK7wV-#g*pdboF86JvlS~P$&Hl|6krQ09doYJZCSll?&QCPO zw6rdvSi6|mp(o9$V9C8}GLkpAj38pTe0El1s0QN7ArT3r5cv{$zUrfkm9$HQ>BwA} zhw7>hSb9y=gX862MM|<|e*A#=eWsXx&jq7G3O(b9NxaWsl^%~Sjd~sDwL-sY=ixwD z*y;1i{#XU2WIK1`O-z{M&f#PvtNYiliQ_noD&M3*@q0!A@I|v8I89=(>pM);q)E8N zHS{=tZv`R+eRR)%exkv|63SgmXp&hY)18yi>L(P<;th}B`pkA`gHcXxjtxuEidWs7 za#>m+Gmfi}G+%}Prgopqu4bgbxDYK+=B&EB;z&Sm=eqZA_f?(RHk2yDSm4+9^y>4I zuDq?`Et3PD4XVvyIU-XmOzVb^D;J#5fNxj!XQTxS=IZST@#Gkvsv^Ix1q?qb+FgsE z@!d0{dvDnmZL&@bQovD--aWw~URm?T2|`N9AZ?M>T% z1fPXXUA1YxG@8aLlPyrxbe&HL0iVZn&J(mgtD%nh^4dW#<#JVeVMYFDz)+B*j*)u% z&LJFxOT$g%=vYKYz!3*=>+!18u`GWy;&W@yb6#qXA#k>Tl)%I`#UYlb46d8JNbM&kT6hUL2nG#Cso-V&fGd8aIzB@__MAe1gI41Yl$ILFa?bKsJ-kr~~ z!$#G#uPE|WkayK{oVh%(ra(g$pdAsKd*0L>tluyVj9PVWyZZM7+-ks{pyhOPPG$e~pV~-izAJPOg(vQP9 z@5uKQA#AUzAfeswU6eO%Ss|gKG@jn_dtQ`J&5cj;<#t9G;(Ca1BM^Q6Ji>GIk$8X= z{8`Kx@D|Y(QEactcUYv-?w>Pds32zT$M8e&ziF;5+#YAoG?I~R@f%D{PgQ+|!lE{! z(BSqY}=(M+zq3tK$PZ` z->=U`0o8T4`Is7`k=X9ZkAY%<=I>Ni!U6ZrIWz}-Ov6gd24w*A`b*(^Raw0e>&ly@B*A-*sW zVZA?M6H)O&l)rjpa~YskzuDwtfpjety2J})ND#rcxo+RNs?75i{nq*u+Ap9|ve}iQ zU?rtcp!On>6Ta>Nr^cNLZL%=8jAM*z$a<@;XnGoBPDd*@61yZW!o%b&Jz3p4$OK8t zaBeUDMgNuX(@vzN0*?5WT7VrgPnb-3s>-4CE4{dY?VIq)tV>_PAD;tJ_k2n6kp`S3 zbkX-otD`*ZNwTB2_yEsLmgSehuSM-nkbWjBH~$oO%vsN@6hs|cF(AS}ub*7|LiX6J zRZAa@E*eqz5;xbw^LvLW3w?5^sGwSsJzN@lI|n`@d58QP`%SP@}TxeR?eCg4jm zOI&Z%fzjbSQloA$`5=$9#hHY~`|comE8+=BL7*tU&15GpO^m<_Eb~_+GMd0Rs3Gh0YvjqOQ`ED&A;b#SrEb1SJqpxTdCV`7JjAhnJhco%_8IKyV-g zX-9brbZi5GUxFnf?%XV;X+O+{VQXuf`j%G38!+*6mcPyf_T#=hf*ZC; zI*DN$8z$b9TD_n61gnV0ehs^C0Cmi63j!<9r#%}EU6-#!WyjII8;;h_vPgQn+(@fz zEVK`rPSN>*E9A!P9BIKO6wRgGaR?)oxcMRa)8LvM5+4x+t5dp!0LAz|{qCGI)5mgK z>^>F=y;}r4 z;Ao3|F}31dRfqsBU)w`+DK$K{r++A<>Z2(r!?GuQ7%=y}ZODTZ#yTJ4l_dSB#E|&j zBUU^u^HOSm7brf)J67+2Q6z-}M;&}Po?<_#2+X@;%V-ZHfYGEMWc{bbd7Kg=^`d1G z@4P#sh2FM?U-pr2h{l^Q9?);ank{;!>*xo9TegsfMVGOO^Woefc2(9r2?5+Ch3g0% zkt3k=6>oo4@SV&2Fi)b$lIBxqdzswST&*gHZi*oawD=iaiyIAemAb7U*k67WDUb;!& z5JY<;)6PEBe#z+fIbSbZL23gLw3Op%iMPf=mFXb-=R_KA(MFF(3`YNv zc2yPYzF%hO%CMa3=v>kg^_|F*bDaf#x!)XZ3xyzP{Xfxnt}}?LV?dkJZ^ZK`ppJ#_hp^T8Tkcq3H}wXu{ZPKIk)^$b=09M1?XJ7 z_7kC!sqUoTvys}uysOPH@X)vw0SW*zwu|iWCV;Eizs+f1PwPoMYj43Y*6_bYxs9I* zvw^yat08>U5MBerX49Z;sQO@`A@JSFx!bR;uWxtYiz#!37s2Bhjy}yGXQ-gdoO_9h zy4kwF+8-@tp){S$jV$E29w2_4{)L<5jOZsOJM6ZqDBx&)aQd7FhpZVe0vm8Ged6=N zIcT@UBTrSyQDBCr@dP+x6jP}X7+7gxx{V#aqx?o>El>L5hcCJ_*n&BK=KEtL5%icp z13Cn>>p0mL4dF<=p2g{#tE=Oj+cRpVu9E~2eozZA5&gQ`Vr=4J;6@_zpVk2^A84u&4BlY*_y2< zlI8vp`14`T+<(NuKJuU(5MgZWi(}X{L6#up{RX=k^@w@!eG^CA_TbhfG|q~ZN>8=V z-4mSq%xhaS%jczA!~VmTb(8UO5Qltb*eiF}0ezEOW$0*e0R2*u2e{I%Ae( zWU*2o^ek7$M1lOP8P(j-xNWJp=(yhs81<%nV7>~g=li|kr~4^=N}U7N(!AC`Dp>8` z!*DFRPiz#_KAt!s$=_e$o#;I7?C}^Z$2jsGb_f$~VpUxT!3GpI)3+ka;Mo2sC=fD^ zan8tZnzQfOQkx^nv&4ij;!hN=KqS-+>#M8Fpk>>}N`%sij1W5pXHC)`s@YE7Sy5{0 z^SlLzf?{*Hu|-*|lo&!1KS^cztxXL0e90&;&9yE<paXU>TH1C&{7@yq^j28Uo1w z95#jPD6xtldRn73=kjmd?gbS&{~*@`+z5r5jI3=5Q7&2TDEvR0{!*mt0Tfuil^1~; z{L>%4)MB#fZL$;Nu0E0oFy9H`d=mci(Gx|=x#^*ACUr{f2HW^9j=Exiye=4Q+pS#)pV%51 zDNqCM{FY+RZhO&yXvRVkwb%u-I1_uLdPZ%fxe_qNzl7R_3VbYX&CYt8}He2tX?@`#vUq- z9z3XZ5Z}Q+V?y+wGJC75+G9s6`f=d}%<{c#MILBW>btAU%~WTt6ipWEDI8e1W?kSj zdo!A8uNXW{-|4St-MWnGpr&q6n%nq5>r+-c;Plfu{meC_PFL_i(>qCf`>@UO$iEVx$x&*)S)pEqCP0C|xeauC<84=X4~>4x zV0$x`t5|a267@BlH7|D^ax*T51nLK+gWOmYB-{J(igCoi07u0qSBWD{h}-tV%mDdN zP#QQl#B~E{I(B873#6>(X0vp0)fO&7KiVVyzc~1o=->DDTS%^IC544_c9#sDYVEmJ zHnD8C$h^HB`2p=<3|x7u7hg6dD$dK$5%`vDyQM30H6**Bn0hE9<3YD|QOoIeGIzoYf45_Fdc4dSkvXeod?f$V%1z z`ZJo6E#_CJXqUK8=0I)>>a?d0Ibub*)>lDJ65i>j51^nx&`mIsG=(dKJk-BjH2`A()~NzU@ZQ1HX%e$*iDc@KEmJ}FSo_qU zza@ezjR8!Z&cE_`t$a>>t{a`b;XL&jZGnT)#P+2QL#YnCduc}}6Q`nJ$168UU0$ho ztLMOZZKZ^C>d4;Wumd*d%zaNiCPvc9K z50w?^v*odh2J5iZNETr*TK*tANZdz_bd;`Nv-bU;xxuh2H3br<0OWY|E9$WJmA$TRE zBD6NsXUzOuX|NcB36J_EZ8Py0&hSzF-*Y;%1hc#UB--hs|MSb%aAjGOVpb^faJjWD zn5*AixQN~ph5oKE5 znbNuZTUXCF)9pEGQW~^R(fx@(RG=i=ldmEal>N+lj+Ld&8xKVhG%@*A_Q1X~Obr|Y zUs8Jnvd9JPpt40gr@|+Ck7$U2EU|*-yyOezP4>Rh8e342o2eQ7R%&}sXj1;ON{ZR3 zct!U0cbKHc|5%N#qL_}?)Z-)8VghjImO;r7Xjf#^p4L+dq(BK<)awSJ6sHza+<;YP zxW6_IDzfKGS?GHVuI~Z{SX`s2K|(n1Vt9U*zjo1atk1$~0GOx}yj-w%H2O6OONPq5 z8=^&9emRv#aEhyu$fjqjH0A-bJ2SJtXNKJcWN#}GB03=HD6r!|EZxwr9`-i&9R)uP z+`97XoKxi`SN=h-tK)(zyyLId_}W)~5`ZP(mkC$(FdTuYBiHW<9&&=28~^(*^s*)v z!0FOX*m%f5rY-4V-!;9JqSxRea|NNGkopuY?In<(FF~7GORtIt=HM}Wkxb5m-k;(N zI7I*sw5#1#rzLV6+*uw5nW*f9kE|b6(CuY)4R^Fp#HBnz#!3npX0qS(8c6EX0n=E5 zuA=WR!olN}pQu%WS(;8N@-;qVDmzhkVAPATV zvzG$AUt1y&8~T<-$}Mt*)xu~`^x8f>aC_y`3at1YpF5^@{JOPBbuPCO)%BEs3op}4 z-T?jB7c97&Am-ibZcU!n0$AA)PiT1nB^>bM7p=rvmxzRMb@vZ|RtMcn%$Y}k`zS(9 zIZ@^y4|}6ihuK$hO3~BxYNnd?f3+Yl3YJGG@ z+*-eJtVHl-sn1TfH$G7f?ORbYHuu1~I0ox+My3D^F13q&SVzwF*HU6E z6ID+iD(!#qv+dNGlwXRrbf4U`kaIoIE0W0PYw+@~S zz9&||4+!jfL$uFpOaT@O4h`jUe@DN&oGtTQQZs`vcIrI`mYjfAE3C4qtPnf-0sP31 z*8-O+?+w2gjL(oyrSgB2Oe_qTZGXf9_J2&d!+H5*;MT4U_RT!*z5tS2wrC7Gdc%7_!#kN^sQeJs3A;_eF>m4G19jpjB8o?nlN^>8X%&4Tc%R^tgsw9pCMM1B za;acbkbOzMfhLYzl!Zn4zY=6X>AZii_GQPQibmYWf0$8QlDI?*ZYaT&Bm0zFu`Br zCnoMTdfy-K($YV{f(M8A7R3lR!9KxW>l_4Nwva_g3} zhPkd;80YF+R-vn*khhLbUVPMQm@e zK7Ln#SVF=w$#XWwx^HGF&@~MAA)G=;W_lC)wQnm5xcC=P`}9SS;7KfnmY3M=|DXrK z?60-o6d3=+6t*ge5;CcZ6HeyPc-oQUGf*N|VPD-A*os>#e}q!RF^i651UFU7V1clx z@H65Wlxsvp;#ij$frVSA_UVnmvHiTwXa-O}P;@vnDTbLx4G5K1a28HD+oT1_!G3RN z;H4JU0qb*CNsA51SVfWRKW(G_*Bv1$4GTI9HGlA%~{JaHxB#&CGC=$Zz_lmXzlw6VIezrrN(N{kq!@%Q=-QB(gH$(Y_U&tlAT1Y@M8T-dt zdXzKk0S5oEX{BB((^GsX=H}&3)FONt6dPGTR;>k%k(4{>cP9YkDCnZn^bPzPfWiXL zJ_fM*c2;(7M7X?bI(%c$Rm~#(d<+5Z-dNs~+q%cfN#%GXKN&7+4NBOef1g_}>WTd> zbGZ1Oc;#a0Y<{m<>Nu>Xa;7NWEKc;YIBX8EVMv1VOCyiA4B}Ff+t@^Ke;!$t`L4gV zkjBiPsdND8dZDCD*@#@S0)zLe*!Uu)lJzOpH2n7|=JVtnM#($=&We4re=55Cot7~4v8o0CfwcMQ&Ng9((3uiE0H&y zGE~3ACW#bLv%$f%=#g(YdXGX&%+@3y*F)B9z18GP$pazlIGQ3HY$30MY*77vgMGMY zHqTQsQCR{SCC$hBBF%jr)h4a(>Wrwj83sOtbe*o8Sex39Sl^7n)?GlAxj|Ht9d%0p zW5Fo?k<(;$*cs4R8L&R)Zb#J@r~af=HRC)2Z&|aTLcoy3y0PU>RIdmjwS61yBjpg9 z7He;)kKj5>le2OL3fw3rgS9jOm{oz*pL)uCmE*CT32!p@EUAH4#Cq-D(Ni{_EQRn4 z1^)imOHb+4qlgM(*!o74a(|r_j+Z4GfB71SL)v^A zR-%wM!&&$~5x%E_6T`f3o`TZfX2Q(uzj5sBXUTd{TVTYE4StP7*iu96dtTx5K$LMT zrn343+ODkhmU&W3J;*o8R=c)o*kfO!xWbiZKt46V*MA(~ZO3y-vPYDxS(%gp+`(V2 zmAY(yzxtM^qiUsfg8{3WM4*0EbbB0YXwNC|@P{6HSMryn4CB0Dz>zBfrU~3$+P-i& zh@B!Rp5Sh}xhmEe$~1UFck3%RZmjBhtnCJmJes-kJK4tQR}IR86NQb{7jOcSD2B7k zlpPbde@R;IC;Ua3wo(hun?g&n#lp6@-wWv+mJ+G)aVGiuh_{vOls35~0^!Gf5+ZYt zq9&|BB3=blP>%Zf~nL=drgbsP7OjGgpp{<2C7K`6~Jdh#w1q4dP zL4!IDpNkVScrqjbzNRhW=P(@q@rV-%a0Uyy0UM5ssd>oMnxjvnggUh4@Qi| z>i!d+dckkzQ2528Q7P*|5&<*YRV)L1>T>P(TmG`TX<-=NITMuZs{HI*o2>h7a*^W~ za(E>wt8}eBcA@Vwwt+hI2wWKWN~S7Jh3g50j(5PM97O?4)fxzS0{w|eI>cr&^t5nM)%DCm8PccX_ECVJ z^~~$sr)0S><$C!^>r!(M+>QL&&xKLZpA3?Cv0}?ZnI+~J+pEH(Ea`B?j72%H2)sdj zrLawppvK_A>vGT!G*7A;`Zuxnuiz)!%-zGXfGJ?3f*LiQ=ASq-_Rm}G%H%o4W#*^y zR8Ui$cxd#e6!425l9q>53!s3>;b9Lk9?9)u7L~>`OP}7HXhYTRcYV==4f@Z z5QPf`+Mi&;l5b8-6)qTp39;&@1i00Nt~K)C>j^}O<-7H{W77M>Wh^!Ra-1Mo4=XH?)GBqOuC=uaXAFTqHGVgi3t zd!0bxXldTYt#!jXOpVtCRa4)oH zWg%zrG2$iivP>NRv1EB8I^`KG*EtmTZVc12RmL!+pQnpJLI%^ID!ohlQ6dq9t zc&-ZWFaIRQuAF+1ZGW;zbt^{GL>Dt1?p8e(7>y5?cH<#6KVloD?ysD!3^E+W}iSJ<_<`<*~v(n3*PqLSo%6 zS(A5CP08U?B6UAEdq;s*Xi1<}cR1;dmiok!6tac}%7jskvx|+KAh_B=yVOm}mJG;4 zY)-RYH_JMWGlRvDod6uWV!YBB;f#Kf;xE}0iPeZ|M?@|j2qDjLD0f-%@ey3*)ZTJ& z4as|Js~hX)(hbO7LfA%#{8h;(vaQ)!&i3RyB=TJ+6R#B83)O7K+!yX(-UU*9=V=t^ zu0&_R21YSE+S(pRF22CIolQmMZHTP;eJ*8knG@dexrC_|p_0!w2;_ ziYbibjpm7xi*L|sKk;ZqNgii861-Ihq_EDlyX-;loW-cgrmoU0;#TtC5}09PYh-IzZdt1D$&3|81jPYi=`q@QjgBlfBsE z2_uc!@wc>{l7kuauw}RPP?#v_L_Ma@1JZ^^cpD@WQq_0af|JMea}||Pub}nof*+;@S9$1}_mhgsC$w&(ibKPc}{ZOuy2k;KuwQ9*1_5^GG1(AD}lhI=O=RIC{O1!n?(d%vS|tsQ8Nt2PJtcZ(H;7+QlG zEvF6m$48dUHL9ZC736j^u6nu2?~zR_?YTwow6Kypx8vWhmtbKt20VIT01*hlcZ2m+ z32~3K#|TgpT~r13i~%MEBe6w$`KUGLjXdcSq}_m@j&)Zh$Br;?RvoKtoy~fYae6ou z;ILiedw_>GSBwPUC{Ph2Qg8>a))=UMR}!{xu5WnGyUh|;Un;$ zOSj=Smh}ndcP14#_@w~s+#IzE#;AQg;u}*|?B34qJ>4Xo69O31<6*IlGL*Jov6S#) zZU>_Qyyz{bNDqQMV`{mSPIx6AoIU0!4j4`hjeLI1$j|Cs9$w^aJg6SILy3E6eI4wQQnu)S?$ zCR30wI(T(+g_yS=;P6YJ48tUGU)>AD_4taD1~&~n zyzqh(bZv{KkhG`QVkcA8*~Tw_Ugpj5(X9irV+U)rFS99drPX+1Q)NoYsYtZl`OXV) z16Ex^q05gLoyM^>a1txs){wLo3o6P`_1nrEd!@;xYxPo=+-ENKmG|t=jM162n)F0< zVw7`cGcZWi!XwVhpbWal(orO=G=z4{@95yTb;Rk18(F`7lRl7PhK3Lf+oz|m;izZ& z;#)8NRUGS20Wd>{-JX=AlAMZaK@i#EZ8r^0Q*i%^J8Fyz(d-*p$u?gy%qal$95(rR zBiQH{a7=JG%_vu{?#btFV2<^$NP9OBQroM)I=8Pik=u^)q$P{#b-&`)W^-N?YSmab zA6?PD1vaL}s-g?rQAfmvJ31O159rG+3fT@RoSt^rIUQ;1{_|xPv6XnK@oDnqc_mpb z*rSV}Wp@pIFFhgbr`AVayV{^fQt`qORD^6WdGB7nxP!N-RjEKh0k1B(rP($~j!Pks zV#WaxGHa`9J*ygEzv$w!L8ee67ZkK0I8LEp1x-aYM=H04F5P6d!% zm*$W9oOVeJ97$3JcAI$DzJ8Pi z9UA+^bj^~)xB*y2=ZrNnL}vn#QcbZv4C}2lJD;G0CLYhp2hg#gzL$SA&21K6%l?!{ zhs$j|dI_+_{d)>V^Iy>8+d1eJgIlCjdiREAGSK!NpP*2buaO?k-Cp5>=3ckgvGmV^k!nr6K-6g5#MO!G55068P;VP+j|OBHA#Ez>QY` zyJ`H!RDTlj{_@kimieB%U1r=bLnhLEWrC5=2ecK7<)z9`iTS%FQP&Xz^2&{#c2l^l z!}~@G!tAQeidX$t=pBD@EiWiOkR9Bo@ZmY-c7i6gPWg_76cUP+Y ze@>ntVo^E16OTK$R2s9=huD~Zzt+5{N2C|q^EcK9Yl*Vt4+fp*BRRU4TUsh~u)$VQN>Wt8sk*rJ4eAxJ-lgkjqX{6|=@dJNrx z6)Zt9Rp8=j@L-)wcGP1{Ai&6UDMLM zcb!l#zY2q^Bml;qrcdLhGp18NkRd>RNo>F?-8FnqJmFW&Zx@`qPTZP;l2OPa6EVmm zOi(9jCTWT5yvnXZYpVJy4~un0V!03mEYaZ3t#O;=CNlsUPi~S|AjkIV*0J{@IjD~D z9ogH3`wFee0;c$yK-V{7-)8J;`GC5~s~%R^@rw6V)z9`H=48wlZo7cUgk6P!Tv$J1 zhcAY&6k}-8ax9=FjO1ZMv_pi-b!S+Q}4 zjdB}Dvz#w`YqwJvcVzF#sCtWXUuu4e-);i2LRvtw{&H?tQ1Ia4{9ow2tpS)zQl#FDk4I^{wUk8G`-xtp6qA=Pm~ra&Zs?aYC3Q)-Na z!s{*4M&^YHb>~000TVM+2VDJ2Cw63_39v=S{zX(|?1HTCGdF}9JJI7$8d88rtlv9@ zZ%T|kR+U(Um>}xVSwJ3bhMZVyI_ILssWV+BSo9U2d0x(gR&cpW_L#Uxow*7F_jk{t z4D^*CVA`N<`A@t)!HF2#tHqs&FQ0+4>J21D1kwe*o#cjw^93Q}vsR)RS6O%LLv|}D za9+Xb&X@Pr@S*ahbLn4-EF=E&iw5=29fMpL={uw-TNrDq8Ny01wDWg6(IpCd_Idxq zwbRo1s{oTyr2e@9>W0AB+3l`f^Fu_EIX@^-MAg+rOPXafjR0XY*?3!CyRhKfXGXM( zj*!xE6LjqcrU`}z;_;xHYO?z5-XB}(CWGA_0u+OEO?(+60&6Xw#?)go6xgxx@A~q>d~I$ zlLX!ukIh+zJ}yiI8nCkydl{25?{Adz`eJnP5r<$pR=CDnCY=#CAhAL*nDo-MVW!2T zr<7tyq0$RpFh+VVsQ^l*MpIRjL?Y^BZ1OZwqseehTl6vzh=Y z@-A?m4!9&xtKU0C+2U~YkqHXW(N2z%j=0t1S6q$B!W%r3KdLP${+A|U&CyAqG2@Ql zRdYL|5~<-~W_vm=S)pnOg+2%g86kfe==7Hcr;G|YO2oy1`b-=w5q#t0kW6V%1$>|V z`CSNc%&RpIbjzo5idWSAF!H%_6H9AMYEMr_wfczkM2@jb8xcecTXynVWu(+X(k&Z( zb4Pk$^icGvS`09H5BlTiTM7!@E$jRi4MTQWA6srOXbefE-;-njvZH0&>_;(H*LCt?OG#-!6UV0pbbRus#G=^MWYwU? z)&)Y44NM_lvXCW+>hdr4sQ6qg{!c~~P=QMcqgcU9;khz@v0?X*-X9W3?g8v1y4;Rg z`~7ISZpAcn>4x?`WTg613A*(!Lfp&DuhCc?>IsJeiFrXd3832j>;beRmi%I@yna8( zwFC>T11e>?9PNqwOGryY%X=X9Ys4%(il0-)S&~>|m(Py%l2A+YTEXq-2!nc- z1D0>Fk0^UOfbw4PhBQHbwV+U^^A$~-zj_BOeGt%D{aYMy!k&1d zbNLdySC#s#6UA4jf*e(>nh*$4ya3?ak7vxW-ISLIcnWQ&P)JX6c@%w?)6E$0;XpQr z(>Ygzn6Cm{0Zc};lrFd2Hz}2S$G?W@>n5N=VCpYCNDXz*q-2iI6jlSww7?j@*3^I{ ziR^fJEGb)}i^i>Oozl-CD738l$N05L%a=qGVj$(AF#rA^X&uX2Ev&1yCKyg*P`ON2 zzS0odB1bT_Y+BgJDx@mD_}&s(RQQ&AId6@mvDgdtU{k9e97qAAzMf~X3l2C$MbEDO zqqv>JKS`Ljvp5<%5l1F9Yqnw4HD&C`dJfxhbDV{R_Z*F;?bK6nsp`LT?Kx?FQO^u( zp@_487%FY;ee{sQ0iL8`eMlUoi5QYUV<7;(e1O#&BdZvD;hd>lpxQA63h!zJUOrk#IC}EFX&+bt zQV*;c`gP@BDC zJjLq5imuF~{;{N5suGtY-KUgSz%m5<&DoZ(RNQn3-F>a-YERFv91`ID(t2=XH z0`^Rhk);IQys&wWroBQQQ=?KQ>*&wKe{;-J;p({p*V1xe(<0YTno74|`q;qAuk))= zG_e-x>&y>~K;$8E6rf`489&_em0!()Mey}Jc?zlHVDoSEo_!boZh~I7Ncx9YR!5PE zy3PM<&Wr5f>IVch!P^+?A%X0d@Ai2*RS%Fk#s5|2}-h4!@Uy|;SzbG7xl*>gDcU5+BOgB0 zsVZNgVwt5S2M<{pvr!fmi0dGO4qRLs&agrHEv4p3eVfZ3{KuqJXsRG+Ki?{<#u^<4 z1Thj-sXkH*9Jz|;kuZG==ut}n1LLk4YCh3oJ9|XS8)~q{yMak3sR2qm;M3<)MIhLaR zlIqVAq{k|=;&`h;iSE(JKNMJA{qU*7&+xpVhN%-RnY zH3ot}f1XbQQQIZ8G-iOTT&04ARkQ5wJv4xm|FW~5 zun_l?3MkEyy<>-+cSV!Mv+t%28FpHcH-IE42){zzy3mCEVp%OHwmsqgl}0Z3dXCKA z_A)2xHByXB(=-N5W(Q+uOc{oobrs9)9UPN?{n}*(4$Gv&A$BDMbjddm~4CLM)f1wO`iI0Zk8KWf-G|yh;VxQU->PE@8aiE^ZB719 z`1BpMCQQM@#B^`FT%~CxI;ZO9EDpYV<4kLba28`cO@=MpbJ&U~wcbn`RblrQXeOc_ zdfppJAu3TbF-)LlX-Dq5wONJQVL0;M`-q}d_JwAR52!M<*{l3kVtwj7{;53KvUA;P zWPj($*OK;`_~mqqxirCwXToBrD-#Bsedl-4>qbp8pA5VkSSq+A-8VKHw0h$(*7Z>- zMU{50LyuIEb$KnzY%u>_LlPCU#+Y!DD1;tD81h0zlM2fnX9ag|TC+;3v?E1;kY!uy z@7|++!YeR<1vz`W;9GU?Ar?D<`D>BXo-7~}Vd%1hgG%@XSO=lKQGbwWJ7i1!jy~dC zS5_o2r#r4$gLANd;^GfI^vnlx$fCUo%dQW}WfI?i{V0l0o6Yq?{ph=`79EJ z)p3ChnQNmA!b{MiZvdmZOOQ=iS@Ut53((Gl6g$BKY3;@r|i1G&; zSJ?jp*HKD|&jTXc$<5wub%EKO09(xw-LBWQK2Cq#CDREZz2aDb%6D7yFpk&5qc=v{ z6Kfmj>0B;m81>>LAx5((jK|gxcAqR~jZe?t>8PRhs^F5o_@bks2_HuhFA~w!na4pX ze_!EL_LHnJ14a-kHZ6!_X0-Vc48xmaqw4{va0q~@uAez$3Ih+N%Vh*%Pzco79)};X zJfow+$M8G{OmQ12^vH`U(+V2ls?H~BH*(H0B<{cTRnEv9)xhX1S>*~?zIFV<+GHLz z2lA9tFcgVne931iu&sXlh9l4Vq85o4YAY39xyNa%Sx;4b@*y+9#Oe?r^IX{r)N05>s{exBf z#O%QuUXuF#yVc;{zF@dz>ex-kQ3XHyO*16BYVwHBwo|O6w&XUzk4$on$Q^#a1Ma!R z)!8gUmmUd&P$N1gEZkC<)*Mmk3~c6k2aug%cqp1V-$qm>DxC+U-{71BycIj@WuOF# zw1YlDZx-T_4<+%eUjg(0r#OFW5WzHF;_)pk8pAu{~=wqd@8#3nxf{Up480bF{ zUGJ54vIfzrLfWXrdWF@M9_f<=cd#<1tw80YkYq9}>22Cl(&1pFJqn?W%%L)hjf)_C z44_1{bV7FBBMVIWRJOx*r9tC${)d?d^JuhL#a+YLO3?I}72@R?bBoD-goERW7t0mg zQc_xJ}DJMn2Q9@CvTsrJh6zCamVJT=+iECU0(t( zZ&B&?Pe~KK9@9orGfbCXq_Z0!yy$bR?iKQ$XN1&5mN!I1;86xg7A6Dh=Zy|E z>23pq<^r{o{PNU$hFKe3<(c$FlAersfD7-A5q4EV&90PusjcpbX4csiXwR6q`VM-n z_lp)Pn;JL@Fq{|qfrUT6{yEygz?rA<9icbF5=nqy*ZkdKdF{Ga!N{NBUA=iIW&ytS z;8d3ZgMcl%!g43{RSBWsfZ100^LkM!0)7W|zh(P)Wz70}8qniMaaS!T3qwJ{JN1>- z7z?}*JGV?%TI}u|nXx7_#xvkdZg5x0d-F^+uGSW9D zAwJ%pOx;*@Hb__VQh>^6qJC9y^@Fa+)h0gz%xvjT@rE*7PVCNCY*idqw0Qzltsm9 zDK7w9aoTvDPBb=33Wi$m7C2!ag3jGY&~!1>1tu{9l+C!XLU!Tr9${!y9(RuFAPFRX zvmx8`>@=P|?#ZhH*yy^PppQ#C3Tz8Yw3E1Wpl(11lsT+DL>oCkMlXK=i`i{O5LWy~ z`@e&0?mCI|eb2PLaa}9-prnOu$z0rBOpbn-^Yj2nEh`!p(L`Q}->YcL#@_!kl_Oo> z(sLXkq273E{PQS2dh#1e;aTvwinOLo`;UVNGC!fclQ?jWrb*0Q0rb?Np6mRo%mGbR zNU*BwU7kfyOJ*qeGBhyK%*IW&|6BDwwaDd;kf7hmW#@0?LvKqi%|5)25Q(P%{xKZG zl*NF2e<1rGv|?ee1}?8oNx8$psA6H8+YiqMIK@#C7*yI5^A|52Bj0A6T*L0{yRMSzNpPmOrwUo*4dfI==De+~{pLnjNeASk>~$AyRj{ETgc?X#4z8TICU zfNM|$!5owc(qwVWrBKuy?=7IUVJC2akyeI=>G)c;T!Nr7H}hXCOT_EZNo1G2Db)b9 z3@R8VLQSvft|*)gWec-k+~1u0ieDLv2&RYIO9To-M4XoujL}WK<#nB#{W6mdkYaSiG*~cE57g9a)_M8e1sFMCim)d%P#3fHwh5`8cH9wbVSk8CZ>gk+c#bINEN)wcZ)deP1$| zcz}?56K>&g+^19-YxErW`egp*FaHD)Fbg1(X2P#Rpg~zsP;P+~Y#CDBL?%Enz~1}H zm?~KQ_mDK6VGZ0!aAo9jWNv)`8tej?oCm(ZKmq2b&(w`#6>5kgEH-&2`WCOUCr(RN zrKy`ABN+wr02f|_!3!^CY1bk1V;y0SJ1hc{ihrB@ShrUKI!~5o6gOSHB=q(_BK4>^4Q(-WxMPju;v@| zymuNT{9^CS;pyRXcsFmKUS0yTLSjY$spKvD&)z7X$+^gi;A%nlOPZg?AeEbn)lSI5 zr4yS`Gz6IP!J^ll9GyKh-e<+myQ`Xj+MR}Wfux|H2Ho-!Y8Z%@*7xAiNTDYNevU%n z&NDVIO`YyiKv&(Lkv8ZqmbP4@d^pbj|A#rLsnh)$)>{1GE01BUz5*21wsF+b)npi~ z!Vxf>lHC2KvkD}F28=M26K2w>2u2;0$^%ACpEYml1vlN6rI?%_nUL95|M~kgd1Wzj z;(F~XCO$Euf~Ho~5r8w(5@paJ*OlPL`wu+6yr}$up|tHAgi2z&JpFuUFA1zvNMmB} zbCTZxx#EHk)bj+E_cIcq)~oSPY4e)9ba#QbH7_!a)~-3IY!x@$6FGzbrV$~CbqZl4 zWgm3>K$?K#_RVm=6Wc_$zZzW2m|U21V9AC4yVP^EE6Fx*CL9p{pr=zpGULi5v+5M! z*NByo3hM2lK5OEMxq0LwnZ+awWV5m_+i_h5>*eASZjds zV2cswz=U8y_@ZI%#RDy)NHxJ@xO#?P&~J)DjZAWE>%H-y$AC2*xV(oh&ah~~W(%fw zu*j~{P|>}X``*1oG3S^GG(P8F%FEUEo>1ZF|29alrf5dv!;Te|qv=#w;bwKihwh~) zG@yKbIkf7-jJR|_7pQ=23>JoM?*4z;0@zCTCs-H{hjfRpOQ9&h#z<)m~>NfD4Eb={z%Dfcu~H;DqOAAe0DL z9SsA6?WN_-5Tj?_WUS63C=Fk%0S)+DWaE-rWpTzKQ6&`jD{&NfkG|{Z(tcav_{2+o zD9|Xq&cEFs8p1YBKU3;9hq3NMtA8hK?Y^LW!tDeYX$LetvU5EK26;v=Y`YD1J&@bG zWX)$u0#6pHbToDaU`^-pcx~fYBtxzPeMm#B1XaBBL(+3LvLW#gay-%o|w@nN%h(oHoYQl^{eg5dw$BI&@`kL9GJf{ zV)ZxtsjEkdR^n{dTV(CRH#dV-QVwkqV6c6Xxe>_$@c@x{losk|`2TA>;3&khQ4i>% z&Q%MtxQUIz(hKPVLlPXt(ieqP(~991HDh}*EAs=tKez&Vo2lt>r9nJlGX;ZIAun4w zDD?Qi?P?I-wAY7w7Kh7QTkZk^yn%s20N@c(p>9Ln*+R?fz)^tzS!*f8-e!!hGml!& z9h1RY26-n5yt3kBOC4mjJepY1rU7uKei;}|!A;7ij}|%J_e)wM8JissMp3r{xpqKl zt01um_lrN|{84N++}p~^jKRdtOw2wl!HWP{QAlm@qa9^Lb=Lu%BgI55ZC^7yd8S`H z*4OCnk;G?b>aMs5AB4;Rm%>Sw?Q#YdGKpC2erQs(OCTsCy_RJnkaCYSz1<sy`maBQxp>#0!FCXd6744s?z{~-7Sl1W=vZl0JFzD(OweI;R@ySp1WcJ2m5CE zB_9Ny%ZH=#C5Z65PR>PMg?0hW9w5Fv5@Dab{~a}lgiCejPIAZEUv(~%d18+Umh_LW zZeQbw-V%|-5LSHE0~3#9xNkrL2u#GL@^j>TmGVg~eQsvgZc?cF1<}@9sGSMEq*t+_ zUmN!vgzM9u=J>}X@DNhZvykFkhz1A)=|$H!h8MU27{)v_cQ{ru2tH;`h#8vD|pOSn~w5a%lWapNUX20oajb>j1=^=y!n zn@*vc3x5A1R(BN#-v_Gx#gIYB32ejLpE=={$Sq&3-J1c>EFFsj9$1eK>3))TRj&xl z>}bYZT!o|s>Y}!rQW{~Dtttgw7q?sjw_B$!kQ{dEBnf0E)2;??HoE>IOX0kcyaU+c}Re#1$w`U=TK zo39Z60@-3CD~ZHI2lsS)uJrtBLM`~K{%@1_+Nlh#dm}CR)i6=^O1MyAwxj-C?$8U3 z41PC%=`cEb`BUTw2J;i$2?r4Ze$d_2q}{=?GSskijxQBpG&UhN6HcQW66k)7X)SdXacfQcymq&*YV!8z$IV%pNN83ITnrV zNm`0m_?3?<29}o34zVwDji2%tL<4k_Xo*xQeA*JbjaUrt)8|S`bacX1{t8L=ZjO=d zlrbco7VS_Tsffg=TvBLH`xq2c z!1N}&MdJGuw{{&uZ*7V?R+fgsld3VYPXQG|%LG1bC14+D3783OYa-ehlO zq~BxduDrIvB`O0H>@MK!@edNxbdf2x2|Hf&t)XAJ*9TG~l#WFbCwl}RyYYbd_}vJr zimUf6v%40;pat9F+Q&B83KYHam}Z!kPfMSyX(g^HFjT|$YU z9ilzDi&#Wm-_<((zdg0C?=M?H@S5hMw;JVTq3g6G5d*xERM*3+X-FSQq- z(;dnAY6$31yuBtjj&IpLG;U}Zz9?$T;;Wr#u5TacG&C8T+46*eF7|f6;Gtp+; z2G$tG28nwc8`A8ow*oN0BoYi0h#Wm7=b8bNjr|pvrM&w5Iqk_36N(-zemoMQaB$); zOfU_C#MZ+~+V2!2nBQ--*tDxb=f@m1Vj{645zy3iPTt}}PZdhT$qQt}oOEB7U?q9z zo-|5iJ!WlN*2M@!n!c&mS)hj9a?MWK6K?q~^UbZltcpnbb2ilkbI*}&V@~FP;JjQg zK<%&`Mh|Vhgw3V`=#Oe)r0q`ODk*S7@)G!Fy+V*&25F7{Osm z4Ea4!lWh)k-VMcb8OpBfbff05pIr~GWjAEVQgV~)TKSmKvpUW+{ir_=O#PL;XY(AB z|A;2MzwC`PdU<0iXmKlQc-a>b4-Y&5nmvUlY-^;iS{ zYWo&gAtRbC7&lQQT-LP!U0l=z$4(i|2Sgy`caIPoO`9t5eV?pZvENLt&$dg_*#aVg zS$NdkAh*7bwi1vN0)Xo)nYyB5wdA2=gVtSti$I55KY+D&K6(UZ#c^xvI~a7A>NMbP zM~YcwP+;m95bCQ-StJfI2Pf)4V;+O(h5wJhrklgB`ljHttOs}Zd;vC#<^cpf!45S5 zP0Ca(PMXGTludWFiS`jKoLriaUUPXRbV9wP*#Z{557ht680DtLt!-j=-%%UjW2Ge} zAx5cRmI;T=tyK1pWldiw5@=q|rdBnr@;&CU@x1rq+PZx&(4+06HTPi;CQZ;CazRkp zYovHhb)A^gNYS?4gu*}7k~_2|t`&JQhqI^kV-^kqEk~um*u2qY4aUI_-T$_f2Daq| zrldZv=r-tpP)08&jXN)CMq)uWdCfBjtPE)uOU7pmtT8+Mu5JUR>s)luc zrK?s-6o!*q$hg}hik$HKjE|(HZITVGl2*gQb~wy^PM-{T-|~ONk?p{!Wj4B%v8=d> zq-sL2xgWEK(3c4qo-8?p>i4pyGVuxkA9h=U zB+gR)$hG1)0?C3Kj(j^nMix#x_S5G|9OjO1VbGVfiS$JBMF~po(*|;L^_+yAO6%z4 zC02Syj|uV5NO8m!GD%+`if0JYNbq>iCrpODfsT732lZpl(`)Rkn0K{rc@#6;GnIVMtxVizN>KlS$83B#(JhRj9g+%zTL|oAx%_L_PWGVGj$Dl^eXzoz{c32MKX5|cH_SNbO$coZ) zRvf+lGw>a82eIH`E}AIjgS+sKgkc8)nMrJ^q#h#CNmUuHGT$=REcCIBIW^i>Ge1Lc zy}fTk~#Zjz4gPqJ2}oz1uF)lt= zy%@dBKm$-I$i%q`f_I@Lmz1iu%ONl57IcZ;!on89@ELdM=+ct7VM+e9{kr*@WTW?_ zIT~fi1EIb*!PMKgD%;u$OH}$YhjJQ}H#gdF{~Iq0(h+O}ck#Sbl}=%{9Eb4Bqs~AG z;3aKrxlY>eAd_K+mngj+e3i-}M#A`K%9*YBP9aA|Z6V<>1y^i}? z!Hi-RY}wrX4av{kMWgeci^Aim;{-CZtsGwXdq?toj)t3xPO*Hwx1fyleFm@av!U4a zBx?|D1Lr!!TN04hY_{f;`~WxIOQ#>ue3s~u;6IYUW-Rh~T)0TXk)_o~qi!<(2v75o zO^soq`jx^wn_fPSAy@-rPko22_ zh)E|VX`h%~S0#Jd%qRCn3*Royvkm$A{>6m$xT4H#*1AukSu{Rrw9N_9ad}!{i^S1C zBS5i!>L-F=S7kv@RXfw$J)97&h70b+l-e&^aiM}5LI|XTf}uLByVNq`lB;srJ1}!A zrCOmadtx=;;?$>YKqi2ZAax^9pQDvV8ZAQa$s8)Y( z)0v;@op2_MjKsp=fc&w_F|;3Vjm|2<>Yz1Sv{U2M0xYlub1T7T!(@7srRG3smB2c%20Luu?F@_L~`kjd~PWi-15mULFV{$t7EY;E0U;1@Er>dNlOLsDOS$!RZ z`#M}yUJ@0D&dva8Db>80<#2kpGH8Tn9_!C8m*_nyM1=H<)eH`g;zBhx}qExUTpkQWi5Q4S3$@M|XGx?fAHh+7GoqqgJMJ9))t zu0GNc(bSJ?Ds>}69{T%uu}F5pOd;ePh+9mIW0XD4u|iB!XjoG=k4>H_iqS7QB6;)k zFXFbRA;D0x`hD|Y;ER#DP+D6QVgxYw_+bwPQn4bQ-ZphwO65cR2$jBxts3Fq7nUEL z_-AA@W;0bo6nSzl%ak9ZM;`zL-&EkRtGd%1pUhpd5yiF5c%KD^5(!*^LW5B78_e# zF@8v5z~spAOfZ}mn`lSCg}@4t=XSDwnqR$EM;{_j*J*0Z;E>5Yw!)ld?jS z)Dgmewh;2pZ)|7#)zrbD4i||Zp2TM)k?)kb{lDbM+`VpTls!hHgoSCq zI&r&6uYbhwyU((SqpVYo4!m$yuWa=|=uc-|Pc8A7(E|_;4z(UK3+>vDF7Q44aoi@& zF^zo9TtPnPsJN(4QKdkod~;;UEzzXsc?70g5p&GrXWT?p;DU!xB^7R&Uh0kt;`;1y z5!a|duU~E0k5LNfgRE-wWByuPdT;rdy-$6%G)bqE%ca6>XA8LLcO%w`lYp?e)jG6z zu1w2D^U@!YOTkSsGg2V9YS9$pGpIC>0G&mD#NKls<~eV8^2WfXAqMqzA8S zP}sj9Jy=fKy%3rXo7} z2wR-`=8$c}kvkn^0;B#Ppmj)1rpUIv)sp%>RPD?lNR*Gk#b2xjx?=$r-w6;%aWTF} zeDm!2Awy6^j9>|AO}?259hzKsMA1BI?&6(Fb#lClIvu%%LYb0j$ObE46i*~Cpnd{uke>zuQ@O8H37wTMK7C z4Y5|%P#}>^a$v0X;ejSL{iu0&-KcWXlTRtCCHMulHWm|lC${xTC`9Pb&wqw zgNrNC_x&%a?7**qF|lKnmi%g#feKx~C_ z+0j^_8f$ftSkN*x+DFiFo*e6D?>dJrf+(K#NV+jj*yfe8wo{x4L%xk{@e&UoX6mQ?m0F%E_zFCfF9<*8{v-xmF0kBcXs^y^m1!Ee zZufv&2$W1}G*mdw&eTst4%C}=@HWKy=0`39?QjI^>h2J45`DujN)q}^b$z00QlSno z6OeG|!ttLds{8nz=%095f9gxgV}`PT!Z&IrB;F>=HM~K+9>-F0^Q#)i=)qc51!p-B zV2nvZJvkp4r9qBeuYq!3HZu}jE^-}{G=9fuX~h;Bflp#?#=*OHDPeV`9LwYfX5kAiGq$Evowp8MfUENzu!3L-Af?j@1L)LMW|E{a0%?Z> ztNu;J@>743xQS3Y0mpSYYAK%Oq--W<4`blMI03QVLNCwj-;7&J8gk+pqT&W^M?_ix zp^@WBt=LWK?HwV+w!keMrRkczS8W58R)>asPGvOvVAu$5fV)v9;Hwlt5ESU-ec7NA z&J{R_T3l0pDXA{UDDV>1Fz2M5nRnG}B#t2RHjr0}_t~v zJJ@NgZC#ncwApNRw?2DZP!~Zkx_LnG9LH_>LhleZ4Dk8l|8&Ja#-`a-07D_tAcFVlr5;UI7AdjufLLB+ZVhNShBX<*!qSS)4EIju_e zU=phe$dkiyq)m7!hRU+yp46I{e!1TAW~< z#!1eX$?D{;4C0yXOHk15_xqTP32LUCFhvQ+4xTJXPJ>pziGune)Sr|r6WYh=BGnQd z)qHw(+Knqe-Lh-BZ`R5{>Nf12uGR0=9leiv27u4OYSq9&zo!bbS$pI^^`!la^26tk z0tOpknO`&{ipqx5Ku~XJUQ|aN0iaAVr49EjHQrcKq%^?Ut^GI@?cJ87pyDB<<(MK= z{O1tEvF)X7{D2egWj^#gC*3ZV>5nZy8uf0@FF6Go*KCdz<_$&r&9GZA$v#H4-1ym) zeW`6rj0M;IM$Ug@3HgB8CfJ6+EEWX4V=IeEGn+=bRERmCm`~AsiIZetrW_Yg-FF;q zy1Bvt=C{wctZ_c`BBbS;hWmSnlT7;pX6_J0{$WIibLjNx603Q~zd+*!q&E=6;-E@DvpQWK&xtn}mB} z{BGzbJRHgVQmFjo8Cy0k#!+#p>gRvZK~zc({_GD9RZvq2MDq zRG|cCQJbpjdva3zMw=#^4Y^d`8RXt&JmQsq4KJaI+-Se56j+t1&}kF({-es7x6ZZP z0f)^kJsRp;5;t(-_asfc@_Ae3yc~CLs&rR>%qa($cLV1Okf-L3zI;D1Eudrzy9UCA zLJh<>yE=>_N7haIjTPOSy+}0XlpQv^+t@qq5DeO~T&V_muS0a|=Zm1;jHThEQZ(i* z9J}17glZi|hCs{kjVFP@Ls!TeuwosE(|-m@uxP+(JeJz>jMBWl|7pkT*RLidz2KRR zwD5(5G^ETJ@JDvN91z+wGBaT*8X1jLhJMCaX2tFR2yu6ob?l53=J$RuoY!0GuoE6~ zk%VFgICPi~LOqSj$O5k&30fwp#0eXjyq-8XvywK*o3HLsOdpfJn-O zzt^3B4V5b-`}+v9_U3u|MdPGn_)2!cdYppDz8caFKWE_QBX~HDr@c$uE`8w zgaj;_4H?N@M3~&e)eAv;?6RPFHlZY zav&KE21~<*;LjZs16H2Hi$x$A-pE>Wp zUe;bL%my6&jU>`9Ww;0(?dW+(r}wGlVh#1xQ<{*=9ar|y<2Q3>E~#>gV$cObhJRr| z9)^;Gt4Tn%jYwY<7X?-!+S{q0AxFA@(j&I)S%2wIaA*0t^R|OS8+tx9wS5sKo=b!Q zU*U+jmV;#HQo|S`W&E4mB=ZzFrxznqyrWlU!x0HVp!=_~K0d zx6QX4^Z5zD8n53p7B3;HO@%RPUL-V$Dv6R;w16Q5h=bq^e9tgaRi6#oSPw}Ajf}-R zr|LM3oQ|XLBe@u~NL%*6tCjLFK-jXoaBWo?8x)-*XoD4qqi@MVu=` z;4rt@w(g6MVn#x%Vs<1HQI5NzW8F+AUNk~Rj_U+T9*B>U{e^D zY*@Xap~k8CN+@0h#GLQ1owoB9Svzyv4$7jLD^w%j6=(G<<<~VWFn3ye*SU2_<+9%3 zA7fM<|E9HR1dBZDuo8|)CQ9SxAm0Z;VkUN*pRId;9X2UjV<%C#-k*A1vmPtgUQHWk zS-Mo-*tlPFt9;^*m~4GN8U21s`K7gOIL8jl)7_HA6Cn46S{AdYw?A__!DbqCroVEurcKJ8_Uu9|v$3z3Y*Q+v zNV$W#u|Hs!t?2$NZQw6W|WEA zQgrwFPx#s#0q45xBQjxVttz%Mn!<=vsww|)47K%0KbL&73)w zLKE2s`W;CdYyJqslCO}s>!rxrnonagbJ#|yy93hi@F#Uqt8SU#S7DoALJgeD3`y}9XBlb(_4P~Yyp^?z<*{b-hU3V$5nAl2<;ze3N3gvKqq<_^vGRrP3-kufQu0Fw&^1W z`;tR}4qi=xEDDv~$BfTi2dYI7JQsYhn^*{#kKbb7GqpKJN&~oMF6Z3g9&~_F?+P{? z)bKgz#=l)?#;h&dB?f12s=&}TvP0stp7zzaJO$jcvUWNc!s;Y}90rTZe%~EGUYi2T z#zVe()Iln1?{LOOXhYeI4OThuK4XJ)BI;^acGZfl!WkNyIAW5D*QXCBTvIE4%fV`B zFMSiuX3t$>F$zyLNR%S)ZNFlo4fYt~#bWOAZfFrFJ`Qm<|7QfYh%RyR&ww=*Sefp` zt5aNHwDYK>7kinn7vwZ@UbVCbwSdD(x|CQ6EEI@IBC*-A>cA16Be}+NTihIUmp#!7 zHy2A-eM2yiEWE1HrayQuEdADOLori?ge}dlCPeaYn`4CiK)`d3N2Hn`+KZZL>fuYQ zhb)-UB7LP}m#W~?gx^ItUPt6Ko1%P9)TL``>?z50qiMpV!-q?-cvqC8sQrV3(qhs5 zlIr;m#J|e|0mR+Mn1$VcIPoO;ijEOPKLs8S^Ppk z^DQdbW~5Y5UQ6em=p1V;PqiPtDpX|RnkAI+p-cioZ!=vL=N)JmP2@4Dz0s+;TO!%z zounQOyq5>Ou$o(!nDiT>0vja5>k}(N7FPiPZ$S3I0FSYM8sLxSPelHvJH-n;16$#; z=Is?Bar!BrER|$>hGd9UOjb2_l@e>qY~A@sens~SdH8j2z2M+8!Q7vb9t#z=;H>(t z&p*DVG~)?20oO&VV^HTl;ptv~beA@R^f_#0iO^Z?u9XG@%VY zHZ=hQk2?+~(jpnplA4rQAc;s%os?PtN&pXID#!Q!QrsdMx8RI{MY1(5&qsiH&;1HQ zhuRGFrgi7Piw0ffbmZUDdK<=o{qg$4wEFBJ?T|JE!6v%hg352w#A=^*!k$~aK8Q;*Ajw9|7<^U+e8@< z-ETqBE1)d(oJaks0B^lRIE4R+tjd7gn5xNI+Zb>4PqlYu*o~<6p!%LZYks3lgSF83 zr>;{zUisGT^z-7UV%~aqc(Gqkt_-`MZsU+KGdtuUE_Fg+nrTP1R@1ovJM-=+KcyP{ zr?|v=WhD&ziI~Pp&oDpBSAPnd*Q6c`sa9ISM+5&-N?Tu^IngYGIm5bQPz)EwA9Wd2 z5DofpsAinnaE#k6r(ZA=;O5dYwGfqf4;6b~zRuaRoouUOlg$@nInumA`*=qItd+Xu zE@`cH`hY70Vxi*3p3%bXjqPZxoJmUd7kGnM~r*k&`&3@Aj`Ozw4PzK3o#2(rfxTlt-Mp+c~Gqae#`}oQ7uYE@r0Hmk47y-Cryu z)@T2N2w-RCwx?DJ0_ys8tDBT=a*gk!Rc{h8tPUz{lfSs1uQ|SMXcl@xc`bzh7h*yM zz;K5gHwv3?g1(Qaz$2YUJ=>}4`VvKBspoG5LkFaD)j3K!Y3+GxvBiJ|MxP~eDz&(P zazH%ZTewK6UDQ z;UZ+^NUT2~sV&zr4#8n5;OT%QO8{~ppMKArFq(n+%cRXGlh?(vd6cajX7^m$sdDQU zU=~?|8ZIo1@n6{Up3Joei>$oi8Ml-T@EbtndK}R+}$(lu^dAGmD zF*?dsoJvAh69=9uRu<ck6m) z!^7;J+eh>ErfhQ=USTHFfDG(QD*r*?DKeXFBjAbH|K=gHG)p6mJ)*2Q5}D{5Wu|OC zM?kc;B$DWx9Iu3t!jNsm%s0W$82d^>`{e1FB zVn0q418NdaHX)|P_;(QN_EE(xtnf6TllSww$tB9j;jLq6!3Km8v`D^WP>{17N7xTk zmGvW9A#se6Z)e0`(bJF#(@w0z0(>7#Q}?3xWNbOC4Ki?m%pA$?{NV@nIFF11RUdD` zLY1qkri{x5`06LkCb3n{fwa2Ms5qpz&gs&za1v}TaJK5XN4g(E+6J)TH1G;pAH{3q zBzHJ8U?N+ia!6G~ylaIe#9@^%oe;2I8cGFZ|I1|9R`JfB7_a+l`^Zy(9?HxN9ySuI z(z$pf(Z~gPKYkNdy^+(!&_zw?tzSeDaw$+|qBaI8rJ)5k+Yh~8Kv{M8 zg-t zb~oS2CvJmW*?{2%k3$ea(Af2qt4yv}F_~1!BV<({=mpNm7E8QJcq-o z;7Zh(wT+Zrowdk_!i}caZ~z7^oDEpu9N#@{5ki!QqtI5k`x5wy39Lj26uQXJBv>sag+ZUF2@{iapT8=S7%)MD;-81KL=xU3j zXAXuZO`xZDSkVhWkuxJCXACowb#tE#vIj^#*3vU2+Hvg2R5;B6B5Z*jrkjqA*y8rU+6x-{1D-02!txQCRZJ};N%Q4f4k)fBW5xp6i3=%6G5J17J zW^2=2?5=Gq{?sZ$XyXUM(ED+_@c$IYXC6{#5b4^S_j>5Y0Cgl7*P(`e@#l%TC5ycG zdScMHteAD_*U_*3LjPx%^hyw(K2YFtt%1k@3Y|lK%G`et0S%TA{$Eg_k#kWoj)o~_ zbXFjo&Htt@z+n4&G>UX0$mXbnaVy~W<3ZtvysNaVZmeZ_LU+t2vpvi{%0g|y>3qEb zVZ-~OC_L;c`}7(2H|m`F#^GepGvbHHQm#xTyrrbUruzE&sZ_Saw^aK?X+d2P)EYC_ z+K&cySP8F``YMo5Wh_4lwf>U!supO>^9MJ+TXk?_l}x*de}1sOP46 zd=@f)d2?>yH9_X$JhYrPCq8yYhll~sa;Tzd+$5+g2qL?bvSi?=^XT z+we+9`*)bHSHt1#$SsK#tzxZpfzjA#T^My9$;e&>AjyuKp&i5zdh{jK`pv9WI_9h`5M{$Y{E4 z1;FAMRkY-wcwFBZP7nk{U>T{? zoKXY8J64O_w1Bxzz``>&KGM&XPnr4MjHbM_VDn1LwKiHlMP-ZG_1Fv%kcQscqp=x=>PIk4ouTd+**!#iwBd zg@31I^vx(OJX~NQtP%@f4^~SG?o`tPmu*dec%!nz?TVFn09qC*NqK~+dO*AgS)C1# z8ipdG^d{g;K#NswcAye>&0ZIC>pg$k6cdYRj@NdKbTNe;dmEmQG6_oSs}rf}SZ(x` z{0z!a>(h`l^a^j3YYY>wQtTb%u^m3qszRqsl-WHl&($4vb|dO%S^`-w$|{oFDCR{a z7SW*;HG3APd41AM1j-7+Aa)v}+;5ulrHmS?#GAQLM~?YKG<2lKukojRb*bEP;85JK zn1q$dq|%u8fdX!#wHJ9vHasX_uJpEp4hP`NbOcI6BJreAP6%L{Eq6Xj@_Cg{e}HQz z4tt*%JwM5FH?>D~JQ;Y9Q7v-#W#A;XUJJiV>Og-NGaKKJGiGPH*memx2YAPKexZ?_ zLXPO|21g0yo97p?2q8@}N}V(8%@tCxxJ2?kpD&wwO3PDe4|yv^tI9XDqMr}i=LC=8 zAKF%iEiyHbbqk}TjCBree>*Ol0=S^aS8VWjykP@0GWaj3z3Tern32IDocPVNEbwf& z083C4ZCqg>G(Q^7sR2pc7QbZm(Sh9q*90XG2ZWMKMs?dWvvX;|BYq-T=FCQzl|{Nz z7Vx7}Y`Oh$4cRgkum7A~7?>?nhp}g8OGP2D>a3b_j5YT+-PGjSIKityPxj#jRa|wA z7D70r4M!E@Ll&PmBS)6z6x{Unu9`E3xQPHyK(N08&`q)gY_Rj|ys@Dsmo-#e^xlG4 za@w9^ID)=q$@1wH*&aj;2?&gBA9i`xkKGqUste~r)jlV}92y7vPW6BGyT_HA>Diwk zJ~wDxou6U02e0Xgu6sO0*`aB+tvK5t?S8TU5sk{G*tfYG-ex7_nI~}YHH1HM7M;QU z`ibuJH2C=Dr56&8+T$;tS%0hge!L-qJX zmpU?A(ZIx+uGU*aa=COcp(5~zq7t}n#W&;#x|bni!YAn->U76a;IijUyW#$4heC4v z(3WJ$Nk_9rX6`XD%1Z?q)xhU;4%#$-JQ$uimy9#TV^Ls}W+ZP@zfqWSN4c;U|A!l# zei(9blGe{m@}A9f<^5H|^u?ej6`bPg)DW*8Z}fLNJUE_S6+9@^-1_qFF*T_9RiDl@ z1%yZ;n1ic$SDT&IJsEoV=R?d$)TD3!aJn!puYTA&WW3tQdLJ1Knc@-PeLYPUZ+n1K zd%=kQ>XgglM@#sDYjy)nivM)bXxK%MUB z>#7Dnde7JNAA0Vv#{vsa0@ljMX+YZtqzSfbPE3V?k{8M()uxY{eyg=ju6}V8G3K5+ zy};;(wzm*dKd9BprF?4Y?bS4cQ(DYWdCpx`!vnyEkoVAqIx0kc>o!&|OS6j%!ADC&N(M=B|mdIv$V ziJyUUYW$xpTnM)_Gp>^@ZBlsQE40)4D_=(-zBZd(QyC?GZ7SPN%*+W`JS_*K#ZrsK{I=6M`y5Q86hRFw4u^!1e+CN&yS1$Z?yw=uI}esx->IQX z!8#rdhAAlsA%ot2$&R2b>{7MsA@D_VOoM7sIvYkB>owP(&9o{c%)ve%yDKDLqL z<*6|>|3ZHH3I;5`AMUO*Ma5wUt!mOzwf?573e|PS(xq<9)*!EVFLiH6V$RM9qtt9f za{c);@tGw19<);cc`$jqJgeg^J(=|V07el@OOs+hgnjT`>hv#h}5)l`)({qJjyLh2{ zz5*H1Bs4J^`xa1V8#y-u>Wq}SVDnMtAaf1Xy^pp z$%`|SUU|DIg%#(7Wbn|hyA=tI7f+mppk(9iLhtMv!1XDR;qc!H%%Nh)9@R7I#Sykp z;|vtvCk5q~Kdtfe<2T|`Iu1K>E9-px6xdG2D3kN+sQxJh=_fv z2>!H8p=b}J#dZmaQ9fywItIt z1A?=HjOj&X^^!njr26IVIM%yqN#(e8TNnnvHn@+%4C1z>5*4CvjUJ;cqZH2<8Lk-( za08xSF4hZnVNN9;ia&fhgd+bdO=2~eWX3-Td+01VOvdlJ7oX?Qijti}ChC*ea{E&! z4|(PM9XMZ@J{VCi&Yikosc(tsa;Co0Hu0qWPxN8c7cvoFD4EoKRwR9Qj7d~w)?n~b zj-mG%dB9xC&!_OMT6$mM?T5Llbmz!tSi^x~fCV)kKjW)b zti0HsNZP4J>#x$kS|i&bYv@Qx>tnZ2R-CufOmhxghv{1vHQ@MUPzf$KlDi-7a9qdh z@_ zaLV%YptP(Ij$4oei~|6`fA2w?4cg?MD8oiEqO88O$hPNwxju{nQ6XoYTYYsxwmL{o z2tc60(o1m!Pd7;-zBuuHEz=u(NoqybD`?U;kTz?@j^`DYD6bn0Ylk&##G(=kg|td$ zS#>cM7?BTg@)3=h%jy4Yp7O;$<@Z$vzbP#j17YwEY0&=@(q~;7luIg<1nN@Wwp%2^ zV6Ty>3B5Oirf>xVHx*6S7f?jmt&7$!^7aTFI`4AOK;(0T^G z1M0>%Y#^XRRd?QLwP@KRPnsyp;}Ya|NdTLY}Xg;ur!D}C6pU`sI zdNY-1S-7%tNgsqR?rHf_lxIjT*LPjoTNP&bh0N#XTo|baf{{o>GI$XoTWU!iY?__` zbYy|rsTCx~HcO8M2GmdYWt5S>f}6N}j?t4<7-(6(66Nr|i>BW7=U=1mT+VDHr2#5r zqd7wZ$A`J0Piq+Q$>OzJPc)k7~f|wS!eR7)Xm$|mv znhK1YFT?9;p6HVu({cA`5nW9|PA~KuWC6-^^pVVa>9%F|7E@z#v%#0lNF_swD+W1&?~l~dDOxYCM6?YjGrv_A!9HMsEx9=2j=O?!;Q z<8kP~cVC5fD%tlQgS{;|mPP;L2u?$P6Ar_=+-E_P;p&q)_hlsuahRY6g{ zB`F?Mq;(NRF%eNy;~xwd+>We8^A8@o9Mj$9D1 z?sl^quZD5&8DVjxJ;pbMhcebOdd`Fs9atl7z7{!oT`zXGf9jcvME=I~F(C}77|_QO zB});JXB#C@V4_(kMmX;7|1QQJ8lhD6}e_XA@DvBD*V3F=#!9pPr{6)CM;h z_=_bCq7EZ(Z^4NWG8CefDX_75ayU2q5pR0*RT3&vtFfX!IL}#yhjIe+Z4c>0$cY}T z6KY+xAQ{J;+phs0?5umc8^-wkxR41ng@@njCeBPgtY`w8d;lA&)Kj!m16=v_$+BKnQ zLF{mWB9KivQ*lYNq|g@Azog`QemV-#$0mQw$V-|f{`aEp&!b3)@(DneLM(&8Fdos& zw-|q@PeDEHGZbA{kL_k01f-&PlJB7zGr|(p|0aA*5#x^@ zKy*=-un()7}gPB-m^_=9UtdofvS&LyFDS2bFbr#zRP4|9 z*WA;!!|Hp~&j_}4=Cf4%7$`{7t%PeSjwfo3lzRG)M~1+$I@>Of;TX5vXPjB$H$*a= zS;y9to8DhhGYwN4U!%3NjM$22udb%u+<*iN6Q@lhw&2;vj{$=Jn;%5y@qz^tAnNYk zJTXK=*9l_T2o%_9a!|JF6gby56W1Fg1lB$MWiW%E}z7mjWZ281To8Fhi zmS4$eU=CBng8k?H17bA_oE2>Z<$hr$+%>-}E9A{w#S(rv7L$Q1iO{Eg?bGh~3^oAC&L3;#0;5Hu6Jv6;cOxSN~mR3g{yVdpNTEbq1i|yAmvycmj*tnf&0bg z+F_Twc9%SqCXgeDZ+qtn2`-5(kNZ`K>>Y>BZ_WhA`GzVh=0rDGmVbAUnU@3iL|ZNZ zRFnhZSDB>6(D{GqBj~(rq#+0dHv$Ym`$~~-!@3V0Th|7A0tP965JeGxo;c&Lm?JtbwmahoD<;9uy@b2sZ|L99-Iz zcD2xx1&;Iih6cI3r>PKY2S*7|A#b1;tFwCnLQ@;K$<-P{%7=fYULm@tJoNQ^@ODbc zBrv{C;U{4us!Ey-5vM@z5yHZ7kQT~fGbsU2evFFqR!6|Jv@OmNDIHxe#uHgGXCTdt z6e~TN_KljpagJSK+297AG(wrm>35qV>yL}5fb~)Nce^9wg#YCo@uJtELL>lDF*-&% zKp@^6rr{YO!_;~RR-;IsmQYq)|E$Da^XIb2LG*r!5k=}Ti-wW_J%TMh7OK7reCj3$ zE#kDLo~5=MgP>L@4Qx%s{lwnlv&iUJ1#iw^+1Je4a{Wi3$#A$7*Z0tf1=g(*A8?*9 z<(}s<9c%wn$q<&j{-E$n7YIC#UD;>tydJkyVbr%)$xlcLrdX-CK+7J2RsC>Tm?F@8 z2j0;AaoI@MfB_&E(&PxFe|N65abUZnL5b2*80Iqh_G8cFsl77o6yyNH$G0h(OFIV@ z@(&0|wXHiKlm?$`G)o((Y8UCc$Q!Jx3Y@`XgS<_&)@;@j{-(itJ9NebkrjQ#5{p0Z z9SyuK-|QokqaWD`7gG3WR<@?pQG+hIYF?mcAlN@{O0Qqv`Q4dY{ke6bg1X$=q zl*x{jUtuMCgh<9=iqRx(B%7q)J*Zz>PVmvD@onSQ(=u zus4QUZ8G$sQy$<4cApp^VymKO{~0lwQVGnoske;4P^cc_!f8r67Ud)@sNY8y!3F-O zcvIw8!P?C<Oq<8kdIk#XGHu#g63uQT^ zeKFBufi~V+yife>=YvFe++FDt^CrKMG;Nc3&(1XuL()v#=Ac+HQ>#D3}KY zUQGvW;m}DFJZIY$rrwT;N}YH=+ykZEef6`!+cIdc2?2hbVs zVZ*rWg2Et3FN56zr7*mkXn$}1)qkMMO$qOnZ1Mdk(uQ)cviMZ&kO_ve`MAU!Rs{1(6Y%ho=Q|Fw z=xe(uZLq zZZH4W{^dQu=5wQA`T$K7u^6?yassiqTK#J@>pZ8aT6(hV&}iVpN6(L z941}-PMx~F-w8o+FM3LSdNs_Yh>m<0rL$;m?c`)+!8O;UNy#nJjS-eTcrHE;oZJr6 z@b>4BaHCC}!{95)RrGUjOIf%2>BSY;aWCd7{s2pi2t%x_2_FKnZspkIr=pQDV-0!` zLd=MY>WnwbL=UkzX_My#895m-ajNl!2vuwndXGHKN`{+9hj(*`s)q~k*g3*q@p!lZ z4}6;!TKsgTD_jO_ATK;4W zm}1GXXV4>}G0D%oG1V`zF0iqsm{joyza-ve+>j!7k?GJ($^kh6dm}`+0e;1nIhsu1 z{unXJV`JtgZk%^%0FmTN2(_ba&|c_aQ`bhJn_Sfqw+PG{F5N*fQp?O|S>t=Le~mAk z{9nAA<-l=x487lYOMRom$W1HB9=d?U_EJb=(DJx?9jB+7z6Klrra^0#0U)NXv=INQ z$rn3YnZ|mgQH4YFavXvCR{xOCj8%%X>vI(s;wB6H(DHjvU9kWUCUWf2+;B)@cL_7G zNwKY6?wdhC_`<-0`|(SzSlSvG>n^8SSF8!_(vnS9z>%DgZ&tY5l7~Ff^RLH3;X5ap zQ08tqXl2RIxm!z*XMr(M8(c{=iNi&n7SQYc2q1qqZnwEiFq%P?F7s@0J9-h*)v^d4 zFZ+@?;|{@c#j;RRLGNZELbFMUXPTYQq7EkgO6K5J$A5!Fhr{i(mr=au%=3>g9}TY6 zuew4yPVEYh*iX3qQ(02w@aZ9ZL8`+!!4B1#J5kNjJ1;QU!r@i8it9xoNfKKa1+ZML zNvagv*XyqIC9;(_n~6pW|1p3!+Kn7FZ)0qPmR>7jNA;Y)!!eOyYP77Rs6#o%KO9sC znrhBk!NPY+*psMtqtJcB7~B(<-#nMPTGCagn3p_YUnj@YO81KEn?fVgB`_PgyMfj* z06D_ zcy}dxaaYJ}bOcc9Q?zICJ!Sw`MAXm*(O<__uw_G4pG4b0zuD}EO_?2K7|w^+JNDtBuY|}s<0nGt)zNn2L$rMS+EqJ1g9xGcs z3lTD52WdUr-<926!zy_RT7#X-g#ET^*8wQ;SqH^WUxbt~bQTX&xIvP`eNK>DY>^oF2FEiLz(OH)Mb(P`(>@7?IvY<^# zNImPac4%CZWAwNy54zRZ>xG5nTw(qiCzyFW6>Dep8@lFxr_FS32Bd`M&V5-h--SE7 ziqI}^(=`10z;l1-F;mo*C0N9c4jdw?oC~rPYZh4>YFTtB(Aui21MS9UplLdu6FGhA1A=-V& zU$jKosivIW1n~zGFSZ&0$CJ-rwM8P0XA!GICIB1M`;3SLa}?fB@y{0Tr6F=@I1tPzgQ9KX<5*q_Edf&NSP}ObhGA6` z;}P0PXca5Wg?<)i1-l&_IjKh;@PJ-XQw11szVFLEtiL-!Irs1o^j3aSt2gvyweYx) z01UZ54mP9$eTn@2Z1d>%=H7Ej`mvfAfc0x-4EZr~c*5H+b{qPv@t^Wx>jLQ-Pl&n>u;vtK$!k zZe%T%?8(qGG04nJE)jYZIaGypxf^@La7g^SX$w37?ZTU6%O6~*8Y^c}!9sh%{r*~T z!Ly8VlZG68hu2K(O1#=-?(bKfjL@&ZSPDICelVqC8BYUE^M`tqxRgv4MQF887@T}r z?z4QNyRcdx-f8o0gE!V&-?X<6dq-jR`m1C-$OK(;3b8*FG-e__x}j=WYk9$VKE8`# zrTCy4tc$>zF44_0gjZJe1ROE4RW7af`z!&G^YkqPJ*}~sZk`@NveIbDMBu4KY)(yGIqo&H`3M)j2U(X4Vc7r4MZsPbhF(0T>2py zZ#CC$S1w%Lt)TO~%|3iSaZZZQiB@U78G~U-62PnVea~LFWUKCSKylz3Z4yb(xVX1G zDSUx0_k-P#-u>*cVvFl;tjwtSf%xVbWDOY*$#Du%(>q*mLmA1<|6&>$$L3B-@+&xU zNnJ`SRQ)QSHGFq&WZemY_M#UpyM?R}EQZz$h>@&+xG?T0u}w6ovh{)04NXhpzKHw> zEw=Bst|MNYik!6XV;^ldKc8`QQSX%pHVHsyH-m*J2^s~V=#$UkkHhHwoG?SvaPL?V zs37q*pZP=xLR0UVOyht3yxwdBlP0XpsF9CqU`Ki|&&qI7vSy>!N8!5~bXz)1%xKdckj}6m%(o$X-F_ ze@1K(fQ#NfK$k?@n3^f42G~Op?C1*Op2vmWT~-H-w#;GHXe4z@_n7Qw_V^=_5ZiGe zsH|5Em@edIeiqK(7Q0Ej$|fWlNe$v`0J^3tOEQ=6WLatqZ+xYCo23aL05wdgPeVLK zM-4=h#sZjXn=@pHtGi8t*y7raiVz2#I{brTmVk{tUgMT=Z+A$ttL8k;xSvYKQzk{0 zS=Ja{-uF%Hm%#<6ep~Bl(9=k}#C{P3muuOGZ(t_SHnL0M`scjP9ml|$_#-vsOxKRpGnz_{83Isyv4U=LQ+{0hPIsqHBF`l zGMbku_QdMF9D;`;`)xDcvwIvr7a_h+d0q_ZS}bg@o{hJ?`A&{ksYg}YL40h!Qz$Y2 zD}%Cxj}A$t<6gn_againImW25(KSwn<7UM$=ys;C65gqu7Q0RJ*`PwP)dCd;r27hh zkl*mI{}sSoqn%Rpytyd)GPCf5REhsT_+E$o*h6!X9$UchydET$EocH8!8@4X@}|j* z4I9y%5k;uZCouEpoxFH;m}kM3x=2(_h=mgSwd-2cFm(b}8R1D~gI6yc z%o`?!Y?qt%CJj-q41vN6t_ia@<(1Z|hHaheLmO#harD<2Lm9Rkvw&ybn_#x$HiPBv z)rIp4yNr$|TmV4_z%5*0v3t+&|C}kKQtlTr{_;a})}zm4f*rq*X}T_fIl9g8nRdzyLGxQoHpfO?Br(%}y4@jna!FU#PBc~S zpAP#=O7upc5K@8{sBta_(3rH`SiS1;|{yb`THEo z_k%lDj3Zz2&mRR zlwi*27=GWd*eBRm*QwnXLw^^XNTyo&`~y)v=es!a*NW2JblkJVGPs}RSz9KE@~D^f zpjTS@RB?oIuYC`~rP8QDu6weI?$7g;iKc%D>e@aC$@=lf$ zKo%KJtjHL?i@FIe0afk#;HybW549@ZG>eiqeZgM&oKs(9IQJU0C!l8VtiiPUlYlBL zlHn8o6p<$Gz&PHKsZH_EfKd!2eCSzTk4YlAKzO7d=8m1DSWaM&W2*x%EU1gNX-HnB z%BrSCdX0%2s1CWQ+_2tqMQ5%>FMrH33O8x)l}+P2FS1JjZTax`PMrt#RJMg1Dui;lj~@Uiow)~YIbK?R`;_A5@gJVH#4LSB z5LX(`#sRjF655e;e8EH(loT?+6E=LW`yt7yGd(}YR$GO^n2nTQrW=nj^}IYyzun3$ zERl#Wl~*WZ>GYct_8;F0+yASB*UInRh$$2M!>4;_<}#na&{_GM&=IR0xdG?tvA-NA z=*-Zun2ht+gt5%lQiOJOk3@b66fa7C>6{nIN?z!#Yfa;E`-M##bIF7R?sNN1n9sdE z?(a~Pt|KUxx=WcB^F+$~y(I78-mw+9+nr0{Bo3XKG4bK|XG@<*hgV8vM4&oW8S;%b8@>hWxYDzA=UV%M+ZU$K4+%64*EAQ z92F?aVXXu&Wlp|1ltuw8-{+wQLZ+{2>J*S@*SP?pj=kzgWMA3I2K693il=SA3@;XE z5P?Byeyj<9;T>yS`|4Y>Gc74ld3E=j^ovcR)?m zFqtQ4msL6JP65oatnV1bv`f0M*lqFOD9|<7mxs>16WG8X3CiFM{8|OLC$wQ+l|W2? z8(PO3)nc5(yFd5e&Q^Q`3XnyQ5#$DJ^IV9sXRwyiqFO`VoV?Uc8_Z38D(e`$w7vN| zL8%_29Kx0pv{S+YO=G*r?q)u-dMb?C&hE>YzFmrx`S&gRrB@oqQC}Yja3f6z~}Gk-rCXf$9wDPoV)dWb{a6rG;P`>0~FB zkC}Wl9{m=(sX?E=ivCV_ivyka7$|3yMP$h85!WhFAJxD2ig>Rby;7ARoInm9Rfy0| z8aR321MjzltC2M|l`E?~IqUx4YA`perdaAtdCQd@^@5cF)D)_}Cl0~r8QqSxBlJ@x zg~mT}TuGUWeD%v7#-P)NncF`hQDlRGMWnC|hUQJ^JR1QPj%}Bv?xhglczbCgr#W$f z*=h1gA9U&YgGM%p-0e$v!2)@o6e*U1B7lM&C;RmP&X#`o&~*|6yAGCr{(oQL!cz7A z*|(}rHUn!t}oWyCnSDqHI6ouZ!XE+lWkBi+35+OSy8@GqChQQYNic*f( zoy7FFIIf$_5vysEL!m*FGYT^Z*`QjpN)o>_)M6zSup4~8E|HE4(swoCjRrgVWS`pT z`IUv!^fz5ycJQjBRsE((T-|R7t(wdVmhU4PFAcNi=}oT&hKZ`3ULWC;zMGazu9}DE zcoZweb0Fk1*OG=Bw?|zVl_B9jPwUq%=yW^isBc})b&s0a>pDK;u>H$QyhJg9t5%_> z1SM67`}msbLml=!mTN+7*W~Jk8$h5|JEx2qq1f#EUK^f>u33;q0P|b`a}kt|%LE)! z8y3uqgkV`(*C*@3yzBNB)T~7M6+esthD}5^L-OM{|!jro2HZy`*YuH1f%Q z4xISaPKBmsEs!v}o+_yOmVpUvFWe*)q$PV`*dYR!|Dq~RmcQKi<~}2Y0v&E{bU&cq zKgrSZ8OOl__9*NkN#W)4v8=LHfWuwRE%1)&=o}H^vVTL_k_`Ky`O8eT`B{r4>X4u-a>}SGsQ+FYvm70ZhRRh0i(zxsif2@L}*b1Vb z;vE3G@x^pav)Tl!!z^D3)$uE)NyZhl1Eti9-xMz~wsMYc?c{td6U3gOrj0?KPe z-lnFjh_y&yM(r{ca;El3vLdIKro}%4r7&(lGMCy&CxiMx?^?SH@JiQjRV0{lgFf&k zM=XjJvqWO?Tkh8*T#5=99S74v-S_a0bQ^~o9oUBt--e#`YnjgutCvDxusm#-8PGM4 zWlb=ee@(f~PO_a=2fh(TJhJd{?sp|T`AMep(YDRfU>nbDHz?7xD_H~2d@d5(NSRr{ z6d~XO5=6RF3~KPT0w@RiP?rYhk_gslEx`-=E+B zsQz2-FI2!+w2m`WX`P?n4R5Fh#wZ$LJ3-h{gAYnA5~8p}V>=`~MI7<}fvhCMseOeW z+6~Q;Hr*L3w0ss@)H;NuM$BYm<|5i6vn*=}+l0Z0eB)B*dsI>sH5kB8KjMe0gw1whJ6=S;fUmod1j$d9FPjfY}DcojjBDYqQ&V>;(flCw`mp3ctntEen-!R;=_j zT|03=^Zsa}a1>*#WQbmy2N83+^4)iY_l2Tz6Xc{qBcHrvaSNB9meUduCyT5LOEm|$ z=yn{Sq$aP{$CYijYv6~FF$pHF4PpY`NCZGa!|wj%YcN)73?_9n=)vp1Zkp0xuFzU45XFtZC1v|#HrtnoHnG*<>e!Gfl9B*tvv3tHbY<1^3(h105QuYN;l>xkr8 z1lMZZ7;@d#fXHvHW1Jc5u52h3!pIQ$Ol3?1!oSLg6{|}FX616d%Q}0$;lwd`NQuIB zP;ak%G64-9q<_Sfz;n~)I#**Mb1$<_L`#_fUZoA?TVg24*9!>V<8Axkj-Of9TbZ~V z$1AcZ$K5;)!CEz{21b4NQgrVlk%Oz4{Z{n=Ao*VwM|k`jHr-5SjXDZ2{k4HA%IX^!>JikL zDc4tP45Q9TJKN(M@om)u>*m14i*F{7;9lH?t=6%dWrKywMXR)nNw(Ci!F19jyOV|r zNct8jl04lvkz|b02WX3aa9`>~Su}KWMkVn41^w;-E z7DUhB)DHhws z6|8xo((cfLLa(Ol(1$U0s@GYR*#Ykw6A$n9Jt@E-NRI)g)tb{Lc&8q``f8Qb6PSB} z&tMg`W7?E%vnJk70;X*4hGdYPdrQo~C;-d>S4y+6j6{}rt0sBDIl6vQ7RwpYm-BE_ zN^p8^1ME#LlY}R-6uha48)+LcpJ0DBs0dCe;NbzQ2kx2tF0G(8Hkv)v1rd+?w>uTk z^n#=d1k%44fqLSZnwW_Fy?R>jY85trpYO-VbU>yPH`yp~_{3e)q;-=A{nAd!iap9K zhV^enaQhn&t4dOGMX5Z`KXwwZpr22(66Z5$Wq10vvEHOIXblNmivEED0_!$qm_+lE zeZExl7F?xnrdd#o+5I!b#u;qiJsQ)AbcElJarm;SDchcy2K8(sb~z9BZs4s{zjp>3 zxMEp#WZs`f5S&V=teL^6m;OXbLQRZ@Nv>;vxbYEgj3psB*} zmk|xW(5)P{;C##3#kNDcUS}LW;u@|0n2xeZ*rfI5Zg(QxV1?iLQgv)H!z-tgGjDhD zt63_n7TBr10S>e}r1~E$XVuHK*ebbaM{*H`)HBExH2_bpK)7tIe)^bEv^f>_J8fVnf~%Uw~A0??RYVT+|rOrV_}?l7dL}wK){%+P z)3!jn=N2O6S1f;aOABQ__xEu4>|i19=*;D|p$KqoY5>)5Ku~Fg`&xD+iy9q^a<2q) zW%k2l>*~?(WwJigYC`g!SD({3|Ihy110Y>0ak1cc3V37fI2N;RSqZ>17A4Qrp5_lI zUq^_F{@kqF2Awe?6e*5v9TT8EZ#C=QQCwLf*5MpbQR21Qg01+!^9qX6V62^QJsfXq zNBrC$ubF0t_IMh+9LzbZmcn)x_yB^MMMPvnNTsSYsP95l87GG{Ttc4z1LITBxt+OE z0FlA<@r?!u{BeZ)7~*MMu1q9^mROcW3SqN!0WjfW+gF^$n1)y-a8l{+umYhg;Yy_0 zSR7U0zbj)gwX>y>)ZtyxgkPW%y}~cgSF*@*G$CwF#3ro9DXX0AWy9<*;*xD41C$MhOk&M788kuv0hJj*qHUi20@9saU_CsF*P zkhM@O!8TT~f{Q82ms>U)OiTLi-B`q<7VEf*O65N$kuD+oiFrmwrQ|Xy>X8aUG=Bhk zvUh>-4kFek?41Pu`iE6HuvDW#cr=I(KdVu`YC1o8k|tOcrAW&Q!z_E6;Y+t)-`yZ) zDd*l+SUKX1#s?)=DW?a1%=usiBgRKl&nkJ-v=rWT1(OCxNjNf)JB!89aq&e@{c&)O zGDhq#0=|4F&8MvMBqw(ld&V`ji;dc9T{o1L_LAucxA=a`YFf0Lp~f%F8(rwTeFRn& zxk4&hR1_biEhe0V*C?x_{96mJtn(cwtR6y|1^tpJfqPJ7WmqfYzRbCPPFH$yHok6Y z0(a@#%6L%YVVud_qiThn+)iN^ZD!PvKZ~lfqGOwvhQmfr37ROu5-xkl%n>Il7aaf> z3heVZOzg;m<%bs%J&Blhm;rPxajCWl*PqB(<`)2wFT?75OA2@Ke_RM-t0`C-f-%Tc za{i_MUg&4(z0*I)Y(GF%RKU}24+|fSTGMD6VG>VMQpuc1Z#0u5b(MSZhhkO)5->jT zEOY%`{9BMfmGMz~!HsrTRk23$D=S9|e(0cKxCvQ-h8M{m)2s*L5_&lwh1fkxSeVyr z1<@&m#-JW00c|=Beyt$+oze7G*KXICdagM{erI*NAoEpToA@mlHnDHIsw5&^Jp3+3 zmNl)}xtDjA*3n()=qQXLWFy3A2sax#(%36f#U_nq;rQs~?i~FEpmf8Prc*#FXZg*e zi@o^QGOHE~V{6{>1F@F*`!;W;h97eM|5VbP%;h$U!ZvYHw6l2~(d{aS0TX>QGNvZ( zyVa6c7#^7<2s}79-tDbDNC{~KFl9Vc)R6|^H}CWpwS;!%((8)y?E^y`$P>0aSstyR ztnay|HP2dK_Xs0~(o?L&REH^G6VCZBCPlj2N_2AJ4tHWF@4h zL|u-YCv_R!T>eQDs}V`L(tRc)RvEgB*jJDK&&IYB^mpyAYyg-4XWkuV)ypP%9qC)3 z1y&Tg_xX@+vP4b6HCb8aZ=(9{|Em8fxZN<NlG_fBHS`sdCp7sdxK3qDl@jmDnpx30wy`z)ovzLKydN`ts639sAugw%Ar z3WCgKir1Z}KP2?oV`kc42rE~*oyCk9*fF0?_GMcuhn8p!9gsKUt!uhd*lV>Xi#t~C zTDU9u2mLgi>#31Fu|IpmT?=St*}eecU3>#^-cp(0-WrAu`jkDAMx_j1k9OYfAOCc! zEWrsZN8V(GI79sL)FL9$SUdCB|I1`l4*(ZD4d5tsT0?~v$YllsQ(pMpV(+@nS?R2Z zc|Rcz=k4|;O8DQMN3`fa`X&m5dp`_#23v|vYgo7Q;`xXdasR{Tb?gL|I$G8`jn@!@ z+_oHBTQYrG+YR?dpz3fTtTua#KsXxxpSQQ4O`o;6u7Qj&WRa`>=O$TZ=`uJbIhx|J z2@!l42dT#)IR<|mZDJjw02Kg=Q9+tQ-Rk~Hw$$HuK@PU}ep+2e4>B9F~)O!a8YTH7~ea+L+fM2oD*T|#rSIh*4 z1R|Zkb2t!ZKfqSebv7cn-Awo9C*v&}pUuwt%Fk6|Qv&@Z8!UIxHmN?E7v1rz?-G^Y z-Wl24=J46OA!6@DEkqlLzjbfd+CXT)vhpwn~X;Ky-=H)PC55XBI_KaND~>yS{0u&ON+ zYr>_$z@kJ~T)d>ILoZT@8wXrRWwS`>wDak3<#S@Hecv~SsM&_y8?am*rRC6CI>8!v zxB^=#Z{5l!>cTs3rNlEzfK6~dwYgafzVrZ>C~s8zVC5A!xiUpmYTzm13|$Eb4@l2E zv(`)sYbjw3&h&fnE*lcb&^!mC*$D`k>zA(Sf|^o?{&MF1-%$my<~mDVXZ5n=;Wjuk zA}E-IBCBk!RbF)@x$kYi&g%3IyCyPvt=+9alCrHx=%Ls+{+E9cY9h{vXqq}-@E?Ph zEB2PqPVy#KA-8p(7-<_C3SiSnJWK3#S0I>4zD`O&oa;plB(2GOED@&;Goe_!{a^yP z&b_J1srS{2jk>$^#&5yizZKGhBW>`@fCUtFNG2m$3vt{A8HDIPL+vTG^ZAKwZeh8()H=j{Nu#H zp+8kZ=qSXw-p^QDzXu^g6pRBux~T<3Vt{uwAj1kS{`Y1J@Et{b9^6#9R8@`0{zwpCpU*E)-$2@tBQjjqc5 ztwj1k3EB@QicQ-8!+7Ze7hN;swX{5!$@|8nEJ0)RK$Ax2tgwI+3*5lB%j<}%9M;5g zRmT$j?=_8I;WF-Hy>0SOBV^zo2&zr?82QM-Rv1l`)-#avb7o>w1VZ9pj4eCz{u3AC z$Fw=|Mppn4`NCgd*D$cEJ@+S#{vIlM5Cj!)E|Oi=bEv{9?mez9t`cI^mMeDEJOj2S zdh$3>3-L=5){XZoD;ZSj$0N}%E#+C>s2)>?xxttwvti<(n5)wEL9iBo z$0jXRWGO-VZUzC@b;oXPC*cF7Xd|JjIVjRiL6s0Io-e5x*Z)=If{h!f@N8#>vs66e zZN@KB2cduBrAM9R0r|xulL3o^N1LmS(vGqGkyLe8BOb~~0HK{T90Ovkzq;K4=d-2c zg8@#ZSlCe)XA*~An6#^gp@o}K(V!4%Iqt@44Kx*^8ifj8vUuB3jX!-Gk|X-&NTqEJ z!}E2nkH5}#K&k*sK(xR5X_*1V`s{_A^ZoGm+!u+-ucsd%)`18$vRa+Gt#%UD(Tk7k z6GoVew|HE7oPwbRfVZ2{1=M0>q-cCT0gg7A@qxo4aylIg{iIuNNr~$usXyo$YR~{% z?giWg0!BB>ig?rNP6A!nv)TJ%3Cshf{obdB+bh68`vTT$AIA!H79I&)B=+((CV4tcq;^b&+|O)&p&#uggsUY zFzrH3k>#3qo^~L8wKC0FT3kH2k#N&6o8|+Yz!4gCkV@J1#ijd2R+c!=$K=x1&@fi+8p0zXAZbfYB~l3m2XcihFx0}3xO}V8SZ$H zqywS)NzIO^xN0iu8(W|*cHaUdy&j7`50zibV93^Vh2@{)&@PqCr4@^zVUz-SF22Qy z8jZquLX~(HjU^NM6~TrX(sAiv^;| z&;YfN_Mgs{lrabmK{tnSlhr=Xxm9&v0!aUEk_%tm9dz-W9u9x@tHb1p?ck{ebDGRn zMiMBQlbAfiS?sS$=Ur*&lkxy3!af^K>Zc4`SI3=AbM>&;Z4atXBKtf}8P6AkDdjEG z{+$@Jw(I*i1oGn%N?>}Kk99qp%A@`;(;*trk3>B?35we}MTm=n2yYX4dtEhbIv?x~ z9VmHz`w+LJ=9kt#mkou*XlS@dCCeL0W&a@Y%qzD8X$~mc%@9I0*MzRcjqfG|>|uh+ zePYO>l?{WkN;npsU|a)FwyUSgL$uj&VyuM%(*o2oR+@Wx$(p90m@%6)pM_WWnjz8*0fa6j134C2 z?l7X6r`yC=GAhcAhO!H(NT;y?WlnVnT#m zzA1KIX6zD71p{Y~lZ-qaWOubf^q|P!UNM3SxJUm4SyL)$raK33i2Rt(niuqNV_4Bd z_D;KV{&pF1#I!!3$c7T=Fii;WfTRBFLY`ruJV6l6z+!UVN`p2ist5%({wv9dcBJR# z38B3TvlNn6ij=?EPKrr+R}D;%(W=3K@5!$JSiECXGgSa)cfn3M2FXdt%Q91{^Eo_Q z#%>~iiz{5O*+VcW{~KnHZMb#a>!LH$Wktlv$JXBf+K#uV{Cy|!{H+8XbjUd!Lp3;m z)=yWNL7t<6VKk$|&M%e@W(ntGjH3g`Wa6dsjkJ`;V&rJ6jJ%k=2I`jc?+l->c(P#* zmU2yIb(=2Io#dNpDp4H|2~aXT+JLQi$X3Y>InpD3A5D+13vkU9!Pe2 zQQ2K##I*vb+^O}BBBI=+6=6dgB%j~-!y7-1hbJfu$<&Cb_N?E|Aj0k+l&zOW#1DC` zD7&dY@t4g_YK34E$Yr!&wfPd9x@(iegWl2FLhv$Tm_mde^RF#+SGMNLw`9?Y7&H=5 zIm?9V=tB=SRl_xeLAz$k0IpMHXyJh@d4&e*N??=L^j~KiD7ag=Y&iXL6aPpIpe>dv zo;o6G>7p?BU+D~j;ZnUNc{X6MihLkz zwh|iWyS|7)Gn)ZPy;Ue}dlZ(jS^htVL%{Aua&X=Dl&hxv-xD71{U4{9$3+fPr4+0$ z`5I4Rv#^k_s;L9NKdba62alnDtVR314MtGlyX;GV4uQW@F`k=tS3zPX)s_=GAqBZqOFxCg`RwR|X)j^la{CgPsKVXiBR zCfK<3;|unb#H+*Z;?&^Jo+e032}8Ii3!rJ_r*Jxv?+8oQ#*}3_idKo{k&z9lBGPyN z6z)r+Fn0%eYox*Rv(!Us{V(v#drfB91yLpqG<-HxSDw37=W}qgDA3qfzml&fpGsUY zIT6@BQy5Cf@jsC&!9F8p)5gHnPa)hpKsyfDS*OYZxT9a@S)H zrOW`})BT8X3qLo!=AN|1nSB1(lBj1$uf@Du_5bEz-&q=t{;LE;-j$swn&$8l;fV8J zVA&Scu*!8rrIvzF*5T#kmL$hYd`{J%x2f}7)%znQBh;xd96q7t9mPbjw6ykuQuiQe za3Q6q9})3A4Mk;Bb83N|Ud>ncwk;Cja2bc;>A0^)tlvQQMj1mAm_lLUkQn_f0ZY?1 zMo__HMHn9#^;DJB0I9~`*e2X)u~&zc9SZ9-!XLOCBe)0TRz&T0C81^+9Y64%;SgRm zu><9jzKgCOf?2?j4KY3g$Ri*FI+jb6n&f$?dh(b`yq76#tQc5;N#Q6|#fv~rc;n`s zsCE17riLD<4%U#%amgHZRg&`wSR~zKB4Xd9X!cve{AR`-H8I8dYpC>NEX(_eFZ-wK zoZi6ye>^43A=ss%fsxB^o+MPrI9>(>U30L`feL>jq%s?=-Q>s}GXj9#z!-Gj?HUq^ z+Ar!h@>$KK!@zfEZqasjzrAzJ>CZ^@9n3i9%ce5b0?Gtq7u&qqpUvknjn&rLx%8QE zUaYDN;U;z}b-)CYGsiRHihq4sT`?p7OlT&L;JlkGkCJ;1QNKUQ=zg*ya|$_~HIzF- z@#;<^etD#im%9?0s(-M#x82WCnEB*Y%@Il8FFRU{{xGeqx2QGCEM#j29}CHE%yxSUCrd@Zcy2PSCztPDe5^*2xP zYb_@f0!#iinbaND^@k#t`Fdg2S9bu{*XE^f9~bh*WOS;%3*3Wp7Ce*kK~;1usXn7& zwmU0)QzLg1KH1WON@5nyYn+PqEXalfPpp>8FwN@LU1f5weL3n=(Om&2)c=E}U^~t` zQt<}8^$d~AV&uv{BPg;w+3dOI{U0*p;cv$@!M>q%bJ{~m-4XtHNCQ$sA{JPgoIoUi z-!CGm5-u)~4hFHgYnL&aIYh&#_Q2RjQuw%;+BjOXz{QUY7RjWs9R7nI4l^g{d4-BR zV;b-cf*_(-FJM)nO*M=43w5TnG>%@rV!Vu}GHiIc7U^_ZTG!BPZ0p=p1-;$}Eg5ol zwy}ZB=#NsWwRPS22)gM8iwcXPGi@-t#Q zCxF-Fu}0cb62Hf`v=MHevKLaS4TGm_QUn2`i+05qeZm2{27wLhq#KY$erV_{u5-7* zialCzhG|}EZUXe+jK0*mFNAgchcA{R;D;whI_%hOZH%Y&S1NA@Pi$5+l#`UL)~JX@ zX?@_ml8m&=U$COuv4Hi$n#W<5D9~WbVyIl&cF=rUiM%Fge|Vu({zzTJoxSmHpZRiH zLQuCxpuh^A@6MOfkPU+O%4M954$c49(YjnUTySgVutzZYFJ$!tot8}PkFd%V1#h(< zs8P%WlpNE^{}Qxj27HomON8@ev3_Spk{hwaERll@-3O6L_jJ1DvAvyQZEO$u-z)bD zScR}2Xut5U5S^WCvL)wP2UDMqa zyXtdr*cu`xGO^LqS0_QB(9?N>z8O{Px_bP&(B8*p!Vn(mSxOt4MrZvEdbe%$YVNto zK?ps!s7m)hZ4qHHYXUB-cT`t+l_Gr@vrhVf+9E>dhQA7TKYq!m zFy8&DRX}T)>yGqqF|kRR>7c1HnYIB2u&xg&##Og~XHO-(W#q&0)<33z-}1W=CcZ?M zdOc)}dn4K}h@I=Akb%ViEvo3hAs7wu77HF)$oDm5OROv=NeVD)``KWwjlr-EB-{;6 zp#O`-nmQKbg}SOLx;nV6#|xORO*N?%>L8J+y*kR65NLb(K9CR|b|} zhF3+mqDSM3UQE`IAC0<5ngj%Yn*aSgWrp7o;ody(1@T~oGsX9(zSqdJr z!P5PtK9`Oo!JgO{&N}VmPhd=lm3X+bf+*V=@E=I0rl0aZgOX+Pcs-E9)aJ}XWSYvP z3;|gJZF`2C{5gr?r4u$i4o>|x%}*mP=vfg`iGwh28sN=ZKyEzFwcMH$q zl!4dE*u2I)s$ry9_!qw+n=h5T)mE}{CN59voledx{S{EVA^K)XdTUVbBMCVoS4
TcHSkp`yqs;?c_uFbX4Cr>~4EzMGb3l{C*!11#Qd3j0aB394_*iB9vJsC=Dn)n_9 z8JeUWY&eD0h`?E`It;P8Obv6&8!>9uMdLzJrUgH0r8ZZm8(2pNR-2zcAJ^5{`^(@O z?x4vbSJs3j_2R4MwIY{29$oxoKHI%w>5Zku-aPqpr`fRG6H^m>_`1or_hJTqFA~Sl zeN|zx4GV|r(PBsMVW*7Swx-!s4jWi$7aM(SX#$w8_}$q;o=pvtwXeq}xRR-65;#K8 z3hgaN1PspQcx35{o_7)8{Z>C#uN-2_}TKDz_Jb&4JeAR~6=ROxtQN^y#4NFD3`IJ2+x zL5jeF0e)fWf4%hXS$~xgFPRbH8k~v6U!grv-=k~Jx2n0&SUfS$7}|XN=xw!nyemyC z_JCuq#KNyZ5~9#O&VJ8a6T}4{s1L?wgvOWQ-Vy@*+HoLa<%)aZi~R0V$dk_NffW&u zx`(u(-+o01;CPZdGE2uH>bmHX)==!Hh{54;ih4+nfKn!E;RrBX^1?C>{`7ZZ5r2K7 z&X%9C0Z8ND8QZokc}`wMM_N!!!05WAf6h1MK}+{ zgJgi)!WPuV{>Pj+l4|zPg*O~F_!aj$Mjv4a}Ia8|R{$CuOwX;lDITf<_O z7jm8vOK=o?RVdNoH!d^`R#5#-dFF_u7Pk-9OWt{~WE(^3IdGNoo50|LTa`TME>{n2SC3_P#h zIrKRPab)GR@sJFtqFQ3x!urvY3ku|DQFQ8?HPd`FH8JgZh;&dgpij_FssIy+>nzU5 zELPpLH@C*44;Q+V>}HO?8|XE`ZZ^GNf!izYJbgY(^kh?w0nbC=(Im7(6spGoKU6JBr{{Z}@b zs&^?zS<2xl6cw8wXV5&ZL9~g;;R`w(K`66X6`1NXd0Q)K3ONb((B}ZomAr+XOQk&< z@Ck8&c=O*{uLAb_ixbg!MSIS4@~?@%H`dU5FJpC=m)RUb{OdDQQOn)$7F=DPfSAPX znNx7ReOaSzE}dtv;wLe+W-+_*5h{Mkvv;xBH%aLYnzosN29a@7kuxUiSE)7hq^&DO z1ZlCm*|~z10>BRh`$Pxzg8Q*!VN{OHgR&lh()S-UV)BYFus{DpOXW31X366{kT(#`=nXmit8iRfyFs_=a zVm4rM;L{3LUX{7i<8={AaetK?$blPXFhB@w%QdbSRvL&2o2a0R+JFXo%n1K+p%K)_ zy5ow{-%{g%9=HM|j9Jy4?O@lk0wT?SwyGy$-C*Bt@~ez~xy~&EYaKfs)Ak-S-5w9_D|G z9~ef=+U>jbq2l?(;D3$;;xjaS!G=hOk6=&d8DIM>ukUus(S8m)m@B?;4()=G42Otb zXqM@)2mtvGh`0GztvqfS^jbq7!MHxbYpphOl0dUOp;MzOr&gT#|HZY84zTwxyVqi& z(QkK0%5r&AcLyFv&$`~!gQ{K|k@qHtl=!$DtQk`Qoz%4Y->aw-hH(4XaFO*2eBXEr z%uU2>5yuMDNQQ^7l_1a4^W3mxX`*u7AtE=qJ#0Ye+MuCVL;K9naVBll4U{T)EUBcFUGOKd%s z~nJtVJC?lO*WZ6Kq>cp6*8+ zs(iE?c9QYzCQ&0s0&g=${nX3nI+7yjMp59}yZor9V?llH+G;BW*h9Hu@U8uTJzxLhu?#sZwv@jjM2~`1 z#svFDb4OFgNEHc?Batz*l&~4=uQbsfR$n^3-D%OLBmqDRT)OXt9|S-Z3ZZc)QFnwG z6BS`bd(QA=^ho={AQQ#LY-?(P?olW7$zpmB=D=4$m-##DG5PgFTVaZyvE;g6?vcwp zaC+7}xxHG^qv0(s{b6L>w-t_usR`+kF|6BC0;vN;uHo8ZaW~$uu=H1yo9~Ics3DVJ z60OSzTmROtP!RzH(w;;i4B`QqF>RI#6*Zd>x1478Ff#Incp`>=Sjc9zb-QkI{IiuaTKFQR6y16~D)4QcFpg>u z*{z-;i+p-6Ed%mh#8ljepKzoR>h*&dY=!;oD}=D=e$T`YEs90GbAx*wBxG8`A>m>5;Ax4;TTahyhfCN3^&G#)1$PkxM6)U2voa#QYPxw|Smt=2{u?H9)CX;LX zxYX6C1EqrEnAC#FgFZb2I*L1)M{RJD7+a=7LT<1KIGXRF{lsL9?t%P9M?)yu?u0x{ z5EBjnq=&)Phw-YeC>Ge=&Q%|6aPLqaw1P4d;Y&shmJsB`)=yL_B1ZmX z#)_vM=0}4GDAd5@N&z+@gQ>mSIIID2P1Lh{NXX6jee3UsxoCiEDXzktv5_0a``7VtH)`gMzz)ERV zQZ|m3`!TgM=9S&?H(c1=kIH}Sj;@$GnI)uEZVtIh@CK@C;ZI=jray0)WY_P`kty$tnsum;h`_Fn&SX)w zUwg3oMK9K&%@;};6+>%WM(c^f?w$D7_!+)YFgudo_$QeIT^+5-ea*-q4$;@_Gg4EK z6gaNMPc|qXQ#BVu$?T546cnA;W;>5-&^JQ6LQsAXIsM9R*v&f|{`!Ov9AlKT=o!8* z9+d*e3wxRcw%f0V_bf_N-yvgG*h_I)=pna|QN^MO-ha1`i+oaz7rz%3oI=##G=V4K zYWBzVH9;;+>R^Xek@NWeX!U4}RfcF1=!nvgMjZweULL#K)#y_E)1h~9sw{KPGXcf` zQ;9=H(>5MuhYuJ*I%_vUEEZwV??<&=5}Fe9AgV;c-jpQb+a_w_Sn+~UbVlK6P=sO( z_Zmh>bt%}r{bDez0lgee3GL|70$s}7C z?=vDMCBV0Ab%hfCRn~i~q^5`Lf_>3tLu6E9HI`1JV22jdX&XRszb{3ZdC<0@ig5xA znEgBVNxhp=e59e;vo1ogUu)@BLelQOXR?5KiOuwnT$C3osT;3@C@KFmqF{DMnlcTo zksd32uAH*+?RYzsPOcQ{KJoKIS9ur6NWcxHMZddBk%MvSRx7VtT~6JFBop1Et0YRL z-)$I`Pa+Y=4n-vVIU2v3c?fP_sY2 zt$R^eV^1U=?e)+4pUv#G(zc93b};LQ%34XB`Bo*mKit3NvPKdDEwk};vmDr@jGgYu zMG8|f+dzK%DXw_%Spky^V|_N|7ybPq#P<6K-xkmmyCv_Ua?elfNgC`@D2%MZla-@$ z#%4EM3k%VA&~8CG_eK*ObEfwTiZpdLo7w1wAm-qvh?C+T%Ox&IwL6Us(+%WJLWEK`N%!^u~zDN38X0nK&z!qr3y zpEa7V6PuFFstHhSA!T{p=;o@^$Y^);S(M1`vP9|~Tu=mmz-$(q*daE-mID9h+@aKU zUfioeCG47bHy>aufmL!pwiX_4<*QNPUh)uf@F>T~M40igt$w793i$mA#h*=ajoq*F zAsq0O@E>r{kQL^;sF#m!d?y6tPdlm$^-M!nE`F}d78bgn$myubq(IU;K;Vzp?tWFL z9p5)+c?)$fFEqEloFd?^yQ~P5AmvgY(-R0natR|>6Qu{;qc42fZR_Ek|3*S{K)&Eqp3#*Y`S)aSI@Yy^^F zPgl2=3J@m&d)na3ht6^|LTAC;5m-0}h|ow9q%~ zKFmzavD$?zR+uzaWaWEL{@n&lhy>jAE4Q@)FeHPHA&BR@+DIDlg4#u^Hc!x_!^YAB z3qM8UOtMgEw$3MwwZ809mR+S?No7D_51 z^{skGc&d7oaEHLDO)`$7`UTXPK~9hR!5^Yp_!`s_nAHlA(-j|X*T4{c7TMz}*U{OI zyxSLXqhXZx6!#5wgJ<&m>im!l)w&EhxHq9dQ_jqY! z$KP+Qcg54-3yz6KTSMQj06~jcm!;LJ5!9jc?dO_Jb@F=E8%$^EM8Txa01UVJ*!t-> zDWfE*FzH{GO>P-c$HxEH(37pP@#hhWlAs<7gr&+rLG^irqCo`fxbL=MkA`HF5Ew1) zZ+DiA7h}UHvJHGkG7#=U`bU6}8zIG5uW!33HU_5EL#%z0-M(c0B;AK9_4twuE|4V?ctZ3fJ&680< zVSHNBM25^Bk&n3}T$pRrU>W zG1)K~Y8-wB(eL%jHphh?Xx3%B7`vegY!+JhKMcm@DFl!EzVaJ(oH9lYZ7pN; z(lt}`Bx0R=cfZ*Z%le+nZ&C#_4|ZAsLpgvE?|4;9S^;9Y6%J4NHr=cP9OO#@!hb3Wd46JLq0O%&$|^J@eKrq zz!?0`094X?N?j}7HVv@ECou79!Be>)R(<84Vj|2iUpV)+5#$EZmzlQ%LMC zHGabX0L%4MF<<@`#2xtrksUR_{|{`6NFm8rvA<&K8|bbK4rV9@=u=8UP&C^17PJ9h z0CydLUzXy0aOE%6pDiK>?r%$RbP90J`|I->QD(XQO8z0`h>rYRxu^(|g zq|PEWT#iOW7=PxXKaV(S<515<8Z4@V146)!LAkwtOotP-@5{_o6b8tr<) zbHU?Ei+|$EU$XgT&3sp{)&l{f1KRgT0;7XACH+(LMQN2AA$+*;(ki?t@-N0({Eq~Hb@c}5RqWy)y_oF6HI8POr zqCV#6!gP#uyy5oc(>}mNR8ix;{+*tlEjj}y@E;xNYvqJ|* z4})ilt_jx3WjNqf9vw#krW?)V-jd03Zx!=Lr26~H?E4Wfbn_{KXR>eqAdjJ7Q6O7; z8Iu^6j=ypa*`!{S1@C)4iK~3s9D+uV&dRt2>WGS;3$0Wc9#H?*hx>phYe1mpuY^T1#M+z#Bls?0C-&l zaNoWxE`n}(a-e_1(;QE47Z!Z;M)mL4*u23~l24aRufhWdUqXV2M z)v6#OmvL`HyYx42hCM|uXbv3|CoA|>0{2^KoOiHtM;%~6yjOe52B|!eR1x;Lr#BS} zBixaU1b%!(IHiG@AQUN7@WuLykaOTZQlTj}4jqDA%kHcCl~psW`p4Aaz0#r3v$?MM zd)1nayltn*wo~%Soy5e-T+zoS;Y~#F%Xml>q;YHGa@kpwQXtHz&Ef>BcIhw=!Bw1g zz9gM5Q-m>>PEN%2ep5Mb*uljJ44Htt7`Rmb>lCXIIV&4>?wmic1>;wl%~Aa$KIn*r z4|*#TSAZ8p7#8UT=1;^P1VBk~G?+=4?*KqQ*pI|;QsKbgWAIzPs4}Gcxkp-*o-z1? z@bTOvo4uI)=AW~8=0`j0??%hAHI^9WMYo=HUYv>;jJYZfvi_i~*4oge@A_P&J5Y1; zv)-Yn01RS%L60lEK@39j*MK~v;7m7a96aTxP)3tryAc`y0Y_&%7)g6t-$~Nwzdig? zVja7%iBwc|mnHB<2@vvLqDS4O2>}I@#~K zJDCp5kZ`-_@RsG3jp8{6 z<$%toAO1Qyf)w5wF*e$X0j6)IKB!uwzDF`a2{prN!((ODANO)BF|?T38Nrl(i&XQ0 zU9t#yIQY=TulXrMhYpk?TNxEgUigj58q3LI*WLjnwuyVU;|U^%^poPMmqEw`hzqj? z>;KT)#(cfMU`Uk2<5(A>E^?vDiI!laGAlWTlN77#bVLf@)Wr?{b|-hS29Ir$0+dam|5lQC(K=^&7>+M&TDA=cMio!|4qMgI zvJs=+CUc`XbR$F*Z?-lYSY^HFM4ORXpOv@r*@1rd^ttMr_ct#gpP6sqs0LD6Mrb_1 z(d|!=W{Fvs_Du=sQgWM`o~ zD#!NM)%oqLJ{_Y>UQKpS(zD_?Vk11uIP!_0kSsk;z{y)l8Yha$s7-D`#?DE$)kXOI zd8;rZTcs}+l|yDqY-_4$)blyBGz*dkRY#7?A0%Sj43+c0Fx!>gaPS$+NN-LD=?KZy zJDm3*_sr_Z(i~6zy=0CMLqYyPwjo7L!*$QoB=`kzr)$%u(l6*J6go7{~k+ zG!OWYK~%&Im!Cw#S>Zt~q;OCpzmIb-a0H`dRX$7+e5V9l>teMNrR*Rw$@Zl64%wZE zH(5odKMu!k1h%jK*Q1BNDkV97d1Pax)Kx~IssTxhia^i!9AEHJ>zq?zw0W|+SKEp> zxX{$wCe2<*NGU4wB=nw^Z5y!;fbSa>O31>|Ub$>I{@sTolcDywRvtbg4&S;Kl#iA(I0V$j##vAzYAz?q}0P$JoL*e!dOMce}7UEgM$ zie3-L(Er2hO*<$-sLXH`3>N zkz50)#c|)huLE$UZx7f6Cta0Xrvhy+7Z$p*bya{Dvw=Hj>Y0=}Hgfx-5W+yEocP>t`FlO!L z8=!T{&NPHAT(@MB{83JsH_da`nofPGR~D&Cqti5#(67ecY*zkFeUgf3Tf4zay-&~* z^@H;8P#loYrXS9xW>>=-Z&BdiRUBAR7b0FLMWtAYD;S*7ef8r>7g90UU#wKjew%ab z^pAuF0JSk-uJB;6qhu33K}#wQRHQwn?$TN{x%(KLz^0epkuO4hU4ER~ue+fp4pln_ zm^YFAs&^KkQc%r9%5Oppw90IUoec#_qDldy}pr9hefDx&e1NDjoFV`WPs1%4sjQ25 z!G~sFp&pvUYqfMA6*R>wa;h3RO9P5MD9OO;@sonDx2~%4;b|{m`RgqUd)VMRW{3~C zsmI?B=9LdskuXZ@8&WA3dGx@7Lk*4V6!6g7by`;K@>`%h(FsI1jZk~h zI9in|L<&XR8H+P|AFW=Qt;UOnAylyAOGHzu0L#G)xcT>AAQ{mMY`v7H@fNC?<56Mb zSRIYxeuySA`%;|okG*bih+8Se5-$eM*Mt8hA4xIh`AAu46f9Iz;PDvS-uNjj1L z!J|G|nw0(svjDL5L7j@ynKnY}1g zY9mpWtr^Wslo3icD6KwOOLo|B2hDdS^+92J0J7w_E!$t?ri6n3kWFC%3IHx!4Greq z=#dM4@=D%LbJqWzpcHbbE(?kKYE>;JVu^!|=BA~Yu!SAX3;OL?WjV>;^qwVbW|){$ zpRcH}LL1APv_y9pCMy*~RfF(Ynt#}lp(~0AO<|gqKjY^xF5dl(=~d;GN&Rb_kSi95 z;wb&=fuHFgcTGi9=Tq1Il1sPiY9p^x26N3Ot`x~92(|L@eld(hFu~)m{k2=YZ@6xO zd@q-|GKSOee1s=tW$rvhF)@QjD#cNs%@4xdjL8vTF3pc%68IIlQ6tGPj7!*CVMaCJ z(#<3aYYfL3I30d1V%T!7sO56j`~E{1yd!uon&|$|0wuEK&H}_^BG5?F?&e&Mjqgi6 zprXn_BI6l!(ZF30n>ph_WU|)PuHvG^)$^1$$3TB&MUby}v^uio)Dm9c-AD=nU0tLm zjYwhyHWNV8NP>MqDejKsZc3G2&l5sw{UyTm0d+e>6D`K9v*jO>8dwtY2OjB zwMe5afo*&RFcipFTGIZUoY%zIWA}$fZ%@E}Eh;@X$V*B=yL;HS9d`jIHQP_f6Yi=J zc?D=A^#(HZfY$%`j3XPti%>-bTbRwjO zqhV+VZ(5Myi`+FvPgF4Rl|YxNlsLJ6uOUPG-|2j+pASZfCCVf{?<)Ey$TCF0cEdO= zrWlhMRyV+9ed@G8ZWuvA6Q;*JKPxx-8WEhVE(Oow@McTT1RHx6)L(|nf#j(YRZ^n}{;lnloFGM%n+qc7Rx zrnfNGF@uEaJTIcR^ zg#&n*(%ioV5wL@Lm~{-;~ngb%=Ia1>vq)hq@Fk(SfQ z2-B~)ln7?mR&=N(jiKm23V)I*xn1qmK>>&p>Pr17V0U=l9)?jC;45H5QL>_{{5>Ki z2e4Nn(~x0smdc#1jmc~@FyTf4AI9MnI z6aMAlB;ar;UOuP-?<7rrIFgROuTisI|{=skCeD?+#V$777>grhh zWb)E$Mo)xS>KRmrWawUtrac$^pL3h5JK#{6!Bd2JA;^pPzh%K%VMbQ` z2u|-`BeJHoX>;j?_s~SvISiv4hv<84;fMxvAyxdvvyp9)yrZrxnI$JmR31bSz8t(` zjJ}*u#C(Q0_=8<-kzfIE`IARHf0Ajs)+obPqw|E!TegHzT)s2X(u^<%Z;EDY3I95- z+zPKL1y1zQa&WMN0;9~=ZKeAEmOm&44?(+cTZG^bdpWV7)lLX)CwEbIQ6dH{mU-hwiGf_mXLF721xQEvMSpttrg4KUGQ~X_*Krq^UBHZ^ zC-1px3F0yoO4`%q%L7QZBP@LTtkAdHFzz|7c5>tXzR*$S%%Q*i9h*OpP9Lp%(Sf%a zLdgRiRS*gQp~rAr6HIFJ11>2wMn4Y~^L0}MDiiO!t9ZLJxoe0+(CB!EO_q=<-zRDu zoUDG$R)|JMrS!EpzOO4|C;_UQgGCWHu+Bf>l%vh z``>tK3+j?+jg%lO$U*#jvV$bhqZQ0eAn2bPSwaA1KYGiL%Be$*)29F)q$EA@6+6T*ULuGNd_-ZsBswdz-ch7s5)n$AByr0i8zf(?B4ZDi zKs6Q?7EO)ztV0i(O&4J=@49}J22?2mxLqhLr)&#ZaqIcWWZ7zDKS)9q0PF0IxG&Fg zFo6eneR!#G;qV2OPe_lKlW|sJa&tK#9q$bc$=< z+`}sBlE;0t_$FJtFo0yr*VPZrlTt0}FDAWVcF1h~q^C%Nbmq134Lol_R=M-20TE}A zXAgsrMQ~OPjEJGGHyNF%^JiBAF9#0r{>ICBtxFOHix==9?R*x09B}#wTjCs#;T`Rq z$!%75?G_wjofFIav!Iw}hTNR7Sbx0EmWJtk+QN#@zo&k-K44o+`I6NYUa`6_hGv(u zEw&qtPk_uSvPFo`36pJImI+%E8}Z`#=pjG@PA!T{R8r7rzXe|GfZwOmy4Y*jA!{vt zfF}%SJy_iXaVS1b#RDsUCJPFjH)zJ%Jd~l;b|Ox6-|^2pA)fZy+*9JLNi^$m+CZ!> z0NFTZJVSJH=uJk>*6PrntR=@g-j*^>+wG(NgR(as2K7}Nq|-xJ>}@iLOH>g4b=iMQ zkJ{AV?1BoShT6$hQsfpi;LTdLH*#+Sb9g3!NHBHs9)!5LD;n@&t(Z(zn-gKpe(a>Z zNldezzn^VJ^dsV09K~r1`+~#7Mzi{3;Z4O{q;=C^ym0OVQg;LVu4s~0(_dMPZT%stTdN$!*G!bvsP2uoIv8Xu9r?y_A(|QH?`I&p^VX`B{)ocXSfh% z$h1ya+Eb%WUR`x_gcBR;pD;+nD=f}dAEM${zV7oDiAZ!k+qR=V!YT*)WvxjCx??O1 zmt$Ss7k#>1e~rUF2f#qE-6OncB{C5tPaHSWmJ0C$;hPUb25s7Jp46+&$g%=)Gl7M) zd^APr$%)ChTjEzhAy)%I`7M>U(u_a{EJp2~``OqcGbb%^%ws|txo)dH@pY}TjMKbs zPBqf_E1f1K``Rl89Rx_aQ;(_J38yp1m~=d|puVG5;o1bV3z{Nl5Bu{jw+r+G#Tlc7 zGnU2X8j8pZnG;pz;V6ZXJ+cc|n%!kI2L8^JX(Jr;9JC8%85p>HY2}xp8<0^di3f6U!$%1fD*_Rq1UpI1{N=Dotud z-u|xO(J)mMJDrI^fS+3+jL-xhv&jtF=y*K+2U=T*4n0JPJgx2fvQVea-~6gXVz1&N zBeL5giXHAWfU^yjfw_UtIwNvl#(vfV;lG?2u_I8{?@+K#6_r*LazN55+Apau!!k3! zi?v5VF22#`OJ)M8I!3w@Zv1Na{vY+*G6UPrPW5x~vJHM6rREhij9>smK)k@XLk25|M={XJ!qykV)m`F>znrAeVs~+@`1X*|!Ed(zbO#4dOH&Mq-Ws1Qn@j z1BzVk;DwHWOkvS)YEE;L{HGLZQ6PsSmO#3CawA{@ zIm+cZGLV-|7}w7M_*hIfj6i?|=;{@q2`z_K)2Kct2iFKs_rcXmj6%k9 zK^BL`t;S6mw&8=>HKDZAX)68IhtGguIy9iSX)!$NFeW zpWJeTES0+Hf`;UA7C_{C6z%MWR+^x=u9k7Nk9@9U6Jl63bv z|DX3(w3!mNYPop^5i&Gbr?*~8;?98-p(jUci0s@%sy7Ay+Nkf`a6@DtFaFWVjQ`}` zO%4E=An%^ft?t{GuN}&X*aFM(sl~=lsKs0yZRBo!!FqyG(#dXVS~trRrG((y^kT_a zS}7bL98ze^064toE?$5qe|acpg9|7VF22icMKbGcpdRuN^dXDb`+N(*&5~2P^QZC! zt8m=I$#EQD(6CqgV&zGL+K_bPSBJ7Kk0H8~t7H}bx_T*_>`dQJ4c3vOdK`4eUjC?F z`e5_pPn|q|btj}L zM%5UNH6V&`thJ!MAT6UukY|T{DHI`g{w#=txqMpuf7ToNSpVnbnm_; zHD8g!WTgQ(0&22ev9A%xM?M2~D-ZKgjG}g=jpi!U?Nh;cs5xV{3pkJ0oFQ-A6;J$K zX(FK5D+AEc`*zmyY&9;Ao!QDIcHS!Bxh_=eEO-}6Nz*oaM6~V4CM)#JQ-P@^q^4#D zHqDCcVoG~87M{}IJuF1xy95@{yANbbFabvMGeT+(xCS}Ho}PP=G1&#om{;1@BV{4wREnK+%O1MO&V$YoNB#F-EOqy!)3&2L>CbCv=h zzNH>ZzPMKjUm)OH^APjqWTtI406KVr;!52Zj~_Odxs&&BgBH-)E-{7?klBA;^s5c$ z#T(u+!R+Ck*|L1SZ2+FSt>9ufM%HB*emmRp{3;BzEpp>}#mMlv-U?S}5{Ndz0YX5H z4#*5)PCUShXcY?;y>C~kWRu~6Eb$@e8$Y-MV%IWoKu*o#>_jNZU{?@Bfn6_9r{*rn z*}e?m8QzF8w5R0Z zT`Mx!wZDw)s1&q#A2ehaT%1on9tyI~%8t6Ly!a~h>4oBEqqFRCo~R+!>sgBotG`_z>?Uq7b2D6P8qIv8QyF_igdtWiv` zwZXvn`J@*L+E6}}3NYhGmD%pM*tWUQ6ntW|-!3wCAd;xDGX{Z3M4Ly3#8e1Qm9W zVK+!GY{N*iZBAT7(@wRH-!x0Gq}aNzzVFzmV`Xs(gG}Kp#=gXi8^96*meyrMu>Zs2M zaD3Wy2yD(&fl@7xY?nj9X}yS$-KG!Anyv$1(5mJRq}V5fVPurhevV}NwDpE?Eagkd zGU=9H4m0hpGGOEIb8IV-{Gr2v=RnP$smYsAS_PLOcZpCKCrRQ5DYt`5UF~hCgd_t4 zCO9VYxp4k!?qQ>E4Lbe&-t&Ee6X3-7fqFEh&;h`JT&(ax;WtapC?o zTeJ@XbQm(w8vhUjnJouxYS}R6ig_jq2L$ERt@t_^KUKn$VvsnpOo!@ zG6WTcB5`Zb2NE$^p&ie*nkgKw&OkdOSENMVM9DRobCowhnA75mTu@+q3wmLiX)AfL zzr@e=JH)6y8dU9o4^I|%DSkGNMagPXiIMA!TStGHXtte_jNz!)d4b!9F_x>uHhe3O zi-|{?)&C=3Mj1lIS^Ze-Kuz~1GmQ^`(1!yMGT|X>Hyubp!?Redj>#a=xQj==qof7q z<}L5in)S%|KGi{ryMns@bJF)6UcYEFVv#4-(-o%?(54h_Dwp!bU0~5tvgoP z5g9kD>yHIgUjFb9hkE$-$_dcry%k0!`3^)4wyMhdO5WVl`0KUF46Uxtcrq|d4tn^& zXA1ZUR%Nsq^@Rr8I9}YBr91L&3;Gxn$Z4ydbK&}qWyRpEtnL1tX4R5O%nD>RiF~5f zlt8i~l=bSC*`ZG)Dd$ zYKual^rlnvBVn;Aa=y1pBEN?=xi^xoHZN>b*k+X%X9RU2e8(th{D;2@*WuCUfRJX; zz|Pj2XMe9&p0Ep>)ZlniH;Q4vQ(nx2T0?CJwQ=IqEgnYW@==v}KfW#yhc>h6RKy&o z-Wx(|-4EM)CSomCqJb(P5@N;>l@P3TmUpvS;B3O8Rf$imFKi*_~W8phg6NmD_lP3cL3po+A4AW_1{fI^Enac0%y2o+E!WZ%iWU~YO8 zX*@w!B?v8ZB9BWB{u%j8JhH$&*f(|IQE?!D!bS%IF61zBvmbS8!H}VmuCvKH+c?_A z>Q3XyvXe7m)a6jF2Wq9|B9{0sHP)>PS8Rwtm=)$wkK_>{Vrr)00)y ztBX_9qRfp{wi)h|`Bg(|1hVx2i?eM>ki5t9X|i@dhL3!|qG+?g??00tkto^&Pex=N zL(m=dt_3ck*}$rr`Fih2ti5J~IebqB`%E_8wD5J+<^{})o?mu-`e>CWN+2L5XWANk z9v__c(6e6zSS0zR*D4gB4$OO-;L_qD2q`Q;8k5>tY2lU%+Bim4!M_eb&#oIqD0Vd} z$-UyE55x6Zi|~gN&pGEhb3(r`Sc6JGu8SVBC6Q){^TIgi;IvY;`sib11s7a>dm#r> zZcI0+G9mrC4fWPEDRMOxAk?Ng!Vzio%*B@@a4$G9ia0`jiEeT50? zRE3y2{++5Xdc_TfUBRzYRhm4an7dGx0{dXQq@E|qp@F%@R)ZEp?i-4-M%9yql~o~? zZMXRKu6AAKb|?)%j6Io@v;t-$Ro{WRl9L5SBiKgl1ob8I)Y{)4N_|~0}JD8X62qMA6{(oAij_sas4H*2n_+Jl_=Hj0-rhxEL#mC zo0RsTDLL)(Y2D&d4O1TK@qW zo$~r_4YHxP%tBd3H%`&cJ=GJAR#L;X7&VbJtn!TmOOmCGAMjXWeUMP=i`g8ZblM%W zW&67RwHR^*YjI<@0v>rIu=pU+^`b!&NFbs>!7?bJmJ?&v{{ck`kqA+I*caFjasd7L z!xU!fRC|p{-Vgj|uiG+*WhL*`u8ev0U`Imb`R2hHLRG2*xcf%FRvpWc{qRIHknMr3pE^lLAa!4_|gNfW4&E|&b4gf z=rAR4{Qzvu#1pJTz`wCq5Bs)#2MEBOH8jhil?w3-<1ze4cUzi=HkLGB zR~59eV|i>fl_S}ipNf7MRJ}9A(knM+rJ-o#Nu#84d}w15=>j_R?Lc6QdooA{xj#@#Wi7=k8^oj^?aqm-L+m>A8C34&`_H=4JbjXRki%+1ayu_1bXxhJ_#hH;P2ke_#W4Un-1l?YQ_SJ6)Vte=H!9?Ql5i1wGh)w|q_aY*6Gs;;B9gm!tQ#Ksr-to&g*iFf_ zQoV!ZUT5mjAoaQ$c!V}=vpK{hFt6N*saaeLzyqBP4&Y&tB{T?f)y-PD=?6%jZ5!xI z_nJm3W}T4`288P@LDxqj(4t{0a_s3gQU(r7WtP&DQ0i$K^-o+tcw}X63{y-^n%Z2; zuXYd3l#c@}*Oa@jEhLNja$S8@78~$;b=0krz-;X1WM@gE?te=?2|~D2>S|XK5eJaG z@XxT|0+O%Dihb&rb8n5)d-5?m$T(K@C|2NXX)1sgt@D>Q#Yg*B3hVWoG%7{cLfv(# zmn<^7w&4b*KP0-}r7Wu#dTXyb@x^W03o$O_HABdV8=Z%^EzO8lz3SqKop9bUk-TSs z8)QO2|L;J@K?h3el#BZvhR7B?c3GmJb@$%)Pp49-=*=zxCMqahxx2`&lPLcq7i$9s z3uWWWb`89IJGBOD?(fb7di1+Tg6T_zpkS6)yEs)P+(Mfh#o=r^Kwtuh;yn-ouwfs* zK1&%?3dQ3O6`zLC3W9bQlk}iRo|i~E$9A79+moM$PRaR++|!qEIM9PYi;8P{7?gWp zYA_<@mmTuAejs#l%Y_i>XKSg~`MKE5ju-5))S6Miu0P(our(jn2sD69Yy@pKzDyIV zm+pDJq0W@gUh%D5vm=sai&cZ>w)B*<5^mqOwS(Q>7EI>dfh7w=g03)ZRu)9E2~>Sp z#smnsfC5*4pJ&-RQb@)0?)}%u=h`i5u2tvGNciW%(>r2<(^OQg+{j~}*T)WO<#wfr zC2rJ==C%2#v2hlYRAs_bYABE@zcYcwiY{X|+=Uub{=fFgzvRuC`aS%dmm8x-+2-u% z_>$I5qqcJmp}lGQpX%^YjnA}NqaC%2F9hP2qB<^CE_%u<3i93VWkR}Yj+ZiD8>n6L zP7_I&o`!B?etwJWc|$R#Z$mGHYB!v+(%)mL%HxjHxaMsiG8`Jc_|vIGZ^Gj?7&MS! z1PDcTQLO@NgF=FK(YI=Y>i-8T0gY6tU(Y*C06ZyG_%GKPF`l=q`roLXL7s!&o$~Os z+hp|QfStfqAIdfWg+rf0dh6noyXc%N4PdArg&cZZ<*X~ZlEM?`+m$vb(e3nYEM!Xn zKI9#^;@NdRh+BrmVdmw)LSt)yC=<$8-5enElNc~fnHZJbq~A7$37hdBzb$<08?qx-a@Kn z^tp!$4{D}~mr5O%g{t|~U(Nd@y(WF&G}^i!z3Kp9JDV9+G+*#34~n;MNxcIQ(QUnm}hv+VA7JqrN7TQ?Tyvo?Shb{1^P7HF4v>lVjv)l6zA>$$mw3!Yz_$ z8wpSfmS6VlNal}HPcv@^o&%+U+ug}Tbf%l8e{y8zJ%nXxZIwz4`51-yA=19 z*R#=n_F7&gM@$y014j1~_=0fuVSF($%d2Sn>X<=yraI^17vd%;Tn!+7hOM4UMYc2j zYswE+PqwUwBL)h zOE)W@qeyxx&AF8Puli2tR3>?D)w!F8!zYxIzy<2C-Hd(TQMi_Oc^yr&F(%s)0y2y#-ibo<*YnfSXvjX5nayp&3XF_AWS<&vEk8FH4v6>!hMBp~)No*D6pWxqcQMs zU}O3vv5=dzvT?;OE{|@u2MAJ;sfnC>UPtf)Qut1K6$6S@d)XyO=J>@)Q#Siu0`^N0?d_Xe@@cJGQg;ga#onFbA7P@D;L68nI8 z_sR+l3IMqY=6ZT*C!=Z7k6|AYN$fZIqQ#)~xx1+rTiQEesUxu?de-jZ3=~To--~NZ zA>wbueRtJRjE5o&-XUK)7wSrRH%09_u!}IDsL>;df%p2SW|xd~<5+%QVUnalpdZ-- zEYKcb_MujphnEANAFm0FydP1`pk!1?#j$q8CwLXd`D@h-@HW51byaS z8P2hOZ^K|ucjmmFj#ECkw)VVnm+k6#)mT3Nq`u`B%ncIP&`B+W4$MI%%iv}R6zB^-tfzNLL@@QSdWJC1js;ggml7h3FWqny_HRv(-aW=plQ+i7yv@E-%&D*Ns<1|m zU{I2c)A4nk3TBrgr1DLGhl!OZ#FM^Z5?ZDjx5p#nq-NMHj6y*A%g=kU(9`vyRfGUP zZl1`^s1`nkS(0a!9$gE%(oPw%{glvQ9~49O=#H0Ie^3J&ieKx%bn?SKpQG`*0h1m% zM~=RffCxw*g{rHG%e8sp=y^(U_|=%Dv`} zaB?nT8-Kc4arruK7=_pV@krAiHr-cRMP1ly9Vk4vM3+0A*iSg$Fy`XC)+m`vFL<3J zYJ_psp|6bU4eEE%lj&y}Q>Cn>x`lN^M@6$5<(GEH4g68?h^w;DO_t(@oEcT!L5uR} z^im#%N6c17=8){kF9kn7%xWV0Q~QDr^PP#QHk6uRblaq~(I<*7N@{0g>@=n_Gl$$r zxLoxThzAnq27#^gkgb;rAvjBBHF5r1QAT2^?8CbXA)6(RKU+E>G6oNP`u(rj0V{#VddIT}!1L z2F4d&^cGlfdRasnQ1~dv|FVP&YCpl)Ys&JXFwS;u3!_3Lcy~r zvjvv)pKK6?D=8=jJNGbQ7NJ%Y*>eko`wUv!%hzYgbt2#iXF-v+wz6y-wsAjij)O%g z?FWV}m5R?0Sqlc^N-JKyd=j&De_UkNCc|L2H6qK=u&GJE0)oC`sIBI9!bU$yIXFP`PqvW5yHj~5nH=C1a(np+%rESUhY<4Xf5oX zhm-K&z*wGujzWX}xsKpUKTW+O>7pvoUD(L_93s)CB?gd>DaxF=tZrCbjg3f1^f?Ud zmR)IxiJ!S^Yo-d_*8bL|qNMXVi!-J;!Yc5cr3UM}k3VE=$E6fDL zdD^vYj$J}rT%v=|RBM$kM!2PD7S!mw)3|PD2U)T*eb~cqU?BpYP^jL_uA$Oaszb<0 zk>3dmHN*GL`^ylJ_G?62TeJoUUa-X?a|Nf;Tr|sRo)zIm>sZgu-criBEO$Y@m=@B!`Flti; zV)JEqj@(JNX4)5%V~YLYnVC)Y0%zJ=@j3SLrg?1K4vTg=F&!*4zKl0Dn;?bAfhpAbkUPBT*Ja*+4gpo;w=hkT4}6S3T( z-dn1)a!PM6)+P{JLMNZ2w=U_NLS1?P%-UAzjGJ%LO81_kOj-heQo$E{BcIUos!kN; zK)=Bn(uJIb(Q+8_hi04)gY=C`?|zx`FyJ==g^(3`1@NOd*s*di`C(I?q+It;c{Jf- zwLRk){BKltQ7ycMR-T|KPxMA*THJe-v!u$1l&*JS6v5zWY63eiV0H=%g$@&W^qvN!bnIA?I9mKy_7V zf2n(&M0e^z^lDR2IM?7au(&mB7N7Zpl-K7!8^yIjTEOX!9)j7Yb*~SJj6SV5RR5i5 zPiNr|2swiKq2}|(n^0~`Z+@13JE^?zsD&YD@EM^KmgO@a{6m6)cYcRdpm7$oJXek~ z)ENeF5e@L(Rx;ABoI$`4QyU! zC;T}*xq-v7pW^?H|8yxYxj183u0Or$kkY47nZTQC1j8=gbMK3_uv(~JYuk4 z6FSZQFAG`>3Ezwo%w*J!qa$VzK#T|cUpi_o(6=`&BGqsCk%Zewes0^Z2$so?^xeB4 z?^X*(5RKU{tlpZJu#tSi@JbD247BMmt9GGg8?uqwYFzyTYKciCdhZ<3;e1A_oB%WE z>qfBZy6X_4A&>CZeruZf>5(`NcL_4stFXW(OB&if@$!%q@Blh!8Ozin{Lywd|9~lU zJCF;KI}VEPJ&%WR9zs#o_}$!T7*U6%pPQ%5R+M5ux&lSDGCZK@6y+AE@zt=WO&7Rd z>k$127t9pt-#{&L;%*wV{Q=uGiK;umMi-m~D_li%(#8moaN+FaZ~ujuJ{89OFNN_W zr>(u@)xouaH=a~)=g;IwD&S%UFr85RZ0F&5A~`nL;rrO3*GXZ;FF*_@mWklWCz~Ag=kSO3RBn{8erpJOQkKKfrwDwydXtxV%aFaXnZ+Wj19>6Q z0mgCxDyAsGZ>$fd{6xRLHZ^>)VY4wPhDU2n=L5%wX8Ut?@KdkJ5&9(B0xI!|D$LvyFdT1pW8G8nn-;YgMeB2*>sXP%mO?%teNGN7DhsSLvcr$Q!9MoW}dr z0oh(5AZgIeXswbj2jSS^duz;dBlCYhsZZyC=HVkfXm61;+8eXezaD`hg&o5IW9VmH z_idn<*$SBfpa$0*{Sq~0cGOgGx(v154KNzlqV$ul0HVsx3-gX%^ZaY|G8|xL-p0M; zE2I>TMK_1M?Wp{weZcI`x6T&eY&)khCw1hZturF;Q_7$Ko%_|9Fe9UmHD5E-I7|$P zI6_)+HB*agDNky84cJxQi@bkrs3Ub!m%sig1h}`pc=z_Q6wv{nuigB{iktV759 zE&jtwt;N$$00~%6ZN&q%74-KFm|14@!UR$$$i=8>r#@looieXFfru$kHcPd?vI(=w zeqt1L`+Yu|pxAXA&(^9QThsKd`@3m>*p74P^s1J^hP-4flvXTehSBix+~q^gptt(s>YYMHY{4i^ z8cDK`40-zYCabe6h}Fy+T9!`jRP(2uWJGz!P`xUu$O)Gzo5av^h--?}%sI9R^S5?c zLYHZVYr?&cBqgWBNO3~&-rCXf1Da-VH`cp-`+iUP__q>S$;a5~^q7>@*C4Hp|OYNIg8a!Y9U zl0Rcg-AI%H3o2WeQy?6T3awzRT$V>vK~Ywl*nge`JzqPLiX(TuR*IOyDX0sTiz^Eu z623~Z7#=cYJN%he(|}-0g~Q{j<3)dXcd$545NAH8k9{CiihA*os`n%XwXEv6Hec`N z!RYheHb;#RYvFZQDEMTD5Z$5fw~MI@7fh?cj-S%;>=PCU>A*JVOSpF{GEYWRyM{EW zKduH2u14qq@hC?tuwC|})d=U==!}mWw4b|UVDW?k^V@$kv>P6&M?eAV`0ZK{!_zV# zhts485=FCogPN=v^m6u+wGOlnqV_weJgIpO+DE5*l5ta#@&?~FaNi*6ni)oT0Yy6c zh2$T-qbSH}d#UT>9RA$f7t>^Mj!P3#`1D^t+VB$ExSNj5%VO+*byp#3y&tG@U_G45 zrVdyt{EV3Zx3;36Qjve88Xvs)w68uJyVvoUG`T$`j_~85PF-#cI z?Rh1>2Gnq(4V^6pmXa?1i!%HK`}W!FHr6SL(m+LWqqiOi(V)q$g}WuV7S_+}#a=Tf zlvPl39gypT=jARbsJ(W8vMVo|2G=u4iz+qKgclaNwKQ>nnemWdk_-tV z#=w_z4N>NvCciN#DZ8$*_V)H+I<0`%#R7pre-J~*Woa%L;o)!F^K9VtEpx(I((=+x}vXv*Pm`f4T;>4=G;-eFjMEJQoGnxdy+R0+7D0 zhmkex#?oZr9(E%GX1?tCy2;}8fu0xzyPx0KS|J&wYceoATzdBSZHQ-n6Ct~SdjSb~1 za%e*MpEjDZ*z$PtBjwTTvKz|lm80doc<=Fw;1?@CHQf zIDW1SL2dtcyKCFA0HS0@%T+$_NQ^W3us#Hl24L2cY1q1?Z2XoFn((J>{1r)&ErflZ zqL$m6maetnXhJgwVv_u&!z31^ zX>x#BQbSZe51xT}dZ9Tj`0`lD^yVTGII|32FFlGlny(ULP>nAn4?9B2vNwD!%EDC0 zBqWfoxTd_Jp|lniMt~XHTVR0xfK`C!$jvoI>Im-pddpl8hmTYr3X`IqwK@!=2XXPf zK{frA<((j#3q+84kQpSs17UcTv56_oc~%dtRVDr+y-#1UdE4${U-YSATLz#+b8w*L z`*J7abSNGTDQ3jQl775T9Qe7%GT4L;D*n(44E>(s83}Hq)O~6;dV&}|k)UD!MR=}g zqMv7Cv+^7leS&-s0*erBVXDuulgsdvFt#ZQkG(ot81opm?k2?mK`Moa%Bvh@rF|6) zq$h!@5RSMevM@bstyaU9#}E35OuaL_#w(0tUZZPpP_VWluPSZ?B6U@gK3BW8M(y;l^ z;+g6sXqFPd-bkp8g*C17w_@^vughwee2MDT9zw?Ac0X!86AzH<-wE_+AxD7-q)yun7`K!PKKa9j2y+ zC@R9--dCE-r%8Q82%9%i#YY%q4gb}!hz69AXGLdq!I36Yy_McH}uE3lCHUQ%s^;PfL7&za{e`nwA>;yI0SRzDm^eDqWKhs004+*Q;x>BNOaLR!(yRr%$Uf$W^I{f5=wc zI5rf`;8m(buZ?Bc8dX)_BEyxPnX_6)Xd&|u;lj7KqEpfS3G*y= zX=Yz7nru~S@~sbiqDV|Z@RbWSF*7N@-PmMq)##=vP%Hp^9pu@sk#MFqq; zD5XcG9T(XLs2iM+`5+?d`*UrZ!yLgHNE8krCC==EpR|e%%|{s8FSYPT+@z-wF3t9* z(ditNk47Qi1jhP!?yP9}bUv@wIlNhk8fnDqVSTY+mdg4>o)7riSeK#ikPBG7hcvhj zcYk`9nU)~!7<;)p4JT2bwUgHcJWA%Ik(hvAOQ)~ac$RB!3xL}~C=HWgYLmPw7&>DL zj13qxdkW4n?rL|Vn%LqwsJa3q`v%$y$OeBmD!KPW)-9-GV4DeTe6xH)xq5CQyr4Zi zPVD440_ryuu`a8^G6QCQ1#a}pq&|loS*d18x5}We^IDa`-?xy|H28fp!X_oN5}}9f zrVQ6okLHcNc&WEHar*BpbrL$PE=}H6Pk7<^pc|NB;uu03pirD_uw5*mhC--Jf=07q z5ysik-48C~-@Lgw`(a4a0diRlY&&mRYNCAdVu+$6+K#zSm@tOMhCa;U_FlX++hJFf zDf6p(<5JYlV;{Swd)${4oUNzdQWJ8BXY(Oq3H+gGzryd>Csb9 zwZTOFf5XuY_?rtK@M?MA4GFH|)a zsmoo61pw^O4_@lc#U1=RJ|YSn*NiqkLJ~JbM2K8x95Xf5xNkP6G?El;0iN9W0%U*r z3~ko^(T^Ze<0%GrZ^NP;GdGiR$i1Q8b?f#1FG}B;!QCqEX%!n&m;jhe=L-D*qNW|t zx5ZR+N~BYBmtYn8BC=6Ql$yd`#r}_CyC5CXi0(|(6Hs%NvW7Ly>u+wHj?3J5Ae2iZ zqhP z2w_uPqwYFqzdF^wwIt=g+?Q5IMF zZ{5ZQn{0n`pzt{~_pt=_j-eMNKW<$Y?Dqkm5sda8#@o;TkUb%*FQ*NOZ-lYep#Jgw zKDkQnD3By_936A|X9QeRlRGCEbIlQrYBcMYWA}}y-7cs#7!-5wTFe~E#Tj$6MKGRl zk3ugxbLVO<)}&evz1~sPRAt!168ebUP%IMuDSit+Q*6_6B{c{8hbZS-J%1;Z4r;GQ z&8Vfg=R;c3w#uuN>T&NGI5Z7xQ`QSCF%<#aMJ?5v#1$&c2rSEaDaZFWy`9V?SKNSE zRU&aTy`UGSfy|nvoVK;BVPp8Gul!Ng#xvip0L>)IiLb;)?%OnW2PSMc?66)Bf6WiU z^+@!-@x0hv$O*F}(mLSGM+xMdJ!3p$;aMMV9d}FhOrSWbMqP z!Xroo@fA6@Zeaa&a+IAS{=x1&zrVLBo@9Pew^CKaD6Y3Cvzx7I+uHpKJB3?SGVOhS zzmEFRPD?3WkT_572p9%KaaE==8_ z3Y)MxHrbs}pYGIDe^?OOzZZRfICHqFU-wqz9-?Sp z^?TDRo>(C}qP$|ay@Xi#6O29*W46^V`dV^tE(<{u)FpMn zX-Oggh`s2wUKdTb>7<9)R;$F4>Dbr=F}G++fn6p3)-Gj99`&qXVXvK8edu=2FM~ZR`<3>Nkt=;(zn*PsneyG$A0591t6>})|q#6tsuN7)UIR!4G zOErH2PTg-^YMEXKn}2P|qKWM#x`Sd?V^szTX)t%#)ld9UXrYZO4Pry~ji?;c*)>hK zP~UcUF!{02>!NMFPVYL<)18_F5Vh2{7*{#n;b^Im$mFck_C#NyK&o!`aO8kri+&n} zu_^iUi9hiaa5x9NoL75=OD)etElyyy6TOlT+5&2*`4ou|3wX8XXI# zDy!-m7*XND+fedKbvtrAjsiY1NNPL`md-j>vyZ*(9xrb{8>EQ(>anX;OMYD!of2yL zw@x7K^t$-tcE*rCH}JA`T(=i=o)Vc}$Dhk$q_`z{mHn+UQfa>6?tDZ_(k`_iy;dqS zweV_`ZgIGZnOgEX{S+X@t&}F4qE`7Jm!!8n|7^sDL+%!fVjs)~7%S21smy)husE~+ zmjar$t4-ixFCVd2loEmFze})4u9!6#Cp!uUdw%7cw=G?ry;DfNcpJjA#TD;4bSmP* z!VX(jEIho>t~!>Bk7DhsW3?*_jPvFz{|mIvrh+tAp6lhBtL;f=h^1L^8cf+Fvas~! zQiR)NQ0rB4wGk2S;VfvTOl*oLKQLGacA=vr!j;{*^MH>fUGX)h4-bfqwKf?hZQq2L z0IcoLT^LsJ(KQzvrqq}$hjMmJx^~b-d3g!cZ*@JNiX|dAJG$6`&d)NA^Y|7>puWtPQ=vPGvF|<*PtDy>T1R&9q!dYol!>}=q*`wiFu~1XV-e+$eAFP_Ou00No&tO{P)c za1B7PmVgdc#dX9R~-J$mH+h#h1- zMo&Q(2lNjbS+~4Qu_-##UiqgwBt!}4ni>*?2E+Aw?Pa=2kpHgUzapM>{4uolvuvXu z%5n&KsN1~--O}vH@6rz-eh!cdLtN%Zm{tZwcQ_h`d}6E-sTuFnb*37;0Z^gtGQvln zy}LnZJ>U-XC9)0LTu@{9L@Hi+U(F1Hh8F)T;lfZz1-i_qD-u-Xyz_d;^gy)(LzWL4 zoxR_~vs3OkPr|gpb%@8o6bA_g0hBcFBoe%aG({_Qh%g1dVnz)cu>o-KGmLPfLhPou z@0R0piK<4f40P>o<63d^IoX|Wl0gk2!GQ6!-Ya0F-g=d@T1U?ngRCTa2y}!vXc&V# z=<_|zJ_-JH+F_MUACYGV_#luB5kQ(D?of)t25N*=Yhn{1eCR?mG@uV6OGeb@dy}db zTWBftkb4H!`6@Loe6_Chd_Raw-z6S|QkYzMJXi+zaF_TjFWq|2>=*y?7T zJ-U~FM2u}|%gW+uYcEHMAyW@v>oGCBSIfCIXP2}I_{~LeCbvsh;KZUvA4I%bXtCXQ z<$U5=>HWhv>44K?6fMA6u+y0uE&+_I#=XOc4K;=f8HJq&V#JD==Kc6)Yso+|F_ z>&4pU5(1QD358(+Noa_!vBjov?7rS8N^a~z_WZx*S_ykQLwc!UOvqvPh)(*KR<4g6 zJ@Tt~jg7iGbZd01VW3@+uYyh6mzQ|W2ztjZAPpxQc4%#Im9pwwDcO;UJgyhGqlMoX z3SIOEzJm_0=ya=)s%2s~5QWu}HE}w+=gX=@R4L$;caj3jyPf8T-=lHRy6EOA$UyL! zErw?-h2N8RP9tsoa(d&DXZ6G*F?+0PlO1qw&h(eDLp&B+&50O*YXi$~oGJjhUm1t6 zXEN}`KoG(3CBI%faDu12Q=Ph#wXa9{mOVKR;?~~P}#&m7gyus z0qO(AyHo(KJ-I$pSwPuhit9`a%~AM6pO1MP9PM;y#@W>b?szjRX(BC`?F0T$4?(~- zwjE}GgdXDv=Qkb!RcOqcJD*jq%b6NV5bVjbG_2xYcN($f*GFi4AmtE=>!j=<*;+B( z50EQ;2b%OEC~6~4>$HHs1bl9-Ok?d{oVuSSK*H`ckCk=@ej+z^7#bn7neL&F=E|sW z!^e9_p(W#!g~JL5qJnx4AB&7DP50u_R&ICJ>uz3xq*Ij`FVx|zSOMbpyCO+T9 ztyBf7Dp7sZr}q7R<)n#Q&j>W}rcw8?3Fmh!fFxDiu{jUnl+EEYc}#9INB6>(v2T2o zKX#`&6<#Y1v1NXqGdF~I@U&dn@IvTID08&0Y!ZnHcE%?X&C z8vRkAOR>oCNVyX5brQjJ4g%-QnopMTOmRd`aA!oHi#N*JbwY8n{exvX>*LCa=Qqr0 zkQf^(#e)RO`SZ7M;SPx--vwF~<=#>t4x((icX=VdsRrsa$lj~SPBv2M^4tpYMm(ku z@XT4xrtb}Cj->;Ki|1!58PNzpaw3Ps^sAlm(x!&=JI*Wi{Z555^GB-(C*70ZOn9TctI_3PF|Ovx1pjPAs6 zY6dO6%-ok7f6xWEHu8dEhI)_^vN6Ooh{18$Lfc>~`Ka0LrL0EB#bcmo8cn>t;kF6h zfRyJJY-1CX^jrh;I=wt1)zQW+5*iP29sk4(;7s{aK=Fk@>Yl1|P5rb_l(-er!oY|D zX2^?EX;sRW^n+7c`llMKk~>pa;fHi8sU_fr>d7m>Rt~iB7VHvk()hmb&y)QEjSl)V z-_s7uFAOk0UPMK!r0F8p3qASbl+9U6Y7ipKEro8FQf{obi0bIQfRh1 z`naG~4~|e7(y<4SPCt9WZ#9Zi@;M0xrW%7s)-AGpvzgm{hVP~Ss*T}Q{nprX<0Z14 zVINbL=!x*VxAewsch|B>m-5@TL%DtjiEwsk*}bgC&kqGFrW+Sbcgc5v_xrnkpCBl6 zZ_412DXPermhzS|i#O=|A5)?5a%!FIk*nd!mOFqlhfW{4{X7N%*m1X$4)j_t8@s&A zwo+7EEiCW~&N#YzQ5DIwa%KR6WCFTfVl9&u8twjTWm5Qb=0qn+TSEPtC0{N!Vp^{* zomV-%5(ZM3N|q~59bQ#CQfK5l%_&5^G)ngy2YA4)SqY^OiRHw>@*)D9#{ZnN_Hce>TET zsR&VZ>Iu78)+pznNCl&K7!`x1n1_H~R9l^`YXQR1IbK`B@7Zs%&O(Ow-5m>R${AuA zv+-z@o$=#lgyrfSh@v^-MuG^Et;_p0ggIa39-*ll?I17q`!9K)=Ow(B_Wi16Do90V z^o1`1>S?lRn3QuF{X5o~BwwqIW1R`72>_um5~Pg^09gT)ofmr4;E{B`v6_^vLCMmg zyp;T0+P5_%SrJ#G591r@XH!!D%^d!E0z;L55v>Q}vxMk3NU(NX}yUXI1!;I5{(y0vzp-JeCjv zC4bD_m67A9ZDmJP(KX5vi)+<`}^>RaIjw<^iD z%`eFSa^OvHB<|4G={Kw{3Up5)kv0#*`Ay+45aZ{gexdn4TH73Z z^B)&W5RKz9$Wolj>dWK`2A2SM4h)ZuZ$qK84BK>&kc`9@T)Bk2UL`YnUE+?GevuvkuA+^mDO&ExOAo{+o3h;=R*g0c+8*{6Ax4a0k0rYnmus`2^fy@Vy4U@jq5SJ$_5iUc5bzm$IHF#CHhM{ zBAET1J!3u24%=K6w|Na60GvnoKS-dSjIhICCSG*i6U|x4hR^g1@6(j{dgP3oWFE=X zhWbP=INj>+n#Gj*iie$!BtdmQVREsp-)QkPi9(c^9?SsGGN3(&4%^!nb`9g zcJ|@6GSYI^*V_`k#|@Uge!`Ir>+n5aM7y$b%UZwSm`qELG|O7ZDiKtYP*DrJ0!=zz0Oa$B+ZNR^O%7UrG?gH;E1Pd{3+ zc}ZeCCiMuW!X+N(|9jcDhVp#3N5InKZTVcp!NGxmwvgZr>nQ{cEd7;Mn^|Ih5Q7)h zY4ygkMk1!#ZYJR?gm>?h{Zat{=ANl)3SKieSp>pbEHP!F-88R2tS~2d=;^kYE_xU2 zLpg~&)-p$>o4vv+$P17^CSI;RDcx6Zt}Q+93y$vF@~NN})KWGMCs=^l$zRovIOh75 zWEkP_jC*C@;36%h8mxAI1P)Jbi(k6CWepf+X0fuD0_X=>!U(3;jpmaG!9FY%qIM0j zI;fN8Y!?Nn^+%yyrDzg%=J-&eHTaOaTbqb0;_%R=N#eSnG2ZO{biC~lkNs7=;uTZN zC`C=d4fZe|t3>)B`^=@shFZx`Mwlc!DCZ9w+sdl>CNG&8LtFe-!SqoBAnXkSeCart zn>`sonY^I_o|K7oNpk9`!Qmei64NGt%_#ws1OwERP^jR4GI`LB$yv;Fs+WBe$=~SD zT6IS;^(0}QLu|63%+ALktt2gu1^+RXO=IbAv6z+UP+Yx0dt$P@t9%IN63UlTXWIJGofj-5^$wn8p-&6FusDVG*h zI5m9XpH-HG@_3^2Rm?S2e^<;oP23b|+dU;7#;J@Qs8sfa_vT!J0gGP7;2zF9#=5ev z%8U#5jLnwjHGw{-g0uospG*=zYGDZvJo8RTfTCAygM`lNV^j=%WeM-{@T89EG5pJF zD%RA71g02>X4-bY!dhSqKr$PjZ0t&U86P*cA(;OkP&g`i>e`E$NB^iBYVpP<4U!T- z?RO(QBMOblgBr_f1uXTwn3r%XjJ9Gzd$e{I3$!tlp*>9z%DWFl)!sR(1(M<_Qn?#w zl-{i<5lCp&kMSaUzGn+H(I$vpH>z{{B2vx|4;4olZPnL#YfhIIc{9@6XDXym@0~$X3I|1h$)v>tZ+?M|dnRCB`*5Ep&$6kn_N|Xvj~Xet|ZSSmIqc zqX*W|o zsu6QiMH?ajPOvj(i2-<-;-gT1^Eu%5orMvoXZcpkh4=nk(1scqVH<+IGPoZ?rVXHS zKI$AsbXtU`PwZtQ2;E5X%fMp#G(`I>tX9;KreV`SbHF4@GhDqZ@?xXS$E_HTW{<7L z>8Q!42P@up`~*0#o^9-!Ve>^lxEEpcVR;<o#upw^%WLEcjyoXB8ZqnX-aEo=2pM_QanHqizG_hUK64m?Dp$iLNJTWu&w zOO{TB1#$~#fe{{^<#>C9EdMyUiPZtD7a8ZZOin)#ox!}vogaU8?`3OL;nVg>b3<|V z$7*;#m3kyW3mA`r`dX@Ruko{x-``e)Lh~V0J|I5=dIH&7Z-Fi^aU&^hSEMp>p;%7c z7<2 z^Cc$3ix)l4GnT=h05S+(HZHAWgV5O}hOUin172-A;GYu`V`^r=k5K?xf^^M>N&R2< zCd}s0jJI>|L6$gBlJDod1|mmnj!Go8j-7CyuMoAAW+`6OObKX3VUq`s_-kyd494#p z=Jr|C(6bGvhicA6xU|~T~z<@$Xt@t<%!e65GX^5=}@n4O`_J~5OO#ikh4RW>_Gz5p%Yoaw!3?*%o7 zi@1P_AOABn=!4R1=U8}nXmP40?sjyctGb8j%LKE5`sdUU1OT4I6zA@n$Xp-yN!Rff zOF@W(>Eyoo@gKtVTdGx6A2mqp7{;ckN0Xstl@D|y&~<-rORSfuGg|l&F z%W$;bJ`-)#%J3eSynoO=fZpz}3qJhb1Qv3mULmcE)fDGy2!WIqmNR7kNWTfP+w4JwmTERO(y9XIM-$S-H5m<_NIzk33mV(p#bWdh7SY+B@jcA#y#7EC@t^2&gEv< z!b$4D!c;sI6!5ld3gWzZIP=Vo@&n?z%X>AhNZ;)7h3`dVJhgf5vUq)IAb-)n3^^-^ zd@Nhs$V*`KkbG||-&$5m)!M)H2L`27?}Tt~Vyi>~vm}wBOrY^_%${d$54Fl&znq?OEg8 zp!J3q+y`N&lI;NQe<@fl{WwE)7%1#lH-`2W<*XYKUF|w$Si~^t#SPe(5!`}phMSHZ zXWTrH`ElnsS5pQm3Fg6|{rl5p1?r>}MK#fi9;oP|yz#xeJYx~v2$RV&L5SaVFMQV+ zu-2)pJwPyTgCdm51G=`7Gf9aOAqVb;*5gh&rh29f3Z$Y0&`vM$GWm+6IUe89V*Q{$ z?CRl>+Cgu=#@biJep#ONjvXX=>eRHakS1GVmaZpxAeNz`6Sjpm`cdN6fPogf3^I*_ zCjLgGP9`B+LpL&5LiAYNV~$4jZnNS|uHDlnszwOhg_u(NY3%JX2gPz2BZG(fKC^F8 zJse7Y&Rq~_GFs1|28E-YzAkxgi-#Pm2=<|x%eTS9#}6#K+XD}2DbUSlL%j&6M|@GT zt}(|Y`v>8}p|()I`iN1s(cx_}6k7ZiF!D|GW!h(4S@^GCkXY2VoYk->H6~G7v#zw| z6urt9;Mgi4YC_;=LGE(IajmiLc~yUSMS6SCyFLfh0jWD^{$8dDpaM_q8+%>huDs!h z853}RM#A_i`>uE0eMIEjC={Z|6^Ezb^(=m2qrcH*EnP}9vrudUG54#X?s4FSJO6EJ zAwqJ*CBIg)=QrMxji7*lwR^Vl>T3Au7>g%u&C)ZxljLz=NtU0t@=J3Duk?X zXaXCd#jJ1Pj}R%n>AxDkXJRr347B-mNiMMZ!^#<`8eMt2&oANF4HQJgX9TP(K*oYt zmGs=Vu^?jN!3fw>e~036Lcr-L>O$6Uh>WKOxDl-B>J=uXG*6J$+y!b@xP}4g=nFd|>AB4RnDmL*1^s zu)b3R?FHzv?TE?T%K1v#`hOJRaQbAG13(RuyWdmP1D&L&9k~y`#j;L_RRR-GK(Sp1x7S75A8G+-+u%SAg~%>^y#fzs?1kNnCimR)NUYzB~P zvTaNvVSyCT>ZR}8cpmIe&ylN{Hb&o-#gk;gwS^dXdFi;~B2Uy?hL%mT=Ax``IpK(f zPu<-5PY*!Izn}fRP&E>qz*i+HB%}jPzH6i1@wwr}&DtY3j5hd=r$DD11T(6;&r~bb zv>rR@o*cEC}W7-RKA)*{WGJc_cm3!y~vk0*gK6u5RUXu zdO(&kt$!XR<1+uh@9}5-&D>gGTBW_A8PU8(MJ}Pw_Y>D~9~XXXK3?l$e7kc~qTJ|V z!w+NsRLN zFmtyxDHX;8@P3mS?Z6unw}64bUPT)XO4*m*C%~)ZcMBGugvx0(WJvOOe;&Sv+bJ75 zcGw{}EWjo3FprP6xK~u!+hN9MwLd~mo_?bH9KsbibsMST-&O!ShgJ3~Fop-UKMNy5 z;`^47TRR!ZP;5q*H||5rys(X>0@ZNiEICkM;0E}tg~TkDhTJ;cwhm?N03k~>CbU4& zM67aHasYwO;@6pc>+trdb8iPO?Sbl$yow`C_~jsMLiFmLFPwTNX1wbOiNV@WZF-WQ z#OoAew(9u_Gfp4dnhL$U5(Cr+D8J8aKsEC9>ECKWX;mLOkMo38pCw=9gEA5uJXeYXiyVABP9o#2DVIo3R`$5TV%(Dv< zwik*e_FeyaNt2DAkzxW+$eU_K}OJlD}N&*g|f}zzD>|%-0}+o&Xav*-bN$ z7Tq;-4J=a57BOFJ(SQgc1$W)(tO~sfP-N8sUSB5oXI;Y@PMQ9m;T&M}pEc+#>C}%D zZYKnsg#4fnlx&hs_ZuVCysB_jp>fR?`NIu=|Jv7{RnSkhtd64#t`1*+PF8@5ma28p z9#w8CW{Fsc8`~x#{e1BnIYxqW>-xc)^XoH^JuRx?jiJ8Bpv!`lD)^|*-xX(({RwDx zgwN+VI8}evRWWip7^26Te~yUaxa->iQ>;QlM+dy`6B}pWlpz;J8S!-T90u^1WQla@ za6D5XMoP~5PJxjKb?j}hJpztA+(4pCd^$K2O@4eO4d<=c$?GO4!VXR6SBS(w5ZJ9_ z&OMa06h~jvcr}&vvecA7;R0Ha#3Kp)0AU`Es4?+|kz<)^h$cFv2-?i3UT+Cmq%b9B**?Pc;gyC=hx*x(vYU)Uhba?;;& zSp%TRL-$%Wt8`ByL9uCFP11Ld7|Iu;Dl~!kD_`=}0~eclbZo&T{`=6oi=*yj6@eoo zK&mgPG7OpUpDLh9@FcB;;@UR0>fX+Bmo8^EXFeAL6DMu~6b#I`zz2kBfa`gfIy{v! zC*1`wL^@Q%dv?6*KJa_bwFezNuC7T06t`+D81@gIaAaF*H4dCqRQLC1IJ<*(TJz&| zbf@X4>kATA)iKthC}EVXeuq6CHs-9{xpLL_CMvr^zFS{SZifAQdq-gpu9qdOKHKi> zukwsP-n|Obq!y3V^QFBt47j?tYpcq&_jl z$R&G%)GPsjJGqQr(NVM2wmhSq_L9q|qn`Wr$|HfMxur#PkLThTsr?$ceopr@W^Slq zesewLpHoE+D6IWv$%0GEPG~tBA{Q$O`9yE>$SLkjDlcw_3PME025yfWLWNkR# zz7QvxIVW;CrJJ+YF>MSP3*>88S)YoEn3{X;+aNxdlKti{gP|8SYD2iBOekr=r)qOj z<~PEFOwD2U5F=*>hSVC5|SMmsngTK+qV`FYcdyl%Of2EKVu4@)QtcLHr`8ikS`e6yWLLk6bp{E3m50idJ*3r z%M@`*SLbsUr9uy}t8=NmrFHraCmJNK_Q~{V5)g*BgQcjLX*3j4iiQW4@&^^a_?;YM z=FzVGEJ~K6<;VHPb}ZNam28`&yL;VV7Vnbi*u`E%{uto?^_Y;3SNc{~=JP=O1 z4N%*1agdk(S!*8(FH;yx-s@A?(G@qK%)ColHXAS8+mGWP+f z=|^wE#F9(Y_9*j}H>st$gDdjWo71eaJd~l7$4_c648fNkmLV{TC9vH01>j zZh)nphdND)tx|B;Ii__q>DsGBX1WtuwfPYCKt!QYaf#VsTM3m3bi~HZD;R|l4`()u>3$VQS|0|)SuUo>H8cg9SziZ zGUi*c+k6>N;1xHeoOk;YIM4a}>A`Qo^JeKBD99GyBxKfgX2c!^xX#!}pH+%hq8~BU z2+xCVLU?bkMw+t%uucwAq8eH2hs=}IAY<3dQ@sG4!r@r5XM9qk#^jb3V0EKqlihC zd4f8fDl>H$Q88U=A;p}=-vx%SY6f<99#<{}9Tg%ls`^vGsx#d+te_L%09Q5~ST(X7 zZom)ajy(cAJHNTJE2xQ2m+*eYHfcI}M1^Ns$?v&V?>CiCLHiJ_Gz?%jz%)yg5uo{7 zbymv&>7CLq95|}vgpFer*6t{jBW~0&oK?I>l1@sC(-+J9V+K-HSuWs*W_A=u!rJn* zoX1Sd!(cY(-jQwj+3oKYevL}4Zh7WRa_(SJFyFxA>ne;7<_j4AHQ12w=dyUih(jHs z`SjWQn%IC*e1Fa9vES>OSMBFaHR@EUnZGkWOp5T?)CBaH5c_37G~_}B*f$5RW&dD$2bkM`9OC#Wpn#@R>UiLY6*bi zorBg!k{#)XrpZ@8{~Qoh3xdIwK;TLVwb9ZlZ_P_p*EimkN`cq%a*Mei^lT7~m)K6$ z?5yWGcuj=r(&foCn!c#ttRHNmja7Tz<_^xj#m*^ruqEk;C4Gv!DRO2y2+km3dx_Uv^*JbRwpE8RuP$>%OGP< zR`SL~P{5_uD431IkCkIe)L1^Q{KoTa4k-#$q!iZ}+er-0+?WN1=|(Jk)3+}C-CgBi ztg8)A7%?!6N*Zsu=5HwH5*C8OZGL3CMc9n&$`&wxO?Lp3Ns3tiWz@eDT!Uk#8SrdZ zN;|eZ6Qt&n&M4{aL~@)P?3HE4ZFf5Xc-NHfi?u~LU+a$$Wsu=i)d9;{La7X)b1%0x z-SKYy!{@*~^aGTg=Vrmqc$hQNNdj9w!F9ljppWZb#0ZFb)<7q3<=q7b_p)7x9oSQus1t3AvR#pn5kqE3(hk zF=Ooi!O4bdwS_EWW8#M^Ixf~8NxK4a=7jN+oQwNb_KTawl`oB1*mRnqkO!%zpgMYh z**=PJdCE{JS}di0@D(c&>hx+0KO|Ry8}Z^QVL90Ba;nt34(ZPkM9(MefH&a4QdNk} z!PKd3+dRTG9YK1Noq&&kl)56z9>QdysUoedmCB={j_#BUo( z3@}{ZH_Y1j(lNNlaGqr4>OnY)AjpwQtgk@#V>grf- zm}r3K7q_A)haFjd+wOnsfi3}H1CE;Z*dcrU$eoEjg-G4%03q~JW9*$SmK&eoo;ZK) z_I65-N#6(xq=jmmL;jre+xI(HYgxnbdtdq3jxvkAgRopT^5@CRlqclQgRB0uXVdG! z*t+&m+`5m|HrUy-WimVBVz0Pb#gz-~rGk zaU%p8IYC+@auVTfY@pjCfkp%P{?|=gst)C8`E9M2EznKXa-ab@0%f^=MbNv$`7~q8 z{z^TkVWU3HJa0sZCl~`QY(;caS;ZpKdarFn5ti7f%!cE{sN0!jC@(wZ;4So`w7wd` zIi(u6`4po;Na)G2cd@0;vp|nA+4Q+kTtgWx`>1#a+s0U*p9YRhR~1q?1IAL~ifVi* zZ_*Fs3Hhj=5wI6Yp+=B~(0PTkhG0P0qc~t+1#J&|>eO1BoE1I`EMdZb+(kY)X}occ ze?4*s>BBM$Z$ywYeY4}@AA&Eyk|4obqQlJC?Qr=a0Bq$bQA@K(1axo zax}ZNTNl$*X@aeBfIqg<0)b!dDHbN{y|)$6{@kH5-sg&!&*h+@K(H6E_VmOc84 z`pG{NJaeYSK^0aB5h1=DW?)taaGP-AF;+T=3Q|N zWrn?vEr^i$$P`W>_3OM&dU~2VSJR+PW+oLrC3G@8$_qIYr?4&wsCX?e!m-c@y-P$? z-rMW*sj;`GyXZzC_DI^5HB0XHSjVXzG?lpxUd$6G;dlYKOzVL2YJAb;yk>PEeR8?6 z-7hJXrHnEOn!%?ohiUnh#SQGHhrd)3%AUD|q?9R@%i;HL_^HLM#tjC_BvkgIK(Ho1 z#dan=QIscBXXYWyA-*U3iYgJfPVQSBFZC7yFEQ|(qbID#HG0$FUFPlAg?90&if3v0 z!|h5dG1buk)Cq_869oRoI#ptXrdi5xZEHWFY;){V+u2MuQL_|OaMp0AM5YKWRtd)H zQ@C>#JcF3-Uuo8mW<~{bxi1~%JbK`{{OSeN*rD-6h!+2NO~tcnRCD>@VS}=pHUAy< zRBr_+zsd>a0|i;VkOB8FSRp4F)31)JB2EIuW-c;XA1;DRwaGiw&RtA7OpzJPzNaTykUWa{IYj7SV>#(BOyV22>u#u?Jz*0;X4Yk+=Ou= z&{N1!n(_|zhd=uCVg)e<}r1a*aZov?e7B9Iw z#JVo|vtFO(5=?3H2Apv)uGmTRN0rQQw1H(lytL+%IN9`@??~9_``Q4!`V@oDh@w(3 zLOA*2jTs}h2tt^Shp2DSE4cS_RA@13lY5$w`YBDO9!Sc02Mv{~(_C*}Q@vW_AE8li zJX3qJQwb@0b@Y?ZOFDLLB~3rrP)NPOdDUa%R9JXxt!260_=pRB_LMXZ7?g`k=$?GP z9i|1JH#qb1WyqjLUvBeCgLKiAy?M`YJ)xh2SfnYvOI|A&eQp?6`q}1~w-PoLR&P1Y zBb3S{TcQH+oWG#E7Y_b!q}ayYBECt_k}&KI^EJX6`4I%8w_#;So~#ihxQaD z9)<){HSQO2e|sK^O@MQ$GrRy3qzNFjGETu=%AAt-%L!Ge$n%`isTIMj$sqD4nH7Ry zulv@$+JYs;BW!-Rh z%k^QXr&*|=V;JYo!8xqFF2H)>|FPJO0N7owzh{m2s#X*Go1F?q zs~xs_s{n>;0pV!T)cb1ANnt|Na*Uw~_8b>)`j>3NIU=`(-|Q0{YwMvIt?Ig>JeWJ%G*GYzr6grm!jcngcld6hupVO{d$;@*yG=Olr<$?XtOq zZ{0FYNbu(BY5SHRSZgg7VmkM(&M8hQ{L9Yy-gIQtjs-2+m_Hsbr8{d^J;~xp_ptPn zwAO|WnCQ|L2Ar;DP1hY`0Rt(rgvR}l_c{h(qmb-DAW7llsi|lsdMzvD?^c>vMfA%_ zrjH9Eqc@1^3CtNN4X*1+6WE?`+(7B}C?QjBq}ad%ll=)i$$_?>f>xnaScfwK_wfHm-(mBEK zB_mvlc{pKF1GRjf4DDd&w#+TkTEYl2*58FE$P$}D{1IQe+R)2-n6uc6xARhGJ6*}_ zXG{}uEWl?gPcb6qq&an%-OYf?23XG&NkE7$rXIP>BGwK31tN(UNW^L0kqG_C*F2Y| z>_!_m89`;Yb_PFHNBuT(f^AZ6M(~u{t`oEYIo+=Fq>M>tuG%ND#Bl#P8#}frkwte= zh=puL%$+vw%VpSSj5KPsy(gA* zEJ=op6Hd>9P|M7+*Kww2%H4(I)FtbAf7y^-r;McAk7__LSCoV8ZqF&28SR8AlEUJu z`!9I|SDcRl_lhlT-%IGBbF9;ZYW5ci5`1ed!MZkW(^8ABMk zo6N-rJ%om{Y}6zP_^lkUQL{VL3vs{%4+cLbbt_7CQI5{6-Q`2(W3W-CEHmU1YUKPd zt1B~TBYW7xMHI3STpI-^D-$-#_X`gz1SqMXqg5V73_OM@nHZ0V=aW=W=Q1+p9_V9l z72g$M(lR+JqVLE~T`_4DiBb=KAzL1C)#3ccgt=WomPf4iX!{Q&2~%gXj$j=AMHF`W z>2t?Y->{c@u@I-&fl~{=^q1BB`lYn?+F&0$!*(^Veq87l-IB7SaJ|VgcW*MoHvSVO ziiX1ZbBXaIb4hhd*HF*9dltzN%OWbsi1**B@p~r&@|q73f086>nm&O2+OPuiP8Qz|)-~d%HriF{dsITH zN&DZ}1n6J4L;RRwot3ay^*9q+C^1M-sR6COM$Yrz{hqM$N_=_HR1>!0D2}lzhqQN= z&Dm9k=;7pdm7k?+Bmc1L{GC#Fqioj6jq2OoFxtGD;w9?IJNNc7P9;&-^`n(R~>`RThI%ZAjpHPw(mmh7kC>=t%Jb z&{xV-?&*D$H6)0SJK}e7(5Hr=U5Uf^(c6(zlit_wb8Gi%yn%+vYY!1v={DMem&*MN zZ+;iZ?d&4qnSyB)Q2|p6LqaT{jGM+}46sZ6-_rtSi(f%hsMyOwdX!;xrQ4*8?_~}utl6Y zIjWgG9r&vgMW?TAi}z4wxP;mZl2Qv%oYCGJNDt^cVk1xO@s>+M{tJq73Y|V3RI0*T z9CPqK-IwZYSa}fmJc(bIh7b*1QJw45?<>(Lt;vq@v+GVW!j7H= zlBFFW@gGWsQB)h8{W9Nqtq=eEKJDWJ6_)2l0mWdG*P0PZ~GRtbtc=>nbcCsClx3gr({Jqo7YknOxN-G zB&-+@v!J#`ARC80S3(i$t!?I4=qqt$W}C;l>DZyuE4m=!L_DzBxms15?a+smuui8N z*6b7gx+`?tYmfkC(Yy#Znh@Vgk!XFe+(Yyf=18t_)^9*cKl{-UJuT%D==N!c`juRi zuXIMl8d;3x3&|stWkstDGt_5-jUK0(xg)56_gHPhvrc^9SRLJ-QFO>T_$`?4T2*w%L z;4ApNEIk=cLah}0aPLZ|ZEz~K`L)k0BMJ7=4p@soH2vll;8U4{|;MZnh5{9uFgQ8g8V zuLsnWW(jN3B=e%7LoU#pEr&F;49AMgdVV;-xRq`IadRElG9f;$5mH!NnQR)6^MjxJ zX_7R6Rh~DgH>yIvWfq3Y(dn4H`nkY_aW&nQBgGzibsrx~-MX$vUswobFxb!E#r?V{ zn{5a6c+=?6qlRHr$Q5i0rUMRbWC5Ow_Isb+6*(efHavT~ClusS8pBc~)8CWlG&{p? z?J?zECvq9HuROyepnLg2Jel2On25qqA{xU_fF^=i`{~+3L>p#EA;L9 zs%0Su?oMSmK>|{_LRl{kNT+gSpOi3dM5iiP=QIU z0Z6XISYQwQ5WRV{k?PPKqU|F>T`xD5)S0LY_@ofAxKVPC3R3)O5SGUhHITr^5+f$TlM?O=q{Ne0tI1S=cdWNawqu{}vA zno+-F0H&=o$cty^2n7`1LS~AhcN)`P2q>)D$N4hXll+{N`s(Z%NM3I@X9H41$81eo z2e<`3n~yIRpaLuPDrnp0AM-1nXIv%fK)&;?MGV=Orw@Ji^vQuFU}4&}Y5158mP7&V zcuUAden+4zS>H_-0lMUz{X(4JRan-y1V1jy8<$>fOrHVuPrwW;w#28z?2K!*3a{uK zzLI-W!j!-?;s>uWXm6<)$&h&W(eyM7kB&HVN*QFBQIHR8^3wWA)Khj8>!0{NSHfl5 zDY_}$7Macj&w&B%{iR1q6-kY59HGle)8?QFQ-yr<+%<@C(d_Sz_7^nM&xFqOcDpj5 zpQ#PCJy;H~GO6!~X6w1uur7nbTp$^d`WM{I;g>;st9d|oLSK4}BoeR!e1}Wm#MSMd z>{f!BTbVnPspfYR1mwP?kvWhlxg%{|@~jQntAN-)46Lk3#yTc1QheZzUVxUCL;O^r zz~94Uhq@xlDAN?mnmDlzEyVizpitL;K?%dX6C7K$NekT!^LSAm>Qe8vCMmT zB>FQz3^1psftASuDH&iiqNgC9Xv&ps`V6&p;WR3Oqo27A$K>WU$Y91tRnm#xrxjf#Y=yT)J82f~j#T*qgb& z3JGHNZ-Y?pL^^m!$xpE|caKt|l>mD?wgcT!mnAK6r+sErwMUdqby`sK(G1WDc<@FX z%21<2+rDs)`@72hkIJP8QWP86DrD8x+nbUe2|5KuAj|n`jLSBWM+jMux`w_Q?lRl!>MDh1D1TO?6CB4_pA&w;HwIWnLPGG)tf|3XKE07%unWNw;ua@E zlpokxz(01oR!9mcle~pJ89Lv3!M%MGcGh0S^t!o79=uk-iYnn6f@U4o{>7QZ0eV+TnlxG(FOJCXung3nI5P5wJ4TolkNZh_730FWRb+kX2&ry zP=}Y{didVG($S8hK1TrL*bK^scJ5A}tlgOEko=>m=HQyV+!4o73pDfqE}Cx&K8q2i z;3fgc!VXW|JEi>r9q#)B_Gwmm;bv%XDwk=j(x)u04e)>y<4jC5xK6W2Rc3hv7qA*B zE~#&&Ho&4#Xr#2$_Ix(r(SeoqwndYS&j`GVg?d zGbZ^taZ%5`O`6vta4CE^eF<#GLRBUFJ8d_NUQAD}UUvVCwM;%=b=!}gOKkh@s7-@pLCADe`n%Px(R&LfSZh!h zhK=i+n~Sdxb(Z(<9am&K&)sVK_kkUe-Ps&XlH#8 z$}Gxbcd4Bu0$W(LkkS-xj+o0n%492S+S;oyahdra2Ip5US99F>?vmm? zb^$h=@Hn1=je}U?mIj=|g9wepnYQ+oV(AZ}TRM_wF;%`a^@Dhg@+km4^JS2_A&zf_ zAJb@&hi~U=byvaM8N=EX{h4;(7Iko)$XmctnmNPf)awI)q$ak>@eU;QaS3UPzi3E$cAH(~u^D0E*q z$kwRJ;+`p9R@oSq50$eA)jpZ*@cK=Iaghqep?^tLINsOeBo9j)Pkp&Zyw-3qxSv=_ z`9&=gad3{G2=p5h&RATbsdkdsbb?#>If<_bJE1Y)*d{B(`0fD-mXaO7C@N=V!Bb{9kSlT;HU5!M?HJ8m4Izs}TOz^{Rr4mXx+d2NDXr?>|~ zQS`57 zP4tvIZp+>VUc<2l0}cmgOee}~KKEzG%>q_|z%MShop$^~2^RW}pn_%{yI+qUym#3b z+DQ4SRT<K&jX13sDBXBsr*rg(8P>i3M}~aBF*bI_gJ(M z#k`#|!&C%QOX|%l`rYvuL~K&0vl2Hacx*Bc%EWXTv6Q<*3$kS-aq}y5RBkF}xCV~Y zOode>0}$W_4d%{0n-1)%isuS(I30b`$*p!=ule&v+!NZ91&izR(OR5qb-pbEahL4gQ~DCp4OH7Yf*40~XNAD>BbPn0oo;7mp2BC+CfUXAPR9`

yQ3TalN^9V`MIDE+UR;zZbp5DyM1niBu_SJ8I`rD)Dc;A1jrUa1| z-v^NnE~7iPYqO$I^7N=Q0m)QwK$&xd256)zm~kl>En5Ur;HlKeGuJ9xS}})q{^wQi zAhi~C;b}=lM#zAddIUY|?L==#%I|>`3Uj7S{c@l-a8@cEhm2Rk`2UPzFQD`AP*2j5 zb}3kWlr_EwRhg*E&CFoNA+FjL{Y$w=6jEZ1Vk@Ci9eHE=_e(+GrZPur!|U+sh-r*& z9Cj5eO+{8S#*0ViBdIui(EPeIU4J>fTdNjMB!3&RNY#c_eRBzlr8%}nXuR2v8-fhk zD=0%Vq=&0Yg7+^>0V7K&*+W|X4G^A(@5Ffp9~rO0-tbjk;3{k%Gj4mgFCTkKU}fw`hk)&#B4P`EYq zujtE@9L0r30TZfTtcR ztELbC3<_Gnsd$wrV*C}dO%T`4ui1sks=t0cTT?PtiozIRF4FnqizlO<)fF7pQMzj6 zC@}Tv(O|NjFp>B!s9LG4=-P#SG=+DW@HwHhnpE_H_u71CVMp~t*E5Lw=*%5T@}tIQ(|Nqj_z1JT&>$ym!{3xe@Ogsv@u53>=@2s$#VJ zz34nyjNvw-{LmWTpyUOu8$7uk-p(a7Cl=D0Bpryu6maZnDC^@H3-F~7A>Od1l7-XU?qLG@#hXhG#XyKMbKPl!C00t;r{{K)th4j!kvQGU~E=nG+nz^@wRJ?^%XJvErfC zvurUj4LCer%rV7_j0>wBIR7Luh;TqD&&Ol=%KI3#y(Fj%;VaB z{2%pcCAGQtXPTg$-Cr~x)Kd!cb>(rY`SA8g?b(7q%IBj!phzTY={iBjR*Dkshs??P zL*2%_$E7l0*aH&BmvYd5J3~hFQl$iGw4ZY_p9oc=73fv^k^?m>odRtn>RF67G5!Bo z!st+K2{3t)Pdt+i!~9>XGMC0B2kTNK4%gsyQ>oS{Kwsh@IC1v5rx-+*m9F)mj-o%p z%^nJ=*O1^wU`ePVD(V`DL8OU)%Q?^)&BAs^3}|*>EQAg_nQPSuz);oo(B$_B1LTD9 z4QX|Iq$e89b3bP@l*_&b+j~sk`aE;MEx#}i`6|sggLjE@Jogcy5gdscL3Ugj!_sn3 zOxIYO?2<(m31D5UK2r&tKKmD}mzHp2wZDq23BaC;B~-Tc*-JG5|2w1g3>Aej z6W3#-P;>neVc1)d(bkPrCG)b_>|tD!s*^7x`5csarrAb?dp2J@fIf}Z-2h0ucpj#! zazwGx(<1fJArx&6w=~6W*fScbX||ATa1eW)wV`MqwQPU;O$oVTpfK(Z&eGuM6!+o? z${(r{usAHpzd;QLHD$GVsw=h}tPH2iY~lb`GcdS^gL$^gD!N6|uQLdW$cDA4U7vbk zMwYlT)h~phaC-b9%uaLZ@7VSzDSi1U%?O4Lgods&a{V1d-b#asV`Prk$!0ZIG5S0 zrJpSdDbY7#d}*H3A`cA7L`6))g^7+Cm=1xg#>>ug-C%Z2_WTq(?{y^^vA^ERmcqy>j_q}b zg@2MliBfP#Z|_}jTxj+{^PTJTcmxZDL=z{vzo)nf-le%ZhpL5qDhr|$xd8U8YQcaZ zPYE_9|HI6)g{~KrFW;$Z!hE{(5bXaD>d#s&V4f4!%KyWmI8NgBJZpv%VOZX4qgO?4 zzQl1*G7JaB8oS}79?DxXCC1$}m(c^*S`Vi4{%GQ86jqST{v$gleZFBT3}L+<15*D9swn?&C`2jw?><(*P`e14FsO8Hjk4n74r zuA%Qf+uaNk<%$QKmx2EU!bsG1%E@|V{UATZbyA!*7Ph;k((}y$>|V<&=|>&NxqO#* z!#l|3ktRtw3=8aD`RxStydUlQjGaW-J?r~GDN9ey7sV;-)kQ1bX(B1}b^D_=K7Yl? zvr{RRDLLpi!P%AlZixfT&p^r(9$h!6-_ci!FiH&5JxDZ^C70`jm|pk&j`}>WS0S^P zL)W_S6aLNm71{V0L|nIur-Sz_=`c6PMSG)fZ~H*M@^pml5GV%b85wXBt4C`A_&etv zww_lr7a8ilE$jq1X$GK+RWIBdP_#V0=hO#2mncac8nwf`q9^uB2p1^~rdc;Rsuvd) z{SqY>h18-7PQDlLdv^(x*P`!`LCChmENj1|csh4&>t$DT2|vcMcl{2Pl`!v5yd#f3 zCm+Q}fP!@ACdO+`pz7J4=7~L%ziY(OboV0$^a0KC%*6RvAR9ia*anV;e(c<~TAHej z0LtptA($LsT;Q6}>(vB;qIlg6ueKy65IdQ_pB>5--csg_aP4@oUUE3vm&*e3OpRcr z)l_?3iCj|;F5W!P_%{5ZS$t$QXQbd5w(OVxyXIV{ZZ>ipBC%H`4=6l=q7D4v(4)w# za&Sm?e^@=Oe55((uP6#v69^Vwaf9g`ae&4x95;v!P7%WXh>Q5lMo{0)G~X-+06)82 zo)B?fWP~hbpWzL1#ks;dhg771c*5$X#D!QG2+mO_S6Zkv!RHQFuI`=KfP3;+D$nxY zMi7V#6xitAwuaI_*y$RZWFlbte|eyfC~R0p6#r3vDn~QQ5O)a^?!FaGqhwAR+X1b& zHjkr(V+U)`4;Ou>j8jy4V{z1g5>t*#Agb6qr%`DoDCBU)udEqDt#A8;jbQ!1o@c_@@PD7(}Xbw=5hiBQyROWI_WZL|KL)}xHL1^*RFrSfE)szad>nSjPl*x3* zk)GRy&En~~awfW;XdN)>R;tD(Jx=;oE~4p15@+;cP$i1NF9cqZa`L-mZ>;<$qgl49J%jCyauI)z-sKQLDm$d0 zDa*dJ22i&+iHk-d*`ZTQ*)GsC-Sj-fmw1PQh4z-Px(n9o1@aY+gv?+5lxIjqS9N+{ z5CezVMVes!Jzu}t`}b8O$3jN66R*%6B3|1-R9Bg_mRSx2!P+CLdaV6biS82L(2dPLl zjrwMMRHaAE0M+WD(RSHL+8eUBpnwWL8S^dA8TmlTz*H?pu{ZkOnvnKUBevaDo69n! zM`kIx(LH!2CdFZ@B35t4X-0Qx?Wd@tvYE&%8_izu8ar8g%IOmS6Q;ki$$Ylt4Z+Y# zf~aR;JizYAnrx1j25NZ3UKlB4@qcU13qI`0qxaPsAOaawR!L%UqY=l>b~(X>p^t1S zkRS6G#)$MQ>;1T_(1A$Ik?VY52;c6_3dsn+=o)=U8SlTF>}qc)+%2PZ&_VaN`6@Ze zszhq>w=G6Yx%PSp?A1J-Ub(O~jQ_oJb$V?&e>A9}WIU`D;O&+NYzySu2BU;u2YgC8 zwK>2-&dD=X1Quj`^RWw*4AY)pi$F{8Lf2E3G|7fwJW4|Ml}-cV+0nDImIAr8@>rw~ z35+@N6s>6ZeU6K$C%+qcB>9>>_}=xDiGRXozer;Pw35hzT`g@*i$LEN-IYs<>MEwd z>w5tmAfY8Z|I|Rvc>mQ`G358$cmH7N3iA|CJo_K{w>&P!`#)Pr-yiS&b!*ZR#X- zZG~b$CW!B-0pYjwpQsv5Z|UzhRu6mnFR4n}BlMu1lkspcfI~hSfiflTxD$bL9=!lA z7*BMhA?!{1z-2d;moOEg7AI3dozwWRO*j6#zCJ}2KJo0gJjEwiaL}JkwqWlXWv@Mn z;#6(YS*$)Mb$-7fSJLr?TkL2c%PW|FQMW>v?LPbca*oHf5s}6oI~4EqrtVXP7Nbh% zf;I1{ipHiXKxEvP8|c#tNF#L|B$~GxRq|N)YFXsO7?xGYEqV}|6n9APN~e*}*8fmZ z%8%M7*mE#D>jKZ{i+)8A>>#zn3nHzJj?eKZI9&15GUv@1iHLnYauHk+mhq(S8fcnm zhHWZ_yv<`pOse$GwOI|CMB0_>N96UVV5EHu8DL6xGC_z4CH%os*Mmgqc(0_?qZ)z8jSw?j5X3eD;jDv3K z?imRswys~r3#1iA5f?hdx6HsFxvM%i_{Q4ctI8F61ZgTXpaQF4iL6FiLojeHHveMb zxTnCYtNlm#m+xvroI~bjdO@2y+p+Hg^&Pr4E%7IfjNCm=lDNdkeN=i8W;EU4u(#td zPla+h5CNk{1QhEmFJA-vgfOU&yp(-%Sy$r`#aylq!r}y+Plwe>Pl`}n{4X7l^Y^Y0 z$G$(_JIOlD;nbt)OSP-wI@g)HUYlD6PJ#waVi-eGmsVKe7Kj@U2LiUkJN|y-?fM8W z`Q&6OLub~>J}N_gYClnb1E5m{k;A=u%yW4!U25Xk5OWPwjN*xu1zR(}{8>NS8MHcq zptgc-uy zo8Nl7w~cf@pSk-rMjJk?Su&I5x5Rif!Oox;*1N^YX+wp zR$TpPaXOl7(jYq}HHnqwTnEjrq?+9f$+Z%|*gbzmX0BYcs~X;`M4-Pi9*TT8Ll0j% zC(Cm3@S2+!1#sU-BX577fC8Nu0*1|!d)CSNwBAI(tNO=1nAzw!c(A^u>t*_$eGyU4eR#cH7b4YbKV-tR@#SGxJcY^l6+3=cQbb$1Y(obenF z8k+t$lZ5B8SuNy{@k5q(lWn$|^wYZVg~fNLmS$HBu>WCqx%Q_v3k+Gl;ZK7bd=*iR5zRe=Uk6wg;s~m*SA8}7fe@sy z5(!sgeaChMuU?j=oRjENGDO5)M_TRD)bJA<5&4PPFc}F&SjT7mk&zRa=sChwi-E>1 zn5xt-IXdCn3*&TaFL^x?giiR8S0w*aA#exQI{irAi|w(Ii=plr#z@I-UrYY6_{{iC z(A+w8YJ@+>{`>B#UTe1+k54s@^vR2aE zJA)^ik#MIz0O#x@IS)Y~YP zr?H8utaV_h_3gUlz!RR75TTlJ5oDB-hax>iG$2}Q%mT|ck7%7A5Vj#=iWb7M$yG~L zOsmtC)UY}{-?h_(CJB$YquFh4xNene7I-ik_1oj)e3j9=3@yvstdo{?DQ;H($K zu9)+vggXK$LhJ3s3a%AMx~C%)LkMVPhVlR1^KB{~xb*z=Nz_FGS|==^8ECE(aMh1D zdGD(u$Zejh!qd|1YooiJ+$zJ+?Q4+-(=r?pq=t51dcLm;vE0bTqDEAQWz$)&%Y3G- zD17n$ZJrMaOCKn|_Mw#|f5LCzFLZzc{a14kZ)Hda4`tf^g;o)|E6A7L5dE1i^2GWV zA4(z@c>xb)J?%`QXrz$p^0U~r$R%?~_*dKS)@|`DduaBL;eH8`0xoTTt@rc`j@jn; zK)L!>S1*CgnGxX{CnXE(S5Z=MKA!=!Epm!3#f)!fcUYRaSMzo&3j1~Jw9bg{l%r74LfzMf)CE)53p+m} zPuN8oxb7dosk%0i8hH?6Nk64dBEr(LxwJ@9(yd}WujDrOw^w=$nLA{uWzBNPm?qxG zdccq|QK8n{`$AKvb@fE(NUG(eR@QdoCN*^2_M16+@fQt{8L<(w*Ao1UA46l@R_WYf z889G($UcbJE;U=bm&;Etq>3UEJXdS6`3N?CWxHKlfC+cl)n%pS)t^lU!HbxANEohY zr@(=wPnLX=@cJ*0QyFwF@K!8-2*DRAoJ!H6R5~nc6nwhxGCy&LX8Z%A&FfD!oQwCx z6FDs&Q0l+Fb)q8h)X9#5W2pwO*}qVy=Accx03^-qzYn7d_RDOPr`ByIec^auWAz7Qp&P?C7J6 zffn2BoFZdp`a;~u#9M^>(n^2tcOuA~e&U%_2oEH@yV=4u8JRLXP~;H)s1X`hfk`uu z7Q6sOq|f~*FLoX^5*`Ku>EmtIk${0~sm zQ)qR0xd;bhP4!?z=$8R~3A?UJjc^m)v|_nMgLFwONO506hif88E_R^w@H(k4*0o39 zbbl4!D5=umjmUy*mO48-lQ9sA4z3+9kJ<T2}}qXYV-OJJYn%qefGuXHI)m=z*O$t>G*V7YZ8;K%2AiF64My)38)t9?#%o?%i4-ll#t6c zJ132a!Br)T0#?yW%z&}EH|q zMzwaJ%1)x6@}vqa903ZFhqV_-9{tAzj1S(@;3NINCVK8z$9S)CyE{dJu-z0$uC#Tr z&iEp;hs9-M6#8~yQR%YV(V;qOukKqWKosw;t|hcIi#>r>;CxJ=FcBk%Jn*dlJBK7D z>V5e~!C5W#$1=AI_$xyltnki-XYtRpj;4tb@ya5LlKg;gO`$wEzSt0;sN@Vf`P^z! zviZXcIw}m%KSd&puth2s+PFi(;ckPqns+3nPC)CRuc_1-+vofqm~vSU_uSV@jGP`X zEr4;3-9EdR7<-5W-Qk=+PcT?S;8@A!i}9rLH6CB65cywf+$J#`>t#VTRJ85 zAj>=oxj9|Q&lr{LS-Njd5vv-UFW+C3zwcfYk+OT3mX+*zwTa2V?o03R6hhM}4Mnr3 z#Lrv_Aof307d`U;qi;X9?Heqe<7+JzL-)+L^36_5A#$$5X~%&mFdpdx7UT(|Ld!GY z6am;r5nREJQNeEsK48<*ThiEX^3J&sx=NN;l>fNj0a1&)uTv|tGAKVD z^Rq(X&kE)YoV7IR+W;m4b!Ej9sJD_5iSgXAV_KJzlH0oayh!3j))9zye=(VaHt2&c-<3dD$Q`QE9n@ z+5B^>7vp@hq}ey+_`3!iVGA!NV7AmUSVwro!Rr>q|4ACA_Z`lJt?!*qOF8oqne_s0 zV4O){G+VM4dLa>+&N46!-i^DtuD(*e>|&5Df1}y1)$jJ=8tS;dbpYxkofMP$PaTIM zMRhyw*6)!&%V^+O>W~-X*wTM~u)#CoJN%Zl7s5wTgYDvr!LZ|5kbYkVH|0S^*c9J5 z4;+gODL>A_2z@I3JTMb;+_mP2?PHUm+w~;) z@{(U`;=G2HJwzcsGC78hb&f2UWh$(Z<;&725MQJBKSrnQc>^*&iCc*gc*oi79zK^i zXWkchM!jwyh^94R=#t>aAPgPsDFp*K0?k$mW%TMKlNI5nVymXwfJ^_nS;uMjSBcNq zQ3!M|3C%zP;@Q%_0UW5{j2uI;%Ckva@YySFiwzNKL`!9kxI7xZ&v0m+T%*=MF?E-3-r0gQ z_W(|kRLcYL37>6|NVA%S*W{jF=dwcKZ>8zJvYTa&lYs^cylK9EyPkJ1w;ChjUZ&na z=|V7(70v)PRCy(0aIyIH4tEuLNdLk|O!Mfe-q=H6rVeAg0}NQgp9CMr`S%*9*`cc) zb3TC6#}oBGrasx{)Q*jKwrvp@L|wl$@{Sa${MkdS1`JME&ZPKc|yzJDtyB1`EZ)4*#t+&E=>;d%rin2ed1>-~-dJ|cq zM>YK7UhO8!jFpa3q6d!|L@*L%Xao+@3a`qyArlp%5$77ZVc@DMaZwMpgO9mjI(o z;vdEz>|!m3zBx+M*vzom|I(`L{u)YiGW6peW+-5>HN1WQ1z;k_uR@C^WTb#fQOiH9 zq1{l;CCAFm5z0w)$(ATT4-5B-=ODmEjjx&QieEe}H7MOo zN#{gRW?M9iM(uxDrd60Xedb`w#m0&|IG>Ls-g7g@c^XNSj@4|Pa~WDI5ni^_yQOdv zS@}V?E*}4LA4sjwUTrw3zw414&GzcQ0)OQYpJIi)Z^GE%#yj6oR(=Fy|KoMk>L2Rw zE940=0pZX@+xDjYh8Y zxSt|Gyl5D}3L6L8x?%ENQyb;t;K;`e2qr`UwS}SMFsSxwEa&W5D|WGhk|JF-^!wUVV`8 zYVo+Ik6R}fhqwV9aj>wQ?|R(Kg+d1`rPhWEY20C1_fG~aJv=x~WB?eMuq(43-&w#& z?k*h9X#|Egmj2RNirexBma>&%(DVTmGHCJtoq+th+IO@^op24(-J;03zCF-m+8Xv9 zF^gJ{29jF%b zF{aMshCQR}Ll87_O#Z_Dp6IFqkX%4le;#9U7<8AJWllYPY)>w`D9dbe`sDD!Tv#~g z+~-Dc$CcfdzgDvV1T&i-Ul&e^sMJo3I)fX3ZG?@%_Y3J4EN&jL@CYOibkf~&Zs4md z4w>Ca>UIzW3`d~kvhRjq7D}*cG0%Tn^dIm z6)!+(kyNxUSB-tdDd6&0-3L)%2fF7?Y)c%dAoLv!;yOtX&PjwFGl8MM8%{@6%`EaI z>%`BJBEn0Y%iF@W@)`xih{#^%k_Xm&q{@~-_+e(h3=$fh7P57XeeA~}aboONfyYS2(YHL8bEzj zPk50IHPtChnm`x+?(Gdzqt2FF&XZ3s-AYYxlB+}G019$kO-yI62mnn$vcIRfko&Q| zeJ-}A;V3Y{^K*YB3grNnBK7^cJR&@0US%jbCq+t`-U(ad&&0-bH!k{2~hh7r$zgmm87?lfx2X(%WEirEMmVtCkYC+VATfcLUQfj3GaHiL!Qs zAfB)NXG+G0C%^5?q+yeQRN>zBwO_vP)3-ts-f&tqYkizv5=h?%#qPbJ zVyGD1Gt&;WS#4*{+Pli42chkRO}%O2<1~!%)h!$wmi>7syy~4Y7R3zZSUgrq0>wOP z2O{X%>t)kOIYMoVPxd3pt*3kuy`?j!ijPTwidocD3Fi3p9{xLb7Bk-VGC(polbV(@ zf~ZFY*H>w-39d+O5SF|5%B^8&gC)0(M1eF6VE3fm93MxK9iCNC9|}|U!IDfp=5Fq8 zBB?HrnqM!^$?MNVU%#R_a5BxWQ_;)cK#}mKw3e9;*@9aFo@(F*iy+us*Vt518u4Cv z?vOT`{E_F;Px>|Tg(!tGUZfQJ+y$}oD^y54!0v`Hj zDIkD@tkY5#Fi7-YYOkM*wln@#1|WqnSvwuz$OmgogH(#%nUI`IC8`Vf4f{GT_xK%ZbGcJbmg+A@g0We8XSw3l8Ff5*0B z;J>~$p78UZ4oDUhp9Bi+#vqmw+z>kGKmX~KeM>sNGYn|22ZfNejufC`r*eh+Xi0`1 z^pPZq@-APyk%mgP2e$aM$ZzBscHT`jmd4&0M2)b7ekLY?%Y|+ZH?ZCsl?_ zfr9O1!5#C(ij|DI)7&_M={l~su3ucr|4h1lVWb#;TTxh+NYd~o5l~D{Dkw7cn*YBZ ztB+d_Qv47xREz_3Ah^xSuRD z61?uJuDxbGIziK;L$;m#E2d>tmsW*r9cA3QB7^Nz`mTskg$A-Qy&c`$dd^qqn{dBt zQjtg*Fi^Cj?b2jL<*4E}rj`95+-Z_Q$*Ky$i8w3>Swf;{I+PHPVCpP>7*XrFM7Zl| z)H*Z*C$fgemxBeqw0?ocL{Pl)lf(evG{4**z4T~P8jc{&Eef*uZ^1d;!~H*7HwxqK z2x1s=Okgw5Eij4g1}nDko^1d}**URi*S04v^phYaF+a@3(b|k^8JwW8H@GK08Xzmt zIb_473t_4n-2Nhlyll6MyP~dG^?d$giQfL8CBiX^Lg4r{T#eGQHPDU(L7icVXqQou zzh%Cm6RJU-k$4+JSUT%3Q0%DtYNMNVpOFUVJ*+IjD}t|RZ;+tyXk*tls;YGtG0m@; znV0dTi&o9F$7?0*_<__R=J>myMSWaV8WKU!J_?E0#r2% zeTE*!7uNHrD$gf89*i||&(%qMX2L-}DN=Za>*2SHp7Cy$zjCp6c+-5Vee%UQG*Ze@@8^6ppGS z3>@1I%_j1{7orKM%bQwIljYJ^`<^piG(?#hdif`{MY5qBaO7v5t2(DI;#0zxF{dGa zR8p@*Af;vcv3&!ra*YSukDFf+qeC&&yPq<>nkFF~Z9oEAZOQu*7*N)`TKll6sTOv>`Z5HK#8=|UAYAQ)<(SYv zUwCv6i9qKbhHi#C9s%(hvq18`>F35W#6l8w)~#%Ct$W^A1xi!Zdx6r5!>@4vB~H6> zKBHMPv3{H>B;80+5PXLs@A1L?5otvz?|LuF3{drovFtN<=LML4! z&|}B{Vls_#VS2=rQwW+y>mmpqTe{)Y5N)gY3C7%1;qqzjp)e>W1}DL8PDd)@KBOU* zz0PmA%8fcB_kx=_D&A<6Ixy;`b0Cl03${Qr&xbDU-$!INvI6WKDX=Z+3f5RBgE?W& z5=d2B4!7qLgl0i+!HZy#?s>=2s6&ytOpMg42!_zEuu#^L-uy-?eTnY$AD6bc<_EE{ z`EzOND}3=DRP7%QBT{Nr)qQglvxx-53khY%zSf7LS*k{Nu-#N54V{>nC8>{Ij$_1F zwuktb4)@Zi&eDbi+U%Oj!p^`n7VZpZG6)*WF>P0sQM)1! zl(#_O_hSESWQtEI>eD{((ZM#)h9jTEDY3D8vjNYAn6n*$W zD`tspr!ggN39>Lz#Cz2)Cs%e*A($+68SVo~`;4$T)iI+oFXQVPBfr_4j)wWSqO*7u z#txstUN<^i5TVI}h7qDDVKKq$s24g~kDI5@gH|7WO*WF97UdTd}gLZD6za_$Qzw> z?@NaD2pTtNvN-0*!C42&tG=^iQJDXEU#JqH|J$Jf{kfbVyoy})v=5`r(ol0tVZjch z#gv){?3GmDOLBU*eH0V0?O^~}cZm9_lq~U*{RH91KJo0{D7pbR2WN<8#XEj@>cLcO*3YnkoU-W zHc8+Xwgj-(n1)fx(nGeJ4`VEiN@Z`&k&wD!ub%0xFDxh#wK=&196F~(o|yj#?a!Pg8a{tuiEY}oq(w&bT?^2RNB3~@hQ#fxK5IB@*t~|&Jq|jmWpXt zLI_Zgq53};2tyZqB5X#IA%A%fJFxVFY*Ey5wnAtS8y~-|{Rp4m;~(4+=x`q2&&u9) zF5pL5E!xnW zKV8t1r=A1o!0WL6ibmy4NiU>|JwM+??sW79u-GK%F1BBJr){iQQZbgU0CnPeiLr`* z2r?1iGGRS*&<57-9Gv^MQdW;Eck%dl0627&6 zp`qvV0-^J@YV=vJj@ZCt@H3*ZYg4n)Z1Qh;|Ejf(6zqs^D`B461GAAB={=U?F$-(} zY(CuN6N>&2GW-c&!4oJ%zC)Ia1?@v(v>OREKY zQ@yfETMB9pbi{_%k(`#Y;gom@D)la%I3ZsaISn2h%@pb`29)LWd^`m6SCogG_UgLO zp{G|N9|Yvn&lC{+D-o-)g|;9QA2QT+=Wa)OOWU@qlcI`CcG*s@4>nMO6Rj(sKukM_ z7-WxoBdL%Io8v}AP1Gs*{5{1$^V5ZdCE=@DxBOMmgROc#pQa)I$-of{>+^W?tVDTP zXSi2>%n~U4Ejhch-6|g{YP~c&_TREeJUX;fo}I&c^Sh82qU(Rt%ZprUWQ(HgLZy!& z6p-cR{HYg0G>FMGCbGbu!PB)AEqJC`1`m?gPPo+M;ao+Un%%8^djLe6TyBkc=|Hz$ zYU?bg&`Hq04rrMui3bPaLAs?b?2vhC?s$HEvk)a1ZPe9vhZ;Hpmb^J46@8NyZ89dx z$`D~Z^a>~)2#9M1$=C}lL!61DdoLg)89FM@zTqVRZQdXc@&ASG3q~hr_D@W^T{7wl z+}|HVp~bRd@ui`RXGwybUx)ri|)UUR|6sCQCFp^B_9o=5uTq$bypi0N*{Lm z4$JUAlFvvylf9Ef7EP1`0b9o&cKla=JO+HaLKuNm+9luLfvQ#*&!nnWpSzFp*=LHh zrDI$kyN#l>Z+HCLs@v!| zVzDH$BU-7aj_WMYiA3j}U=I%|kPauMw5R|tO5eDja8ywZQyk~~v`|kgjvZr-k+Vt) zkynZYlFM>k6tyHuzH-<0!3U+qoFD#=GsPJ+_T6p*p$#P2aSxpZ>u?9f8z-5Egwzs- zrkB+UUdVcDqP|Wbz@_mqp!shimH^SFsE$So)_*3yA-O~jA0OEk(#?m89LIP*OB+c0i_Sx_(#4&mysKi0= zU#y0X#0h^@u&~nR^QXsZJ2!z9{}Mg0THJw-8RB9X{eSSR{7w=J;zS8=v8ESSTkd%$ z?qbi2K{jJ{9QO99JYvb(TQri;>`jSZDp#+pB&HJPbr(FWu3nE1j*l+~4^W{S^=oND z8_Y_z5|hrPmoFiv2BPGkR1ZL7u?^8I7NC);*b>xMM2PV*Ypvl7uwGnc;Qz}%QP+86j8=R~4EZv8Hp1tuoR!NNd&U`8zW zI8aoc4YuH|0^XeBPtURByyt;PlUJsM0}naMu;5upbN(;J=i!9~C^c=VC_XJ004&R1 zKb!@)ZWu0^1cOSyNfh`y`Jm<*g%%rdODU59Q_NATHSBsTG(z#IU)!t9X%4&mpG>fx z0@v%lCDA^(lR_k1r&?i!KaQyM5 zEm3aOKG1POBPy=4Nf!DeB0NBtcj~@~k*I}*>bH%=pKgz$h~udp4on%v3AP8^fi9S4 zo>z)zl=fNcKvh00WcWjCj7smk+;Kjx;&l5aEzTqil1b?rwWFsXjs&tZO_LFl2H(8$ z^sOK9{TR=+A5WVPeZuGF+QSML9iqW=8cRS(IDAu4o zC{$<)S_x@$G@r1NSH(~i~O7c~84x`vjh;8Btt)T27ED&3q+H6fvC zz;FYooYBsq;%WhQFUHY%!e6{adE2Gl+Bb`kt`X>d6E7assz#Bg+-#%jy=JOY$;3c_ zV+H_NbK>FO3Y;#C+KhY=Ikz9`1-5y9!@tXJkR^K{f^tRc5CdLUq~rD+{gh45dy+qC zfg^p|hSuU|jq)Tv9no*A3dyMqS?dFrg1U@34QL#G2TUpL%5&J&dH`xl)7}rx8+2F! zo12^5{jDh+p7=hz^_JXP|9FlQRH zTm*%x^GO?|Pyg-<&$gP3D2jQ+Y(qyHqLF$^0Z7K~t4!jo66$3MJ(R>ReFBi3<19bc z`{RD@O(@zzSsNx<>^U-7ff`;k*vUyY>qkG#X})9%hVeqbEY0em@3ef%7AR1>=A@r)z}jkXdAhh zOe-L+GN*Z1-hJIYO?`u2sN}mH&u#bnR<~*0qFTN13qdCmIMj9LK?u<7+moc$l#P^) z)9R{IZ?i+WY?A~+(U01kwVkJoPs*(HD#;FF2BNaJ zI}6(TRY9qBBBV-Gk7}E3#S25p&pN{BkWK_9xuS7Qo5ll4IhLm%y@G4KKI)3|YohoQ z*QxR!F3k?(`v0opGnPE(u1EI^>gy5w8qS3&oH&@%t+FK!#j&hY6GG4ex_Mfb&-kl! zIG~}#9umaWmL#~HF{jjUe3IO$4{}$f8B5ep0=wn8n#LPXKC3rL5%L8}y##HfOev0lhnuj47w?4O^8$j8>Gso(mW^yl9*zYOj?ecP>|yS$@O!7lW_T^qLU zNpz%hHKe4)g6E1qK~`4B189#G!@@~9h?$&B+$h=CJKM(C$MH_-N6EXbF-7DgRl3Kt zQykD;{)BTxoIb2+(^Udwm1LW~O|yT%{@@+i*@az0_4Kf<)T$t@z5ueA3Nt2=p`UbT z(>WnS=5yhQ{R+j)r9iqNPa)4pHX)@E4!ea+A-%)H$RXA%L4bn0knT$?PfbMM-Zkb$ zhY18CQx;>c%a=z`?Bo?-duea3ZJUT!Yn`6kNM${)e1Gjo!AwBkSUZvlO8!E$ySbMu zb9NpF23iZlnIJ5k=t7m0pscvonEV`_n{B4`v$}=t@LTog&%d7lSU#$rCVd!4#;zYU zkm)|+YR>|oYv)t>lFn!t%3U$pJ3!c%4iI(u)mYbNEF^ucR4E2UIu5L@S*r096J?~( zRsLPtLTEU5w0(6Ir$7RzXbh2q5tHq2b!e#pF-D#RelzHh8`BCHPb}&*Y~&s2LW)HQ00Y_$CEG{MOPGY5=W)#6h@Ni#7Wr%F>F( z-rA&WH?glYGn5Gv14m1ioyH`rI7;r`;?o3C7m<$_WCGd;FQQRcznH%3x#-!Na>5fn6i_y{l|(^pA5Qxa}A=tpaS!-;Z^~tcv{|E5Jricy>EUur;)6fej)rKYNxl zlp*=z64}xZQup3_%4G#v*7)u!`KxaJ#2}^-P+3rmpQdkl*$vCyanq8tZOv9wo7`+z zrt>gjoGZ?A0%$T<8#=sP;k4c0UZL;{%N*w#l9^9~#)bV^C9VgtbCV}EDt$AMN&VfU ze>n3Va;|XMjo?<}SFiZ#@dDlj&ZR3Ye?55xW0669dsJclG;^&&*)SiqnKbtBOrWEg z;850$r;n#qaO&T9BMUFB-445G85vTXWwKlbWipjjQyqPYQ#9sJkCrgHnTR zq=4rN=(D+5w)jJTw<0V3GiEJP#}=gZFk5pJZ=bPD537%b>yPQ39aUwRf6<@2K?B~0F*}1qfIO{ z%n(55w5yEI(G_mu9i(7)(@C+jxaR4?oWq%@gVvzgZM+DHh&l1{`;cAw$k~jsx{J)t zZ+=1!tcb&qc_32{dyZDK*lADcu^VqcDn-MwVDo4Zzd76DNUrE%@H!kZFho%+SD2?j zXTwJEimn7J`2=*h2NhS-%wtZ#EwL4!QF)Lxt+&wIr3c_E1Ht1@#4VZ;qS!6BIzO& z{};L;>To8|IOyBr+90>SC(*GHCoa|LcU*xJi=HK-r-?4LdQ?h9u4CSDDDGcP8^fGc zVD}-iX4F+=+^EduQpt;A>A^a(snyq!sJ?n&i|!`O^m%9t&5KHlWGBY<U3f%j}xp6##ld3W*_UBU*B4x%Fo6Ik5VyrJOdWIrz%f2}z(CZGc++q!& z>F?xYz;6BX`(oyj;Lki-lBa6Qb_e7SPd6>*30de2Xa;>g#_ITV!*Z)?2cKwPy7E^N zRNF~<2nOQLS#zmgF4;?jTpcF`9rfV`T=_eqNH%;2tYJ0+ZaMZ;X$mw*^>I>56&{5l zT6gNM+V{kC=y$ZgmY0`(nso)df75fCCK^b^50#AfvGYEY*(y!qLW-L|)_3~yw{t7_ z15Nmu97telb@%;7BIq{8zzR(O`gaGnro!IkH@Qf7F43@g)4t15JrkY!NX7njjb`m{#T+j&nlf)rOwlEsP z^?lV~H-M%12~cGDObcX)y{SQ>|3?_)pm3L(`C@#XT&5V}!=2|>EqQWYP}=YFyrwEx zfXd1D#6&X5B%Nx%er5;?G&bvq|024uNXS9)5)u5f_KlVdgfg|E`yNVpkH-zkcXJii`jCtUI5nj#6Mndd z|J|ToIg3meiRy?8l;dFJoCvilzPSN}?D|E{>{)lwIzY3CSGTnTtK20Ji=BXF1gA?` z$s-|h0!pc3Ji*!m*tZTCO(VQJT-1Ny!8#eUhWGX?Y+4&k7pjo9vq~gpUdr*Kd_Uf) zs@+9_00F9kf>NlvZ^s{o`r+aHm)fi;jCySQ)R-NA#97mB2Q=Vl^mT532=B!hHfB2h zXw&wWk{q^Bq2_o|1_$bxRa>X}+>Z}Gnf9UQP#MET{8byuY0HT~{nWfCj-d9c(uT%Kz8gv4PkD z4LuwWKefSRh*7`=zzuwq;t*}QIW_d5h@!d#TR&YnsNr`OK(ikY;}bHyC1wA$zELb#C1}RaPfaT}N%!LEXiC;90;zfTews9q;f5lB{!xqA zU>$AA{I%!>i{b+BF#NX=E5V1VQ>-TP26T~+l|2~NiLRJpye_dqV;NE4dIhS^rjgvtC-LB`1;|3WO2PSL8i90d>d~MlN(r0 zX9H96rQfTT$SVVft!)aH@t?d)AF8?`{?3oAqU4M# z#hx;aNc-0h#J1?o&83rYB)5wghiC_rFn~+o002N{Syy6YHh&V<_ukR<{sO5Ie4=r{ zD*wVx922+kakR^oY@6$BgDDz-f`l<1-d&&Q+-DULE^No)$ZhHvdQAIF|3J%F@W3h4 zd2Md!fz2{LPaoN2nKL8q&Nl%3L1v5I=V-X(tgeF z)%lf;&B$)xrmAKEi#rU73Wyo7#aH;``>@`N0K;r}6DR3l;_d!JQ2*wo4n^si>D~UK zGRkkGTq69BYw!FVWW5<6?*+NKQWsb2g(8mPKka7zNcs8ed{&^PtZ$A^=D{CJwZZ-8 zZ;BQPn=U+dtcxOIOFGRirs#d6v5-Qj18Rnd4jc35#zTLZvz_DjeLpM45liP%6;nb+^`y*YasaJ<%mDNa&hvnNXn%pZBt z-~0pknjJ_qbI*Tw_vMC(*}kz)BhWuN=1B2R9)h%hSmn_`_V%=(`?xC?)A~*m`g&q@ zF^o<9H;wE;*`b`OosDQaz@nnB^Wi>B`eZS$s*oap0~4>ewKE?IaUu)B+yaQi5v!wP zQG58?`L3_h%20kRD)M%?BJ4&K->$|uL8lYM!0>0x_NS>@22JlO!wn(1g-rzkv3j)P z-{hVE-_YF5wEG;Q6<{`oH)B1er%`v&*u+t-dUHis#ktoJs#)^8p~Q%Tq*O%Wd3Zcx zA%6(OTo%5xK9HdMgg!xAIT!73#@jy*{y-{@<>{@p-P0~DgYROpsmfE^WITfJ?VFQ* z&ID&vV9$gtfd3z=Pf~`eA2W9BJn}B<9@FXnUf4C)O5J514z18^$~iuKYsrq0)@WeN zre~G3qAK>d1w?Jdt`|sWQ62weUbYB(#gZo>A*W{L0a??nCHgev90vJ!vF)=gab)eZ z!5Isd%QF7}@`SUTQIFM7q%!*Q^M|;t z+p5-->Oa;oys?JqtoDP|a~d4xv>_Af64mwPobTjpNpxR`x(2C}^fu51w^kV6)Pa86 zU9<*VncFE5_Y@XKM$wt>9p|%G!VuZexU7f0kvOt0wA{M6ziZDw&^z+9Nw`N{!Ee*QjeZU!f7G z^}?)={iPhfc%9wDUX5IsR%T^ZQsHRc=7$fE!++~~=>utPtdUSrb9e&y%d}sCQ7L5p z*EpqY{z}S(GrXrVA}m`R>!_sQCg?y&5X*K;PSO0jAzO-M&IBI$Na$VOk-F64t2RRs z0}q)h>C-JlDq=vQZqg}P0~pybM~v=MIfh8tk-XP~(V~Q4!h>U`x zXXNm|D73$^cNpOvJt7#rzn_K=jQSJKd`<_XX#zf(9-%X zdo{$vs3f6eJ!H$4r^TzmSIfu@Iea$CI+*4``wR@IxAMXj0d;` z*>}^S7frMYcji9Q0wirtK0Gs2HP=oH?n>(J-V$xk-03 zcs7_^0~tI7q;dFF!(_1hU;@oipY0WwJL@<6KF9*h5%m>Ge=fOgA#jQ19kfE!0{|Ui z?yo7t_e{7J9bfO;655viQ0*`C&tDRRap33F=Zyv_B>D>Nx}Dqp$vJpCkAd#)uj#CW zy=k)E-Z-%wIR6rPJhAS1J@xs<{g-mZ+OJzyqL^e3usw)z_|;4pE)Z-rZA~3@yE;!^ zP26lw;g?xfZQwnr!fBz8E8yZJ8|)H*S(=77etuv6)6b?|&GG2J{sdEuJy=P~25Rj} zNjV$-t%e^X3@ZWK(57b6l2S%xjZ2tSxGedU4_UuOO%0wUTGvxWBXd;wpi&*;x3`l!_Xv#qwx&9;N zL|(s=K$76{8iGeOcUzqi4OBJgWoow?Cd+jZVYPa{ ztP2|hnI`z20_V1Sze-Tycf4KSjy58DcmgT{A1@^1r zSxs`yffE6&n6g^RLACoKe0~@sM(L~9So`2xpb8z~^Uvjv;0tY5>jkX_v0X5X$%KR?`nD1Ax6eF~>d8PD83K&Zq;E53&V zJFPMVjTjf4m!UUkQtZ##%W38?qjJ5sJS2sk@`Q9-{}E^cc5UaG>94=scT$BDL#kn_ zM}NW>UnHVX{}rBT<&Uk$D`Y7sBRQ%CFxV`q9I}G-3&aIo)*aM8SO$>fG}ZAUB6hb0 zluVhu4}<>JyGx~BU=$j*(vOF;RUPM7@}E@q_$1mRF}EIhM{3@Kr$ z@wdM4)y%8JcypnXhogaya+%qXTLbb^sql*UsttuK?W3)9%^w45Rh`XYiF;Yaa>zP(*b82ycOir?*8|lDc9N-G1Jg=D7^UkF zzDhM3+l#@PoDPCGz5*`ppqLWw&4-5*aI3M?97G~9ElsZl`Xu&-A0-sWg>De-$3qx<} z(l*R2a*oo3>b$0m=+Fb%ORP4Ky%M;CGpwo;8DU9$3_3HiZ>|)ct@;c@PYJMGzZsu}fpP#hl_Gd#d zu1|5+pu*DTwA4_5bbcli&KuyOHZB7kt;>JyftJ}{PQ{)T1At#99P*T{c%2UU zKeM(B=h9%Xg6yg`eh^a~nTrJt?|6*-)R%35)VyUZAjB#a_)&7akf1FZu5UOzmv<6_ z+@ObC2MuIlW~8li8E_4IuT76BzablTj`cUua3EF1J8#|o&`}(z2{_%qG0KxE6NVJ| ze~Ee-shk3F=415CtySGZ?SDe=3_bR^3L89*2Lhc=5F)AYJ^~F%li4TeYVIZSPN~%Z zMoZ?_Wi{y}^h{8u^lS~r>U#j~Unk!REqRBvI;-@9}; z^(y#gFY1mMk{C71TMs*rB+rG3@MmXCwSt{4_JesCv;CRv5NKeVwen> z4#4l1z^%CGEDIhFW7ZX(?gu}hKuOjZiL+bf8rItD-#>ih^_u`ZQr@l-YEW3Ja1jUXoiS=Fc* z5O{xo`Xr7~;XO?ci;#^!RUY${hhdmKBPR}#H^Rd|n=lr~uKgMW zbVFiR;T-JJdtLN?ep#V9&$;#0E+FLtMv_WT-S4~-s?X!Z<6N_q91Av2glop5mwMYz ze_`PuUueu!qij`U>_&+NQlzGGfS>1mFC><;1y;bklaP)S(Ravw4WSe8V?FMzf_^tP z&3i-BqjZ4Jkgf;w?sR+w{Sq=pncCx3()J{Br~+rcmG{gSU!|L*HUxKa^sC2(V3&_) z+f&v-`c*NZkKG%hh34<-VcEt)6<20{@_SZ{2!s%I`DqjqpZa~+>ZlS*(pWX&9Q{h( z50ed1?(CySf#QGG^|S12+3z6>zf?EB@4(qhy+n*jq^^>qyWvA&*`j;@^3eT zy3ct9hDvx?BCRzgz$f_xLgkI5_)X4QwlDPe-+WDqeJ;O<8=!~JTWyU`S^4H@XnT|$ zVh>7~L=>3$DVJ<{oS(Hw12YSr?!)~#80nkbWC0KZO1b0MxpsQQIf-y=q{AJD@LGq z+1pc^ftzh4^L*;%rqWFu@5U`V=C^y3xJvEWS{4}=z( z0XT~?&SC9~p{$&OR8;Y_F&PT7R65R~O>(#J7@|6KH)j)FjmX%`tZ{k2D;uhcU)@2p z7KyV5yyQud!cd_zcD@NCe_|7|A{a;PG^phLa>Lbtv0PFM1js(XmmIV8opTbW0>QP? zD%=p37dg{t&J2g%An!C@4g}O5@~gpc#Hyldz5P^+IcRBBbz+Lv3uH1e!WA`0hG3KF zoB6`sDy`fB`)&v1o;reJ7*(R+RN2X#zIRu-S^uRCm+QWOP^PEDbhg2w3jhr+TSW_4 zBum50)e6q2G953VIx_thVl;|!x@I$^+`>^3M@>Mr@bKnYH^ z&jv_R)M$536vS^h`U^>NbT77R^0(gy&SHZ*YK53VqG5@H6GXon#Fft?i+_ixwzLcU zB1fr~1J7bBWKxbuQ466~T2UsxBCqa&C6XsC_wh|oCaVt1%(|6CYk-E{@1=K(d?--U z_IgEPk-OPRWLMXT?y(0Rlp6102Y{4(+c|Ky-5Db{NDE1^ssH2 z0XHZ1ic@Hbn7ry~ROXVOBjuR;)3#}Txf!g7qS_skXXJFVu){dTS^{m*Cz~t0m({1q z5MN@Nyj_DwS{TOx{UEcNV8V7<+9D|8dx@h#kVV@nJvkW*<`ht&TNde&!7vIV{P+Zv zg*(!9Dn?<5GpvNrdKnS}FMQe(2Oct$B9Do48UL%V&Y#rfl!~*YLW4SDX%%OV8oGBD zlPw4!OT>1A|J6NKbSuJ4MN?`EBBk^(egi#GoyV(`-i2)fOkFRCR62Fv+7mqbOXswn zH&MRy`dab1#>e)68r=L^knr*B;B(d1BXYf=2H2mod;!)I`TEuzAg~w<7106aXt)*2M$G z=?bbP+ZJ_R;DU-5{Lq8FAnu~oapKcP)Ff(~?`t}?+pm{DD7*maG<$xd=*aT}V&V|! zZFb%a;c28ewBk-}s9;a>v*?stdo3kmVdN?+SjYNX+o;*J(4L5;nz?_zXr$208)AEvM^3Kx z1x}3V38O=wK9<8eK|_-&%g6`DQS@o))8UMi%sm)8hdl=TizX+Qt+S{VRWL8>U_1ND zDxGqcxEDL8=p)3tC$a*o3GV-kRtJyam7C(aWEBlunPhvCeENqQtzSQV;Gb2O8}}dc zb3N>DQ#!rABTIPI%QoftH6e2OLYDCBkg;_JhpKEo_p%pxe1=iyybNSf6!~&eOx=} zO-xUxcm8`k#cMnlo^W)a3HacFz`>wi;f7C8E=U;8mPZ8XsFVee@loX9jcA0Z>4XHw z>@55Vdw(A#avQotRz*n$*ts*P&oSlRR|uMid6Ofj9AxzH>L&p9iP&-LnchH6GN<}W zJ+V0^cqOZTPQ+(KpY^7CM*0R%|CQ&OLvNE~Y}=Nvs77)yKCpSO_t885LV${Vg!xGa_oFN+A08Wl&wQ2Pwaahy2Wp}%2RGkUTA3?C&&Te{`jP@|b(qS|t?5Og zX@HZ<6&Bz>YfWw)MZHTU|_H> zjvk?kCKRL3>&H%~Tt-GRX3y!AC94c5D(;vbVh~%E4ql==59U2SuNAWNBpiPO_$=?e z8x1wRdt_O0{c4FBjLPr=JZDg|r-ydwCv5-KXni^5<0ka~$F^65Q&jR7%>)ULf7kF2 zSpPy|Rn_b;hL974CrV8#_2ix&MfMq_+q{Jd&`Uv%dfewaR7gc`unB^Jmi%P?i!vY!-YNTQckqdw zPr}#PfvZQSmgf}Xw7~&wu^W>5+}$d5>$j z|DNal|9j!hHMU%g>y6#P?W25cInGI+V5*`_p2LalTw6G!T8O1dIiM#KX85*AOnWO+ zT8rL1VI1K|2$Nbn97PZzLbK*6@hHTv^7H*uc%V9{HWC~%MbQqGC8XI-y3r;;9UGvX zb?)^b!<;J%5yelQL3b0PQ-#>gsZ>a$Pc^a*fIFve4I{aoyTQV>l5ebqEVX9F)?~H* zK{vuRH9#DY_GElA#K253iP(-w4l#FJLaPb>a*(5%Mp1qNf$oSb0~zw`@PxcYLc>s@ znu}%-^qe&1%*shn>5->2z~8ehr*~6#h~SXl3`yO>bT-{OZf2Dlfc!+&Ni}FI->p^kW$f%kF@IA=oE&}-vQ8t{ISc=@O%8-F& zWOAq{T={}lw}8s7XN4P;G_R~W7=!^Na)l4%aBM1IE~A8o>pEk9i-qb9Kk94X1NkWJ z;-&P+|4ni?xPWxc=K}V3zb?9yGoUN6pn*DQzQ@?AM{Cr#ShNn6U5_rrwUh_8s4GFq z-W-Lq)`gkMWX6c}cbj3fbr2b_uA2BJd*{~+zn~}(Qs2AsAyDd;-W8d1FppRawyjFU z=;^x(8(^gwmxRO&+k*p+Jd1Ysb-1wyA;UcY_i6+3Rq>2Q71HZp*XH9EmQ>j0-uEX5 zXf$6+*WB-Wnr-j9CwIA zanBh71_^>+tav{pS?m-sHJA%?R{I%ni7qbiU%6~fCL$t408{Zyggg)G7)uU_*xINN zw@Cqf;+6QkeF|W=n>tr6mu~5@l*6KDB7)hpQxgSu+HTE37n1W`U)+z{^tu!QzPCYQ z&~VHCJe%DciTZ)A}9dKMi{I*?UN1=a(Tg^0`pU zT!xN4@GW3cAV3--$C5Vh)qafQFC{~?dA7sI`PEiJoK0N(DHHTDf+z0~@Ue`Y;&TfL zV7o}rnp!+dvYGsT^)R@--`zTOo!!G^PtWn3$H$CSZ#ARYoQRWjnma!EVdpg_&u~68 zvk^CdfyFnbZWnMraYXBa*om&={llWy;qSk+S0SYZ6JNz-sAToXdS6LW96P3$-mC~0*flAmIC)Q7c-bn4aTD4ft?L{kh#Fw^WkxMht8ubOj{ z>rOT42)9)e2QP=1_J^t`J8 zN@WvWZ@hb!U)7L;+Gy(FP??`FFb*>|Cz!%JY zUQDatX@I(s^Zh|Sv*>Tq1A?-YaNKAAR>lhWdqP|nYF%OzHYa8h0Qb>LWio(`JAF6g z;%AJxYlN~(k&i3_@P_K1v8_L#;3k3qOhB{0VQ-)3kxZe-+gF8(3;?7*Am>PNVd4|W zK-@|b+3uAP)$sw8b#4`kSL4nQUB44f;td1w#XRF2M4ZLNbMcTh^<~IDtDgJ*=)AQQ-hXgYtxmKWVCu+Zu_T~ z&zL3n$o?_zg3K&jfxtT&0%wk$f}*xV@${joQB=}Vx?|oVxurTS^5@RxBFu^|!keI3 zCxU6`*!My_sHLz^k=gq(z580c>?!Y{Uz6r9AWjSgUd4L%J^dZJK1B_5R@u;n7*2&jXEWrBzVd#oQ@Q>40(rVK;DFXLPiWqb;X2?62qyBDByRq0CQfZ)J| z2VLA8DWILev1{cU1S(FU8YN*`cj+uH0Fu@xlTl{XDJ{~q2--iWUk+}}C;D4^wxF|8 zApt}|r(hL?uAG-g<2@+Y0sd`P4?Nm>O2(WCWNxTl=Dze5I;A3x-N9(Es`7&vWYC4c z(O2AqB60^)e(z}>)`uNNdXJR}R?@R)mMGR9w#!=OIs$a?O;jF$`JkS&e`FYtsQ3*0 zedsl~Q2kVUKW|Iz;{XP9+TZoSYexL#dyX5%EL@N71O$^7KlP;Q-!F9MmL><)B=$R1 z$2q@gEYl2&C_Jpw$lFzACG3z_~Pr!3t9{7Y(<22FuSLi87@ z-TKEbhR}N}5R)t=3=c?tF@917Rl(IA1%!xW+@2rlHyLs)q-%vLa%Fyo%n)u=Cb(Jn zEKpq$6F#tiVo~qpn2hR;Z57KWOGL3PgNX7&(H)n}MRD5SoxDxyVX%F3C%>K^t|>6> z=zU?Hm=}Xo7)|>|%i4{uw z_%|5IyXQ|aUth9>B(VO+7wV*CB9v|1KQF@SyK{QGIAsE0u<Y? zNF-ABIZ$r3jH(K$XrBP?XeO;piSC^1!}Q+;Gtuv|H|oc@1Y)k$EeItPCY`|vKpP_V zw)M!ZRqN`6OvZsYFwsuFL8)~k*KC<~-wCPR%kd_7!Eb6>3scIM;#DVn;2*phLhqS? zf+W-sO&m6K<9!Ev;eeZe_|BfSuV9xly43HGGII`w3PIM#C2vHU4{C}h=?(&zwl*$GZA8Xomm!{TXu zPUa9(p;uP1Sv=~7dG1-Bbh{14`|!V*rcb$FePO!tRRUFiR3zGs(9QmryCazG48qWr zX-U*cxy1hPsvt=IZaDn0R?WRZ=Jx^Fm~J)G`QxJ}g>UHkE1i8xNC#%3v&)hfQw#Co zSZR|_k7RF@*B7dMzMz;0JB+*vEZq?wd$+ZSJuhHE0_% zRZJiYli?Gp_+&yJbp-Fm(!qSj*`i}HOX;+F3KExpGpbg<=K{|x0mS<(hELeujdW;f#1{`{Nf9{E;+fIo zW&}L(m2>2e4~Hx|fa7|gSSGy0~kOejdF zAgByp4=7t(2aW#<4q)j=nWVb^{dbC_q@yQf;m}5j6P^_b&hCtGJ_hkZN!`J%PN&el z?1t7(RZ_dmqBh!riYQXVgNF12tNNeGDQ=a*1a2*O73j#_`Xrt)cdOm^s3z7KEzF`$ z^G&@K$>yzA?l~xOfP-C;p7qfguWmpZic0*L2g|2Gfb0W;C-o9Xg`>*@Y71vF1GtJ! znITRd&mR{_$dms@_u*&liKuYL>x7Ynx5C!PPUeMk{H13a5dq# z)p=}t0#L*JQ5)1h{}YfV!*?AuEyY}-wYMEqf`}RY7nDMI4R#9AH}U^Slx%dS^)d5%^)Rps!bg1W%s_mb1>ud6^R$C$Iwbb%RemL|; zD`2@-LW~${S~u#&n9F%IG@Vz zcr^x*+-oCPU4YYCkl!L)r}6hXEnOu-PKH8~yp7;i8;CePrrR?y%W~Nt>~Qe=8kf@w zPV(A9L=t}A+Gjs?_=N@88<5UIrzu#X(zp_O%I>guqy-Zz#G6N9=P- zVxYWdD|I{Z?I4{FaS8FM`s0eqH%~A53_ESES?+aRmhx%uNz`?KzV;G1&Q-`rx+l?C zjZ-Ic0j5%xNxPl4$vxc)VF@*$&6=;(5c{x+!B}~mVeWur;aS{(@UQ{7_CG9UD^YnG zDvUJJ+dHvvO#(lHG`AWNxs>s@H_eub?`3t5b%A37~jZ zP2SI`vH|v*S)F0Lz^|e6|4fb)v;$?>^bnQUuK8%wpT1l@QH%A}A-7tQrTHg|(NJa+ zqPk7Sb1h}E4&HAVp1%u@vu zV2lEDCsMJsWra^S1um&a@Sru19L2GgT>hEDs#*s#4B+bYlra|LTy|oZAt=PmkWqfT zroO1o@ZVPJS%MRycNw>36I`Y;BaO2}`V?KwB54F2HLgi{!vFaxAe?vah@-*pFTMP# zr`>j5$|5Q8cGuC0o_|nzx=?5+S4VOhiTI3mn@FfjpGtYLct<*Qbbq(*SJ5yhrkc?1 zYK-Zk@}%M^={R@hKKD)2U?76cnRo%)eh4O1m~Xcqg4R{@DwXT53(7%z!?^1=aL{UHH! zU*e5qi-UN0wFN8^14iB^dBBCLhvqf<2=A70MmTT57a{HvPZskfxhjlm`k>jj)?dFA zRhoI$0#n>BdL4{aNMBaSX}zOUAmxVU#naBj{*0&^p~uW8N|HoK!V)iWuxmM@?n*h2 z0~~%Ki68o5NjO7v9U;va)jieo`oY*#o=He4`7wGEGaNk)GUengAzhK=p{=G2#k!jd z$Rgnr>{N~@mdH;mwL$c+ZnL-SI_*+gn7mkgoM|fT!moZ@(-u@tnRbhRi_(<6MSH_% zQ#HZhlgQ*Q5<{OS&WZYKRFyX`SXv=^!b01sC3Foe3%Uva4re&?6^Qt}D0-C*AF}C^ zOJKlhSL zbL#%B+3U{htI6?av~ApC#fezdFeN*1>^l9o7btQ2OI>~DgjV~|7TdJb)`F4$tN|?m zerHe(kcts~-@_HdgOR}cMhJT>B#;)R{FHV8sVx#eYw;7kwL|*3i)pec%}a8fNU9!W z9+rOWUnvvAU_=RGC%YO8b^CChmFhl$112@#m zcUNsmo!_bEVM=9S4e@Xk3bJUJ7f)(3ky`Fda;J_ z1f0eQvk$ut?a*M^QW!=(7TradEghL~Ljg87LQk%RG_*pW@!=N~mY%4c@L^aV zA_ATx2J{49;$XtehDP2vGHB8rgEc@u4HWM=3medgMfQO}8e_1A&CC0JB#y6gIJSd9 z<5B5}gy1Ar%FHX0fJDWotC-)fJn|wEkiK9W1i+7wtE&`uE&4L>`k+QhjyPb`4FK=E z-pp0$g$z4;6)-55`{b7+U@S9^AgdU8K~y`yIMlU|Ma_qsDJQ${>{raEMjS66=AW(J zIm#k=yW~h@gwbG$Hlm2p%P>p!j)}Y%SnNaIB|l>vyul-6j)b`z<#pQ0*-Va;r_zUg z7T_~~qk1GKqEU+Md8Hw75)@VG9Iv~9q-qBQBi%QCx-tn}nZV$zL+WPA+)x_~Ld<@| zHcTbjQ3ez=dZ2Foz4VLmjl&%4FHA#O)`JjLBqdNa6<^*4!71OH*xHdx<9C^ct!zA^ zG_sj41N&;0`NJI)XsC?2 zpvwTv@wka|Qa$N9fK{&x?iKVRy4=gBFiD#Pq#tIb#~OOU%nHjnd&XA1Ij%CcgLBrc z&pbAYBdBTlT$@KwEu4K~*D^??a{Y>YCVDZu3x&mvVF#^gy}a)nKvy%@G|!h} zo(h1ZD&*Y2==&f+rXJK-2*UbDFW;4L>#jW;Et~?Tg2P?arRlO|CRRsXclHXHuEjh9 zduVO$G3pJ6Owv9Ar%hbW(Rx?5Q%WMx!x6hrNETCoiPO+smdZzHcqyj(jW`+Qy>{6) zoA<>;Vh*c27wh^4wq?f}eHfo;KgWWw@bnN?J-KNk<2E(l+-(QI7HiPLFmRk(I;gQ232d|09ghMs^jb_>!`kUyu2w3VRONT~r%XXV>}LQ_P1T zvW-f!?%!0PYjfqS?0qpE9Kd!Zndk*s4=d9eEIg*vgeK>CKy0>L;(65pXw}fEfT^Um zo9+&EGlUFZ2<>h-RHN)V|HqvJ2P-27XCzm*a^mc|0JvHZD}7b!aKFZgt`F(&z|+@l z*nt5+k=bY7!l6{W6F)ud7!^z%lJ~D(f@ zpQmrM@9aI&4iY~C(J#On!9hUI)a#=&RxW}rQR!QUn{@=)|2h2=+G$<5XYh+}6$T`J zvX2=mcx0d|XdJTEPjB%lss(cs+5`z)+Nbr+C!~Jz1c2&;j^b*gQL8#91lHAQg=L&S zxdFDJf7dGVJ|W`tuz<5=M~T%*J2t1x`~{C=Y)u(>MU;Mh&6A)UT)X@%Bz=ER-3QcS zMH0QQFPR^Slx#n*I*!8PokAq{B~>Nw7>eS3b}yUgfHlf*4dy2uzmp*E~eDJ5? z*JWlMvF=01q8$^DQfIvtPqW)HQWsINqdMHGH%!h5XTPMQy?xidI^%dfGWiB&QiVfe zMOd1jxxqag-_dhaJ~7*8jy!o5w8N@#Ho%gDV?!)I)Z*h$TZ zUfW~9&%nDk;po;*5j`AuIg(^`Cp1k*FAvU8YfngaPFXIhK*+fh0jQt@9gUHkB>09e6gP(fRDdRLA;crgF<+Lk(=Q3{ zZI1&6fqIoM%eTN`(`@a?QODgF(?gvALmGuIIMmZUIm^?d=LBVu0xh9NaBN5ufR?_+ z@qTp(B_)tNX#5)M<%}?0DwI9G-^Y~>5Y3uLXBVk@DC1s8L003w1Gr*6$!?c(qDE@% z(O^Pi#w|LMneFYalJXw+kQ}7@zoVfJWymkzLl`ZG^`E$7d?Pbn5G?1o0SJW%z|m@v zoF+s*z)mi9F@B`s#72%)s+L`PXQu5}^2^aeCf?uCM(5l;t!jD6A;p-$&^(&@BDs`h zhIUm*o_hT=+)!?kAE-w8&Zq%i9T14unG~ut*KgJK!%OITMgCLE_AzY0xDPIPx4}4+eTr3PZ zg^W~)Iui1o7gbgfZlwUtu;AB;d}#N#A%8R_SdOVC%P`ef)8PH?c6S4`I}%bM#Ld<> zQpr5jm+ykKA0#m54mRA@();V5uFg7~2{9T7)P8@g^cn^LGJfp-xcBH=O*y*OTx7%t zI*PRxBq-aJb?aw}hl$wvfgNvj`9OM`hhhyZdM;I;DY-5SI# z7=N;`L)Jim9yK_ApFZJu)P{g`seC`CSRJyV;4XrD`OV@pj|cbhkr~|>CGZIc7ct{J zg@>%n*Nb0DT&XaEbywN%zW!Q7rl}^%a$_w3@n9OcOIZ`w1e?k+`d(-j zFqjJ;bZ-oN88Ve-wD(n$Q|b;NDEpazS=lNgS3#3NEd}OHG|a=|UtN}sB_H5iZ=VV6 z0?ohkoJe63TIX!{!K>VLsO@m`Zq^{a3-DpEl z9xjk&(WE{~npU-C*?qmpiHJ88aFujGH(&fG0OF#-tHLeL&-U~c=4$ieMrCWr!W`1R zFKQNo*{|KqBvMH^Koy&{7hQfP-T$T$ME+rx@JgrNHtc-Go$MBj17Oy0$uG=jE5YSH zZBgso8o$|p_aWf)&nilVgWy_CRCTMkp62Y;Y!QyM1>BXC?c#N`InVIyYxmW8og|(u z_q+NX`Kr{TbLsPfSjdf=6fI5#$7LUx?;MBWf>^`=Jx{dnrMDbz?1gYHwk8-$fyyhU z4A_v53drfk6|k&zzA^aF8WfFjhpoH_>8tRZ6|fysVJl`@|LX{nRg1hfK0+AjcYADK5M);CQuo9Q4UyA@<&w^MY5O-|Fs%Sd&Mni#x;)O%+gICK%&yT=wQ-9+(a?Z z#q?8M)64%Bfth|wtsJ?l=6IJCC7e*3oaJz+WvFxgHQtL2RTqFb*ltNnIbas$61jUK zCnoOl7UtV*@wG|>VD5>MaF6w{7Qjz?Vf^IH7^~xMT#mkv^io51Agx{Ks3eS9yddKi zF^efuvjMPDVev^Vaaq}HT<6J>5GK4{E~qlDs`~Ya`pB`T-N-t4#0#0^^ft>Q#6|h$ zssMm?A9QIeV-i$>h@AWT2kH}U92c3ZtJ?O>KR7#K=ea`esg5dMF5v7tWmRl{JZexI z##xUq7s?1J+7FXsZhA4~O&5@>ZEfs3OdM1_w24j47wd{L&=Z#r*9ZmzTUa) z-?q8VX!`8os1DHcj9ytiCZ!FQghaZ+XN7$5Ys4YXf%P$OQ3S2tQugYXtkI#~1jfz& zBVho8jI9v3k0V_?C-z>;yptN>Dk25N&W_zVT zEG;^!-sR(M`A&lzaivBhG@ahM84K2* z)<-8iS8K9ar*sI)!yf}iYGTBX7rwU3pdRqZ?QzB@XQI}=+}EJ#e$q<=6E5qYk4{1f zvB-0;+PWTlo@#yg%fDD@XCwn!e~z5te#pCEku>0(m#GGvW;3F#fCH}3$0L{3=x|Rewc@vRq$*6bqoL(u5$vE4n^NCGePCPS%)f6|TGX zlcc>=X;3C4is5z+JIn&@j)elcmrRfSYole38Fm2dDo=ezBwr zO_~(yR;~%X1<-2zmigZnkM(;`47c>7B7&5(1L%xep{-mresbrwq13zL@!YUn?@v>R*J140BXud`NE+~lD)8=L6=E>W&c#?D!G(7fL+-9Ve zKh4uooF4!I&~;c1AQ&OY^bA1H8iz;AL>zt#R!|0;%sBU=%7GFYOq5Y4N=hdn0qN^0 zIPxe}AdwdN4P!MbX+6b?D^uh4&L5m7+|ZY6Rn6W5>w0C!`uyUYz8;(xjz!N0vw23S zovjj>p0+2nn!u0+lFCWR(6O;A*rR#At$JbZ0j>fi_DHm3yJ5P%F%COqd}wvXzJFWy z$*d%bSA)cM^Cl7(#*O|)@lOHLU}&GprK2^6A5@VC`BlJ&-#>qxdOJK^%byR&SA290 zG`e&2_%CgH%r(s>i&~v|$vu-{Aq}6&D6rfQd6S2F^(9Z#9AUbOIn>1av6|RIdFh$F z5|cu2kZ5s<0OE1AQ?_c1_hT-AL8IjNpN9F3JNl`Po!{6XYUb8xNw-g&HHmFbcd!=I z0i(05^R778UV0-u#Ef;W3?JMDPzY#w<>_}U+weO6CK6_$)F z_ZM|iyP%aZ{_?(6tVT1)f&egpwP zj|HX31ygOnaD{8N`9NVTpTF%2JToErTVQ28Pte#eVE4)5taKu{nS~~InPVYbapc&a zB`nnbpUPFi0j#fkb{C?p?neCW$du5(&ift+-rbzAdup*#4f#4^A33JeE52$(3AD}f zB%~JLvgzN7!#YYkq#eOUeJ$^OaP+?s_`fDGz#1x2xAL~VWefTHO7|sm*1j1Z=}Z`z zR($oAJLF1u1Ca_uMbFwXH&RX-*$NEi6=sO2%@&w_`jTrUG1~DON1B;|B2=@Ip#!oQ zv-|eAJUk#C@*pl=;RcT6uw?rLi>^W?%BG4bD_d1P=8^!VdDhSk(6s*+^gS{#oFUmF zBn)Hw>h<$$t6`!c$<`#!<~H<)mZN8zCj}R9ikhvd+gN%8Oe$ixAL&{1N4G>ifD~8`jP1O)waU^&~-nd5Gh6X4-AaJ5A6; z=#xX==&eOE<3@Q6g8N&<4U1CgU1WNtndfH&ui2-o8nUQ zO|>@EbZk-C*7NjJLxzRN^bf0_8o`3sD~gk* z#m}PMxY|`SNim$V@^>bT?Bh>L_BC^rH%*;hDLEG~Q%(bwyk5V>;XZ*(1LSosSO#Dc z<%+8mcpGVWgB%Y$q(bmxKIl+zlTaGAVfrTZ+QAY>w}mt|oT}=u{A4-t)~XNc@+oxj zf;sS-R8mgPBi|#&<7#yM|GPEn8^A8SmB}*tZ+5Fol2qE>M5JJOR@eQ+D71OVm+~0S^*dPL`w=1eeZy z%cnnExV}OQS$#8k60R^7hmc_tpL`VVog*S&3z3Ct8x?cH4J#6&x@_7S<+R758R0Jj zp8y{JjvX+OP+N^}t#Nt+5NWT+S#u*;p+zw=)^hSumJnNSER}O`KRNbm4rUU*JJupRGe_iw(8nB#I zz*aOOd5KV2q|P4myi|Gn#Oycvy+Hdy&^1kNFta9boOx2cZ2uBji#%-*T(mf(8qquj zdLk+#L)$7`v@s?1Fof1)V9bE8m~j;i6|&2?o!JYEM_mWsbTExR08Z_)e~P0Vwl9PDZ zBeH^--)(HY!1=V&da@>JJq>cd>atWnzp;JU#igc1B?lvsb{Mug&8TK}S7_1_rt7*5 zaArmdTuMup8d;=w?yuTXZ)x{4<9Adc5jFQ>$uJ4!I^^JMgvI}zXo%Wq;Sn#FI?^r; zwaM>hHME5qB& z**?Jk0B?wc0JO;i@*Rhb%A2bU^-TM(icZ!$^wF7 z(qHRXddaFFt@Ue2Q4RxkiRc|}Qix7P^o?EcyB1Z@}z)qiklTbYmuk;gop~KYBY|uR0u9V}aS76FYT~ z<1n8Eyh9^pz}836)3Q220-p6*lFlKHT)A@szBY94VAxn*4qbk{Qns5eg1lfT`sT6Z zuMFk~3-y%-7ZUD~qL2>*5zticN0-?82Fv|_Ya{-swT&Gu>!^5`CV6!t22(zFI9*6y z?sIq$o}|nKFy1jc461a``-y(MH9{y!q`fr&=1qUv1&$|4BD*FI^1${|Td&WtQX7`g zP++aIWq$aOZEzz{nlsBn(fI_1z>H{YO$8Q4jt@))1^>iqN^>R@KjATJeGzDa^00ma z+UAn(jqn(*JM#^Ixbm32f9|mOq?~VhMk{;TKf;*APU|(WF0zdfax3EX6PMI5Yu|;% zk(#g&@|a=vqA%U9QauH3eqIVb|5mf{y1GV@V3n@vzF~j9Xuyd+GOd0oT-xdb!Ld2Hn4ceDYQ!kBD~2vj36umeg&b|KJ}3O8 zGr_t58_-PhMnCeO`$hg}fPWk7gpoG6=EnjcLTC^p!h)fcS<7p*lwl+8b4r5uT86P=Kv2A41Mu^mgH{_#-2Heh zoIL&~$~_*WIfvz;CO7J2i~EW`)AE^B&me%{9p8?P@BSR%;V%GE+Zz?X%O!?nxX)X| z0JE^@g{iqo{1*EBre+|O0iME|B~klN;w)B%=4K&X?n=@2I~z7tM_XoRIq!l5vPMK< ztSsX5Va3NE%U+*C204yFH(@H<9-k+&VInLfr-05XdBx(hPp|mQDLgqss3WD0hNrR8ml3F z!6zEi%8+P6-H7^k?y-~~vu!m%hUMh!Dg-x5M&@=C*$Fkb8o9u7qn*7e`NyEPlb=wN zBuCDq?;`(4ekFrWUuS_5$9+4|0(&R$MP|(Q-*{vrq^VzVeM!ibXu1+!ncy|o(J=_6 zMbTM0H^V_(XKGVsg1q^IpG{tyytP|4zCVlk2tN}+s|C(FB%I?Q%N{zs{8p}7 zb!(IRt2#(efa(@YSAI49AU4r`K!hi=!m5Nz>2cvp2op+0Zn*DCe6u1RE6>8JlYau_ zkh&(B@S3xvgHy7uY3L&5zm-_%BKfV{qm(--Q}ww$`#Vv@Th&PMDhcdQ1<}es=uM+* zj^b}r1>eOq0ad?&BdZ-S0soB0DpVpYZ2EKi5U7k5X9Qo#vw>c2*|%tPDn^*unNS0- z;g3tm2cN((yui=b9FO%=uTTmpy>7aaRH0Uzm^*P@Z}%lJm2ToGbVObQQkULIs7LK1 z6VyR2Rc&(a_P8SQ_9ND9JGHt-=U2RFKOd>Wy!BYBj}Tryq<4V->{R28ca|Oa&1d%3E;DdREqQW{|2KA&Ax zn3Aj$S=8XIlS|fYI91jDiqh`%c&X@y$RLb?X)AKgA$ZhguhmQloIIm-^IGnn18sF| zlr9EA$zX_j{8Ly9{j6Rkb81nD4aeJe@v3-3Rizt%*0Slo3!-g}1FI*^E>`EoD|^(I z{QKnao97Dxdy^w8ZmHyYAFfitxSG`9G1z^at|om`PlgBUY}~2ovEXH;dK=qS--FcFE=*9x=mcIJHe+Wk8_dF|SvvUMchUphlhS-aFPZ#@iD|KN3u?Y~_&4 z>nWvKrE+k-aUz7XrzgsG9>KcVxp5B?g!ZB1zXPLHt!_@>|3wf$x-?>_YJP^3uV(L= ziz8lpQ>)a;xD&JK{`o$9$GXO2smJUxl_?39$5?&`fM2S444;m{d)mV5}?=n0Otpd=<%DiRE_PL@@PEA zTE0TRIPmz(x95eAx!ms~g9yJgxv|%s#+P3OC%MHyx}(Y*2c-Q;OlP%X;AKpIfPAF2 zVvET&5Y7~%&8SbJh*WhxD8|%H&J6rJk8k!rn>GS=i~{jN7TOYK^t8VPrZ7f$?LvDS zK-|L`08t{r1iaybyJ)Tzx$(3Q`e|2=EjGyqJvepew2^$>jSn;=Ay;qRfG+!e?J^s{ z*C{ZmPF6StWjB{`{nC(QV0);Hkf_ES`je8FGhD*DuSOAf_|L170)@q%3b6|r@b;b? zG%HBrtw8j8Mp@p?Y|su41zWUIR=zR}lg+p}3mdZ-^)SMB0b)eV)M)Hh>=1i)yX~rD zK~th0d}X3PVK&sj*y=dEICk1~r`b9ozV&39(c1jD&x_gcUI<5l%__^^+0e>O1 zHCpnpm+VQDwx3_Pr}*~xgaxo({j=6>nToxiOR4c{+mHwvl%{~AItxK-u^o%&ru2u^ zIdrW>=}EZ^46MKNP+-V|_@6BU5Yw`d074J!)c^kMc5&*iqJ5VvSQwd2&#X_-ZZ3zny>T06Oy&Nq)gnc*uoP;Q!55#sc zRkE^=irBZG0<pB@`__iK`bZM@22n;tU1*}}W4g++N6OYpXe)wx;`(pzcO{Y*UqTQb z-P|`v=!`k7#QR^!%Z;ZyAuIf%!L4uWybSu#!eqB!j!-TzKFw@|YP8PL~2M^O?CAp8Srr^L~+lXl3W zFrz@LfkeEQ|2`U?-InoV!U+umy|IXQfP9q;xDiuloDVlcF6QHEp!i?w2FNP>0Kqw@ zSG>@VKYvFyoaWP-bxw{N!?fvPS5awgTqzL7-yNKT1QzzN(R>4x4eQ!h)wp0HTRAo^ z;Ij%08dzg1br}0My=n2hL(!z5b|H6_%R`HJ2^WhXpo{M zSR#3Hl54Nc!2-D3tyU0w7l7;P#7lFIR){n)sks?!>@*q8jVEnF89*6IRrLuZ4@a`z zwSZp}0DsDHN+VICD5>s`akzDt0K%>o4`%O3;zh9i`R2!R_RtLkxuL|fnD)?mKh*ZC z#ojgoe!SG!DZFT@dD@%<_r#62Z=}!?5m6t1cuQr3!J846@Zn_qqWM|2WNF}R`k0|o zNc5F^r&b*`t%9DXKdK}V5JeErp+dGG&A!htWkbihG@M0+%mq+VhXk>+-0u+pF}Ea`|BL4xxp zOULt`owu=M@9R~Bqaf>N)eGJ{53=UugkjQI6BVJD9F(G?#aw&`m%%dC>u?%Pcr(H+ zfKBo@(+N@Z6bD`-q30=$e~sN80RaVrK!M!-_`>Sc`!X?nZvBw?OI~eEv1UsV<_}8+ zPi)~H{4$!ktQtW+8FTbv90q%#$emYLO;FBiT7~s18=ebnXxQNtM~%+|;qY&mXW2S} zGkRcsuX=2b2-c_Kv~hWVl~N6M)%kXMzAhtK0K@kVJpg&jlk7$n0iS?*m< zg+{6hTZ&F~@<4Tz$^KD~81-VMI>;*JNeo1jV)^#}U-^v3J@CnX)us2Rp$>OYQGUJj zAek-iv@*D(NbJ1?v-%BlaB136V}*c3Z$9BRU5TC-q6Q9bWo=AaE(e)Xoh#x4d6RqN zmO%!7=+uO>&}Ma6*_74i{zz_gi~Jjd(crcU>Cu%II_@lY(~cD$by(8OYk-gRNGk+#QNlvWS?P_;p*KtUCH&zC(sSe zo-FjW$35G?fy2A7fSA&&|DFft0lG2~ztE*?h$8s6x^Fe)f2XF-j!5ZMTw^p3E2(wk zp1vFR@vxZS2SRxa!A8S1UvKOr zitZy&msM~1zlxk6vR$_$Z4w*3Ex?=aQ1SOgznP~%FK#y&JO^r3us1;GzR)ATXfj0V z*e0Khs1lENu*A8j;K?(Bled#RoZYv8Z+280XaKa;R@FQAN?0el#i(yu{+YX*U@O$U*`Y|VE-wjUXI!ZVv1^Mo+luPvh#E>-G3qCV6l}^{UPzB4r-) z>pQ+q0_y)htLv#&5w64eCdI8;5iRwa8jGI@VaJsyzDW4`on&hC#&wi*m^ibgB$Av6 z%%JDxjuD%Bz(dkQc(G8AJQ%vMDn1r67#K-7$eR{&d3c^h238Fek%Z#PLtuy_%4f=7NdEW@aF9EG9sqwG^riIM6Wy zsvCe{7(puWr%mqG%?m=^}1|Nu?)SJt5<(5d9d~9Dz=( zei-&F)qpjqDX&4@Z@HN3IO$IvLg+6BW3^u@N#@P6LWAZa1A1`6Z zkkr1UFEq~u>#w87n$RDF-w{lD;<+!BIbH`1KTeo`SB$Xw4R6qtoA;@V0{(JwmDarH zQsqT?ru1FboPl1jCXlh@Hf<6O5XtgLpIf7a;2ieY$hpA)KZ9`XHFfw;+_==rBr$)H zsYVU@hOu}i7GZCRocKQ75?1Gu(!J_hauBs*?N19tL`zJQ@B=*!JV zFx}xci*EjPB$7P#PaF_;m|f5ur+!*~5yKU*1XM-W5g)S5>9$ddS@qwZ_7$MQCia*1R-Tud=F+oq=0OT3!(7pn?jlb!QC%3@dRPseTwO2i{5@|X$= zuUZS~b)1PV=y+UHabdOA+SX+1Qt0^@_#Px-vcP0#Y!U`;i;lmUNF<2rFq$2+OL+(* zM?u)^`=3R^C$?FS_D&1!&GCjIq|96=5cjKs7J0?0*Z*Q*A2uml@i}r!6H7UKG9yJd z5-1=BHZdI$`{X*YeTL$O)STA#oFCJOThn;wz0zTfjaP>MfdIDQ@xlaV@0QcN&R|LA zVAuPPtgx$<4C<=JxX+L_&M=AZg1Qr%B_jI^C-o{S(x6I*OmF$MZR7mdUvDOAN4y`> za~MI`bbGT8#qLeJcgYy#S+sj@>LRz%Ut7y<7s5~AxY&sJRCd=-lm-(pu*4-tN zEi}pe-_xLO7kk3()I%-t>lc=!m5UaCelvz*t2EJ7goV(+2*GoD^Yw)I2?_=DOFjIH}M*W_A#Mu?MCS`P}N7s*@5v*SVzbs@A5yV!_y17?xLfI?t1d# zjia1p!@XzpmSfcN+Ml___bmbFDkjfx(Jc^n9%}nIB}J7V4`eMT&-dC}qaVE1QOHULd*`vu6IQScL{)cOq9LiKQrIhL$P#qZW<)!&sc@@Ym5L z)M!(7U~Re%r1%bvi(@4;vqQHF3isg+TIuzfe+4tXL9{u>yz@}e5kKeEpH>HV&)7z@ z4D9>}_MNPd&PQYL-XZL8@B> zh5PiQq3TfLa|YK1WiS;Zm)nP!`FJ&vqcLw`#)3<^?9567%zGIUy+LcQJYAhuyxIMY zyQ?%|*K28q-u5>R3QF~^JQXo=Xo=b_!cuLPz$8alTikxB%v_W1q2F!m@Kfq zIsI@OeZ}u!RRHtzRsLmX0Ot5V$Ye@VA(q%z#ZM;S!wj!}C0e*Px z*%NEJPqFPUG2*=?lU>S<%ZeI;+_fpdn;>I|(fV@Sp7~mj16T$fJ)zS>TEx^di^WvD zMU_k=w@mf|yTCk09s=YrCo=HRaih@aptn(sv-hkA>kRLb-{^y2VCANSq`Qu~MU)vN z<2q>xAi5ZmLvc>^63kx7r4ALqmzQZD&Sm>()EVWR1fHBZzDvx>AY+s*GT%7HUcfqx z^Y?@aLf4l{#TH# zt={JeS|6_#X+JSEDC1Y*q9H0Bs7}Gmpq4&t*sIN`IKduzcHU2-hjc9b0b$kmKd>J; z`qdjxXo)EmoNHX^)`9RpOF{)1t#@9u6Vom<<}m=}&`Oq=U|#~j?o60A?wG6G^H`Z% zAmuRMmrLt&(pscT(^8DneP&l4G(aAWF1nr$*&mN)$_1#U->h;Q z_#jnQT=@6-i-DqEYjiA)9pEAnwewPxrD>?lI=V9V62OHf&gKYs2ZNL5Sv))_U8eC% z2!(HSu`*~!*1b?jG{vj{1e(=XiRzd!L(MjZpPkg1O)Q;;q$RFr5deLk9ukX0CZQHQ zN}aB+=403i9?ASFjbex{b3F?oI*=XpPEs&A?3#DIt5RT6RML<8-~BY z+iY93{!RMZx+v$JmV4eOAJ&5s);==x!j^FdVXYizxCR*$)7SI^8&&xgln5ppVJo@&G|yJ^F&w35&evp~Ws0?D%z2VK`|`Ltry8FkCwQy8L@l47pUk=?PJOSTr~UC*IB%=Icl?1-1eINxY# zliQxGd0*=Rc5_)7&}MSu){I0SgJmAySXGBn@wvf&Srp5@_DQSxXh!K6$v_@x8@f1o_E=xI~PEG%eTZa=EtI8fi3XIevSsUxPE z^18~+!Z+sw;vdW4)m}@XNj*PP?sFMS`BpiLx>rdk6pGaYPP~*+t+g&p*)^<(?pL}$ zJg>|o>hr*djvpIfK_8a5?eZeV2)c7n>OO?kix`N?P3MiEC>`kQDi+7G^aowTJ4}QY zg|j0~m9$B@fKaXV#@nT-QOQ0A74n}>^H$qqdmm;yKJ_&*=)$V$9KSQx$wCFPxm?wy zyiv7s5R&F7LZLM;>w^$deA-5F=Zk=8W5INyHpV;2OdE+)1MW?X%anx`1R1IRS5}nO zbSVXKro$(cV~c*0n+2S@a2=DP!p`#JRUsuf1oww1vi06si<* zRB!FKc%EBks2&ek_nxt?R*qG%VQfxdYciN=<4d#&(JLvQtDy-_m-2>U!Ea11qik%{ zdmhq`U?Vz$#~6THfp?Oh7K;lL7Bp1Q;Bd1~3!u=Cs6C3V(7uiLv2{*#n)#3jZL~GN zV;`~Pp9w*uYHkv$V?S&ul?JY}0|Dkmz% zpN|}4<@R#%@(A$XWHky8oDpoPWDuiN$RFNy*fc72Or7VZOqhto;KOGk{~Gz-IJ#%B zpm~qa{m-&sV`9#rogd;trY^IJ@>Q3bx?-B5s=5sUV|QBunZilRBU{AUI#xlgn9%~B zJ@d-)+Pxf%FJ1D42rc?-(*kqz>p+2*IHQL=I{C=yF9iCv zq?uBJuxPU@0Z967Ay>Ek9@fsS71KG23O&OCoh+vF=|bqRrr&~s@_nIcQ|#B&D@KJx zsH+;8W!n-zINqzW(B@4@=Zmm-{PG$*>O5MQXP&1h04h|d zt?%6dVN~C^I6!vCI?u!r=mD2q2q{X#zaa|VUH@I2| zPfb+-kD1D7FJ@O=VV~>rd%>7K{#%zgt1N4O{TuNT!EJ_FxWL^}Bj0Cte(T8#!ju zA-w1teL(lTb-Fh6H-HELZ4FZaz@@%*n64BrKU;vs&iZ+AOzM-#;8|c=IilD&6C*J> z^qM|qpgZB;giDUGy49@bP?M~*7wD+(NoMs!+DIRNge+BqL-5O-F~uS!G-Ub zQrUl{@N`h2NR}Fn7L`%j6e2ZL&(_cZfW(n{sCmg)CXG|@?2Oa4P_P6BigSTA{};kw zW?N;QcvFyciaqXfE0rQXNxpZMuTmiIt>AN1vUQD&eCwOq1RLmgeQknwdB-SR?rYHj z{M0I$i;FlzjW;E(NGnY>!=H1WHx3T1AAsx3gm}fdM56$g=$W`7t&qJju^mUrbB9S& zYHpAEv(((zKwC&l1}1-g$iLApMeYOBs>%D~xkIx6_Mwmc@H|F3{zCrEeLZ62-YdZd z%{8esYRxstB1rCVX`iC~+0h+Bw~P>*EQ3qXDIues)l?Rc>`yXPa>!>o;&M*IbTuMI z2+i;O+-osIn*gB)BM0L#gkVkR%*<(S%3S*K9W%f9?EupcB=z^ z{?V#aHxh|*h#WI5lOw(TG63D;U5OsxOmg+q7=ySCTbYR$J-nU8Mk4c2scaF6uV zEC)_erU1oCoCD+0V^nSxj8O8t_)iRpauWJq-_t+lIIrS{V!!nkuXjQJk!G_UgMg|Y z!ojJXfFZug$G=swa{eL20RJSC8A$5Jb|>Qwba-5fz(A$V$0> zQ=NiA<)3CXwt#D>G{1Bo|4v#C3!3e=cLhxSehp_0EVWRtm$@h2nx*&GbGi59x2DkA z%!qFAO4X-5-1YM>nfP6|*tpp)CF8husb))he;Z432%pQ2jYQi@nT&+0v$%JrUPw0R z545&_ql*H_aTi#k1r^t#e?{mMgR0=D-nGy+2vwq_9h-edZ2glIZ)Y~a@uFKaYe<}Q z5`6Y^>R4h8d{wLh>^UU`uI#ydK&~snKzSGf>}Ce)UrzRT>DL$y0O&5G^YbU7$g4Lr zyojrj4?PRef4)h@%YHxYqK(UEaPp)vspJWpX7J2b_G=)%!PA~%__unDw+MI?Iw^TZ(qGppEdy-X!|G6%sd#| z(I_B)Fd!WsJIKNgevHaOq~w!_0sB!-+)+8nBambjl;1O2Y-8L9XQ?BhT2l6n)S-Rq zl|^pmQcdK~lSTU-)JNDM7Kl5D#(e`Mqi43j`4(6_L;fAF#lWgOI~?1_AT6(? z_;9F)@emy#VAaIJO_lW7E(H<6UcBNsFayET(b2-6=hyu}PiQ>qog45h7S$3q3}r%9 zk?LjN2uep7vkBKn4b2S+k^ZZL-6`D~i;BxAnV3O8uX-ewt)03nMjHS0MDS+?C731z z4;DYC3|HIqVN4E_Z|Il~hn_EY2Ju5%c`&4lA`JLU^PQp1;2n_CGe9SQ@R^>B>oX6M z19#?Ji&m`hGC_{oU@>U#?$C^+L%FG}VlEC>?q?bV*=tq-jV7-~loC1QXPlNf#U%H7 zMY9~V)TaZSf=yXnM8#*~I|Xe3;yWGZgMmAu+N>9$%i$JSV z%mT87&XWNyFrZV0c`EBq<%H(#m?MynX8M5S7`Q~M8f`mNLr++#&*zQ<8jHUpr2eOf zzt%L{QlXOeN2}6w)oo!yJT|oi{7LDlw)6gFuHru-0!V?l6GQAZg1&D+u5&)PbR>g# zCJKI`6o6nDA8M^AT^#+RhG@Q#W%c5j`OTilIvCNIlCK`~}&( zzfCN#@Ja86$y5gUkdatFj()$W%A2ON)O*eM*j06$`U+Ytg2Wz9mPE3N?Fc{^rUJ_h z_HLXl<4&|&#$BNK0{_DY`x2HZP@pgjyxX07g^?Gu>HfGwCU|FsYzm6YMw^<1$$>ic6$a~|F^Rb z;Aen;p^x6Mi5>l~>RlYz9tLE0nYPk@1~-WLV1nQS698wSEgTzHSh@SOYJ8~7oEmVD zY6#N$im>+%<-R>c~< z;AhOZUm-fYV7lYc=eG{K&`jfF4fo2ZIqWXs?83{Y`-4G;z zaGAQJ(u2h`wQ$CrO}=rS?tqE@rIbHK9N4}#MCAeQ_yT7fJipTYgzrLpb_~-tQ>2mp zuiNw7kB7dH{n1#Tgld{}Jt}2TiS5Zz=e*D*+YJ~C?oKVz#b?DfKHo*XLC!VW5^!9L^EA&flEQ$ zM>FXf6g8;x)?a_Z@x&IJSI^@28`*&9W2vI>Bt>1qWEokNRr$0z0ed-{&gOeg3I!5a-?bestD%z#x<=v8)s z9$<|)L!Z5cQcSS%W`7Gc3(5YvbM`M3bZj_$1$LmxNZM0H>m+3xzEt11bBh2bF+wRi z4EJo@6C^L;k`j1hQkqfjYtVQ@(sfEP(;5NLK%4tB+(~bwcq-Igo)!H^XKOMEXan-&FbkSN_nJp%5~kCm%$;wP*5TK zp!zAve3FQXJ-4lb;%OV>7XHu3hCQ~wRUqD;>gao&-dB(6EO_=neH@8Nl8nX(23`J6 zYk@W55MR`zB_DBQ9**^%@DPZz7nN9Hhm^V(#XD`79E2t@bgwywy%FtTFunIEoT>;wG(4WZRg8Elo5MOcH8W6L7Ih89x`lIZ}^zto{b>x z9=6A+*gV`q_r`zz(b`gy?*Rjc>nuY_s`3PXdKTw4rybERuTex;PcSOGo6!-aE8teL zna>D*pM8^uAcam*c86Q8R8(|vmz$bj7@uz)fvr#s0Ok{MP~XNNQ?0$8+D~rTuKiir zRdEsf$BVPu!TyA%H0x?AUCe#wWTkMrQHzA0=u@uCBz`WkjlpL1VjM71rw=B=JxZ8J z4r)*{ETf05S7$f_T;sVT^pc;@!jFM$wv~) zK{$_4fJ>I_#d&oUz2lTvyhi%`)6+%<9K1#;vB=;}$Oo|veDAM5QAlHvU-|=QNblp6 z?g}ilIy6I*`-s!MI)MJ~1!aD6FKKE@z8e7V0?;{+lTLi2=Epu;Y)Y{34)G$ue}9Y; z@$-4#Iz)o0HD7LU96?frI=UT%{b^9s==y zJcNl<_trpSlR7Ff2uv?hGm4K2pZ2j<{xpAzpb-47PioC1T^GEOK)rTAVO}!|6-8u# z>?<{71rg!%tc=%==r&S>F=7Oz%5`FPl-axMTxy!?aH z%5KCeVn*O6>oPYX!q$si0CjPs`j!?E#FF)}=FIx)h=Ez6ut2<0s}GXsHRCt5f^;XIm`wiw0-MqQTkYN2#n2Y z=72QIg{0H&gL2vLls_;$X+ z!~Qjo)-#nY^F=N!W#)*DCw+M7`}&~>i}wlxBDYhh@pr2QOG3{I3Yan|x*Yk)K2b)Q zmQ=st#i(nrIWIt~zTo&S7%#w-qe#@_ew0h-l!*?cv}f@Bv{6owe^=;O7%LOEWSJT14`|wtCSf*&zA=2#P^H+yCCRMiql!kl*tPN1( zfrAeiMA*x0(j6(w)%$2`-Npkrld;6cD^TN06j0g8ax>%wV*<(+cIZ?klsTCz-U&5+ zTzV|M!|u{C`0?3YjF!9?h-!H8YxZ_Zc*VPX^%o`6r8p-XpPl|VUidFpFcU<>=AN=r z$$B~GF|3e1@$;I8Y0Hip@+^qpL6GGAqb_~lCO6Mk#F3MLU@mbc%5aW05>f%znI| z$iZd5sPI)MTF^`CTs?~?2ds7537^^oXCBQEq)co1ei)nyySY$w&ankV0c_oCm&+hd)UOj_oya(^x;^}2bgtInRil#B72 zns(E&wRx&X-rHBe>&$NJy;hc=w%=crhxxTu$H}}N_2_S@&g4~X=tj|l>C}qX;GwHe z3@z`uw=E9MD~VF4v)R?vF;5Ld^_wgj>m*1L z@PZldtLKjC*|Y;i6bD(A*m7S+NuE9gT`%;;Ku%a(Z8_0(Zbp8vVcT&I@=cL@sED9% zgh<0rB7y(|l)w>OD3Mn~U@f;<>8!SsE5h`OpFA1yPK?#&9wf%4ujAm|hm(Um^8iM; ze|TxP4prJdEfqa;?Ml%$N=l6-Q>=AkY~Nn$5q`z19LRWg+G~&WkXC@NfCViQy0kj; zS!gL^-u{}%zaPU&yrR!7`tkFJ z@`~+#1E>`VdQ~^smg8zCJ5SUX+#KnidPu9#V}VP0a*Le$ygx ze8Iga?c`z=RerPYD`HMm1&l^&CWKdn&jwv`s`rwZ#QVA(S*f*F+z3S=cEE|GO$HQN zEz}}Uy!SoG^ab=;qXsg4EYH$rf8d$*EPOdYs&-G~ZFYUw?i@6Q!MMrqC(&;D_T8UfK9$JG1y2&VZ|$QFn`!G;yJlfR6ZUuttjD$h z-q6N}HL{k^X&KB%{D)h)MAoi+5{UQV+x)+6TflfJIAkJp(GK5lPrME^d zRtop9R51b35s&c0z%=HEeHTgi?YU!&*7$c$z0mLo;n*j>3d%n`Q$lKo)V34mdWy7n zI<2pYTrekTFPo?Mty$hQAJV7-aq5Ec_>4Lqr}gN)_Kn3&@~yLvI&vkt zWti(LBYl*x7fEN^=j8WN>symu_{U_<@8D_w%u5OYsiw45BclFV1u@!ZJO%Yz+-N>H+o@do?<8!S_ zFF*qOCpAh6<^szU+5cjFiayqLLVYl%W!g%`&jGPbfmpbQhBNGJ0lFbvUB_HpEOk}{!$Vyi zkCUvbfbVm{qoyEGlKpvb%jqluI*41i#oNd2var7})K7uz#p zEEh}?Jc>tydriHEID_|HcpX&Yk7At#jag(40^h%2dPK<#9ewdUO2Edgi8Rzzos=a} z$m=9C@jC0Z)c^Gyy8)!kf)lXR`S1Gk&3=92~G$P z#9u7r)lQ+5%=@vy&8~5r**fxnA&r`0XWBOEd`Sv42myg!2s!cQCti4=ef7K>fiXDS zDxI16S4yht#mjOwlKURR^(h>XML183FuyKX{gOgn#kJ5^d4EsgTj>YKvVu4N#;qMG ztKwk+;F|0jy?Z`Kap7eOYRC+ivU>9Xy%$uwgo8&jnN~)SV+T3>P-h9@RHzo;%mAf& zmRokPeQQ|>C6v5d)^*`p@M6FBusR0;Eop0M==7m6`M&zM9e0{TfN`xi%wl z&uI(6`f-R~7Hp^Rwu~t_uT=k;*K?lfo&+(EL<*;PVG2C`c`W%3tuMGv$TlMu z9IzuYv{2@%mfY*aF!P8F>pYzq%5iyMF^>c-?F>60qByGjJjL2ikZE>`GymZ=w~l=T z;z4S&`=%{-Eq`&9a?87FH{qed)@=LoTedg9j~H~+m}na4d|^l4rTkyVrh)iiOmZt1jrt=>3PpI6v*t0h~?tUgY6YbhwbcS!?!|KsZbVJNG+F z?Pb}(hI>aeJBV2@qsAhvn)N!eaSVsUF|s;cDZ>-i4`O&$#c6L0Ue zI7L(c9O+1rEVxziP&>Qh%A}WcvwYIh?yc7y%A>WAz0&IXv#U0qZb2{+h=e4aTZ+?+ zEaWso-YQBFJ1|tX@mHy5*`O*XF$br(V(f@P`6oYGhXE|hupaj*I7r31?VqNchPVzy zkb7{Y8jSfCznb%#53$j#35+!}QLi-+Cqb7KvY<*(mbyV+-A8N~WrSf%?k68dE{I@8 zD?e1jb-!>cyt1`YuO+rP8E<`bI(*XfynTGS)ChM2u9-R=S)quj_Ldrkl{{ggwPro_ zNJP$UI?4rGiR0$0xKb6y<;0hoI>t;E=;%AfJ3f zGBQKzdkOxk?E**`I)YTv__!9G{_4RTdJtSwVoqz3HNb;lBr5*%J4Z4&4-SNeZcN9; zoR&9ESCA>)=#`}+r5@wjD=PJ%BiqZ0=vU4zQy7*nfldep6=@WYrUOXcx3?#}TkOXD z^RXbdOT)p7r;L<*L9(1C$<_+*S&!0ZCegtfA!%fVb7~8|N^f|j(Qr0&{rV=M%w$a8 zk9&*4X09~21p)YYj;5ciAQwe=-A0^?6ZnQsNJt3quRb=J{#g~+_5%!bk&n|e9!k%% zYvG&Zo-EdaCA6ft5j`;doaXxxWRlI%n-FXpYOfh@c5tgGg=r_e}|o#uw29~t0i zT5LV=Y?VTMYTVs*-DSayaBtEuh>}L|;9d;?Ul=^`SfBKm+S-n!5hi~n*k(RbLF2&^yu*gnn5 zCH)4iT#!Ic3I%fxQMxb*GA!1c3Zsp^oVR>z{sK5l8Wj&uN%&tOBYI9Tl;ro#gqK@P z>PNnv5wAFsR}kGwsYL`Yx&QJLg`i|pY4rR0g9us}hA0%QEcx|0l?PuBG%?7MSbE(r z7375hHVWB9PbbGE*r2YsFs}Dc2|t&neNy_k z#^SxQKS*jSs+>TkR|QAwwTrv!R&TNDn55q(8=ijfxsNj=SZ7)VpkS zXDe2>3QB>Gk+xAncH$VX5*UN~nqz^V#Gur(DBXJJeT7qDr7J){m%*_qm?z7LfBS<| z%v96nmB+as2RA|w6{`SpMDw$T>WE!riF1oOjv|t-oRnt>F|-_y1(n#Cx)x@bczBH31}oVICBJ_ zdpDIvRaR%r>pG3hPimLNsaYlR{V--d>64_@1Lv2%A9B*w4s#Q}t1ISXmwj1RuZq4~ zBVL;`Q%yqb^Kf{REH3(v-8}WNC0jF7n=Skj3f$8$l1G_Y7rDn>5Ci0;(cv&VCpgp?uQe=hM`oO36|Cv!Kdhr`;EjR{LsJTfoQ+~J@Zfqa}16#Uso%t?w0 zzuxrZ-K5IfL{v1H-=V9lxX`xwO?2xp?`7zX3ALOZ~+z`q4S|{SB zka=CGGyMdvKH5hS%%0MIULBt>)hDD5zcP=4$}x@4n?($3G5xPo__Tf%AmB@- zDuZd$<<4R!EGp4t?zhr|&o7q{m38W=f>hd6`v5|&ouIN{;~^UizzG(1&lr9eo59I^ z5g?_DX6nwt_aJm5@W;LxZMo9TZIV+&AR$VH4%VXU&kt}XGt?!BXEWok`ZU?~0RZvJ zV2N#GX1Xt=xlW=ML8}rYv7BL&Gak-wWyTGoCe5nR>DB`nFWy0StkGO z!Ud@53tn3ed>LN|1_~@VDauj!LnBc>Gn{^a9Ul5r=_p!r3wW3aQ~)7V`-LrKHy5Ns z4L|UU7Lrr0U`Zbi)vYV+&zY9>HcOi@mUv#*V{dL0y;{*~_>WJt>{kvTA0u{@E%IHU z35`T!lB$98h9?GwF_#mKjqZ)(9_lyfQK-N@It-d#*6~aF;7m8q1s|EPJrQO^vEPXa zF)>K~(?HUcj~c4aflbmQrHJ-LLmm}~JTuQAq;9x{3~78rW5ll>y4CY$b()LK(lpKm zB1}L5QVu1RCe2}KJ+CvY2mmXCudWHQ#N_D(TDy4TCmxU-cUPl>vd8R2;X)@l+Tau2 zKEfI~uqUm$nS9eWq0YGJhHC1_`8Os;*K*EQN>`=sseVV+q2Oiyr!z|+UA1FAmgItT`pjLMIh_Wkl>S&taS|zEQbZPx# zWdxh6B{w&vEL2-+Z{qZoTnzD!n8shfv73E&Z%WnVN86}6USHjRkeh* zYk0C43Zc&HVYSzSQ?xS-MAs^Qwn+?_K76gm`R)=+ z;T0_|+=EfjtU8=A+_+__NfYuhAl5qK^|04cw!=fwYQP(yh`)v4P5$LUhl&=}eB9Yw zBdGd$e;?>~=HRKM&h)TI#iyUhZnKYJcrmfSq5zwKsc&w}?m0I5c>hn9ZZX4LKdL~$ z2k{AZHS`h4&onku(}^t_wto*;WP3B?kl$v$Ht>gytGJ=Y?$#KW#Z78QnE1)DcBPr_ zausy2L;ZY$d_~(@ETw*|J^~DHewNpC#Vsr6IvWTtg08WC;nN=hRIC2h4cX_WWw9fb zTX0M2*Yh~){JMoBm{sB%5mF8b?5t7QxL_2~NKI0d%ut%VF;h<9RLnplZ_q#c*c{nO zm4zol#E-x#SMZ^F^sQV?8U_;xzl4|0&fzPeo^D{Z)2jqG@o&MR|-DWllWGK z-O|C{Y0zlOi(q+(573;!F17!KS)gnDi&xXv_mHuP*^^(WZk#H9F&A&tfgUP#Q@3p( zA+;pWB=rr?y5W}1bfg+p{#zxYw6Js{bdpty$1nc==pYmUsG6ENR)oIL8+;-Apg}@6 z6TVf}5&WznH-m*(Hm?aPB&1-!^|FpPJzfy-8XiNpZ1*iUa|LyI8VT@WbXQaz>g0j7|y(qZ8o^ql_ensM=>Bs>cAFZGsavc~t9 zi9kkmeG#h^fd0??R0~Re8@i3Ekk5s%^;f&q)YFnKl4l$qJPzWNHr; z$vH^f8`MnYSXx4WrENSZv6(g0;v_(AH-#!g3M`}pT^$?|3%x_T#O zseEdR-`eZIE-lBSRQ0h%Nn<7uzlq=gv6Va!tUcc6I6?a=%o)4b4xIjVyp896g+_G) zCjDm(%UiRI8jU)}h!(_~ZYjz#>5Q}SsfZ=i6F-+!@bv2Ofao-^?IQlTT@$7eXm5#h zJ%Jrt&cUy6x^x|UjP*El1cHBQ2{i12PDNQ>8T zm%$5cV7sC==L-*RowSD^lC`Xi6mbF$@n?K(7}jG{Lw|k0m0I{>wDJmZx!iNSpmqcR z?PcHzuC+fZ;Xx7-R0dJl?MH<7C(`VGLiz$GP9TsHC#P`VhOVK$Bizyv67# z`r90KhNS^;L6fKS))x_6gL*gi;DXGX3JgoH`mATJqs~E)$Uj?ZdYgGfV+?I08=aJH z_@)>FT1IrPMi0!r{%by%L zeH!c{1&)o2`RK&z&{W&?<4BANiJLUvF4ZNTt{Rge^yUEc7%t5lCi){+Wpz;U^*b)% zIpj%+zq0X*2kcVNY9_}=|U5S8JN2bNJ8eRQX7!@E1b>(qz7YK-j_b~ z#6#DZGd0)Ox*_uKmyj$6^Bv0ZY|hXv-wR&``g!0%i@HFw^4nThb3v#A(n&GODSz<` zv1Ht3Ni(Qn#)L@65wy4_4DDLw~ldZ&pBQ$g94?4To6neWc>>1!|i zi4xw7Us|5G-cBVe$3X>>ditagh1r`3_X^RzIlef*P4?Wjd+7Cl=!=QHaB6O9K08c< zrFR+c=A^w?7}`M_c;)6PCLC4}#{^#Uv8`^eLL-Q*h*Pfx@YxfIty5kA@=&DN=rC{1 zd8E^RDAA;*g9uKapg<{>;*tzlld3Q!ZDbg)b{Da;o0dm9)EPIoJt$+UEZP|xHQOCQ zTZ#5gcGAEk2sr?T&#x)0pb7D!jLJf6OXNb}v^ksITs7NDD{yjo?sV`#H4Fv38Vtn| zUeA|wKptWQ5EL)rPMOpOYTAcXZ+)Jx^~>$7!a^G%IQIZuqs-{FE_S@7$zH7PC79Ir z9=7O>_)=2@5Zs@*@!w>^1XF7V5oQ_XPkGt28=9owCb_%h@y$t25XW3~UiD#Z6}o1^ zPkyo0oJZCwC&jc)H$VX%(7THK$^Hgwp(zsNyq4{usH%L6d4OI1zQU?q^1Lq{b6&Zi z36Mhq)6Pq&5iOM#Ib&|m2BgrvZ773^^uu2kgC}obeN}Y7d;o*O^$=&-C3DsSeqXf( zF!t)`nGmA3y)oB5Q35hH7ei>5)GHKx2541hvErG3NgL2%LL|*)HRyuiTAwU*ngR&F zSz+5LL@8Mq_8+Qbuusm64J1Y+l7^$2MtgotBG@chGQoED|{ zflQzv+)2Cw>u=i2Glg6e*I7oJvsV;nsrt;-t;I3zSf;@15q59s5o%djv#@mUfidAU zzXF`2cQBpOyWhDd4eo*=p~@gVH;D+Bp69@>ARC-NX{&lm;4d%hpLdz@d+@?E_Q9jx zZ8K-E#u-g$2r@5N;*^um-Z@W($-OCwB~_d28P^1$hHT`oxI?~XU!$SchN^AZfS9ds z=-l-=D%nI?OW(`M9<9>V1H{Y$PZtR7{ZP7;?zs{vEck+@3{n*TiZMabQN$g#>kYvI z^i{n{l=9M0y%owO8!15yW`}XZlC;* zxrf-X3Tqt=-w)Lwa`<-_j)zndCMfkNsf}7BkjuuJlr3z!kTn{xaQs~albYYdf-IIl zTPZ&)uFiI18hx2pVsRrrZmD|U5efOe{1Eej+JY zCOWF#-!y{(Y=DGS0|T~r$*3=}BpVZ`9WCTkGk%t)M0$oPiDQ6$0B8oC(Wt|n?_*8w zaNL&Dk^xUGU%6fsNV2i%*x;;M@rEKZcjegg^}n(&W%ohA1wa`QOf@bafWNi%8~^E7 zDbg9>_zDE^zx(fflhN9h`xBQ#XjKLp%P|G6HM#^HfP-H}8nQ>8WTsh(L-&=wE=M^ONAb z+c;w7d84?Occ;ugE<;-dvgDd3N&sJUuNOh2lAx9FXXSiLvuqZKp6KS)XCS8Ka3Tv` zu;<_AP+Z^XAk-AeUFlT(iw`aN)wA|xB7N+Kr*R5Q@aky12k-sZ_7E%f-PZ|~Ww?Dk z6Ntm^fX@_eb42@TSZc>}Pk`+`x}x15SKU-1GXgp^+ zWdf~5U;%%dy$*q7c-k3nF?lsZTYx5(bpfpH(H2q!LLKOz5(A&tnuSFG4jsjNyXEp+`n}(?k@J9<`Blv9Mj@A&zN4 zA}+NgXf?smrv4~wiKa!3T`#slNP#exT4?%|6fHM70cPcLs+T)4=<3FyLX(7w}ZfC8$|@bd2ZuLg!oQ+ zlZ_LCKrwf!(496+wG-ql)g+dF`qcLSxQr^r_&-c=sK#2Z5g`MvL9wW?jX~6Y^2tT| zO&-n=E;71<(Y(Z~A!1rwn0oH`3!txh8d4H!N~JYL*&H1OIje}pOIkH$&9q680Z0L{LjDwW&JaZZbBwd5 zvVAz-m9Z+E{<%|eT>9qG#P)%cr#YZN4)McOnoRSJULNru7xJ7r`&U}VQ9y>_+#llJ zbBY_e|8=DPtnn+}U%Z!3sMG*@ySs1-D{R2GtUuQHfTfCvPrc&bMIhIK&Ef-1IML@&Yw%qKHKV zoMaE!`TkRzL5Sq`$st7T93*J}6U*cU)T&2@pfwCHc)G^g!YiEB6|*WDYV>LFwdH!Q z0X1KJFI8a?w2H?HeHq!SKs7eZjfL=2l ze{&bTWZcU`whxK)Qg1buEF1^zm`_si5me**Ix_uUw3{!GPdY~)IZDWSTDS-wLrwT@wwF9MthI8akb2ZcN4!INRpmZM%$Ro# zR^;D%56EvSI1fjdgv{u6-2GF-VLkJ59-h2J&hhjm+R8AU{$$S?dj0pL2faSJo zLp<0c-dubshsz(Z1qED}hq5p+B%WF&{B|a0$)o>MIGU^PlH*<4Jb-Ee%!{odeU+?{ zIE8_%t<2Thvn9T1a@nIKv5lL$2eng8RwyoIvjCBtrCO`F^V7usdpcm9@muJgpV4~( z^)dj0QG=FZoZCvgtxxErJUwPY58wE-KJE1x-kfAc_DoWp>C%F_B{5zL!dhGnURt38 zE_Sf>iP0+AQaYzzMFo1F?0(F9@hOE~e$K>g@}&DQn;aA#D?ZTjHL{Qf9>P2gl9%Wz4giev55K|`t1U-ezmu;W%49;ZYAkQ>#? z#<`iR@oaEX%gpA$s@rrW+Hif2PI%crDI+2lw(*68szx=OiOHF8YAhuh=kIv<71xp+ zi2dTrcA4KfcezWXupMv8gkiO#-*Xb-H|CDL5}Sk#T`zu4H?x2qFAeihe!NgcK!Jzh z&2Ap!67kz+3O<)L9wgj2R(4!&>~pCqj40buoV@h;=}AG}7(DemoHeB;L9)mCIUI#t zO*f|?q;I${6q<&cd_p|v;qN0jPT6y4O;#ZPXvKph%m!YC-l)fj>VATIbc12N(VdQ_ zOTe!n-t}ON3~{q;e~9{0B`unk#apr@yy`F1z*tKsS?#p+bwUq*PBGZ_RKrNMQH#?c zk-U*^s%3^F6ToY=F#th&zw`nQZvlaJ0Wz(v*f80U3n|7J1iWgs4?N~ z{(Qr|87(OlX%$)7K-GKIqxgC1IJL{b0Duo=AK=;%bwV1xma;b#i7cy2lgXKim*299 zg!t@+?LBDv2+(yHv1?!%bpE96t2r$-g$;*BnrN=rn`_HGY;_^QnI($F$<*1eNh%EY zMg2)_%9ho{ejb2ygp>a=W8nl$6sHDyOZX=AR0djL2NKwsnq-&HBUxCY&QT ztel>vj+~+ym?@C1?cCMzowyr&?l$XU%cLU(f~&mz(3CEv4@DQIIB6TaQ zm+0SkR=Ve^waGHGRz^<11WQRo2Qt>6WW=32J3GLmYEA7COcsj+!1k@!4@pZuS*76B z7$w1~=O-IaAyin32iRa5AW5nKqn=<33pI=*te~=jMRixC)+dRh}uJYo!!U;_3kh$rp}wek7ukNDhqZ^p8)1* zO{zZ$ST*nQGh7W0_G6n)rpW-{Yglzr+9f zW#CFOxP?x!abTlH#Rk4O7WC&|WIkbk04+dxTZ39^>>yd!$CBk(ABc+Fb?F=fCdlxS zx#1E|9&rssR%X_>sbsHxOxozH5j){_KFd*og>vdZ{It>NvAKt&I}yIPLHS5({Cuz= z9zsD8h)KbNV!r2%rAhAv++yakN7V$EwGy0jx$o?BQulkXdFLFsUZqeW9VjhMaSSJN zvosQEx3tst7O=ps*UM#C?Mr#TC!uZTOza`02lZzyP!=w+68F_Q zhy#u~5LLp1k~6j`L^fn{YatHn@8DDyk1UUvajZCR4vDSm$Pg#@@n8-O@fmx{K9J)* z9k)uN#w6p~z3nU2CZMRKURKKg2OS`OVd>O-NjT9=8GUZ&3D?F2Mp>09DoqCAe~QGz zrvURs41t&@gCXE_aI%i-4hUg$sD)DseN#U}VtSn~G$$=?z<^flqutn^|C^K(4!Phu zXe%CQfoGyc*hAz~)S~IdD*(tXjNp!hjwHntk+zT;Ce0hxw90qGl5F{DIt;<*_w%!9 z9cu4=qKKZj{iC|qJZw~W^Ke!~u&@Eml1;t@Iw(mg3mwMx>+m}aT@FTQ+Xd^S%$ywdRSpX65mZdz2{>nqj1rljqhE z2C6CId{zm@xwv>?q2D$}!}D`iuMROWpG}R;BlheKf+0->PT_&#RS}Hg$DLOx8@Q1j z;veY7dAqHFi#)09zZD+ZEro2Ty!DvV<`#SQxxtAr^dfF>k-*$YWxdFcjQDa!BFn5> zmI)BTKX&ZOchc{3b(#u#hJNf2)sG?=X52 zSs2H#sfa87&HO|L@bhWk{J|L@a~|w3ZQ4`8+0O3s3hF}ol{DbR)Y7>f#((OKzH1#b z*R(t7{FbRn3y=;}*oSVJ_tgAgksA`G?QW;GcJS+(zc3V{rN)?Dliih75w3%2!c0aOS=CR|Y9YN7-?9T6w=Q#`^~=^)Pf<1_qlmY^2O zle9Qq!3xFga`gUE6Gwv*-fa|kho@mq>95J)VaS^01*6Z@U^*UuX}78`c$LY^;UOivB4AxwJR1I)xm=ly6;%En@RGtRmb;w2ubrE= ze7a&l+8b1%i&q!2`6@9THS(GVU(r(6MxnP88n||$uv)&Np0vB<;NA2F^WVYI z#$|P_&Cy?s$f2*%b0tk}!LWUuzJzKEl$2D!guMVR5_hTvJ`eP?9#BcHPNy2k%E(p- zv`xVuhs9oIktklZVR7qgdw1|P^uD03RB6XCBW4XoyAYR@=yh&-FZ^am#OF$3JD2cI ze>RY{(w6OU5kJn-K%3p&dX)7sk}ebJLxOb>91SBkw&Vsq*u{ZTiKluU#GPYX4wg5o*`+mFszjgA144_PJK zU`3gDSWyzP9hWr12@L_a4pjR`88K(KpxtWJ>Acfy!tnpsce&p5i1dCj!+t`oWScK> zE#l7Nk2yp5Dy(4P&mmPk=3jwjh8Hb8FJ+8)%3$R1RL>Z`%o{aHdWV&8D?TvKQ&@BLz~!>hS9T~C zZ@iDGg3SziEmfMh+5q+d-a|5Vj&ipMo8;QUP;uuK6kSeg*i7nR1*{RC$RNBsxmj3!$cQ>24Pi?3!e>n zbNfAPbmKmPD~eFt0>m8UE#6=(Q$z~$%Mx;4GLod|M{b~D*{kobXK=C~`CYruz(M0w z`JVtHHXUpuX=1_sg1~f$a9(SAD6~%hVK#{%gC)^=MlDizZ`yn^d3Fjvhn2&B^ctKC z=y`#JJGjLHo1E8t$x)#c;+_q5=2WQf0D*3_pwS$;(I~DWxXgw{J0eQF?#z zDT=!_pc^A|WMWRLRZUN1?h%|g!n{o4T*6PRcQ}r*nJYI4~UnRH?%W1g}p z-Hzzw{F-?fA{2R%G5Tz7b(S{P3W*IWEeQ)5Z^TqNQ=m>F5urtWj^AXUkIpFZncHC|2{Ljz6D}+ zvFI`y9952r5&i*>?XmzRdT6hy%@~~JW3RX-k6R_I=*ef0LI2FqbU|5x?!ZaqxJ7wM zk%p#$?z{S4rb&NP&7dCxLdV(pGd>Hr7t4$&*%bJ@B&)6C$EN_c5bSY(*BiX*|0!zI zkgi>e2GySY7-_*WU2vEMLuWHZ_Li;sWw< zlg^){zm_e|2khi{e@V1EO(FTT2Flhg)OZEt79|r@>U!Q1)E=O#0H<@c?69R~{Z!g8Pl=W#WTSYtL_ zF~$~uwqD(bLPmfwyLG$93e~qS`;j9Vvnx;jXWwjjM>s#fmMpChRAOqm^j%on-5>{{ zG;>!3f7Gp>HbmK(+5UUyVi`e?DA!&57J8Q%I7&`s&}U{tK6Rj`EC2mE4Tgd2Sc;gn zMa?12S3u`QZiCwsV`&S8wqY2glD^3B`?ABx&G}eb+i6cN0=1H^9M{77)@wEIjO{Xb zw8Q0S5!{tNDVTVD!l-=(8K%Zjc#7{CZh}*pcmZdz?bg;Dgp3zB;(3h^q-(V#3bJdB zDLRr{gy>{dxfXkZJ0a4N^}=VEHODl0I}sv-Mu1<1PVj_T6&}ay3hLPGPjkJv%~dSp z8CsM)vP0BtHs?|D%*%ZI zJse)u1sv$}EyKF#uEF1jrCzMz65!kID*hUd>4o=_PI?3?N=r0luvvmJ?ZunLn@`)P zDp)IN=h?%ZlFA0Tz{?ws#gDpZE=AooO5a^rixF6@29y(U9$$)Jl?OvSLhSv3y@FMK zmdvU1pBRZ~P*5(kz2=X2^+Oh;EwHLUvWPZdFb4@DqqK0@0*ztdz}0#$tF@Cfv2Ix^ z!nsqM*qh6IuFr{$r3Cow?F`O-Bh-l>1HbP%cdfi^x}|)ZAM>JVp8(pF@wwtPs#N|}QhP%F4KBvYt3H}ub0QjZ z_ehn&DpNYKl?sce&|z!dWM?N2x5TpxN?zYW3*exao4&|*Cai$uEe8g=^HZE<0Nr*U z7h2ko$3RKsX`BcZdY$+^Vvz(z`Qs#0$`%AfKHm4$4UonEne3!UR9b@im=Zv8L&UM zGqNi`ImnuW)9h8=<01|_x%`yb?~CntL^Uw5HsHvef5zMVFCoVxYRfv24@u@^e1gSw z5+rLtDdcj@;;+UPH3Mcg@o6zv4PPXnz@bwrHN7ibhJ81yYpm1yg2r1pI}dS;Azw=> z_z}HlS{o8y>@Tf3D1*8@aNgHR9C158@7QsP!;4=^HW+v>E7;(uBZ+u`(dY{E`GECB z#E{y^O>z*Ij625jLjzhC7SsFg(|iQUWErVMX!u`TV^?`cmem4X3dH1dH%k?fjGSb_ zIhA~bk{m6&a%v+?cm;LIjtxBXzpaJ-1@Us%r&HC;e?Kfqv(y%<(?e^rq^lSIr@GihqG9d5Mhcad{LphI*vuLNdetWA^V#d z9vC{#wk-yzj|En<#*uM)&9cbpe|EwBn#NGy=n(hK=)nwWZ;Pw^NdKxL{m0HQ`ELBr4njdjPf=Fg+< zgjEY*qc~s%5qNHbyQF@};ET>x?OxH&Jwv>B^ESdg?GUgpr`Llrm}RY!L`|2eLekp< zOa_hs(`5s^&`Td-y`* zz?O;sCR)O+6yV0+<3M5XCBh!y4FN*gCGM0zM;c42-cH_@+kKFnL)YvobZP%W>mhZ$ zV0hM*c|yLgSqv_=3Wp~#1nhCx4&ij@W4aE#6HinEw58pXCkLmmMSEn15~SyM`d8p8 zfO^+p;oR!{+E>x;mbdSD3F`Zdeb8Q)hnd2NbL-w&G5Ou|O&A|inF+YE; z%VI6FDV<&(#KHWbFATX`Yl^&0nGU2bD&CVH__LWm%7emz^oMxn;?qA{$Cq4Nb;lztc8jvTdAH@ey|oCDnsmLCweJ0`w}=p7IV5})>Oid z(26m-Ug4nL`)3yN))Q1AS;;YrWvTP*903f%3%_Rib|`qt&=a>~@o7ef_(`tS62AjL zG}GCmpz5+&J3Qr81O>yPGe@Q=NlfPUtmO^fL#Cmogyra+*aoxKj?&cL;oqhg+q{Wx zi2*mpE}fG!Y?%I3(?(IK;2nVEB1^CtJom5aN1hKk2<{BuN_R{HuM4o@NdC>SkZSwb zX*3p5If7E&wgF(n35j>oJ?O4?9N0F78s884zqiIfcx0@mIMBweM6J64+hLO6@~rDW zB+h(XdJ-Mf~w+qFULnGqJKgoLGjS3#M9h z>lg7$Jwh*Jd-+|W7lUGSp?K62KhiG&;X#?_4Z6DpfzBt?<%m@$w(F!fPIH7$Isl6;tBroXd8ZOnP#)HbnQHsVl`o}c~KI+ z61tB{9F#lKRVD4AM(e|+x9VE5mS2r0MrVJK1P5b-hblom5=h7vZO#U0Xi8Ho6F^W&9A<=D)>wS@@4 z2Jo@~bx^c*eP`q>`cXGz-%5>gwengM|MvL42ZM6-=~`Sby9EV}tu~YdY0D&nT|bx? z5((ff6Dxp6V&kfjWIPUm25)~QIW!uVn<*6EU6oive79pa7=hH51+NyA&c zos?wxB#E3^v|9on#sWe)IV`q@2NA0MWV?}xy?;! zB2G{|(QV=KHyU>-LC0ttFUN#G*G!DVsKsvj{l+^^Z{%Z|XSdh<>ERd-e{-v0XpCU; zyzRsekkjTyWTF1~G`*FOMF=TsxEcF*_H;3tWxgF44&BRfGb`wzG zwY{d?-i(t&`)}(zdIiiUv{8C#tjfQ*rP6=#ReizK1meXm6iX3Wpg7YWD7bT8XkMP6gaGUZSE}@Um)U@=BXNm-f$VPdedtgIUGM z_u19mhqyx1a77VNs6G{>@bDu!Ah?iRgxUZ^xu%wu9hNHQm9&9bdfZ}XXm+(6m z0S)`A%jN>h-h-d;f;JiGmiTnl?1<4UPBw|;m+|> z_ho8g`OJh`Yg3%2(%--Y#^2r??BnpUA!P;8}E%rR465Rob{e_^Zxxw@P>*RFtacFwMYS5_PvA=LthV zEYg6>e&GF&2~T{%go~z7Ia_{y3;mGT9m;aIL+DMP27rc$#K>WL0}RGK7O<)yOeg9Q zM2rA(Sr~Dd(==_YuSVd8;R{e}sVaY#?4B}e$$9>>&X4u1@UoZ88~MYH5mY~8pebL# zEjsc|Dn1^}|9IB-!r7?}9QX!DzVest4(7cjiT2drpF!(d)%!?%{dU2Jk5G|jc21TF z{b@b4^{5Q5H4s|Kk$5BQ#P!>wlf9kyNiXL>&D6^j%YoV=4WcwSd(g~(PoBf6^dE?8 z)sBXRUE$xUH`>jD&_>LFJJoTrD1qQ%N2-m6Or+NlObo)|lx)j5VX`{7|%D%ohsS5t@EV|!301fPZA8D zCwi+T76yzZH`>(YKSyw4$OJ7bO5AlIk_Rl+6@`jV8sB_>LnZKDo3@shAX!-G`Mort zj5)jE_QFvy$HiM<=nh*XeKjK5zKcj`J>()&_(xc~<*=q7CG%5^T2Zk6SnM=0q|4!{ za1cbD2vJp&f;racmFOP1CjjUe4}+T7fW8EG$b?^p@S931ZiM;ZWo_VC4hZ1rt*PHa z8g?6{_zRK3XZHC|bjtRG+dJ;3S-@l~D#hK1x&I^rvN!}LrC2^miv=hgjzJf(2Pmkk z9y`nFG~!|{$N%*Z0I@;GN;F+h)}i`#US{SAhfz6#aXn)grdcSGu?OE@8gFo!LG$wc z7x!g4H0j`cg zb;InMVAd~O>n7xA0PEk(@)Y0)*Z*x%fwZWeGzgdVK0rXKAGPfMIZ{q~(Nn|75OZFk zdwS$cJFu|VF>cQY6&-rOvYA^gr*KQsW0f8VdE7uo2*NJK@OTC39+2&iAx?=PN(E5DJFsCbOsx#T>FM9UIU&4f9A+T<*@h!2m6eFVOsPvE*yerKY znn&dq*qv;$RWdeGUd?Vdc&fUAkQo=3)gSc+@Gee~6pC58c6IJ@l9~Q|Y^(jyslfN3 zK!y`^HI>xThC*13DrlS4hZFn|VZ%!)T;bGjRLM<^967NgJ7?Q;*K9E)pDAZNm3hTg zVzuJUaincU=EU#mP}QSEm`bq_nZA~M$m)`~U07H;VF%@M`BCxJkDs-GHA8_9%JSrNEydl1C;L?RzA9@Q(D zBe{8#enQ#4xA^y0q6;t)uONg@bwf@fh}$j6<~jgDM0Ljr^^^D4>3_9?#C!Dd_P5qC z<7$n0R90RCMVOb7jQQHR=P$w-zV($2!;pR^vQ9>c{_J(ni1%NOqZyNyz)@x@& z86W@v4o#=FK_1j{qz&+_^0;>VMAI7m5q5Y693$aT8nxS-o@O$T6#*-^bVf_C9#Ot< z-IWn5P$L9`l)^Lro5JVzUo`^m&u{c*@B;8vS8h#Rh#BG#Kx~(tq{gMzJKu^1X3mZE zROV?6Hv+){T@XLD)Vh;ykZ0M@R6Fw2*SiY{9XCn!6(!!8fqKeG?UClsHQ%)F5GYY3 zG(qR?Rwq49nX+9aYd7H^C$Zyh*pZ8v_w29E32-d1xxzeV8(%81W+qc0*REU+CgL{D zZx50@TUf`C<#zRhxTe|PL2^KS5%w^#?zYCTg9|`b(U;=FLU#2RHCZ}GgiImDAS1|z zy;A?WmDMmL>mRoYr zQZBcAma=#cp~6d^Fj7*6!Q#`qjamMp zF%}}>!n4Ezomr{%1Tiu*S>(jFMbTnqhe5V$&*CEN#c(|kgA5g1Fu@=Ryvwd}JOs;Q zA;xnyY?n-UryjF9T;yv|)8o34jui7eS3L^u=n1y_K1EQn0jgW|rx4d1GMVetsX!7k zp$#bU&EV|57aH(XQ0(ax80?YWFxvwGE zlk7GTgKEW{4L%09TP1Mdz5-TKio#X>?ck%)u|uIDJh)*hJF7z;cO_Yfdp>xd9<5%Y&r-jwkV9#XyuaoQ4?$jfd%QjbPh#*Ug|)GFp##{7(U8xa_=|4iDhOU+j%nE|P9p2)jh$GNL|>bv=i z_UdzX{+Bo}6swk1@Ua))93P0!v3>N<=c9KQ640}f{FoTg)Y^%fyTcV0{W|Zuu5V62 z#{FI7ogoGS{Q(thQJA>KQ{_RYF$49Auw@YQ22~eh`CIq9sV!N0)5;>h{`|qRR$O`u z1|BJ9@VfSKah@cB(weC!MF6~UFF2EzzBXC)yU~hT{0;N_j+#XXWkRheQ{+- zHeyDIe%20BGaxlq0k12&th%Qxr12KqR&X|G=Fd|sdBNqudq3H024z_egpqUa%Oq4( z00IdlCA!oqmSad!UTy|WWKO4a^Tr>H)Ts$!$y3Ye!#SJKh5 zBp+uXQg!R`cZ(e|J+K%CjHBT55ZmbMitHM&y?^W^Flh%yuE zBp0<)&WLA)o&nGU?aCH2gV<68WX+3q9cv$#pptL6-9W-8lxietdL&h6ilVmezS}my z&lI!)@wsW!m4yizq{jRa>U42;r%E-Cy@m~B;%4F8z4%kMCJiQecICec*7-NCvne0_uhwq{O5EKQ#)fZdSdqY6!`ymiV?pw_8mLJl}<*u(3=KS zuB}1duevov2;I-6FT$5n)(Y%UHnY%~Q7w-q5P?;X+g0w%P z!V9<{^h#gfaWPo>iib;(bE1W=MoV;0ss>4fEJ-!=c7Fz8?}$vZS2+8iJ`v3zQ$C$N z(?EAz15S86gwO=&hQIML!hwN;VwL(}e0`UpXuc!rURL`uLl8h;?BU_W&dH5+c|TdO zriB(aqLm3f@~xjR&5(~UnT*zb3Ea*d9Az3M&xaVmYE=!p66N>rTD1Ynntl||Nl&6FClVomA zWUa|A_XkmEoZKOr2sU77bp_%6@u=12)yz`Fu)zZk1?Q&%0y}dZEKBR?Q9+nKumN(*Kk&9{t0EjC4v zEz?y*KF`^{u|!FdvGq`EGQm~m8bTjX0ku>&1r|`@9K?xc7~N<9X|1(*>yYfP0VIO_ zO3vXDX_Q=enrq1i$`D$84>D7szBo+^5;T^M&Ey8s^I`{exBfUfac%a24?l?$t}kn1E; z8>*CHbZ7W1SKC6DGVKcL8U$WHxMO4f;)ALaU6_1Fd#fxtaLi>VJ;fZ5)q{f&Drn52 zVJ9hvCn0^{wDr{!K9oZwMS;ZLJ_pL6LXB$KDq{WkS1v=T|G)pUv>)(9UjQ_83|~(! z{3fYylGtXh`EHcb7v@u)FhOFmcw^nH6C2{v_+;;R<9=R4BABo8aYumvA-Xw<$r~^V z(*35+CTX>)QUJz|jg6&eH52SXJ@@zUz3`F-=jZp`CcSI?Br;qu6xENKp^An8>w-S@Z|vH$gKgcqO^}4Z03?9c!fqUHk@l22+587-i!9Loy%rvaULDM0JMt>Ohng_`%j8x&l>xUWQ0@{c87Ls|Q zNs^7FLz>v!vA^8^A>^!_ujUrfC14hpO~xk?fjR5)Fahga ze58`9U&H=&bFKElBecHiW405LW!FX|fo}BHWloARrMB!V5lrf*g?~?fK%q7z3T3A_ zJb8u+=F8mu|`u5F%Wyw z3#oc4Gt&~1kVKyA!lRD;4V@t&`eoGB!g1bF`xwG_6v%#}n{jTd{m0{0PMB*tC*)Uu zHTH$e(n<;zI~aj^ZX}(ilfB?6J#wfGei${vxrP0??lMrTeuWTQ%DWy)q%btHw#jZ% z@^isKCZ$m#w7a~#mHMoPXcbC$T$R{veX_p~u)$dHuw!N2Lje1!0oYKs>4-MViw$!o zXHe@l%x^XYcDU6GXe}rFLyNGWtf_l}a#L9#D>${5eQMG$z?^Qsm1H$f4)4<-E8&<^ z+W><&Aq5$er!Ud3#(^_yP>Si(Yv@TXrAO&pDAd@{+=NoaZNmo=MWqSGKECbjj3;b8 zOD*$S8?W(t|6~V2Id=`y8hD5I3naY5h6i; zwo$N+9@>ACk96!56jVL1c}MKts2?Scfx*W{)?S?yb$7UjCpQIlM|z&`DCHU{n-scM zUKy$w8XZVMFu3MWvX&Oly|x!faW;Tgm|XafsRu1|vR@f z{7o)e%1S%9W^)`?twm=iskDeX{?!8`5sB_Nz*;z?L#gu(7@)hyOQtilUJx z9lvG--%pPPCQ^|^Sqgp8xSw-HH)=a4%20E>H!SSbL1m{Rfy>T6`YO0)=Y9_XEX4Zk z-hi4VQe%NjNyxe#N>wIq$p=?WXwBJ#@;)Tl>F*I5&f&sf$)^hrAU-QRp>T6e=-Lqk zXwRG<6=oNjIzYXRY0lYB1xows4+QZjl2|wN1y6GT5jr@bh31V3Kx-aCJ=o|U5(uRj zj^ZPvYK!p3G97~eWk?k+QL83^U2rt{Q0@_i(bfwc5vWK8_;VcXOV`4ie-+I)Bq%>f zvig0BZ{u}3v**pYiTIvJ4lM$D5iLPQn6aK+)pk6s(`*_as3*&z!t6%y*y^#-p~UYT z1nY4u&vD%}0nR<%WJ7zJhZ3>zsxIpttCQD1BDSxxEtzt+oky=Qld7j%Q1;e-6!%N5 z9H(rCmuXH0CkoX$!}1!qPL;S2_-KkUxKS{N;9c^v#5LMN=DFtaK<@>yTGCnv0IE1Y zzsUIeya^}9Qmvm()-fXfL0tArbGF+|i@}nTc(Y!bC>wvM##88bWrl|SV6b!CHGV3knzV}}VjD1{M8Gf<( zccT}>(@X%eB>v-iDI}+7h&&NRe`3zihmF+g3TbZDN8dx)u1CeTytbs?Q_I+&<3rIk z(2+0F$sq7%%5l?j5|*$S^YKeWt}|!*GW@uOgdH@3<+JlTh|}cHZzh3j-eDljo8i84 zdsLQ^{`ZhyJD-ynW(R>wQjTSZ_;9trHwjU3t&3;yuF!YC&QPppmqF$SbvjWI6(-`# z1Ab2K8C~Yunmz{ss*DJ~N~`AW5&ScOVctt?2r&`-$>F9U*z^TD0K`>k@gu)!AxtRZ z{W;?WRy0k&jy(;&%N3PrF%LMGDy(gn2a{w-gTw)Nb8=jm9yI=s6%^aG?df-}VGe#* z?iyOqJ>AZpRlQ$P6b7$ER*J2bR4p2jWq7CJrsXK$=c3gNTwuI~tosuw$Ajk>*r&*Q zrqb6uD1nM!1+L!%%H;dkHwS5&nT&Sx_XN3@tsK;TJgDKj1H&R?W{tx0FdE; zOK|~JF%Y_51=oeA1ng{@vxv)vwcWaA?QSI$jRt*N9s_;~Lowz#y#ZqPkAyxIWnq>Q zfe&}cTQEn)eIJ`y%ysn6O5SJ1EP5UzLa&2PBm#r7FC9gud&*G%c^X@=6LHKoB3YZd zo)ll3>Yvs>xAEffYwykK3jqNa14qM``R-`QplRK;Nr}~A2hT`!8QqjK97m^z=`kl} zpV?U7i&233AU|6__%T`*`{gvHS=y60^FJbdtA|Y5#?-Kmj0-JCr;CQ+iX_I^c(;7Q zK1(C*uHictml@C~#|A$M$~RR0MFuTl)upKFko5vXrd7r=&j*l}bUr(P-q})i`)v_B z0y73wb<_ws5@{bNcim@o^PP`ptQEEbboNr6krgw~1s-8qY_ZB?d(bkh(y8bGNj%Ic z$Jz-QEh4rd9n^r60-ZQQzO$1RrC1jEbt>#VSON^!xlQ);$cAJl-AAPHkf5K7Gm<>K z2o}HClP8lPCyMr8h2Z(Wb~l^?PLCY>AiS2+%xZ&*t#TbA4a*Y$lzQSZ#+Qa`%z&(C=kB$WW-1P?#Yp~gr=gE>0jbD z$q2q4Lt0d#0nyM;+|PN%)P%1b=z64Wr2aZ+brC#a<)7Pt%&#EGljba7BZ5YX?nK_L z;%SfFlv9mE$$yZ7lY%s&mqAzX_!%hkRd@B-c1Oa3Dg z1JA<7tnnR=+@(V+AdvbKqWr`h0w%|CGSC_<6A zxHyWahsm6|=ro4V{IQdo(K@OswxP+;vrCUciV3BeEnY5mJulFehphFS7c?^~Mixts z$ht0ZA0}^YUXhm$wjBhjY zPnt<7_VW_&thoTs9N6k({KZ{wUW+<&JJbVCM$||Eef&DqspuSyobrO#5BLRswHIK+ zJ>DHf$qF`B%8&3~D*#TY(gOyJIpx&sj^nHF5Qoa258|v#ItOZ9?uz|zDoZ}B> zD(J%CwMi6Q4^e8-!(#wl6*%dFIW|wz6l3Aw!d_dDZLU3QB**5u_7#_kEo;-a&4qED zgbq0vmUVI0@WMjGvnMAJv6%O970tVxYr{mn&os#HUS}+W6m>1LV!d~1wcbRe~ha#h$Chot>0n5WI0VI~6bYVI5XNtFLT zuGLInJg&O74H3v7bV4b#5G58^0$G#9$>=GBpiZE+mCy3Q+Asox$!x9bVgg*28!|X# zSui5?4+6GQ+DH(XXPf+_}Djn zc6#aOKA|($UhL19%h~Zo0F_pD<2DM_npvn2!jRo8Sq8Dkrg551!Y5nrj0g@X-$=PD z{b!9^MtO0e#lHHfXCi@D_5=FlY1{qRmVQKkoGyKyTPJ;6tJDo>zrCBbBod<{Pm3qm ze(RjYyc?WkFRg0%*V1<>PA#6|HdCZrcbd?I)Pt`g`F4zP#COW13 ztMWO+rQKVVYD5HQ@{7=Ur`FZ$TX0l>v5_==z#n3p6o{N|mZLr4^m|f8e@|&Yw#ybS z_Z7*QPd#g;gw~i9a>b5GBglRBd38aK?Tc%0aKM2mUt=3Ys~wxJ1RL1B*eO44O31@q z-MRBZL(h8@Gtl__siE39^f>8q;~{FdggwG}lepGP7X%c_EVEnXN@}9bte!aya+kHU zTUE>uK|J1gezS z7_;z76s1fW{h*%LFrY1;9C97^*xPUb9=Yh!{*(TUao+J23im(!^?OiPFkBZ{cpuC_ z&06xqs-13abZQe60IK=9c|Ja;*)z|2#++3E%s5D)uX|W$`RY+#9G2@dJzTN;iW?a- z5WRRDS-+&%vkq0-zd>2I&UWKcrhBg&2Lh!A=zSuVYwW*Xd?pp$x2~#ki!x`h_h&^W zp#Dj#pXZBPp(!*x07f|ShtgukjYHxNt3lBkP4 zT29oFVPm*8+(G_RP{i5Sz8QM*GENdB*?3R8C0!5O!vFhX$nhY&JS#l8zVlJ zGLDD4bLOfu)%c3O!scQTe|`Env*H7aCOCM&f`(co_e*}K3P%PQtdoI8cE>ag_BV^8 zq#k$3hBh=2ED63~GtNk#Kx)IN?47$B?f^c-^J4C1Pu~UM2n3HtX3T8DZJu;MJ$@1= zk-u<<@bz0Pas#qyccO$B3e=G@N}KW1WHSDGjQN)Td(3tF;GV}cJv%;62>IF&`QCv$ zTX(00xM+w{@)uhzV9sZGTPTKb^XXGCL^$!VgeiL_QdDVO@`%GoR`Gt=CsWnvIw0Ve z0BzJ`2%(7Y`u7B>?JuG%O6n^%E@Qsm!6`M;g}R`=DU2?Z$C^Tr3U@yy?gTPDZ*-&^ z$K0lbE=32hi<`7bI5+%ly5rIhVknMQBdEye&6U%cGafr4wFt_8Xxq&8e>V2ib9l|g z%|_Rb!t0(ql90i3yR_6PdBK|}r-r@Xy+LMv1Ow}e zi2y5%JC_E(F9}mAN)?NaKCeM<2PX)I?igUOq7I; z3u?8$-?)paPTS+d0MwTkY^&s;@Z1JvNoScLaP$|w=Xh7sf&hamQh8HSuw6%5Fieb@)66 zhJ6kNbsRf|%Iu5zS=kG;rs8Qs<4qn-fYL(3T+z+?3u*HHQ9Zwd+=Ew6<0Q(%-Ia0o zo{I7pUm>(Rjo*Z68oQ3kVsYeovC+*{;uyM@B1g7kdjv*bTrPI=tP!`rf-mB-{QVLk zR;$ixav*y5BsEk)aYK)pkng%ow1D0*)r3r^^Ce1zBtw$QtTPXWK#piX1@JP2r2cR$ z8#lvmmDRRL;>^Yt)#m|k^%}o{vdz$>Vje)v2SbWQoSoOB+=Kb9Y@5)F=+U>^i!^#? zHdgDQi|6AMEY?TuSDAg)+|;y(M0Fa@u4pi=SWB8idYS%nbH$}=@tsHJ8cL@i>;TfP z0b2qV?`dr-nQ{jbh!NrPf6J=mK{)LvB5T$}$x(m&?RV!~&#KIupy$~lUny5IlIY=a ziDQcrrJHGBx2iFholzA;M8ls}vJ79fJUS_1nYR zeD1kfdIcQpjnuBWr{$;8C6m@p`2C6KUO?nH=7nww){(hi#dD2sbGJ{OzO(7nt#|gQ z?T}n`M32dqyWY)00f1<8-PCqUW4UVGy3}vpeKmthhgNT-nbYa{%m=-QFWv$jDrN*6 zTE*Ke3F(drLVHzQ61YB-D++o*DM{I?P9tP6ag^;?4U)=c!HN6noy(EKX0H2tzOG6KwvxL!vwq=&<^$8q%dSUnM{?Fci4#>U58gZHpHKZnL>O!WVrJSs1^JZfu?>{2rJu;H-@JG(r|4RiL$-16|qhL;-^)o0V= z#|BCd?2-#TAp5$61Ds|UzCkq4bUn{~=bILSSL_SRVysWdzLHku>moye3Xod#6 z16SSfs}Zf21ISB1PcKv>-5l)P=+MFc$MyooGzMCp@2v!Eq)}@qMTF z-RkdvrPlIf>(IuQ4Q6{Y$o|V^bgsbc+3?rZ{^5|TjC$~Tt9#QQijrYB0f<@W$^4UWIAXZ=GBz8Pu#dOmdb5V+( z;pcnvRXr`3Ph8*n4WsOG*n@9=28r(ILvw^d!aOQ8*_5?V3h9CSIyi1beHncLKis8j zbg{4OvnMvzBj4}vgW@;XEGC=##U8XFwpwPDx*W{lk z7AFb&iFQlahBWMAsGMI3%2)!)<8S%CN z&MRzY5RojHDXN<|bJ>>KB#H$+g}7f%$05;G>`&Z5eNP|p z&?p|D54&jv_B92I(vp}OGRo!Mv$g#$tmA<5u62bEj!Ngc@u%qqHjygX5KBcP)F>qJ(a78S8A!r~tHakkIiGiC_% zo3tjv{v-RPlG(p&Y~KuHSRlTsW)m*XlqO&Z7_%5S8^COpBF^wtQlWJtVtP%lEC!&! zFb=O#4Qa{3I%!}H8v}96N>(Z;?DOLRbb}KAYjnj)Kh-iBlh51IN5Nx$jWUB&Qusag z1BL*Cgf^)0K|K16Rm0`lAU+19P~FufNch*`TqbLqOV|p?f)JgEiUmYh__=C0OxYeJ z=-2m&aXlU@u2ZC>eivv+dpjp-FK=WEx86QD-%OG^{mdrg=etm`eqmkTps&_V_U4!X zQP9mTGZv$}(y$ZCZFY5zj5!waiXv$1z(7k5aJU&AKs#h&t~)}?fn85QfFdO~>|B`L z${-1Yn?TMM5Que!VCU7^Lg`s)u6@v8QTbgC%QjC;zly!z`L;CPSm2>|BmG7g1SEIi zZh%bRQ#riX|EI~BUIev=_uijuf5J*2o$ZYMqQPS2NGkS$q+rUYrm!P>o`|f{pkMGL zK}~#X*8gWGfA0UDRXrR7mTB*^|9gUh5~Ck)I%}}cA7yE{Y`w6{BCB^ki=TLI8AI{p zp^gW_)tqWtRYpzs8p6$4HDLzfd;*iZgQ^lt)gYB%XqeORCBFi|+GoGd!*RnCP8swb za~aIdVC}pxDr|NcDT&C)f!e%F1%#yucgx@vlAb4S6|D(8#reQ@#hja%5DSxb_eEL~ z<1FQLOm12BmqA1eGZ|o@7EAU=0X|AN8D^xtrFg+fugSQ!j7`Y?w{_#PNECx7ss){3 z;{ImJ8>`Z34ZTd#qpN<~)Is0a)* zjdoANGqx097b@e4k9zPU+(U7v$VgTO7IEN@kBfqyDRr?CQa4FNrVZCgZ79f$c@SEf z*u(o&J%=}!o)5yu5TS@wwhkXdz$&b7)B|1`p&s_5TyO5+f^94Fy_-)w&^Rm5X;-i`G z?6KAwJa;ki?YS2&b}JH7EW~$G?q$ab;3T9um-s7^vBGEjv3RGGtL1{q{A*(k&O@!# zhR&hkEPJg-?HnR?8hu=&x3*C2%1G|yY~+}mWTw)|I#*+hi{43-BmR5 z=9I=fdKCah@4M0$P$kvsURGyUr;c#Dt+>6cRsFg2wq-nBnqQv?@kFRpIq1%XngAQt zr?_Fge*95t_{6Gq7z&d#k~c?&maK&Kd?JQC#KslNj%SNU@gRhCn(VqY5Sb#ad;d^; zW1--GOdlH72++~TdqrdiU(}r<(2Liz_XkU8@ZHyDy~+C*y4*w zZ5-n2aaC~4vY`SvxnsK=vJ@5F`m5nn_K6N z#kOzKXwedbEpTrr&W|J4Gpm9d`~gYebgHeHWQSjeSTBl8lfO4*c** z*834(5TRcuo>D-g^~mK>K$qd46QW)it8NKvN|w4xqwX4=1b@Xsj+9B#)XK3lenHF= zzpw$IIO{1YQc_NjwWqC(>-3b>S0X5bPae)ZfZSY{kQ*iMDRw9_U6U*_G(w)9EJ6{2 zWvb<{0E$X-)4{SOc<24Y8Nx^_Fv)<2%_UyTh!dBJp;W6t9A}o7h0n^BNmtXl&Que| zD9CDgZOCq*lnob=K_4d6Q1B^eI)?fLKDi&!)f$7gMgGkRdlLg~!45d1R@0@#XfO$j zlfCnx^c+rNM|=;nFm_`&07V+ULkZ01Yu#%~-1jQGu&5iHfe4Afi?0WCnlFT+H!p}K z!{RhkWa*|woEXTv6t`lcR$)I+%{Jp?VTp0^BO9s3zd!MNCjVEF@Q!1#$!0N+|ewq;0BDa@cVS;$l1KVVAX|RCZUv|SuEk|!l z<~&i~u@@+Kcc;h;sfL<|kOajwyrezi&-md6Z$ieo4hlzFa9;HImfTYT9}?vtW%gZW zbFEqE*8x;aT>5_OQ|o9dL*mJw^z1`kFM%FnyzZ<-zgKALMupGSBUU;fznR+Cfw($Nsm z#YCf~s;T_h153Zf7Mj#X0pUvfC)TVJSKzC5|LI}xv~ z^T&lo{g1?tZdf>*C>@)yccofmRh;dG_%X3)a~#_afVJa%UNS$UG;mtpjEmh6Yj-X3!-D^8K2ef=MY zF}$B;cm|gt(;Ov7rPkm4(G?XTe&vWFdM@#X^}Sf_{mrO_Vu?pQxH{7>M3Cdxv)2pS zpIq6wWRDr8M@v03=M7gcd;#hZd4P^Uk$s`b^A3RD)c5nuS6U;Q{H@zNA;XHO%aZEj zwWBN#PBAkQ0ggFHV}=lDH+q-{!~rx@g%}pR*XK@;J0oOAay&W$7M^*4>L-%_N!PPy zuA35!&1jM!G0?s1T7TyY>DI(-#oC&{>U66czvJ#41${uXwsk<8rRA#PLsxqS??Z0) zJ%o7(&1l~`%`=cAl2=mIf9ECUdhHd4uc2!r({j1MoB$U5?AYNQ(s5481zQKAlcUc| zkCtojuuwqZ>nC%{bg_(j9^9{!|7#Gq;w!|lzBJTMDf{6NtbHG3wb5MRsyd?6W0L>b zKejBynPJY}x^2;{rCgH{(+oTD#D>NKs8n(@=1Ssz#ft(MeVa82Lb+KOMz|(4kkcey zxhfMU!nYK1RkxD1gg1dq`k4NsSkk;>l^-fflj6m&L_o?NLST5(5pY{%P$ROtBUJNj zLp3lQ0fWUi@Ns-~EV!#NV&5_3l86gvsS~^V;PY-b)9?w_tTY;XEcOzK2q8(;S^rO_ zB}~(CaUBH5hcyOx7z(#%3u_(1z!yCC4II0sY(IyXexj9t(O+M&hTAG?$i+PYT2_dG zUH0y{bI%R+;*6sdUO0P2bQBIUm8_nyHCPgAm}Pe7;n0ySkKJ$d*ASH&BU+0fYoQgH zo%W90l0)DFGk7vF>m+5hta8ytMZV|r=>G*lgl7j0Y|8uh5Cx4WcQNx>hM(fZXS9Ig z8~eu*LmVvR!fl^DBp6veSRI$oj!dzp1s*^|Q2Mv`{GRW{w(o@bzxVKW@a562A_R)4It^T*ns-N@`S9NtHrsUnJKn-Um)vQ?ZUyc}H z!-XZo^E-j)MjRO@4*e$7bvsab8eC2yNzK@40Z+o-XBI(P$dhzKgJk5f^`Qb<)Ik&W zA9@ybg{Y2S3ASXL6z)w+ee1<|lI^9(ET-)$QHMDrv<>Rmz0&Bmydjb5oBg1S@_|?) zj+MV9L?&H=X|5AQK(4tMp$^DjRNI`?ttj`&J8nMyfbN!lS{%P7aE;*3J9r>;v`VWiaZ5se;G582&dd2Lb?H%Tz@`(ec*6wS zLB&;eLikH@nTN~#MPeO%jFi!?|HRMcVj28V+|@XaI^Q$uV=4xdE1jTW5|EUaOnkbqZz^;-mBqnw-k zs_CZ;`NcL^9+ch+R@Uyn|F|WV>#qa5)GsHEL&%2x@6?OEIvsB!pT?DpEQZyJ=st3r zj4Qd-R8>mldO5Ck5&q+Yf7LeygbK`xV|r;ah4RfguNLy)J{^VZ6}=&AXDN_*B>d;-Pgzd-Q~he9uM1Wa5TUwqEWUu%zoqNu4_}rhE?}ZDTh505HQR;#uNV}8Vh#C2MfZUP}4V+$LD&7(&ufD zqz;oC9Crp}(c*eZ4Bp450CMPMvfAlI(bqye=z%WB(N<(NdPn@DUfa#|ru7qTSKz*6 zM=#hajjzgDD9FIFPF}b#5JRb(S(s`*1wFpD{g`c?XmI~c0mH+UI(9d;zLzPC6CP`?vBPA{Q~@4-p{YXp<oY;XjLYug+Edd`F zh!pRl#*zXBO?C+Eg$3bq+fCpaToaZM@!-1gTMnMg(kH=c98x}|NyH|&Zj62?F=qMw z663MXo2>?|tC3osRM831gCOadKOEiaH6(ggIyTe}he=iCa>?}Gy~>ix$sKn^$qwnPjj)-!B7Wfkcr&qas?uT+6U(W=ehHObvon7<5@YK7o0 z4l#0^>AOMY(nS$ah2R}b8`)7%jtEVyHE+l(s7Nlp5-#~|# zyEc{`aog3`-tIQ$s`goWHdL1rVA~eitIS+_bG}yJ&NBHO<+dM%4Z>zGR@X$Cg0_eI z?SAzb+*K+t{SfMr#qDSuA9|Xvfl&|0Gn#ltH@#W2Gh|}kxzcPW)gtWcmvB*=V6Qd? zi+py{qIZCqqLCOkUwd0rIysECizr@(H%E)$=sDTQF2{N{a*SyPaSklCW!yC8 zs<(%@B%UMxIs$0&BuFUKWT-A5MA}4_g22C zz}~)Z9^OT1DGR0Ylr*-RS*FAOAC7gLtH&2!HY7NISj`UK^;FOMk2C4lG&>@|fk6f$ zXcxde`2p@tzy9wvgOsbrT78ZkMt4yBIHsLnUKJwR zWX`ja|5w>QO=RNBmq4L8zG^6I8gR+hpro1hTO;ZFvwZBFL|CNh-_+{kWt!5GkTp*{ zG8Vf%0t!)%=`w#fL_u7wB76Iq8=H;zUr@RLMaIEyJu}$roF^yZ3gD=+eFM(}t_hZt zlnsw2W4C7r>m0ozhPOe6-cB0geI{eNru0+KPA$_~2;88)q=AVikV4m=eZ#!nq#cud zW{^5*xEu@-()=|n{MmU}9*&iEz>KEBv83n7q-vBm{XZK48$ zy7{_od3VZMPkYZZRTd?JX4UqiB1c9xKr|w=+$77?OQ-bX1~c_+Fwij6!y#PZJ>mM_ zaI<}pSA+(d$ZHMKsT_NQ2tpl-byfP*FO+pU)XOn>-zyk6%?_YLq2$KgXAjZtkSxoG z_v~R_iKu%My_l5L!@LexC;+fvMkvcAH#1Nmo!aPIw20;QQx=Cx&Q{BM=K2ZU7g-mW zlD$Aly~Mv>H0LhR`oM9&p}T8z5*__-;Cn3BAeUa4UOD{PkCf<#)Dl|x1!c;Gu1;xf zKzCN>)_B0-_;in*=cPtc`PgNaPAM(y>zg1Jwh{?-SSj8C`)r!9)8mNV7I5vN`t+`` zi->CPgh`PT=M#MYMwqXDz$h*|r^RNyekzzr8*qEgUCa9?$xB&ugAJqhtBZ33AmUzS z&=u!du`yQ-i6^2=MQy6kVk~C{W$IeF?RLz@bVMod7tPsIyd=Ay=1`njx(Z5dC%BGm zIPnjFelz7uK56+gX>b>g%eD)q|C%`tI&Z`WZ^~x+oSCMjs8i=sdeppx4+0aerH+-n z8mhxX2SlbmN-3_`jeFu!T&dWVfiOuAzl@o^OJ1H#;0ObkJz~<|O^bL~p;1+b2*zjH zhy!UmPNImGi_&w8)1~-KlfuA{t;F|fdzvWfEA3JtGTI| zgIk-csHj-ndzL4O5uGGq(UunrEez^%_|TXpSIXY9ems9z@=ZnUm%h|yAC3KDLqf(! z!XtJ$>YwWi<4`yX<)|Z;WK3vxa(yypubhI2`nw9OC9HIb#)H!ptT{t7=$t+zG9kHM zKKRsmO`$9xF33iKum<% zp!{^jE%BatOc&J9cJL!a>olpentcdTSOU{e^*3#OR>vHa7wMM|$ja5zD6i)P>PI9S zQzl%VewhHg>EwgyrNq@iUn&9YUtDa++;I=$^|p9X_}7I^^eRUHo9;G7+r%>S<4Vx7 zr(L39&;WFzzPmF}NqJC)+wz#z@S`}YJRj_n+5t`1fWRw5jcsk28G3|{5b!c zZ|lk>WFTCBdBf$y>(?H3zZrCv5nx&7*I&zGpkp|owEVm^BN;p1X_e)Q=1#mX$+ zvyvV_m$L)uTU(2!ugdim@)QF^Jn}PA%CZlQfxD>=Vnf{dv^pTlK6g#$1QFggS$c%CJ z>-kisMVqw%QKqE8?6%h{ZIVJmt1DnPhcl8CBuw!KnZts4Po>~ZZG*eAOyIjo8@6fe zJ5yQ3cSTD?An3__SDwxjd6CGY{FCy~5b{$1?jwD!afq*od`hF{*tF?*QZ_{KCwhmB z%7qYpPJjKcc;HuxqV0WF4*6f*$RO77BwrH~84{r@ELUj6wVQ+_S}hxEWdRLiSBG*H z7p?X;2bIeFs8&*r++$u%OwX=5@0cugARqd&#p3cKulZEO!_wzxoX+LC=fVO0MKLE% z4t4_&9hjL9eI*lUZ0ezN{~P)eT%td?Uz| zFZJucKqB!ZrL~zaHbbkTg&aNSUDy>m250gy%y3SWU(D%Z!#PbG?_KofkJ+rs1=@`d zlVRZT;L$|w9WF93Zc5W!oc0sTLxd234W!m;Xo+B5pVm20*4ntrLjwI68NjE>EJVIU zC?<{F&Fq?VX}n}$I<%arWV~*N1ml*GzRA_(0kxbu+KG&9C`Keo)Y?6)tjbHw-##)N z)_u#3_L^2a)-UqU2@$pcN(D{cje*xV>hf`FR&@06ub9bkSSb0l3%$TL#shD)2heOB*_a zhdjR048R6W2Ubst1Qy8hCRP_Jb{8BL352_YPyu#%^a)2ev6W}Myo5`5cwY2NL=4zW z$$F0`k}pOrQ~0H5Ftq#R^5k!4Z`A?yqqv4DSUFUhIjOkgi42=o<@nSUYtta^WES-? z{p6DHlGl%?Ib^_i5lW16EDNBvCFol4J9~IE!NbO)T1GY?29!ifJ*OTqSsE#&B*8kE zvt}wP?$4Cj(@}IAOf@`PB}>O2Dc}p9w2_r~fHk9^ljB8R#*bpBjrevNw$@}~qrJ6# z35CZyWdfEQ>#L2-3V~LCOg8t54)xEjP_mY0S4Z`DF?PQ=tS+0vF{+=Z3=EciFIKg7 ze9IDmKe>|b^jv~#AJGxJ&r=!AK1MJ08OS02G{q|i|K>9FW2aXX@27rMRm z$U6M!&jR+>GDutXJ|KT%&y}@=nHv$~a>`fz3EZSDDrZ6mrZ$^7Jb!NJqd%))u9NtQ zuYQN5aFrG^T2$q812lYy%vQnEFSs9h5B#msG>h>vNTw*xSk9zda{Yd9Xv;`?>D#fI zg)5P%c`Y_|(^^6sAB@#LSLhXsC`xch4&T8spJ$xfHg(U67h}EG=QLrk0gPx^(G#eS z#IIP3ef9NBI!$22jV%0!rX(yzYDAgCmqR&t_05HJMpFuPTOx`1Bg(?w<%oQgZ1e^3 z024PR*S9{Mtn{f^d!@71+SY%bE9;UGWIjZ#b!{HvkFD|(YWrwrzi+<+Ytx^xKoF$3dnV(G;<`DG$G0_@brp!Sr+*% zk$1E6f(xg)(B6fE)0o?@C4x~VCD6TqXa1@X2PToF=%Mor5h^+>)_Ks598KzbEWa7r zJZtpBF?k@W@hd;Sd*c9#lw(pSX}d_aP)c1kti$~ooCYX36TmkPp+S3~Nty!|Bj1+D;IC9qCw46m?y{*|cOozDs#{=zLbfpRbHj+~|hb87O*;6`3D zn0G-YmlWZ9I-7dxj_wts6Rj?af7J_@VsWYBAsT7b0Vi#PJ7?%d6*tsCZzD;!eG(}j zBPfnO5{3(E>^xhy5T>(y8gn@v)u0b4&%#p<4)Z29@Pp%hn8&yp+McTVjS5i~6xp_p`DF`)S_yEja=Uh3DTra zy=MDe9DY;q@-)wTnK{7CS8oSo&tlcg2Qe|4!I)+vIf2k#sWs~O$tfue?Jfk4(!VjRZyW|F(Ah-ns(FBWV#Z>i9)R(ikTjzbNUX$!J z2MotF%b2p`Q#=!T=GGYXM)JadAh_$|d_12&16k4g(1XlE?>8`7UxuiY(hWz!Z_~>Y z2Ad8RY63n~9aa0&YjA8*{jq}(kh|sH7?#iMoS@icw1osOTY|GME8t$-K)p0Ad(e)xgr^UJcM$P8R01G{YJz;m@)3%MED; zUtioU#;359kjyQU*dNQC4;VCY^WFyaC<6-!@{1;Vci0ZRE*z?}Oyaz~UI-87(>E0% z1AGlT$&Wz7((FKS%V6`t4hMapn+*ha17o8qCC$8A zIk>a7w4hpC5&TrjE;R5My>ywsYHK3}L{q?aL-{N0CFn`k^fwSRvni1581J@5nSN72 zyP$v>I~q#XvgSuHEq2b(IDt$>DE6{|k@tG+Q@p>KR0PimVKfYCiUY*_Lm5&|=g+j- zso40n#B~v&Hkh|tjNky(@E&JXREMXn{cana!at9pgWg*vF=ER2eUWS2r#YJqr=dn zf|u*@jzF6IaAue4_A}lLc=oGW?G4#nhb1PlAmcC=@qV7xK~qYGaelik&J;9i<|?X` zwu#6{WVmgB9p(#1l`fDZL%~mQG717ki*T!mYI@BDnJ;3m*u`AByKP0}*?)Qk`=FVS z8UyrJGZng8GtxV&MW2VVWnTXoR*}(UE+Q$aHyVBa|4aYyPPjh4#sTGE=&Nb$pHXu` znZ`-Kt1U|!YeaKz%3HqdiV#BNu3{MY+GoN!_KP+z-;zVrs&&Yt03&&jOeWNyGB zHY;HO@|7}E*^P`bINiN4f?h75Q&yZB`Sf~% zBji*f7r(>>f`ejEWk`rVIk2Qy)6@Z4p+l9ej!>(!GWNElOhkV5`Jl4pYc$A$b$yp0 z-b%J%L@*cGq)vIcQbkTVEOk4%KbCI;N>G?JxTx==W22izFH{A0Z5_1X;nCzc z`4EfLQpARvyFs(ZJ&-eOaq3S~y@6lVdeB&w#(pHoJO{z@{)b#KaVYh#1xoAXf4%^z zSyC;0g&DS`__n_ijjfhXRnt}3t5cu5$x87RLZr0FM?#&{e zpIT_0wnLvWzI;@nx}= zcM7(6)MF@zArwU$5bB}Pk+5jz*esTPuuhu}nj$)~DwABXeWRt}Kg%@jFL9F{ICY_I z5P&m!6TTDCL-XN6ejWm}1ELYg)eh&zAgFW~O=wbWVJ_Prz5~59N3`KUR~+g+|EP)u zn8}E_(Zl_C2TfUV1{+Au$KGZ%noyvmv5Yp>QE;3R+*^{q#I-mx!I&Mi_K2$b;?uR7 zorurIE;4b0?=;I23f`t#8<7pYCMN7#(nS?)uSF3#5$_N#sDg8LBfCuab?feit_Re@3ACB@hZ zwAa z;3fSffUqX|**73ZWWufN5=l^K3b2`X)1?9_sw34Kiby8uD@xU|6~saaI8sDD$7j|C z(>m{yk1kQY)0SbX&$!l=6e>pOyzS@c4xv`9l74-YLv?~m&3zXS6p&tqy25*LQQFBl zGJB+p%)Fh?#l7O=L{jA0@->{AvJJ-WI_gYg_Zmr>N-SGPkVqtS%LfY9(>e2pp80S6 z+~|-W(@-xMf;%}N-(u8!tN|L0M`G~UVpN*16E5)Jt}qcZkKbF=R?9YbJq+=*vk=lXrZ04a$n zyfrOd196;*EDJ4y`9rd=A3rr~_b{wn5O+^EBs7B;)Z7?iFh*5PNk-EaAMvW$2S}wu z@q?@9_oWYk$|Ow_rQj#qw;39mEZ^E8tx7E{%r6w0re`+QA;)Q`G`UOiGOCb|D{=nI zrX8I(|JXI0$}vTx50pPJ?g7B8PE_^!6%cT+$%)PceH4W6GB&Q*q~M8b(B4ELJv*vU z^fLY3eF+QJIn}Oi|5tHqM-d-`gqsxqCE*dp8Q%^rOCh*St=R$F)%I!9=Va#L4tlRT zvf-<_KWk3(< z-|<&PP0y7B!(|68=`Sd&Mv9_axzhs;d9xwS`vSFDaCzOsyj0Tl95(2`nx&T$TH1qBPeOi-9c*az7NHj(Csw zyhl=rHQ?TegR{M)?Crhan!%_#_BA;r>l$ur0}&}G8^sF*EukL?J&%Jcb-^L^MmKJN zk;yRAZ~Z4Qd{X>@KBJ%i4s-%#np;^$D#3ZOBwLh#(3Y;~s;71RUTPLj10?_0Wp z%*g^#>Wc`Mg}k4p@iRh|o5g`GeGP91*s09p;oH%fEkXA%AAep&3ogxLo^7J=3Wwpt?@hJ5#fLur4hD&~=np@#JFe>F){6v41tTPN3Y8_Q3&Y|di z-|r|rWwdMI9%nKln19L^<=o*Bkg&A+&=Q9ZN+eN=UBl=;V$ZQjhP1kzq%9CXCY^lx z-JY9>Bw5gT1yFM<6oR>j1L`2iMp&y2PwK%4G1p06m6*|A;L4*oLMOwgqAGNXd=B8` z$2$J)_&9ZQXpLeOOezK5*628Az*`-skrwrorZn9qGi;tZfEDbI%FI%fRR&7zKn{ym zAC~mvtc*kd^H`cufp)XSgNG@1gMY~YZ|Ty+KeijUHO{LTr@qii3M&hD|Tw<=KX=5xeA zqa>R8?y1W0AQOKYIs{S7`Grl1PbSDCx7t8)*V3+)e-pUGOa9n#JedDL`mB$J3!im< zifyYl{i(hG`S3`mPE>(cLLl8CZ*5k^>hRNUNB8F0)1l2%cfw%xn z)PGM|SJW{)MLD z7vOgbL`^yee)<=I+bhSgj;a>o-5tphP8};?neaVT)_cGl^X501!%Qx)&=^6K%)3vL z;LrM}{q@8H-VOJ*3WrI!tU}Bodh-H*N?(#F2@M!fd2cX#er2@|dh{omqnpIv`q`os zm5j{Ah$Ht9SSE!>3DUVFWha9ia+jJIKhOJEO`Sccst6`e|%zcep~ z(EhNSzN}iz9BF&8ySZWpar|mlYKGfEx2+Wtsj~aJ=A@dvf8Jf@XAcI$v=!gHXbVI&d*z3$)0R{2dj#Qa`T_021BP3#7 z@m-;!J>h7%mW<~AI9#=`W3G-Ya$b}u>J#SJzhrpqeK!Qb^cx0P*gc=XBa2Ai=UTi( zaY-ms5x}?DDo3l6MZ_f2dugKU^k*yWfw9^c+*3mEck<*i4TICBW?O&HoUEUlv6PE) zxYr(+uoYwlDGFG^t-e7n!F}S|kn!NfQ!~~Y;>C}c%YAgo+Yhq=$oU?@JRTCF`Y`IV zriGU-$zh$UR1lZ_1$yHRT$=jm$1})oo|vNI%43MgcLR9$4pW~vpeyQ&znA64fHxdM z>fozkg$b>&$?TD^kUV&f17!`1@gyp|CFPS($(wI~j_TZ9AjTSh)uCsK9nEhqBgoUs z?Lv@HMjP;3Ne!lNu9%c>9PPYf>WUBFgf%=cFV%#=k|VSS<4IfDd_$Br!Rbr0zsdeu zm?c4u>0Qp!dK}23E@>}n7Y)#ocJO?AH=7nyIl4LwZ(4iC1R0`&!#ruoWYqM`=}6@d zxYhMnG6GAJ$jH?4m-a@tPP)IAb3heauAJsGJp^q|r84tzYkUZCl&~gkFPm@i3B1A( z*-6T(YEIyw4F_(XLCZj%okxc5f=zqTNo!ESi=$MsG@rt&f@RayG#TZ&Kd7s;gE97) zc(7nRJ6(%hE8JvtbS)AT)I!r{Q!>BwqDL-A+5t8ks9QlHPm68(<u;}KJG6QGa~N6CzvLGhOx#;78MaUANPC#kF5g5-hT zE?5;^(INa`pr*1n7i|A9Z7o^Xcm&M@iRa3EvW3JA%kMRy8@ekcvW)=^u{`ycWN*ix zQt}!(a^f}AdFyzQglYP)WbTcnnhQx>^;nLkA+80guTtqeeS{v{^Yf;ptboE3_w7inw}G^dE|N-d zu42XWy1|&>udWhHi~~tELU7BtLMyy*R;`Kl+Ae2pjk>dOTz++@Cy@j_%STQA6rF0f z;G_kw6#pgwf?ChK(X9JY$-k=^lLXUZWJ})SMD6lCEh*;gW;Y+5%6PvR z(OI3^YGfRKq#n4<1owhuOo`icIUF%b5LU7Kdj)It4<<*S+fN-Ox0ZrlX8qMya}1Q^ zX+%=GA~H{{VBWJ_r>E0%yZik6SDYwvbiERb=2oPzQvTCW{{Da~w#n`h+Rqkgw|5TS z%PY##FokM2b3_xpE@<^q4U_;(5SWGtG3>P!kH0js6KOJ98BR44cj!Eoz`(zv z!dZ038XZ^Yf)M!2?}K~og=IZq+UE@53#{CFc2Wl+cNgeQ`37(&ljK&qDiAPg6xp~@ zh}iiV2JuDDG2nlKueFRrl8!xZGaTLBzq*s;%#q(^_m(q0+EVFUUEHbBw0KxM4o)Z@ zZDVYAMkYHNCt$*m=g^imlDN~&q{x!dlJ33f$C=gphN#>gLBoGcu;+aI41Z-?{u5;ZF2jwLaC8n}yE zCK_gci?WU-l#MP6c8%S~h@jYuSU@|-8(Zlx_hvL&5wcJhkF_eWz}7Rgab6Y(U;lI{z?iV>}~;)oldXf+ia%0O@24tEjMi1klG1w-a0qIV9B0b9HVi>6@X{ZS9IHqeu1 z9MB}?Xc>>+P;R;D{%k=9UXQwtGZ+}`79*R~tu*c$K#m^N&nf8Yo?c zH)rdL+8z3nCxcS&LFd~7&IL>e!YSc8K&=nvG87c*UzAJu(+C`>fVmV9-%C3X|EWGH z!S2!l#)c-MUBB?edkXSrD;lo>C+Z%{dQ5h-ej8h~f(s3vg>~ce+F&^gn#WGfH@DO1 z!n24OGxvXlt|hLs!ESK;wo&%`l)1{ayGmqwJi2l8o4<|J*_mfyyLwy#rILw8GesON zO|}tHJ|e_vQe&&g)X&dm)Ze-xcwzR8$dlz+i+s>YXEL4J@7gvOW?V0mwuW3R#O;$# zBhsU?paInAFk6v3Db1aYrpt*Nr|&Y_(!J+I0#ID~3+l_bi2tTO+`yajAnO26nUrI} z1BcZNqrE{B*cf8$zAxy6Y0Yv>CO~mI&=dRsN>{zTyr z>!i?gw36`pB{;vVDBWPXM6uql{*yu^#D{$ z>mw{UO8zV}I6TC!6^wM2c&EVBmmq>v$ktBJ$7!$%`ueHmps{hc#t;`(3jc(sMv?G_ zlVaB+QzX;%rlK7T;IaIL$nppuqRgVV#pk|<^>S^Knx8+9ho`@HL>&{}2IgfT-e=#? zLFW`@%>317K<%JgwI5|T@Au57<2DF3c+=Y?!@w1hNJ5Nbz8kwyUZN*Ei^$aZY0t0< z!N)3NgFXIk#|ShhhH+uGGs@1O0ncfi0OV&x$TQy0-JhZ@;#b&poLQf@M6pKQT?@W` zJ$w&|lyl7#0-n|=`eT0oGvHv{0HUD%xqEp!(DY^fKa(@ss!g zZ*xDdvwRf8bWL9eFR{ahcwd7f=5JWuPc8`vEL}aX0ru4H0%O=r`YOTToYVX{3XdM8 z?YEEV+c};>l^vA^;c7o)j5V(2hh}Zj82$(>DvOIfIVe$T%{T}C<>JxII5x9{eX5Iz z=6oJBxe*aAl$3f_g&VniOu|OM;N-CPWe!qIO}oo#%l?T85)`aRQ~R9+Z0I}sA;8UY zP%zMYi+;snDn5a5HclubW@0zq)J){gbkk!Ufc!DO!ECbJ%#zoqE$OPiKm6i>r=R2l z82C!X8KBavG8|PwZbZZ`HbXGZik~7Tu(CQHi0Rr-hTQ)1*jrYctpNfZD^mj9S;l{C zNuKGzH`}Ua(U#SSqUSpw8h|Vzq(e_Z(*QgD8h?;n3H)FioVIHYMLDFABsahg?2CC* zylaK{j7TLN|9mt`jH8DS_4a_?p1?9m31&s*{M_=M&~dOnO>HVkbQX_@c9*nvf^By^ z-j~J>j81{O&Jqc>fY@@+p=jbdyrz`0ggu)bvMD|eUI7XITI8)Z=AGAsgB#SPNa!Cf z^%LOWHekow8_*w+`}vL%(;BD!cG}t12eb1ge&hI}VnMpx>Yz=+Z&C@r9acm^sXO`& zUduC8^#_sq%R>!@s%O!nYAP+@INj_;`vV7sH_7`TkTR^}C1!}2enZ>jUN_u0oKl?K zhLO5caY}552~17!PxOF=O!fVsgj#Bk$}gRzk4~xU!+m%85IeCS_Klgwh1G1ih}LFW zo&KfDFN1)S9+z&Yy|;Y^ma$NaQYtiX1^}+m!ZhL4YY0@?@^D`H6Im|PKPGyl9rQvy z^H${)?trLL&)nvy=80oSU-oxFQm9d1(*XM4_D|2*_{|qjm5C_Spf(ySEeH%K>sDu9@a2w97dbNjI%%-u$7_o zm9;TxC0YRNM7TvnG=D5qC)Q>~^8tg(oJm;KzH{%#6iClQwNkEnRu+^LAu`I!(8mT~>Gq863}W=IVL>%dnX-tl+c_mGLXX!Q<~m;sWrEn4XA~fgY5gV+?A-Jk@WctP6lZ;`=^Vktn?9Ixa_kHsiU_ z(L^%+v6lYV0^jCF21#nYKUh@`|0c05fQ2*epw#5(E(dbj{`7%K;{=Nqz=wb{6fU^HL*F^zr3^Y$8MpC}#j{;~d<9;z3bo@wI~`$I9FcK7`F zHE^lnJ?2F!GuEPQNcB5oC~TS&bS`?`xqfN^O?9`97nD13kh=XcEzdYA6?%{$$CA|E z@2%%A%*iMo35w~~I^3fol?SuFPDH zhR0-N+EQxjP(HexS8m;EMK6T@omeBMl?o6$-F9|B-)#8_f_t>_f9m{8cIf?oDxWNY zLFfCr$A2rtQXXv`W_a*ojG)ABgP%d)#p38P_oduniT&}1qH%^|2@Ec1xBDPtsVCgh ztH;c;z@ya@Z3j#!^#ENhMGO(e2>L?A3`6x`%nd!6yUa+CF-As_{Ss#IfKL$--0| z!W>NQZBKsfOQX0L^|qrGJiUuY%M5m!@T0X_b?&%fwjDFw+t^ekcq+&OrCF$B_gZmS5xFa02qA$AmzkTFG zK>YfF^iXd&Z3FQj3+g)^9vzQH%Z?L+Z(&WJPr&8lkhTo0rCDv%pi_dRp%=7@bqDyt zBR}d0)0h>RF5OdwBH^hFb_N3vd6g{fiA6dl;BnH3=BO!MwFxsvp0AUCufpUY z2}3b4eYc>u(VkKaZr%ERg3a;HWbbOl_uAA(*+7yNaqUMs5l+q-A-iC+>zs+v!}5Utb~=^h>XUi^7J%))NlqCN?wWuyBc# z8r-%Cxyh26(h3=ONd(~W``PPy&;vL|)=W%p(fJLiuUkUj2*#ubtG zCqlUhFBM7A^2DW4=wQ)~%8UZ5WXP^e!>t%UJ>Xct(6MvoQ}%&e_5t`t1wB zOlk-?AtVGH4QzCN3EFRHZtSMRaF6 zxykXoV?>oto`s2#5IAo-8~~tI&_Q?d3Nvo~W@3x=PF>;tS!sJ#oG{LYuuAWvLo6QW z1!Jg7Z{+KplcRx>_ImOn(vdfFyl@tt9lK*SMj8EVycu%#qB?piK#|GV*t)+oc5pxF z4QgZ{5qVm`SK&8PRZ(1Pjk+>G=udzL% zDawK1d23NCST!-SIQclVQ(G788*X0nF}8!X^GE6;khVKO9nG$<#K27L;cSY@7VuR6 zM<1EoCAEVNUXHF%21=Hg+B}{ML~VrN&-hm=1dXBdv(hf;hR-D7_#d1+H9r})75KRW zNI4}Zv=xn;_VZ8EH=+CS)*3ZQGN8espb}s*hp8O_#1=6x3pddd>e1(17W^K5Dv+Jd z&$Aocf*n3xDS5+aC1>Jbfu=i5ivx!K`Qj?{HaBTQNF?1E9@Qalj>!MfGuJb?`fy{5 z*Zd0S+UKk1)Vc~(OUw-jL{~=97o1ucs|@hbN=`5s_G&f_ZDBsP3EQ+xF^7onPCLaM zDXvJ zqWEoxR2`(eS*X1RZI|{A$7-yrrk*TBs|i_gZG!n}yfeR}*WyWa0HCU4cR&XE%2Bh# zMYp-Vl?IQ&N~U_~nUdODRitZzSsk(}c=?n_2&dn685pJ?CA39iSasG|p3p2FGkQ(R z!r4&G&72l;?2L4{k^P?MM>Y()a!)^B=F#ut8gByMg-a@69pH=Y1c#YXjf$I9s1QLA z1t#>Pmgbwy{Mc=hhpA6#1>!o;*x@Y_p8xWLr)~M*kCtdtYu;yJXN?)t?Mqi#Z%UPe zC|YQU#f@Um{|Yb`yHAf3jsZY$}n&sPfEQ&ynz0R$6(~_`^v&wV5agI!!I1iT_6+G_EfIdk_>=LVd6Hp@ARhWwRkFfG<%fAU49|67N_8`P0_Px{ooi%&GrUf zy>3*)m>`9tcEO_n0QT#Rs?-*ssM~uy_Bx|5r)}1S%R(DZ&yl3VN;(6AN|XtZ9P#bp@xP;wr7o>C*2j#^X&+0zzeZz731! z6$@=$_xqAv{m3?J%T1pG>dLqY7~llz>kZ9i=XdWa2KO7Rl2U?ElsP2NwF#hz~8$m z9K#56yxtxc^`YL@4?|^zPJkjAjEIRFn3)h0dgN(+iA-L%ke%(R^IG@Y%(}WeXl#~4V>{NYF(0ruG*)*Bh5&ajqIn-{ zy^oITARZ*S`UV;EIU)lYP85%%91Pl`sA~Hq7B@!EUPelUnuohQm+gZ`VAbrbk;(0a zHuZv_(SV#Y%1phh9yvs<>?lpx4L^6@N^J)QGP3OH*+aN0q>AB_*RptTwqcKVVcyX4 zNPYicjnHrHAt8qOyGhwRg}WE7&;5|69c@YPsZQ})2-y|lGuA2j%kO>HcbZU*k8&@oIzzi$61Hk4_kmh2zZM%|$#yd*zb*eoGDC6`` zhFE6aiZ!`)^EzjmY($GfBDoMLO~=8GLJ?sPD5!E2L-Yg`Ga7kkOH6VL8wc7yMF ze$~^Bgo0Jv*Z}C96~J{siqKY@<;?wx1XLF$T8&A7BEcF}!ul4_ZFYXgDXPq-JH|R1 z6DT-!z`@Tw%zpy*Z>9>ny6N?x-in#2Gw!?3(^Tt+hXM5Fs1|h7Mb6L@+5q->n}iRp zTd;Bbh?FhI)KV!R>x6~$?T(FJ5721+Qy)xBvJZWC0woEZId=}+-;@fQCB#@G)8jaG z)uxN9UJ>4SPx#9=)FLvlw|nMbnr`BSvozrW9Orih;)I-LF=>b!l5*|^^Rq+_7GVlA zY$BzjS=4cMt7~;mwhdR@8U)Yd?4h&dnmRZP$w3Kv)NT5|-uvv&f?eySCi(?@KvW>D z5FQU3rw1W_&#dUSu-GOLX)nB9;N?4gr@>!2!JMNRh;HI&JdC+ zw}vD>IPU{Z=z}Kge5q^H4geUoxkS1x=rQoR6RSwhkDa9Mg%)8Dx}O*qQ@58vC4a(0 z3!@`PXcmq2Ml)SBdN2xRwP;XAYsElU=Jd#v`DJW+WMtd$JU*ao$m(1TX71`k#LQS0 z!~Aq#vzU*^!ami58}QO`w&kk)d7o4C$`$AvT(1_slio-HEO>i6RLr*fbB2&^E>;vw zUcjt{pU!E|7>*jzEV#lWMdy^=`x)&C>c0O2`TAfYp>!(EWZSxd@FOT2MpxTOel`u$ zh9d{aYGUM8HDR?A=825!YpBZx%bx?r7ypbm0nn`L=GyaSQb~p_Rh~~ za}&R_ZT0ETgG5kr^Hk@j!5opOhfEA2!)?r=_E&ZF2xAB?;uYCxjutR)tGCxE>0?|(lAkPc{@l6XsKPFb?c%WHi@gwoF1xnNO82 zb+YpH7Vgf8`qSg1l=uyV8&=7bGo;3gs=UUY(QYH0qFzXfmCG}_Fm^4FhpG1>O*llBt5=6jdrnu=`4A*ssJO%Z9*68=ZO-vn`aK%oU zZ!8>zf?uN}1*#?9%PWGYiPDijr*?gosYx8F%);;vdZCStEUV}7LB!ITiT7Jq zVy#&Z_^H+ep5^hIb>OQQk`3X!|7@~RxwptR$nc<@I6PZy!;!thS%UiMQ~~AV;dd>w z`p6jZgSBvkDT>oiE3oQUDld&E>PZg>0mEqg1Ao`EnSZauk{b@foNv{*+X5;?`ahcNuQXl-oO|cet~w;o+N`C&jUMxyD>8&?P!l^1LF{=4oeSfe%C*z970fWI4beu zjo%aGgkc=n`N12q*;OugE?s1rs@c`#`Ym?pSMj2HP`&9#5A>MtzwQR;r$m;~L>7GO zdw5Vi-|^mVu{=(|Rg^y3T=@M9yCLBk>xp?|r&4h|@4(3Ds`l?%mZscYhdbW2RTlT} zf*Z%%*l~enVYJXasz3A{wYuzQ7`#Z&0IWvNR#Z{4qFU!%%%*$06!+Rdxs?A6=R=9S z)zkZEkeNV^4aRA5Fh_aCaO1y*;WqDAE8-AO2_%2^NOUgEEw$T&A$jyC_d6MOY~Dk7 zTdI}Olu9}kn<^ZzXK9jw%MAji@vQ77s&_#y9J(qyBumw)&nPfMSDCU4GqP3G^6b1` z`v{d0`Sfn#cbtsO)Cgem(Lnq_SO>QJCK7nos942Ti7^zLg*wDB09lYLN>l?B@1iu; zc_=!z?Ez=;{(U2yr>1w|p+tE3v=(JV8;=7yUyeQm=uA}HqYGdXF@8M2tUL&?4yXNQ5cOXn4iv!Q zP6+aCGr;~)e_}X>%#BV#R@`jAgM3@Jj@LQw3vUVrIjhcJAPkb5CQ_?3sqgCwPAYE3 zC3P~Iwy^60hU1ySLt3HK8gqa4|LiisGE*nc7z)^i7Tx)gT)lTt;WL8D`X6e_l5r6e z5sTG=C1G6N4y1wvhWM(PF5q{tW?ls+i)SNfZSm7qT&J1zaJdVJ;&Enm$Ni{XDy_B=6Avb?dZd%~^TKa6^ z%LQYGh$aud5ltuKMVI1ioh?2MGQ~D+%_zorsD>&yO5fK2OA@`>O{?cIkXM2pGSHn%OMBTICK2XN&3j)yM4c?j%(- z;c`%CzUA)b4tmOUiLk#Ho&tk(fMY2sBbgKahLsdnbo~qlZ?tQ$!+<^`m%#D%;c6BZ z^G&R9QakFCN9I|*LVqdKq66Au%tU$@H|%jKNn8y(I{-K=86s(w&0wu@hUAN&&Q${| zP77qdgMC~#sJg!XcO7Yae1Rj*81jb4;hT~1l(dQs#9w(dOWdi*Y)XougV$W(0xH<* zcRkG+3=iYM@TKBq(4IiY;jn~)b@F$Qmu+n?BGld(H$dC73D$)+{m?uR+#W|zZ73C> zC*wn0mVLL>+mRJbSW3FB1NAtY45V4XqQb{)|Chb`+A%^*W`Q?>Dt;F5@iOrw=O)To zNWukDom^W(he0pmOIiRrW!u91i8ernps&yJR4?tuHHhUh-WF*mYMf=o9?R4MxQPQu z>fT9x5Xl4yDY;5*YSh#m{pQgk&&d~tHy!W3k?+`l!bcrmLCt!{E;m3sD*C=N^;MfK zA-jApNfiXphJ5RrbsD|HmBt(>*Suuxop?h!MHv*gmeu=L)sck+4A-ixCTkE9el5$u zmV?{Oan&)}=r?F*H*|+XBUwtQj&fy`mP;F8jA(#u>REha`(;^#y_isq0i9E?&<(T^ z8~xkTbj%h37>!tJj^xQVswMR6h?@N>hv`N&d1pD&xD2b86ueG+*b2o~VVCTSP~j?T7~&4jc~J-3OIp!0Umi}tnbKk!Qu#|SssFM92_O(7+3 zZ(3L7xgugxRVbXqFmMu57~0KKRkEt4DX zvu!&i{KcKO%LdFRLHEvF0p`(Nqq^1Ey3p|?%QaK0H<4(Ddjmq~8HT`9A_Zf^4{p!w z%U>yY$u+;pLME|QCXm`j&Pm%_OQ1|jXkXVH+3tu5^l2%uN}ivOr4YEu$EC~Mbsxl= z?o0fC`vCRJ#aM8kzOCb~ejK_D$dbt41iO!rYR5Xh4~$POvag%A24c-G3qA#G~|> z=y(?rrY(rXeA0mz(<9^D$Q5_%?~UD90<;Fh`n1ftollQDRkJ3GvGixA(%c#Z(WB5V z`*?e&W51s4(*i=ABPlQpm-qXN3xgzfx(OM9rjdCCjVMZ<%o9V3Tc0@e8qm1BhyU6H zN6B)A?}n4&a*|VcM||y63}@E9Yu((Rh5C^ps!q2(RvmrVYdm32OSvMG?V*A3=rz&k z{DDPU4>n65_UHZ>4%>ox>%dEl&V`0Ts5+*Ib`{S@2pI&pTW+$pJ^2D+vBpP=JtJ7K z+OY&KlAcc>u;^W!vr3V+(6g7K(B7-OnMU}wCi#+c`0Ey;4No`mcz}XnZs8!A)^!U6 zu`ivBXSIX^NL%(B`A&;4f?H`=r&(zg9=&a?P)}Qy@FZE*hH0w^c7jRY?p;?{2eBR^ zt0}eJ?R@4-DqaEO;s;@QPZqNG#Ha%hyG6Q`=&Ic=nu>3;pJlWg61^9;4ZZY#V_^76 z+HClPF3s8gfL-tM6mpg$Vc!O$m$)vamc zEIe?@F1sh>WEdm4riLH}VVOhmdV_$wDprdRq-1~GEsx|Un|sZmL0qj6%lM*Rtf;pA zXLTt-w7rBTMcZZaAifDp$#aGTH{eM~c=52IW>2-~QqiGH3A(b|dtG35D0V%jXYugf8*A_&2%(PQRldM;No0#L#>2T@5>AVVZ=*YvMK|0#)$G0qM9iQ>nq8j6{m9hcl^ zt>~gxMpdQHtVFddmueg`J>Wy4t!gkG`(wq#buw=ilO3zHLoMm-oR4oF6no7lHV026 zGX#^mq=TexrcqJza#xBg8)WRb_F98e{xMCRHKUY`v5zd=d)@(^W`bA{^SI(}>7Y&z zJ0J%h7YVD3(71S&9*SWpqPNIBdMf;nMLPC>3})kvEo6mrjU^Q^VU2%Xhid?QNLsv3M-!L9m|y;+CYr>NSZyDqJI_w37+=Ln=S!!fz`Ivmqn)jd=@ za{g=1Ron~{r|p}<`9ivpA>lwcTu71sO!5s_Twhb9HBLhDYIoQZwtQmy%T&wSNI8J! zBbY{B962mRf!b9wMi#ai8ZQX7(c8BeY&(08M6FAkrvDZ?(}LJn?vxmUn#ej8>LW_9 z$sn_OMl|h9UOHSOFI8<5QzVfotRJ!&Sl2Xmf!pe;Xxc32f~Y-vCwhaVjYjA93L`$Z?YCoN(E^1L= zjwq_}fF8AFqo)V@KBRvpRe4Z5frQJE_~QYa*GXASa&W`v6gq2+?_%c5V!qE7$?>O+ zmLI#uVtK8Hk2xNGfwdu2&daqWqV-Z{zx4>xSy)u)BfQQ}NINh9apwz3=G~tow4UB2 ztRxP7?x55t_zH$aeiFwYho<-8HynifC%Yn>_UKg9jv1-w*z9ckuNMOFcL>$%tbB*! z5rO{CnefM2SW!D(g6e1KD=Pxy=X;5vsN67Qr^PH;M0#spBkc%&+U5#R%}tyG?asZk zynznyss4nuSlNk|;r_>;(_DR)?LcVvV#9w`(UW^Bi;EKRmL@A=EL1u%Tk#fkS8mpb zgb@~7(FVYoLW4~)Y+`FTk0v)FgaSq!U7$@p*!D5nz&NQF9o6j*R>-rmB?_u}%CZ$f z2VZB&OjbDkA?0Y%A)d5%?syklir?hMu+P5l4*E4uei;W`h*3OKxHRN>+KGWV6*A)mtucXe79xl79fgxarm1X$#fQxP}(Ja-!E& zh6Im?tmQ!@h>r3n%B!J>(UW4`oScp?RgEXO)8Et3lq1|D(WbbsJG14q=aP(Y+doTD zDMJSc;>5uQ&od_apsh0;o)(aj!`;I#K(!9dtq?nsYN|+N!{nnnXNffYqG)ShButN> zG+swQurxObZiLLa7z?x(%BzFYkl03Xoo#J*3Vu(wwGRlV>>5_4x)aTyQ9WHUCl_fv zPE!vXvOflBgkhEk^e4_Zf?!*hIxu0~!iyh)cZQUr5Q`>te`&Wv#H8Cs2Thfp+gzZ_ zeFGtq#TB_&#2{6Kz+aoN&W zEY4(*{^6r=+o85PFwuN+xgJis)Mb5a?a&J;`4QC&?GUahX)-bs^+6XWZs`(2x=cGf zaZm?8w_;Oez!Im+lH}K`oqaW5ea#V`Q04)EM=cB(pP17q&m3ETXxWK-yPUd zjU&wc(|PAiiG0C$Y^a3hbBvK<)^HuNUN-cfo>;Q2SVSB9vOm@nrBhdvlH6Huf$t*P z2PS?$L23+9ay|<6A@Vqsf?FAz&4xr120N+HLtiQ4+Mv(GcM@rPHeQ!htFAUeT>wFH zj@ljgaQ~t}L*Z74~4Fs(iLg zKj=R-xVR3{ZuH|d8QhVQHrEIJ?^UAf{W6uELTnJwmHKZ6*q^)~Y8PgW?!}5WncTx8 z)0>mnU|tl9)xh;huDfkW>n0_mD_gb4qf(?40Ir&hIlEles%}--#Dr2#V}BD@W2jj| zP#fMylTkazAPBt4sIjAlDG|`|DNv@qAWvqNCJL16NdmCY%iV$|{R(|CNz!Y+il_?m z@;n$3u$zqN+&ZXw#(YpXdVlnUA8`zy{Gr{@ z-r)dVVO{r27Y)~K0N8`c-(V)%l(#1pAqhmR?pyT1!)YjBM~4sT9OGdBAI_QxP4B{z zrPtkdm^UL^H`3r2xAVh@)?t$c-X8^DZ<@GZHzQII(P)rXVCCJNe@g!@oVk;{RZ+0V zj8+Uqy8Y=vBZaWO z`FUdtgYVJk#LbTg)@>Tso`8S_X@7-R|98m36d&Gu2wLvDLD=P zN)*ws7+VlBqTQtXM5Nww6oHqtz)nfcJyU)xbzbg-80|~D1+-Lumm26N0h-7ixMqyM zv9O;0#Pcpv)`}s`uR>Rrs@mWs3(L@cL|ZYjFPVaADsm#3cq=bE%aubtTRmQJo9uj za0%3OSm$pO0BW5)!i`P0kUyPY=))q+BK#!3bJS64P&(>2M!gdFJ)gQ z3ZW`hc95e%F_RT~Um-D5cfQ1B&&gP--nP61XuKlwlH02>20SM(>u4`PAHqq!9v~yU z4_sFj`NvaU5(hZ*%1*B~lCm5gcH7l`^nDhICnS-ZF227*TFX>)LPvARoxB6ESB>@ZsgmfT1$ zFp0G7VHVP;%1VltAlU1<(6ea7lSUgzl&?lL*FS0|&ZS4!$u?B}{h4GyO}xJmqLCr^ z7F@^7lou6>EOaF+w&^v_E;*{_5JGK7JN+1a`4d*sSncaF8~}SOGi@AtH( zZcW^h>PUSVWR=jnb2_!#e7Tu6`f`!mPk1HmzyZn~AZCD011pOqPc^XoYOO8v3q*+fFX$PMtqGvvK{~HwQ5&O)5t@_05(p&RY_oSq6o#1=RJSO zWuBx7-uTPq=irAP4IjG#-hM4;sGxlIe;qwCf5O`DRYB#1JxPDR2c2Kz)XMBF(FUP- z5<6#X*j)IZ8l2;CeKeImCf`hy@XpVgJO2x8JFrM{@m;mAws&LH?QlpKc0QSm6e%9B9Dk_;{PmVz79y?d)< zbO7CQBuyo}E=pKmAGOP2c}tWhwR;7gw0GPCC>P=6m8^N&dAw10ooiiH<70M+r1^3) z4S@OZ2-PTQ@|KD?a^ikvo{pT%A}SpcO3%2AUne>lnW9Q_>kB}HdJN3 zer@?S^7%GZ_q$c_q@7gO1!i+wVFBbtj{SH)5O7*6Qk8m;zgohgA^P3xRuj%-S7l*th-<6Naj8E{n}Yf>9FkPoO1o1E)N| zfEaq}=^(}H2qG-7yLg?CVjzbKH~rhGHq5JA?nNU86eA(QB``u*+#b1~RxsJ=P;0l? zjBG@xmE`-~e#T!|$L{%|W8`xj3$*xlplQr{wTD1dJ`0pJT0j+nT)hX13b* zh2X^d2cHdn^ws>r93dW+m2QOq#(xd!_}?0%mZT14ik1Tt{99I^6|BLcw%_RKp3c4J z-yBcM>WhBjqg^Ni!9{-^c?+uO*#*VMc3Sj<6 zFg+*q1=mIfei4FfD%^v$V2yCP)xSQX6KCy1b|1Qt-o8|>>3AoQbD&^uB*YRVubuD* z#S(uCT=}U&&!K9Cu)|tmlR1sfZDca*9R~1nV9^2<Yjg_YJgo#nD&NjaVMj4PdBlNLB`&TvIS>N_IXi{$DS zUnl6OCN~TtO6@{X^LLgDmW+PztWX>AS|=t}TQj+dR8w6H$@ujhUqlI5lKW74Y^1hPQy0?ZcaL=lCDaxx&JjpnnQ@mVwpYqTF&eL2c zbAj+Y(WN#yJ!|VaqpI0m6=O@H6gyA6U>=>MpsL1PQDekj7htZ)NIHZaWGk_grFhk^ z!T(8v3;=IBNa|;(Iz)ng>r4uXr?GKlmg6*QQ6#ax`E3ZjiegI+MxY$AZbJXV(a7)d zq@%>HyTY5fm<@Iz7pZ-Rk(0@e@8Re$gwB&qO>5eaBXVynUo<9Sc@y)|QvQke?VY4B z;|F?MZ)EQeEdjuRM3$6xEd;szeXHmhL6>ac0s)2(&>rc)?;!HYS#VJl_gE=`svEs> zJ?}54n{yyX8}junmJ9sQ)&i+&`B`(k< zP;cL+V}1z!o(L*II@hI6J-tO?A!oPYsW&Io$81I^h-M`Okg6-AHx8MxesZz(fWW<+ zE521+);?h?aHV&i}R#kF_o#q2VY`T}qct52S(K;weJb9HwswiK-oGBq4f@@@Z{SFb7AT0M%c_Ppe@Q!-A@jW!)ml22qb$kCwe*Z29f{x(?o8r#aZ8$Z*p__kAjn z#lG|D{lui1@!!fYg~Fpw*1wa`h}ULt3hz49U7R2?KiorZbx9XCV@}amKEK%%g7_(* z6rN;d{JDHPm$8W2%dni9j z15WNaA(s2va^-Wo_K)p{PjQN!2?I4oZa`)N%VK5x$|?XSY`sbf|WR1Zk(p+UaiY8a~JT_OJ!9czdj& zG>E+`M(Sqc9ub~<1AE&M+Nu96KO#yL)yI2F0hKXcm|C)?UyXyTRJb;J=#5%P<1W2C zC;{UT8lfp$tx>cgxYG&FKlV#fMVED&r(lAuoH1iEE=H?=ovi1-(LWq~3ab<;!_T0- zB0V?^(ThUk8FzgOX$ETQCXXq@jZiss0=onf;}*8z9f{tC*m!kBlF5 zUp)>YKZ-+F5^yUass;~_Xj`pHPB}55KJ4a@#(gDu38RtU$k|j8U zkFc1Lq*QO8d-B)d_;M?TEiGLNWH{*`_CTSH7v%wT zzIC4I7ZTC)56nLXZ!^Ki>`W$gpo)^<-zD35Ts$o1wnzphAgEXY09h=0_nd9yuB#{P zCsk_Wg&Qv076k9M+N>8J#URWmr@r6lmaly|iXIL7=|obcyNl>wVi2j;;%rN~O_ zN_Og$2#2|yXTXheJ1f%_xyUDTR-YnwmL$G#2UGDdqZ>6)egMdCpmBZe4*>KB6ss{{ z@+Kw8ELHrN!_gEh&zbYy{xhLO4eRa7ag&M@#qa|KaseGfWN1jZg>H1WSqIbD!^;}@ zpdZ&~vsK4@)O{MFpym{Qp2=yihUyTknrXGaCC7?EMjXRJox+^*Ut9qPustu!bAvZ+ zySvT7s1R_mhl<^9G8IPfqK17bCDV?BoV~Ii@SKNMGgas38-FPC`H}FE5afkLC`CMT z>+qt7cnRrK#Kt6+`G#8<^`iGE%E5{V&go~;sW=+A25 zz5fhFu(*~Ld!@|P4~H>T%#t-109qV3Je@8yoHR}5PG$4P^maVoux!5MNBKrTcQ-T+y8;GTN`%&n%C2pN5h!fIsb#M<+ltBVxLfGZe@dZp zg1TBh%<%o|j-2+VWk8C8TnF@QzStv$BH?D>5)hy9HN(>Q=$q*u9=pQk^sTom4|$1~ zR^f`~9~rrMtdwaJ!c!KDyLAu`X+d=2XWRWj)YL0X#mo@7V!Qe1A?eoxy6GS&8-oxf zI5-?&EC4+~!oN9c@ygDW`M+DNrDTnv_L-I{wE_7y{Qf* zB-wHeMOjZ1>4I@ax&ef%WOIXK^#A6C5C~<1Xu-{{v_i1jYbt`Ih@bwwn4X$0@Ux4x zxGi&QEgTL~swx-oB<-xT%4O)6-}U$e%*3F?@9B^|hP`Y3`yrfga;SW1CM9yOZ2jvt zw?x1`sv@39k#SFeG`BUrelXx=j;#{!8mh|=5fTx5X6Gy(Q~WMr;;GV)H9Xyv&2Tya z9}n4JUkRWLU+Xo)N$%inA#Uv5o+6=D60&2rXSNa9FxTwryCAYE`pM+td(F&}Xrc-4 zlPHq#nO7ayeHLhj_B1v6`%A=w7S+C%G~W_WhAtOHBxeyl}7i1RmR1%j15@*t|ACM@3=mjKYlGQwv2oJkojUtfk>^%*lP}LC&B2R4=w(zPAS8{~ z%j<{$Z{}gwygK;+GVcmF)0Gf=*(%K+dl=tE;dTU=5N{=x$tQld;h&ONA@$7E^hDzF zvtmB|O@UU=^g0j#<7r*WVFh*_El>n&NOd)yr+)qP5D&Xp+ib>6~!` zJH#z}$IMtI{E<|CYf+lNf6sy*aDFCqt}TS(&-D zl%!6^-HYVR&KdNd@1#HXx>t-Q!g-8FABBU+Y}69*(Wq$%9G;=N?Iynba%iGZ)%-h zmHy>&f>uh0a>8{+Bfc9+$f6NqVKOgBgrH7V6j(`X4|0-c3QjXh`E^=5iu9M)@o>E*>MkskzmB-!nmR4lU3M0W(9UTNN z3%msZB8UTCs8=YG@atDUrWz}zQYkn~o45^3IqPTfj7j+V_ilo5oOA68!hHEUrONwB zK^}bNAa0A6frkvd=wMGD7K-n_nH?^I2_A+rVG+fTZCuD7FMnSkE!gTp{BIS( zP(Uv}c8!S-wkHA16bfP_8>Lc4=$e)) znMpsg0}>I|_$iK+(h@c2-~!3VzX9>Rz-yoOu0jx5Q)|Iy2@T_b0;5hKva73WeC)-# zYl8Y9BboeV{`pi9NzHOo)w*V!i+!Kg*@$Joai~J3mXJo^Eie098)yz>s89ts4{}rC z+Do}yANHU5nH7?0ee0olt>OKMF;4*_03BxoWrnw0?eo}qPY&nsLZr2Olg-1xNRIYh zb@`&NEI0unYK}`6{K6?w zDdb)2J|X>l4MEOpON15+rmqkg@XBDVW6q69D39dL$qtt1Wh5x~3{swlac?!eS{ z^r*<#$&WpL&B3=gzki*NAiK|lXB}N?ABJn7ikOWR^^=ACP5bV4%A36M+-hZBGC;vI zfT{8Y&Sny#KT1~+-?`BWU^EeA4{MR!-=JGM@@Y2)B($v)s_eNHn6RV^e=0KaY7F=-2vUFL*-0%Mj_4)Nq_7%re)af5mxSBX7qu^%`=Po)0T8kFP`e_8bHj z6iRyx2sETes}n#Obm8Ez4&Dz^oSF4U$S8~IA(m^NWhBE{T7bCkW<_*79d_efITRTR z$x(RhDnr6uAVyv6MkJ>a#>_~w!~~Ui032Li&Qe03pE*P6wcn&vJ@m&97H+wP7_;13 z%dx&EMU@!`hS6NvsSgE|Zw@OGGV4JNyj7fjukj3E&w73v z+U>l7#AQ(SxhU;cDL+0rYDF#ju^psM9)wI{mn&d%-3|rIlG2vj&Y!)Vd-(T)-rM3h^C40fmEFeSRpC;mFzfaG?+B06Lo7j& zCwHfw@}W2M`DEig0Z22z#fWcn;vXjd3Gd6>mUvUaDcelI(r67 z+}fwtR#+}xM0sy8ad}JrXkKWol+F$l-*5!qWiV>8L{Rf-juS6XpW$d?r+_jQhmS;a zXr~~XK4%?)Q{?p0{=Yx?@I|?E&plJNR#Ub!+j9hN9lI!MHij642iV;EagUua_dwh1 z-%etLF0GcVU5!a4*%)sA;vf}X=(tj97YzNZx_RIznZ z&J?EUah`8ov(}mJF?(9@qkH3%-?caG_2(rnE5N1qnHXk2n;R}{DMuwZJa=!6Du@Jh z*Pz1cwb@zlsnGiYb2!gp=m*RT zO`)i6N-Wd%?AGCXYh2%zP{4uy5Swi>#*T0XBsKmRo^-T{h^q+J-Qut$J2Wi~IG;Wx zSzWu&gjNp8RTe@lFUZx{!w4>DmihP?{s~FKJ%nD~a>GGGBkDwKa}f#(9%v*iNk{nO zz)T%nMju8`H~*rG%S8}S1>^^N_wVF80#$t71{#kWb;&O8gj^@v!(s*>Dc{<;vv{NM ztQ>k<2_CIMFB9RX7-ViQcx(nx(!cn(O`d;8hG{A=HN!Yy$L^?vfdXq!5dVzYtf(X z`*;D}&zxcdtr5hZq7$F91FDWudJ5(S$7+vKY|9?rIQOPvdV7tP)Gcqo+P%iPP7H#% z1CG1o0nPZuOZ8U36sGiR1H0SP#dPxw`_fC9BuONAv`#x|5#D4t?+Xjb6@9MG8qrEz zW`%m+yh2~a0qcyl@<&UV_#mif8h6x$Nw2%copQ~e5q`|8JmfPtZU$MnZj1b@*=rN zYf>EWjJUFD4Z+@)p`rDB*ZW(kX5cf$RNeUNv%=JZ{Mb!P>XLNGd8B&X;Xzl^IOs&p z9)&n!gdgKasOK=+1=D{wcK73aRQ3f3S(+-+rUSpvH&x%qyT#`z>-QOwvO|FJ`XB*s z9&vtwe!-tSq$QS_K9aP{qc_hrbJ{Vb4cU)w!xF2{o>D>s1`GL|N1;(PfcKF4ef%2X z^>(m&lN``bJQ~84w}S&oQXh^r=nI5=afsRjM{t>i7m0$pkqRZ%CB)nCIY^`<81@Kt zgJ46>{N%-`Zha=DzIUqA=vnFg4UN>kwr_M(S}^+O)e|>B{N&o;Cdg4|pl-VFpD!?# zfnhC+xe{j;8oVuE*{~n0R7x)`R5_3MO2G<|fFw~_KDGuQ6vgADEvxZ*9Z3v$3ned@ z!jr+M9BgZxDW;0=t*`}e;w36tG*VL(VemHuY6tQ~7GNK1P|Wo9Z@i|MIh?h{wni5$ zdn=MY!eD$_T`3J4xX|=oNR_9WvW9$XN@c6EFrMf=%pNiKVU;2I&>O}bz4(WMZzH1v zkfza6Yvb#RfgJ$}6-wk{75@*E(SCS98W?4$2jhfuh;u{J$H&;r&2Pbh65Bnj5u3*Eht$3JG5|OOrgkfsJ*8Mw?d=1#096UkIopCvgdG(ukZQv?fI z1eg1|TKzAs)ph>A7w=<^Mk4f+0_0pl$Fb1soRmu5m?2f?)^aZf_fD8pNKF|j)F3zL zh*p&GhCT*5L6@D!YgF0)*L~wAkA;-^Ouu#mzU8@T2Dx*dgzhzWLt1*m)l3B+7QA1w zUc?)O!|xm`L?Ac>qIvt2AwDgOL2xU$K|i4e8ZPEKoWQx|yXd=Ih|C@#*0eNbUtlM; zJKF_ak=LK$NHvxLpaCsdraTJ_6{GLl&nE}BtP}OpkrYiC55YWQuB_bA^9f)0s?1{|(^zMs7 z6A>8+3ee33;CRm|{;FYO18B=Gndyycka#EGr`my+s8)x?L4VEv9B5Flp#4=780XPu zpNq`k43f@0KnSa~9(XB*ln~%Bm`z&&I?vDW6qz%lbGQ1z))F@M(U3yH$l|Ni zu?$EML7>hQ&=i4SRP)Ogc-K<1o*QNY%QT^1ZB4LPo*lUB(f>s^FroS}kd z#E=v@CL&5}!=!>b0zP;~6yq@VsMkB9iAe6DLS!p91o~_;Sw3!)K9Gys0X+e!x=Jx% zAv|RR^b?{ryf%0M!4Ko>G#jJqn5;Ug``q#`zsT1lRaFD7mrg-gn|-wNO6w79A?5t{ zQ?n6CW%J;1bZ{%Bct#H0TyNgoG$Sj{lao9&m0}C@?gz2u$5dJNB3MjALVBxgVAWXp zi_s%Z(IwNL`b~WAV(UzdJKfU9sF5^%9yJXnq+_@uHU|;+>5_LnJ8fiRu1kX9f?Ql*BOS?~Ma2J9@fP14j`s z9|4UBpNVUQCgXZx@!Py4^tuYKE8rH&K3WGA0oFHx=lSIx+H$n=y=|sdq&55v_i#%C zOeb+bvpJAU_)*?Xnclknn`~RVyMC^&kW2d%F8o^INKS^MSysGm1yGx<+XDde%*b@P}JHUF1rA2xm zGdsCN_M@$VOsPs87Nls+XF!pNX?;Zsf}lpUfi;Ai?F*#L%x&AC+9ZhFkqGYl13RlJ z|Msw;RrM}ehL#eHmR{4UJT=UN{P~N|R9Fz$Y*u|<_ImyU91z|uYccdVn>AA2i z0-wb;-3p&Nm63(q9?Ceg2Mek2W+ps!U~VWo+qeS9mu*j~>lRIXxCW#g%75rf+YA$* z9X}w2=fap+giIH_d~$@={0?cnnY}}N6pUXoUVbB@QY_QK-><<;r6g%|5o$U_1vOf@D^`y&;fp3k|bi}D4mBF@3B)?*K2wl zbr09z{q^#^4?&|*km$%Um$~~?tOn%uTc*k;p%z$@*}|H?jhZvYVuiUK`r0c}>j%ThqD6BP<*5l3J6RV!y+$li)9_I1oWp;D)1q&mk9MQ1?yS+zVTF7@oB8HeD)k+!3Q1iSnC5V@%4vw|)E$GVjN z*Mds4`KO94|CaebfSM;k5iaFn6i3zRfI^^A=a?pq3Iub;vLbk2;&0@cR0*+Yc(I~c!!^S}0^AGtJ; zG7c1t)zCP7@*AM%sbJgRYRva`$k*r4m!?VFGh-2tle4)&65U;WJwE%%*}J}l0$*Xs zu6F;t!NPnjc35C3^*bp;E&t-Ury|R3_hOC^)71|#D_|q!Zo`Rob4_vuf9wB(>bzjJ z`o0T?-@@?y1+Dl$V_g=>QwfpXdBL|r!XF-s;f!cD)d%+#V4f$?+V`RGTfAb;E&KBA zJMapJ4qrep*}AWeNyLcs&G`bl;*#^AZha##lVpSarjX7HNqd#?EbK=I|KufkNA0V_Yh~<+`n6TX(J0?u*YZeUk7+w#vR4V`qK0;ee=wtYR8gj*F6bKM)z&b#bkZ-;0$<3&{@wTaLM$}Mauj-s>C8^QhTNj ze58SQtl;OQWoLgD9pYw6*BxQzUH}YXCoU1#pyt1>g7#ObZem=elU?PHiV^B$m$@?q z5PGZjf+LHlsehv%$75&x#-XokICN4_wZLR`@ap{R!Y5qmsnIZgI#>%;nvY@TDiw5x z)3Gu`=cxkOt6nNiTO&0!4Lc$JDC%lk2RzHg6<*?c_W*$Ql_?Q2ydr3%S|J>`!svnC z4*+(=jA5WLx%wS_f>n0(mlsxH$Zj6`e|Y)rnO$wS7;kJnWWNm0%hiJfUTY%6dK4q$ zi-$$_i`Q=y01@`mE;esSP6oQw8L;~}qet#TR-S0WHa}U5Q-j!Eyq+ql_aNlRY(A(U zY@{c(FS}@5$VrOkidq@1Xe19Hs`gJYif%orzHHlXeLqru1|Y;Hm6lN)AmmfO93$f%e7WKT5 zO`cn7^lHn23C6|0hT%+0B@>^n0u3SmPy@a!yE_snAzGcTgw*Gzd70#jR|wHe`GA51*ozsT`Pu+ z`MGA^E=3kA7U_Mds%xrn1}&TI+WdF)jo-!&7e8J%8|oT zJYj2ieEQZe&kf9AGoj+FftNe!H~|bWM`rr+%Oq6Wv};9PnN<2Xg|XZ+^KGyBAC^cJY}A0a~T zzEoVyTdx>`vY3z>?ezGW9$pE;4bnhh1NKeqz2Y}Ey9h%7@eNS?Q^4hny(d#UMZ(E} zW6ezu2KU>7ieEwahhJVxqd>by z*{#c?V202>ti0HNCbq;}h<(+NDej*`D;DUNdLRkijIPUhf6-|p;9*N>*L+*x+0xiZ zhx;)$ndrr^@EMX7zMe7J>fb~$dW!zyLVXBa6=@)WE&XRXyDA@LQXVPNE=LUz(fywR zc;IuDpiHPW*8wRs=pLk&EFE*qY6rV7tqakJ%BK@~-!92{^a7BhsB`>BR|WfHr3|ce zl&{*bv8ZD3P~b$X+H6DM$D$dS;O#3uIfR|;lsoi7Q;_p0p-<9|HqF14Z%a;m&+zr4 z)@pcQKgdUHZJO&SH+}Le83Vq(5X^S!C-8&3LZi3wf>4`!LW@>e6`y9o&7MEqWz4Hy zgeg)4wPkjx@8yt0mGXD?G9e2)zlyKW@$Ieobr8U@({F!3CULD0A{zVJAq0NJ<%tTqcDgHUrUI!PPt zBrg-1{l68ORWd%2cK*@W=z9dH_&s6m?P7+kt&-d!IZHaoXm#=%cU9?*#f8kk(AB&98UGzoqgrlBTAn89K0$EO?UdIEX0KkDTgCEe z^^U>$v%G5`kE>N01=JeHOfR)Hd^HA@-EL%{=&`yg%$Gg0SMIB%;5>?_oPNZ&IRx$o zFuz7e0(d|%*a#e+u+}*t#unH;@GNIZa)$g-lXD8mUeIAfEPh`=?_8xX#96*g2 ziDGsp#amDA&0u0GkM%9qodxDt50;7B3G=aBAN5cA z!RIJdQ1t_e5t6o;^PDY!tz5J+pN!F(QxX|rDx+|h77IV3bgo^*^5j;XLBf=Q6WmpL<(#jCOB&IBwY?EY!D*!QPD?k#3#lty{$$|_H zg?gmGBq*8&%~_PW;xT&zfPl7BmN9%kM=;(S06(9<*md(~F`Sqllu$++lF6~EJxLb>tRG)M($91^kEa!js61uHfbG{(wian@fkQHO- zZ4<~J!T4ZcAXum6G984y-wW1DZsCfX@jyn386Y}auDjS39g7;~-tz0$-yaYe1iWs( zfH+==#~f0JgB)(FA$8+s;V9Rg6IxE*?K>K(#)!mO@H(rKvqaw2qbW>^IoI}n*TgE} z6!vr9xLwyPOzc&_l%=~L&vYD0{S2M@C0&cj?ghk&n`Ut0@+c+FS};(SqF~-x74wx zbAiOh9b{m)TURp>E$@Xxbprmn*-L94=&@ot?emE;h+V|%i$BB1{Gdv!g0`0Kp^i}3l`b~s@rdvH3n8P`U}dT1an zls;=ar$PYSV54e`xHuBRM3r`O27>7NZ36#@1CHzywgoXEMat)mH)I375mso(;IZ&Z zw?g{|szA>6a&59fHyx&S0TtUS$=Vs6v@9(GDop^aX`_!lUBA^jS0PvgEiaz9 z)Hl2v=a(JmM|ue}C&v}L)pi;7VCu>PY`vaW=U93VffuRJI`QYvy0T;i9-3VOZZO5J z%g?pu;P9`lNKJ3=c+iVmld&sn0GK-Adr>^ zZN%^96$U}@;H>Epk2Kr%rwE9^`-cjOeerp-dRmzK?98*KNFZq~L1mnfl_d0;7BZ5Y zKT-AvklXct8)^?D0VZb`LZz&t^gS~!1MXM8|Dp2_P1-#oB%w)X6}9{n5lI;NYdmc% z>Uf}9YOFUXo4u@-*RGucKJFn^ZN`o23PI9^f7cN`7)}->HhgF>gr936(;CG^AfhJF zC31NK2>z+(*-DKEZ zz6*gk598Dbz5cVqEBQJ>tdJuiLl+10K~9e&D5g~HEOj?B^yHm-oGZUiSQqv`-8xmJ zKXL8@2Gl9=$T=#0Ti<^zEZu)-M$43mp+J8D6HhEvC9cTzyzRmNs{(5EK#V&rdV+~- z&6n-Q5>Lxp;}lUoDr2I!lEYPMuYdnnWf?{SE49p?$EzoM*!sky6lGum1T^0yxVg(m z=~xuv{cv=_A{+Z{o|4!;R)e5S;LkoaP5^4EqH%rrgjVuo6#OfoCfyg8I?3O;o@9~% z1Pxi77TL!SCLi(qg4}5a`ARcZnyaLk_ zL2=sDOcIfqsdt<*Eoq+19K|R3Y&}`tauEeyotQj1DWSmZ=o0sy@@}VCRn>Gx9G9Gz zC|X3(!amoHo_nzK0aIQm?REKJhWMt4zgC?neGL&C{A5;T+}$YB|IsOxSoc)W!Qy~C zcYPb6bPXhw4$P2@u^a%_KX~te3w673`YG+E0BY5`p{OhI_qk1NlfOrekM;ve0^&rX zOk7+;OkIyTf5|^o)n&uhXW@DfuNk!~mpvUIHq!1EG6vGAl#dg@FydG}qVT#K)h&F6HIPS|HI{WUm^<$Y-3O*3jK@6wg4+(P3kNwx(uc>Y3XyqRP9fz)I@rCPmz2Xz`&J(Irw?o=jt&bd91*g-4x57yRk znS9kvX5)M$(!uJ4__x2O-iJ^ps&NEcr7tADp{)0Q=H+MW4_y{-e(gF2BcC%G-6HYw z>6YaJDgfmNrv;v=bhn!mwj0lN(AqmI1UI%GFiK{7v#goUOmL5h(g{w}Rg2X8=PY_~ zy32|a0*W9UmtaiL_&1$l3GOeXf8G@-`kQ^2<2}L^F!r==ca!_3qr;D*Sfrq)d47x%7?_Up$Q6-T?n!rO%^A=*!vhhjYDf{bp`11X#QYjmPDz(Dd31` zS11If8z?biieUGZ!iRehLwgp24l53ir}!xI1!d{J6yOI^afQ^3JBe#)Rxe%cT()hN zU(Yl9;#o_R^k33Oq({0W0HXo(-*7yU^aRSQ&H=&Q(^}_B%VqIw%HbZ;s2OV0>QpTe ziw909Js;~{gJ&fKblLdd-K_J;4Io9d-4~X|xiwufGH?u4lvjgY4v)Fi^9uatfm*~) zw4I~#G06OyB|Blr!s1SrxLa4~&`G)$P?WGnY9o>r9uwg6==mcqq$+HmYQQZ_K7-Lx z^DW)v?9Sj`Q)|)2LqksT*m&^E{s|pNv~b)5vXm1g#!6|;EOj5@b>!N{qNU920j^p~ ze^Bq-w_j4rLc1;XGbx$GcrLb8wS9N~BL!AcrYJzPQVeZCj+R zGGb~?*R95F?FLjIc)KM6sZSSV4hwn8x3V4DzE^q~@S5j|Id1(UJ%qfS-X!m=vy#)c zhnZv1Oz2j-r7(3q3GFb?^ne9(IR!zX zgk@AdjbVR4*!zdoS{P0EX6gcVyy3hFbRg}A5^a2hCS$d%^{#~7eeev1rfacJcp}H7 zl+|{brDEv!q08rqiMbG=V&Ne1?4w9nB~enKiA*=}e$rC`P*I`UQ zc@TkzIr5kfXRSZ|GQAd=x}TRxnvB5M8`hL;<>}(Zb~fBQ^LPJ4TPdz&-y1IX@ZV@8 z5S>8OGlL`Ld`VLZw}4kNJT;?J|FSDXL>~S`N2{^2NoSflEOHcmkU;YM#PAd*;PUI#8Ff*>Bt)h4K$ z1#zqPO3F3(3>N$y6$vx!3EN;`G9);i7QDNPbWdVgKNa?omPP*Xp^f{ufc!a$ajd7A z%5;zoVhF`!948ub6iBD>1E7vJf>@ILLRvwWboUw6FOJf1 z_9o7~c3f6KB9to+x;IY^@#-mAh_ixdl?i*W^7C1$puc}iF?2|L!hOGV3lXd3bkKak|NpoX$=upYap9BjGjJEOOMncP6PVqrL0~sdadE#POmzi zu*+1Ixl^7e#~KNawypdtOk7%p`7ITo6xZ7J} z4DWW_Gs}VtA++T^q2*Gk`bU-i`gqR>p*luv5ASs6hUMj3lq1Cr^ z%%iD}8nkt`35|m3wO_}|+hQ}Z$sKDL5oh;!P%W!jA*QN)+<{^kw9lq>`%{5}^?P0D zC@sxi>m$OB&c@SR4^(yM3#Q*|5B(qq$QA!)wh(=s;5>cnH+Z~+ zra6{aitVf-Dv4eZfp^_$kuAw1H`wl!GhM1?ASLFe1j<3^`D<7YE{v=+xLOLNp58R1 zOl397An8({_V_Z7RmB;%@4Y`HtwGQoG{b}f24|ocDR%S`gxzw5*IoQn!ABo0H~kuY zq9VBm?OY&Xrf8!6Q2{`u%8PKapj)}VUe@y}*PkSU9Bi#Pm7J%kBOFVnh5pnLSsB8Z zU94DsVp6cwZvDs8R;ZwVljE`})X(rCUn7TJ>&NgU4YP9U7}sYHZptUsl(4BOqjgXW zB-&gA!>q%+`A~bOjB&@b6bY);#1?wy>=5$8?U}Q*93js<2#%2ovDVLwX#8f%S0?U6 z4deMH2ebA-Lg;I|kvDC?0d3Iyb12>jNo!XGHS-E{Akpn2)UjYKBBvcBsdGpjq6DXE2RWbl zm0%hS=@Rp|19l92!dhL#r)>F*M&_tm(EU{-7qX)2@81ChW|;E4jpim9fltUG5#g5L z_R!SJp9%sg;e_i$PbuwN6w&2wA%JZB&=qr+wbQu z^`%&l_=wNR)($0zKrV=q$Py!!@?--`-L3I@5Y?G*hP?4IHh|~>UhR@#Ib_?bBK!Fr zXNR*L>O!->WbNd15P_?p0kc1dz}_g6>`?;-6uuBy=ernMJGLn-4oBi|C-KorCQ(|= zzfX+QTpzo}#<-(w8HqsG`&KS&hXDXK_u)QS_d%0p15lVCL5Hu=B zPYkag**{oq)8o1Va-_B=ATdL~XWC>0-Vuv|Q0?I8p&JDw<)9c{Ig_KVs=oKnQn0=% z;a2I_&^=aEBJ0g-cPqbk2dbr1&TD_xyKo9i8&W)b7mtT$iy&a!63P7X@gGr1cB`|y zboY^<9_Q~?@o8cWcg4gcT6lNd&vEnrFz)TO&kat(KT4flT@T=QrO3o7!^an}6bOD8 zM-?C3WEJ z4;afIp1VU6<7z`q25Z!%L=}o_Jjc1J6mNM=VEd8QZH6RgN;tm@u$ON=nP31pLY19( zC}eUIqx2eohX^mX`Ad6;iKmIG!YAH?8Tiv!IZVMZHpWI4rla#TQ`Uq>3j1>{UbQ+* zv@8YWs=Z0(-VSo6{?f*d;@|exg7`%bs>lxPGJiU2aSvYkVWe9Ok>n3i4OZfwO=1Go zyAA9P5qHiHrQrN7{Mi5@nqH{VZBfGT@|dWYHU-qQGnFk1+j&gfEEwG-*l~l^ONt$ki`mFeB0!@ z!5PI~@Ps(fdgdLZnqrC2`3=tdwoZXodF63qoi3{ZZQ+$kDTZcTm;sd0iLg1-D~?&k zZJjN$fIqlHHc7|BxRxH!CK6pgn*9 z;%jMcan>)akAM=84mHA;?Nzm0=Bs#QK<4*jMC>EhK<-IVBZnh(XK|Cv<(zHByPGg8 zbudNy&*`)#3xNxj0m|@S1Dn!|5dE^paRdU3n_?xS91xqd$;Rk1fl7aUniD9_8xfV_ z-Mrw8!$CV=`<@JyOZ2&|kP%~8t$|Sj#Iu{JtKvK0YSZnVq2q*->C60GNkZv3F1jx= zHV!{qD>1!phAxh?pc^*}Ki#6mvGWAliTXO1EO6_O-Wgsv=CeCOf|NCqtRHsQz zhOf*=wl;^j4KyquAu8TxNT>oa0F{gXI^C zP~eWcDRl)TiVe_{LbZU%2se zE#hr3n?Rj+!F;%r>}aj6g_p#<#=58s8320 z7z|t$dB)NZcE&}@Tf7+4e>;ga&_gJvTD4@`%zW9aU*fXnKo674jnG?0D6sluY|9Z> zK{N*fOw+`52To_)hI;(j`T5LFp(8FeWz>G0xuk?FhmmvGh`8Ip~TP42{cJ7RF zR0#|({EIM(*%M%+E(Tv8tVuAgH|Dzt^&8#zS(;9;Yv>2I?+7U%k*}rW<^GKov-v=T z!CrfOG5CAM(NFOe@U&*^!qmVrx+sQ1#wZXusyb&*p)LuQLR~$TH*rW__mYWBssn7d znE543=W@=e2G&4yag{2dVi7(z?yU~wUv_~lk~+n1jj<@;#=0JUI%reE2E8! zDfrj&ORMTW82FN4zf;A7-&iBo;nh`^5$#8eW|+)w7coGZCh7Htk})kjGeu|6OKmR- zH~0ys=;c&wRWv3(96MOGeM}pB@g78W*q+e3B=d_Ueq0=K{^5qfyu6fFTeg2*nHL^k zK3ze^-c}@WR(Of>C!k1iLewwyka@#@nv(mRe3GT7#+DKlvsp^UGy{9C54JL zwH8a;vCg5#GyE8Ih>{`EpNvZ(d~T)I$;3%I5zRJeW8xl1%5rUTLSRF2Mz-m(@f8SZH}3A@SnWd=Z8hd2GSy`LQ|Bmk zsKzV{zf?D={=2(QrU^a=^yiJa0Iag3rvc-+vUSZjp%LTM_d*dEUpJUgX=DzFPhpU39!aUCgM~+r zh!v@N@#qchG?~Sn6}nfHW3Q=ShK9!-2}g-Ta3j&9d9ELlG<>)ts*ua&K0$idEkf{F z=?yDPKZxJ&9wx$T|P z6`{=9Oje#s3!dB%W-DVnJS%-jNd5sEPi*$W0F-?09)Y)6om%} zsqO};%y>3O9?C>mBCQ;V@C!I`)N1iEnNr&W&IL&kf}v{6@WfxfzwaYfqF+(-ENBSH zKf{-8nrb!yOgW`pR!HHje6>mMb%PoK0VwrM-g@@flnt2^eFnl^5+6JPI#O8mf$7I> z7rdq@{|@W!q=PL@5{HvKb4!S6f&o#wd48L>*zVt|WCj+6=Y{2kS)i_nfw%!I5XHrP zFEYIubOMt?D}Mg(PU>|Bi#CJl*`BJkbD?k6CB$}B`+w%IOEmIMw#e_M97wHZ7-CvP zeqQehTY$|0DIJ?_=>|Lz(pt;*z=;S}2SVB@Cl=Vl3#}gIQ8i#0_u|oBSl$Os+6$Qc z;reOGE6*|YW|X-t50NWWO|or(Ctp|?f&s$G1XXy|-aVr;$6=ft?JKj@uf?|`nqHy= zx*}$C9$df6uacJXz;!-Na-}&}-+j7LEE+Qy>)-b8zi7XIc_vr5qK6NQlW-oaQEqB# zrRh|I0FO{up_hB^c< zKHe$hI;yH9>S=efdG<+2*=^+{TYh~#;n}U6d0T}C_`XhDyI;m|wY^#1Mm;KBwi!-) zn>-RhyKaK!`Vv?OETcz_E$}%Py1b%bwY4=2U}ZGmo;Xv>cF4ERObRfgBiLnAG3`PXu zl5m1L7%6U0GY%foiyl%Tcd7ABvH@*bvJ;hW9_>zkw_Vc;pXsK-GaxuM1cIYs?XY%g z(p{>(u1s6z5luT>hy(`2)`_EA3FhN_u+^8lccxhe&Px9Wj*6_d3;`={F?WLLYe|ZR zbZ+AiSu9|jOS=pv%E88IK&ZHQ$FCjGCkb##`!y(O)Cph4AmnNJZ<$~ktxgArb@-n4 zpgNiGH&F%vBpyrz7m|5sr_hD#+Dv2mYoB=LT>3cHvdOBY*{<*c>4U2vl_kx348}U} zKAjcqq1&-6p8+U0+Dfr%4I*ZkAlk6uBA8}t$NN8m&QbV`;&%@&zrMTpV7{b(;#-72 zY58wH`Efl%I<3>kB3=MkeG#MRVwNclm^{BmkxFcXo6}QAQ~tK&huL0a3$x(M|NDf< zJm&Ou?SGa}xo~mpawvD+rHj{oXykjHyf>@n5e~$H9>j2!j0tS>v%GsgDaCQTvsGv} zOT+4fgk65x?E>+Zgs=jl4S{%{VBYL<)rgey?51kMJ}<=(g8XQPP;1U`(Sh%DMjKgY z1W5kWFQdB4Nd10d&|7k_+bWoi+`tq0?O8In3N3POzL?=cJ84}aS2%UoE{$b-?{F1P*jJ+h{>ehIZXC;-R z;6W7*dblNtMYSu_dF^u*B{KGr&yq3#JwU?0$u&8`yq9(MluqR9>4eT9-Ve)I5jp{C zQ-m2!&z^qaPpqKYS=t7n%n8;tV2I!UfbfaKVs1U3Gy#PS5@{vMpKT7ma~g>OO_`_V zqyq6eShI=ly)?W~3AZaRY#t*cjMC1kNGPHk4*!K|;gjv2{w<0iRZ_Agszdjq09;dB zN^6suIbL>Xk%Vbq@|*k)^z!Pj(T6=|&&fuRZlKlaV@Z6ow1FQ5t-l~-UXqV!fnOyzbBj`7#7FR>bh z^=Mu=wN<-P6%Q*NNsP}tfpv|ibXAseM?mc>hw z=8CBL)wv(eUjQc{Aea3#a*&<190iLh?Lp~0jre5-bT}iTT8$yFQZquGyK+Wuje!)+ zO?k2&qdH2RSQb9#OT9xTFmTF8HWUCKVbUFPYz#a?~qt;*48WJi2bZC^4nG1`b3mH9BBLYWQ zy9cK` z$Hq&}{vgaaGvozNOL)tLv8ER)zvvdY3D#I(RrTjc+rY)s?gGB|Af(^OgRVXQqUDQ! z`yF2t;;X69(>d94i6g@t7lfHaR&$1OU?;>w!0~9!arO4ntCS#zMwYZOCaT5CySuS2 z0K9KepphniHIs#3|BB4&#@C@>L&7#5y~az2V!Ef)ir1Inig4#^RykD~`yW73ONyBL zIYJ@qKGcZ=UaGU_>_jRMma3}?J;z%1oIS0pxj$$!7TDU&Q=Q`OXc=?vN#Jytv*qW>aS1% zr|PeL&a8`&&_)>nd9=5}F=KpPe|?JXGC9#fISiCyOteVsPU%2~+3eZ2w>Ij>sg!&& z8vnIcX`k2i>Z;@e%4?F`ZssRhfu;5l z+7C4WeLjQ8b^Yf1c#TnaMb0ncl#6O)+C0@;#&&h!0yjR_42b-0YMee#?XxURp-^9+f^Zff<$qycW*rPV@Q!(0_3uVvNzvGKNfD|rMuwnt z1G4^5&$a|7FoXm_6W1Rd?O3cCw8l9}skdQw-(Np|Jgp20JBm-0@MQJ5O{EZhYi6`i z;*?<%0iCVozLG zwc>oYZ<)xMvuog&%x&h{vOYw?PFGqG_dLbrS`~`?o^~CA@2J{U8e-$;>#Pazr=3?% z>{kG(O1| zPcPY>c^VH2K+q!xSF6u^mK!<)VDb z+>Rh}oz{Y5Pi#_Au5i&Jgb>3Zcm=AfjGt3cvc_X?$RwPfd% zcPWaAt+I2(CmaQPGQbOSGv42d28HHR;D_@TJr$e^%R87RcJ+G>s86JoM3{ z9shjaqc0ZGf+Q--W*nSGKt*C*I;!;wgU!7~N5xXf<eNj>W0PoSsEM<~TlldWy{& z=9HBM{d~O^p2utUAMc(cw0W#ka-8lrhAS4E5HCZED)drBWK{mS%~ad`2~XC_65AKg z0=!9EP~--9?N9-n%f_%+>VigEdZxhuF?PM%Mi4ZHsz?HN{AW{|O=IP=K}1$7t!2M# zoHDKdD!MmQj#(EGduK0v;^lbGl;I^3mjG877+A#^{Y!#S5pFk^o!3m}u61o9iZEPEs+QQY@|v$BP2o4=WYzRa2j z@@cNBo`A#-`|fdO?!I}7gIIp3Uvon*+d%?;6GyH4+lM!^k=zm3c zf-00bh&q~xj!8T7Lr=4{UnyMgdJi81;ZmDwRR7n zUozF;xG(E(5;j;$>i-k6iINmC>z zOW?f$rpP!>D(rbxKVW5AQsu&lHc4$O4nLI0SdBA7tK|0LmTx&yp^2nUb)I*rWrkqL zdkeqbubn+IQDT>aDsWJnWk*Y%_pF`%shDPXczeM(K7bAQHt(BuY%c!tV>tb8Cxh@G zYOtMC4WJ!sb=ea;9S2^xNgVqdOfEOMTb<7>vfs8(5n-NKEbo*Vh@fb-SH-;^8R;oJ~_&|avB=qtk%3|a2>_Lc!^r3;yi?&zn>+I5V$=iPikPrUX6n^`# z4P`wng*a3WBQXMm)WNjigS`Y^>-ABp-4{lP;*#%~-z#{&>cGtvD=Zm0d;OQ8GP0K1elV|3auTL2;g{fuE6 z6+}#Z79q&m&`r#+HQA~kxT4Eg%TG&>{i*$D@=0l28=+6)l7w@+2qnkd5*z4?wcsGV z2|V(ic4)~BUlBAKP|;Vu&@<6SGY!9UDJV59s1H>kE0>N~=;K~Ew3_b^j8bwlk1EL& zKi9gdsoUeE2gN!iNU}|}Sd543nVh3mg%&!tp?Yr0OpI!yRS4GfdBe@pj!#ZHqWT3R zGGLlmNDpzsRk2e4XVn8~nRgC$HBVCap|N*ybtxyz!hh70IC;0uX%f?!p;A~qAZVyH zU|Ya4OSFWkWGRRK(csh3|HVEa82^03V45e{o8He6k>^&Yjf9@#5$i3mWnTN4kEeII zCoTFAnZXpQhE zzhXZj+(HUOhx5CjaDhyv0Y2-CB8>sMO?(~Ob3f?>?T!XneQh#Cy^a_eLwJE4d z{zTcNe8je}OPzRXHO?HS0Lp1S00+Ygi(1?njQQ)hj&dq7hhu{|X~T@FO%~WWNH0c10{kqTEz$s8cmQR>*T6?;aR?foN( z!6$q>z7E7A=b2C#Q3|T>e&m~JF75BFFBr+`XTS0E{XUKI;388_erv*WtN&7pIIiD* z`y?cJ6^*5qwjJm>s5C*fYQD<_t2TC63gsvVR4PPCpyQKK4>0yA)>wOB6oFy_Hlo75m4^Swi8=f11N*9f1ji0?z9U zvy3hlFZ9@5Nx4&HwuDzYCkVj-2&_2#5{{z_LC?^XrtV1W3{8tE8hdUQP`O3*KIEXG z-GZQn+ShD!R8D}M%{8wxOKPf+#TpErT@A+#@2gw=Fn)+Pse1lLPHSw0HR=@QQ1G*O zc)A${iVJT@*j{y7gofB(-(WNy5)E^Yv)P+SqyIsh=SqU7_$`iip|$sDo%?kM)!e;J ze0Ks>{LxLfElzY*=xZ8TPrLeC>4uz)UmY0bEJG6ukoQ(NB>Y_WuI_qW{Os|-D~gL; zO?md>(fFiCox~J2K-8`n4CDi_yI9uT*Ic7?NO&`l5R!?M;`H_|oR7$@7~qgUdzGK( zrrCRSaaNPni2N5UoTgbRM8;81IOQnmwfgOWH2FmfubJyWQBr~yiI2ox@&V-p!nB=* z>deZWiWPPENvSI)GAu^>LoeU>KV9Ml{EyDAA+rI&$eae#EWhMlu@fK}kX%$C{E-@` z&TJhsHZJ1!%s?kf@eSDkUmpG}(OG2DweloTN7VX!_K{sI4=4PWcvA%~UyKj-~p-W6xSi`6NP z)Dh+dE2lwPWqR-M+(aijyob^YdqX<>r8iT<}W`a-oH`AezK-eKRNUVbHz<3__;nr>1^g}b^u9Z+>I!q z9}t73ZjQcA`sK%tZf^xJ6+OqRwC;M=Bw`OMAy>mE{{2aWhdgVt#-Km&89U;jaJ*R7 z=0561qa2df>wFz6v&ntY0;3!%lw-oKQxV~1#U|w?v?z3CSuVJPG}SDQrXlRtO!P9W z?*OBd$#^)BB>x=gfPfsKgPM7z^RGnHxCcLI7Bc5CRAK3d&;V%UTTFTjtV*il)K3vJ}h)R5D!JpayZX4$2>>}nm&yE$jVPLZd9l*pF zr!siNV(-hKGn|(&Sa3rMV@$`4JV83Gc+TY3%;qtICLwDrgPL3r9mlYa8}seHm&PL* ztkf0yQ)cl&(lpe{5>L}^C=%@u66mW4C`r0z@0f$H!yjw7lE_D} z?Ids8lSqM{u&Skn@=&u=zdwC3x%AG3HQ1H##OwJ^gYXI5yx#yty9doz=7Sb>CLrZ}?n>G;8KeS9%mO;FgcBH5M^S>~0%!Yo|-J^d7r{wPwL3xMM7;G|v7{c@%;GQ~vSx3*__~ znHZw5*`x8(9W*4)j~8QGTKI(fO=R#hp$^grTrW@^rP_Z1UdTG0;f>-L=YvJV)##l) z-g=UlvuSXoWiL?)y3mgLB2j1&`-R%Rz?>2O)ulX6r-yUFZIXi0;qMT~~8`vJ{{JvSoT-D-O>594&ktnwlA2~u? z9tm}e*6-}nQ0XXH%Dypk>JfI2ajv`{uf^<-^rs@6FfgoS2Lj>Sr(&HCzNn{w{u#T8nz16o8q;5l0V4HTNj^P6OG&A|VGm(t( z-1KEdWWllsP#P=SzVA(j)mZ1%6f;qe}Wp+WHZ$6~SRZT?Nkp^|0_i;mk5 z626X=e&{Lc>G;*|aX5+&Gy`nAzmlIbzrJm}=WdJ+%QTkvH@i{_vWISOV2#V66~K&- zh~gHs)Pi;w8hH8nDaR7f@~!~Wv9ZJX3)A^@FxfO((I5;YOS4%Iq`YVijwQOw6Nkr%3JbfM>*FKM%`xkOs()zySXin)VS^iLF!{ zz8Ru745=RyWBFCg74AAbVD~axmm&MFw%=yBD9ZEXFKBg1=Nfw0pl3!x?Qu^j>YCOSJ6yk$WGKEC9RFT) zj25@u;*_*4xHR39Ht`@o!*3ZMGpVh7iI@LIQ%zg+Fzcrq|9vsls6wt%BB;O`Rf|-o ztiN;|Na=m+{i%I(QPEIMw&TS|(Nme|KhSEU*g4U75^zr|j!O?~zTJrSZ~bBtpe1)~ ztE(6R)^L$&Z}waCDAK*Paj(aYO^yN|;6|)_y&)?<~QM z6;EsAIdWA~v99n`2JoA=vp=15wy^Y$D934|Qcc2`>-H zk`f&a74UIVyMDoEpv=-9cO-T+=^r{8>%@Y6BqE^51*khUm7uM7vkSQz28W6iv_*?YkVA zoKG98kYq^GMD+_Lhrd#-#4ZYDq<6(>o%FrY+43V%TmKeCW|bey2|$=~)&+(E>7KoX4UQ{>)1h5|Fxu3WK9pDrv!+^V+ zz;LrHf=36OX%Ksq%12&cbcrrF#|)feMeY&6WqP0b_GPF{Z_c2OtFKO5?tr+SdA)(- zHiF>5%jWxiQR0P>Ly!KziXA46h}S+wf)A_T-T?@2WjmH0u?qokd;^$v{RD!N^5jS2 zm?{vCE!{OHT_1;y*`#rQ89!d9S50I97jH!6yOJsJT@DB$&<*5*3eUPFz8nU%yWIgz z#I}sy>S9F>({7kX)Tbkx6Yc`v&+VG0N%t=zPn|A=nGtj=IO~?0Vdj)fac{>t>_P@x zU<^liBb=rK$2fR&;~@&Sr;APTdTlq`5#Gkg{?Npc8_E7BL@G&-qDz*UQ7f@{AloJ&~oeTT!p0J7NJx*h4k(%!Nk4LtYv< zG>v#Obw}%H?d~`s@&kly!Ec%dyehkdokPuHEmOg4WmDMhAO$h~q>?u*r5MDk^M2<0 zp4^NDIBFg&56ffliY_|~q&Ee>d7lup1sYxjN;N8W2xICC-a5JQ=~ySB!4kOCCnh_R zkM{{4(Yi0#Zpe(jYBE;o3-U{Pu`Sk36(YsbbYSS$&@9^&UO;n_1-AE*ozZl-1J}v! zaTAnYm7u8*K&V!U(Upk^;SglkoTLJHyyDv6ko#!htzP`|%MNComCQEt@o4Yc;j?95 z4O8{pYb7=9IV(jZqeEizXWX{)dkY^ol{8>po2E(m-NJ0#6fT{~$B@V}N<=;=p&;Ry z0$2V}WyDPt7!RrjIlOd=s3B)srY3P_arT~Ddmfefxtn~SMZPA6H~r0n7X~y6M3`A|ioPVGQWykI zci?V}oWf;+30AmtIclc+!M@9=I#YSZsO^Gj=kR^AgJkd<;ssF&ou&VBXjl_xi)!q| zq<=Cs8P!{7bxuf|Ab8GF_$RC1u^+5p^aZanbV)ZqiSLLiwR6DwmPvJ5-pOQq=7$;3 zH|+_6z)vPH59cH8se3Sjyf2fyksGdFd9UO_zVup!?0_lr!sH^7R zECn;xHUtXQi|KxFu}qj07IbjS}?Byn_<4ZyxiLVMwlnF{k6*ZwRs@ z`QX+C2rb;O-jWXo!bF5PBy>BGJ(tLGUn2DK=}_$)Fv07~SZwksPAW}2GwLzapqdM< z9Z*wp8Aw3Igbh?EhGQpg8iPwb0CPtxO!{sCL(GJXW;om+3SyRyOenrr&3Dlp(pFrr z#C-DF|G)e?n&RQ+kHpIjmq>fmw~57NV~#PRhtS!nh0MNH_2M;4T4K1ZOs@cY`3_%s z;&*b1E50$ZHxAbuU79QQvJpq3ge(PSe<}|f1xl5RVPE2fQWY^2aHS zTYrDS*gT3RZIh6!0+TPajAW6MDK}s4Vw(SQerPWd0Fn4ICX5sgVI|W6+z`kaB1|aT zPeQ0X72>jtPz;G?LyA#nx&Y}b-xk^$;`aCaMTAaK5jEd8a}VNTYyi+$S^mv%8j0%7E&4$% zNSN>+U7`p~40G0m9iVX%kw1xFQ|04+C-W(ffbI8ruplYvD?fI!)8GYU;$s?5$BJG` z7$5J{Ub0thbD90uIdI47WjI9?4so4t@lZ~@PEZXB--7Gn^sB&xcF)H~Y$-CK046*sMVc^HX-W}C^P@YPKVa2Au zSJu7lZ^HEmzrf-Hb=NY_4;icLfy~>tKEl-ozV9WKPDcPkgY%VzXs7>!76YUDq9?>; zCXac7+maLB_VH#CQ>UMAw*1ZjRFI^))g@2Xpel&!Y>?D9ZJ`e^HkZXv~gx^9h~R3RJ&2A$0Of-qv}vu=(%1cGQV1c%j!S4ajU9M z$+fHw`DME&kKg;i66ewF&Frz|#B0xlk*tIM#~33hzjBe6T{iu??hU7Yb5$I}F+gYz zmPfHg)w4)67>ylpO(SJ026u>4g$gB zR@)sx2CUkT&DWr^=Qg(qz=a4$#7_msE;wZv*$`?tHh22Vj+0)BdqmFEyECZ%V4+$B zX;+00F}YvDJZ~$LET4kNd0bGK4xi}KoLfzLym19HwseUY^(S@xPD2V;5w z0r^-wqMGHIzP;Azm`E+L*HCx%sbsh`Z!ZDvb)o9Jbrp_z^69=fX*|v}c2G0I)CU)^ zcsqoJs5zE?LkT&{S8DHv|Kapyn{qqNNM7HV=^ThrZof(ZVrTqajZN{$ zW~4b{y)q`ucQ83jRwk$1lD-`8ZJECS@*{EGp7lO|ym5MUBT*eC1la!;JPlM1WE`^c zyr&944;+2&z9@7T{_b?F2@_c?qi|hbI&&_<&S{Ae+v~tfKrknLs{MgN6L*}p4uyYP zqa!?on}3!(QV^znPn~N78RI|vm`A4gg!~}Gc;1Vn1_jmSPyoLO*!1{hR*rPS<@2%lBt_1k*M)!zAX9CYGu5aG_|ho- z4Hijb$}r?d51N?IXSn|}G~LDSD(308>HXqMTo2|fG973+Fr zUrI2>KxS9MeNG~fROj2Wm6FT+da!**zk5f9ZV`HGUJCE1U$HjcSKCKYZlD0NbF{H= z4wlCyt0P^x3Op$f#X%M!)^w`cO znL@5RBV45US@&ehAa|+sI=>#ml^%;a;Kcc?m|oEm<(kp&4xQ@(aAAVq_|&@*Dx$}@ zAF(=6$L~VL5x!BLl`ZFyp7P@}I*{ENL+%S3zL9ctKR{BY#CpE!+Ci-&+#GSKA3y5u zX19Y&(4(Il(S1Dx)R1$s_;&0dCYMR*V-b~uX#_9bE;$K8L!c}`p)-KO!ZU86@Yail zp@JnweiW5L+O#6W{2hKg!cTB3b#C6){;>Sxo$y|<7~?jUps;;b_`WZJH`}AKrL?Ug zyopjYOx<*QdI}1G?Dc3pHV9H$uQ@U73vTMeRu+m0*dC%NeX$Yi0MEwZS?!hz(V`8Z zcb|Gv))@>A^ORf3xrT_3dtvvsaM$O;C~VuA~cwk zRdRJc-J5puVhhu@f1kd8myVcE!a*~4%?O$g3KYjiGhL=+g-2k(-QCTRjkPGQQl!-( z$+sgfg)-*IB1?d^8!p0j(9CMl<&4QBfe($tTnI;!5y|!DSB%{`_ZPR0M}jo?;v$Hq z1?O^~;{pq$z2G2xn^6B1Iw3fk7T4!3(z&7PnPI@Ylz`m9Y)g*8;|hxu=n`7fw(clV zUoaLM&B)8bvX?TP|KIt0E%F4Octq~zhrk=JgXl?KA3WpjuYIi=@qeEz)HH#c^IQZG z)+*(kku#-2bo}W4S0X)jl)k!eiuU~G#bz?@ef!^)5@yG)@;WobE-%JzMgDo_&xuDS zw8p1g^dtmrP$7eQs>Q5ul$N<81N#Z`C^-fZezeJ0mOXx$c-RqEHH~r3m*;7H%5IY= zf=|V>)WGqDNT<G4&na6(gl+hsd(WLXV8V<)9ol(e>f^U51W0>4sy z8_~2f*AQ5EZ=!xVsp~mXH-#l`8Xa$Cnp935FQ%)V5|N6Pw?M&?t8>OI)97-D((s{r zFN?Ed7aE9*2j6B{hc+Htl+TOM$nPPn3_7o+!aivkD+PV{$u&T-_wB+*BuPMkJJC~U z%SxC+bGt;pv|QbFNe|u>awBTmGcS7qG<{2g&NT8A>j-EBlxp&%@_cwinFiv9g6gxjrlk5fusI!u~=_tXK1#?d$(Icj2mQ&A;!X4 zBbjV#Q`V$+iEM6(tnxMkN_l|73kXhoQ}HZK;#V@1tx)1ltf{SA(G^4le9RHdBsHdU zm929+5U?D?-G;BGMm&HcSCu6(oL{!khfvA0w6_hxkkC?tO<&LKWPDUXaJI+OsOY5lUyTn@ovV9$AX>6ErGFm0*mb%n{;SMRp4{#Z-2@NCxMO{YYKQuVV=R?) zef<&T^kanYSAn$Ay;Hc=j~e555Sxe|Ee#FGZGgw zSAJRXK))%<_KC~1^3N_;*_loUn9)i8y9W=6U{2O+p>VovZtcM54tB4eJlb$YmWSYN^KZW(Jg7^P;RMs85H0r-)bRUvD8eJphw#|* z>{A=1FY%t-BpxKgt4`-s`bvK^v-G-hT_1n6aeDgqVQ{6X%-N^9mxm{e28c6VrIfP= z_$By_n#Fixb#o-20MVU(m~am>V02arAR5NM1o)=@7he^!Icx#mqNHF*Ffsiz9OXeA z``~X#*Z;V^O8d{zW1&Wru*gH$;#-SuWZ3O zaa{=-K=`16+~J?B-umaW{25YFASz^XfN`InG;9yb#s_|ax`8x_t_2JJy!RM91ebCU z#N$=B((^;XR$HF5#fypNqFpEUFEHyKuQc!fH3>oGR7$O;uw9Z`f+jMd!`?IzqTX7j zg)q(k8p2>Io{kzpjokjJtt#3x1&P^k$$ZK5>mO!#?Bh$sL~BbGaPA~lSHDcVb9C1)-6y+M4-2;A94Z5%oH_CPQw+q^&+snN_S#ysCoH~k z)8Qglnsg$F#?C`u* zEM7QEL2NmLB#w5?s|PL+$(?-@XS%;zW2H>r&<4vkcm;4JFGkjp82Fi|85o8XOlf{l zWj0MXZ>am?9ABL_sm~{6!ARXLS zQYF20<&p7Rw=^+ed2{n>u@+9%+`}H%286SnJ205tGybz_sf_Tvv1EeN%PEdxb39R( z(_V1r^~!xQ-~z1y`Dl&fjs*eWcuAAWx3OY3gqP9GlRH6Ts&R)=uwYdJjR&){+*G48 zAmz9uD*JGvsUsF^%~Ligebq5pYw%$*(}4_8bX-1TFm3UM(!=>bOSvgFr7fij&7!~&MM+)M5sIHm*rhO>vs;w~jbO?>lTP&R69bFX@2dbRVCBG%gji=gypI=*{5Rn zlQo}B&Z{<%*Z-3m>rfbTX!j|-%qRCVsV{_OKEi%hbtO9Amz3x{OjMnN_ajRk{T` z{%=iSj!NpKL7qd9*K*=hDnNBP2ue3?%kQ4tI3ygB=`qZ{^L&WuGK-apaVyP;(MTr^ zQT2Pk;O`Y~5m_)Ux#VSY8676Al^{gX2@H3Xzku*5UdXZfFagj{e^2pRK|A%Um6-#x zp>|F*^I(EJSn?Ja{ETl3d##;?OEtO@(i8VZ^dVkz4W}BC5FhDKzB|XnmtPLbda;<~ z6a3OT%roM_3LGDy@+M;mk=xpxytQGVrQTQ?;|PPIp86&CIx)|$KgWKzd&SZl zFI885`7h{c9sdfN6rUStV3i~|8YD=hw1e6kM0KY3AGqdmPk|j`DPFdfl=FtaV!zG} z2I7s`O4Z#X4bgNcw!RG7ASQBKvnjTL}PZktTI)SH|_ZAWpequ+-|0Bi-`-R*iVkiNYkvJ(+?RnqGDE8JGwl zj12E>eV+o#!?&kS{RnJ^fafwFjYFT55}t6bA~$_Wae6+lW*7`E(bgF0={C@uRt^}9 zsQ;QHOl+Lfd9-Ng*2i1vJO{i`NutrXtC-|$Ht6lXoVvG4hzoY+f!#wMxgH~*hCo}$ z2gZSWKyMSbP&tf@&GcC_vYg7k$X!yp$K1*dPv^&cTR-v1^lwFwRC84cog>fqAECeC zub-l{=#{cre|~t{i_zJ^v&-bhi&#Ijx7c_mV0Q%2c{Asc)QPqu8hVnY z9-|Q}5s$JkaC$!(e7aB^Nh;7=WW0JEI2HkU7d{Q;@O)CRg&nd4yl2sP?2RG{?k?{5 z8T3&mqDp`K@+*ghEN9-)G*8_+#$4p`o*@xzUOID-ij;2SHNXkrx;n>Zp%TDR3eFlD z(2iE%NQMGe*ZHenW~nM!l2!;8hk*fZ_y!V|%UN^APB`a95LP)W;2WIkyOPaR$CYoQ zqrKS>5The-Gj5W(%KV1qL!Ge*R&z!;B5v(n!9<8}z~eW4vSMP9?3VMMZnO)qbfd#7 z6U-nqKq#J_!VSGZ7pPACzOhV9j>cTD8)X{7pH0;*8skRpI8d8za_mX^wA^uL(q9vW z;<2TQ6&pEqk=CA7`_o8*(SYfCH~h4Ye;%S2m2sY&$0Pn*ywD?b{Azsu0?Z4jH@j0K z^vZw(1eeUPpCfGFfpZ^)s5B_O@b)rV8eU?rVV( z%L%SdG(#TX(7?uVA+4bz!AAAtC;0fHPt*WD;dY@6HU90D0``fs|5@JF1B{pyO z8?mA)V9lDrWOM?HM%{y}V%E-Oc!!X{_C!QLic2%G1@C`4i)HW{WkWi?)WO|oTuju= z)NU_2pL_PwJvIEs?i1EN@_;3kW+Z0FE&QHfC)k&1<&LLCwG#MRO;^!8) z607Wov7wexL~r$!uG&U{K4=eJHC`|Hg6xrIAoe%c;6Vg5_(WjDMXQHyxs3k!H2Dv>G zOXMhZjMqSz0CzQgjUV$D9X$uzmJ%VUx=hdrj>>Y<%r^Y zPk-)YQ5{Vr_fv70QR?#qA zPPqOv^>o4)y5wejYLezpwbB;Z-QnT<`e4|9mGK-U!^*fXlg^=t3~n%3R8~5XUuJ?n z)i6vA1f>1X6g(CjDSwMriYPU;{^GM*3C2;=0c%Y!@YnS~90Mg1pZQ#F${{eL%FskL z?poAbyb_Kw-fB90^Idz3U2fw;#*|OA{L5%@i0gWbP1&Yz zE)~`1IvPOuZp$Bw=1-En%jm4Q!(`aNXPtOo8S1`oYzH$KX|qE3Cto-o(*Knsio`(M z08enrr>MWu@uCY6V1Pf1zBj|;n$Z*)@)d7VP9;IeM8T$42rnc};w2v;(R6am+&byb*gK-p%No~@DWKF6j5|DH68r>LJ1_m&k_j~rtyy*T|g(4~%{ZI{< z-jqW>{%ug`>$R5Mdp4dXyD&Ipeyt-&B<LxFt6Pt_q9Jj{Jp2x<;kcPCg}3<*Y?5^p`**L10IooX z3+7I!kxegnW2NFAxTN1S2<9n?Ec@O*#o_p%w|$VKgm`1Zi*3sb5>>)Hc*U7Tfi5vq zIh=`Kzn5Q0V8_wU><6<7Qbm%g0sE?b+1`sq!c<3;@`7m8C*}UYI@?d`;*TS|(LVvS%uIN1QnWwCsfLWhV3pfyF@Of| z#uD@T8i*7Sz**_ZWCr*^Yn#>W@VwZgW#HMh$9oPAU_ne$;`FHj_@#M7)ydR$;pThy zGh)W@p<}@5?fvCKrfICxni+sNegN}o7lW|gREC7O-8WfIQozAzb!AS( z8xh?tRu$$0yfC;+GU^71Jhvl0?*`xm-_{Uw6c)zA`+ zEyOEWD5T|JmF;^*k%W9K$%S+tvG?&uFhB1m)^8#3JCJZVeAOPw`XU@Sebxrk#Ye*| zz!=MuJiyGAp}ni&YqLobNuk4M)}90ITUZ2nV$?ca*EH3&09v&2>P_>GoF~M((nq>e z6^ScQ_$M?xy4xK}PPoG+drr1r?NZH^lznyP$Qb>7IUu}19QDPU9-s6O+mI0zHq?LP z=%ZEp{SFS?;v@j?0BB|kenxb%NDNf+I_NONOYnoUK)rJ@7} z_=VSd!z<*86?YMLaon-js6sMRb2&+Raj>~4o|Sv)KaQ6ZwSuTH4_uqBDl6y~ zbB{Dj+;iD!eg6$8YJN;p9jSGX>}C_jkzh^PobLBgL~u3d;!ZaD`Pnt{Is<7w=0zL7 ziAun&|E<5S>Vx%nd11&*EUiwRG=01$VlB2b=Y0CfDR>8q+%6YJwn5e@iuKVUp3 z)Dad0;?!bL3t^b`ILKH+S5t%*W2AjCB8kHOFr(73|YOE(Bkr| zSVT_a_3kcKLQQrX#_4D^+Gzf#)~97p0gq+ilI&kSiZIV%&c_?7z!L1gfeYZ7y#WMzo^1}u#z7PeirYam5v1It$=(Y|jzI{Eqi!|(rOS5aLRE;Fi$ z-vNZpNqKpx)5C2lBId8{oGo8~hWBOxU`P&x^%ukHS< zc+0c&eqDi?yEVo zYpHh_A2B#n*1tzNc55JHF1;5kIQagT*(%r+7q=RhwGn8H7bzFwICs-$eI@(B$MgN{ z;dLrs4e(hAfl5)^-f4+z5CmIJOSqddn95r|W^$DRvUb&dBbNFFk?b=)eg`97*Y|pN zQQ@Pe<{k{E@s>NLrqb(AUF<}@<-f5OOe`v^Z1y+;t5!%#(J4h^ioBAFl-L#J*tpi8 z&1rC9D;}shiCTP_n3>b)E!ia~wc}1-!b8%cx!5+G5OWd~xCr11Zb{563iH>|vhQGv ztKoBC!f?jD|Gp6k z0FI(TO6BYD7vSlhFaCNjFDGk+5e?O4_R)IaO<7(u1oka5X_YuVx?=^&9@G#>nO7eR+g zLkLwi=qt8zGc~M4RK^cL?kcH~+CTc&+;v9h07GHgvsryVZatOXoXOi#w_pl61&2H^ zgOj-3ZMGLU?=2$EQqB|<=qZc#G<2n-N^txqcymO)CA*lHAO^9RKJ<<1l*=>MBd>6j)8Igx1b_NEb3)dQev6fTtG?nc{07 z6G6lAvxEJoqJVCUo}W9}TSDwHnbgH-JA3DBTqnM9WIZ=7VBmt!-GjzgI>nmI|(OGx(=dFJBa@A(lv z*&GMTQC+ydpfxa1HtbO8DU!(99sOGcjTv~ zu9~%#p%WT{En_R*>~5+Zgh=>=la`LqY1`5-HR(G33oA4sA~8_H2Kc1TY(m-H7@Sn@8H64Pewn(4eiJV^@@aY)c>79 z^~AYqIf&eXS)(hcr=*h9NOKW&Ng0>g5KAggH#giU4fbEw^yP_e87WX?dz!#B)MKb z-!sfJc=N$T)dvO;IxzMDFD^~8x**83iX9qDC-|sMOX%Q`E=el)b@_x2c+(R=PG+IC zq{YUQ_t>;|K7KY0c>Y~T-_{PQ+q!90@Ipic#5oS6apF5nW{srio=ASIFp}bG&C}Qt z1hC2@3qN2&l&GkKIY`}#2_71p1K(JZK6T%BcoUGCS9u*S1=3n-Kh2Z9r2nlF84mtQ z5-N8?sJ23dN5FTdyLXPHtsANr63grkD2f)y?MfQqndiH=&g!^=z;w*%*@4ZrT9j~# z5QcR6Q+eFfDn6FfN^)lsmpbFwSce*XyXdnEG6?wP{|a{2S^6wVEQE0bvEUF*km3R) zB7i?N?Ww}(3MCLa;3Fcb1|)Dud4Ijp0S^{KCT$aeVqYWvUb3(heFKd6n&((rrB2x~ z7jHd4F%a$n>kluy?FS^>#}Kl97-z~RX&WNJv1!cGCKRwrJ}YlE9^h(?o9y{NI;J?j z<|@+S;a~(e8eg~s-TolSoM#V-aVdpa{qd>!TiJP3nwwho6>YzcM6EZLmDgLM8lWc* z64slQE=w@!tt!c8Xr?-Yo53rtJfPr!;`9MevO5D|BMcvy%;6CsUo@DVv4TnHW3sSD zv|A|t>MhRabW+Dt*HkmDm=c5}w5`N2bzn7nX4B-H?}PkMc@tnxO4p_WJ6dh%1}^ln zgk&Ou{X}y%mvYQ+?as$wiYxwk&kQWCHL?S?CSD78G)tAz88!ff_(6Sn{LNT?rieX$ zRp0cXV#j76dpUXI3M8i=1vF7Zib}K<;})&NgMZNU*&?}1d#&VuRjJ_oai{C9J%Jl^ zpC_f_Fu#kA00n~wXj}y3IBr^EK4J29_aYTTgLiSIm1@-`Iw#zet36lJsn`;Ac9{db zSSxW+>LR^Rxh80uD#d$AH5P^Z%#a>v+PTLX^djz_R9U1Cy}E_;T>+njAv4_e;eJc= zdtqF+RWP-W`Iqz5RLOtnja>41WvqBh6niH9mpU=6n?dbdw5lN=BzHTFj#4K%>I6xA z@w@nRPNvET;ikl++;6KU8WMVzT;o7gS4K+K!pT7%5LiyHB*t?h8FB4K)}!LpviGyZ zonOLvphn9^#dt;O22!CU2OxX7GhN^sd)s3Pj{PP6%t6Axt2@rYDNC+$F_?sV_FeZh zg0>BiOg(EE#)gBsAgwGml47c)xcZ1jilQacw9HWy0rz`j^<^0^Cfzt&R7&hjQdw!o zn2>oMLUYt_Yr}iQqJP%lNH0d?HGonwCN^)cmW=!`c9?5$PAv5iR+@6Qq04&HzB`(} zS?6_QoQJ=l>!Vxu770oEnMsa6!p$U<;qV7DbZyaboq@FUiz-|MEC)Pa;*LSVim@8_ z2OQ*Q?j~6eh<@o)eTqkTdAJRviOymzBbmd54hoJ9K6WKS74~N(x>gmc&P8Q;O3K*! zGS*U=L%i4$DoA%T6ME-oq!+s+ahn{xSkgUnhx9z;hMzCXEw}ceyK)6CGZ#1=6ui`{ zfGc1@_%N64`eyyRmM4$>CAGwVlccS3S<;L+O7oj^?t=atExZ9~wrKH|TP6&G`sE+H z!TJx3mZHlA8CpXplo`AgR;jhs`t0;RI^V2}?OZ;19O`wBr0gB5iTd`>_0DrhJ;6%x z3xGkkNE0C!<8!z1Xv6pVge$^s7B~(fJ0h^Ut5T(b8xm73XpKN%S3yy0UX}QEt!&y1 zFk3IpdkAF4`{>z^Y zwyD^m^$Y>s|1|;*c$q5|11@DR5$vlEos{8siOAscL69h}|0ZLFj%6-wk*yXy*nC#W zS*Xj1iT8_*DE})w2@P?D;Tr6?Z2&JCjq}4z&D4k|MoMXN&sH$^|5h)L!+s5>yO|@P~Q>#FPkT?a!iU%;2}dx&nyDLvwgUu2%O80fDqhStA|;2SuGb4agDiclZApKvoFPtiZIOa9L*M5j%#7#2vN z5%fmav$zv31!)jm>O+HV<7<=9F``Wivwg6Y>UaK|e%Pv(W;w|GcDn%a!H@Svt;E#L zYuHDO6luWc==#flzUW+|3U6e5tt9JOLF@e?Z}A$AM9Q!&7Uv47@Ln}x8+e&u0Oc;o zFAHmzavpsL+w?iz7nP+G2|~o%8na<$>-D+TGsmpH#2&Pz=N?UqCKrIdsV>1hnbUwv zsYJew87D~(&n*|cTP7B4H-AK0$}oy9$+?=I_f74jGF9oCgsA!&c|~|l3ns29z>l}b zrumaIl_$5*dAv-$ImqzKPN=SS)ME=<b5T9b=mKyl9@Tv_(4Wzz{#3a+VT&E5Cm7hurrILQFRj(dZ6_UL!vPzx5s zvbf|7+uQX%o`t83gbS?FjJWKw5*vm~?*eq|3)UQ*0Ht|fJ!(9Bkd}r#1XnCM9gTS*)mAS|8i|3o( zS<@?LH>Gmze+5>a@_}g}T%2`e-5GXko1+8spnNa*=9ipi{0S)F;CI|wgBF<%XoZyLh!4XwK;@Nz1G;zH zt7>6z9-I+|Avv+qeAc(!XiwCTtHy_0h`g(AN=kMG^hJLT=s=c8ZUeI#JxS@Y@B3wd zPeB~Ym~%S5snR;|GFe!$Buz5AiqKzYIuJ{Ek_1i5+~FCZ{l^efKHS*^JEnAO-%Cst zUba~5=+vo4ZfTKOLZyFkB`DeR`_9ciXSL;am<~k{g_VpVcS@{QBM-L{n^X!A_rVj11hwN*JJU94Pn42o${l@ztZ- zu>5KS2YB^V*42S7Ol#FC1eWe|c+}#VTepQldGj-gC>DdWF!B8|r}3ox(#7w)Ek@%b zkwV@g%VCo+t=IQ{8bl=o`>&d8{U?8n6UbTEZsPry0wyTlN!Rvu<;NatJTh~h>NYJ3 z_r71%3XIrqQdx!5)Xs;k4TVN9}M5i|2acvi>MW2aGJsiU%XCDeX0 zBAr`hR74Izc~&HUjHO}CH!h|p@5n?c`Kx#R5*d)vNhs7|MW8^y`fdlX2)gS`OZp+w zUh;AAJg!Wlh9Yeeu8yx#0C6Je-Tem)8{VGMpGJaOdPFJ+eK!?w7MCQT&43cY&B=SKp$u zF0Y2VA+)8DSD1=mAmqpY$vXop`J}E}9)y+c9Ih0L1p9EX*>G@oTN*0X3bhW$)!m_` z-H^cEnho;IW}X+-m4|sTRi8K8#y>`wv%DB4=7glhU%eIPw!@5E;ZI1R^tyf14QCCn zk6$RtgkeWqH(SrP&7=c=Yh@C~v_0oHmLoHTcsYUrotXp?BULXGDUFOX3FL(q+iJF8 zn#f6>rKA=wkKxfgOFhq%KS~~%Ab3wRgIR=x>W#9o{(V%2?_7Own%0E2+c`hPjW$k* zSgH$PkkrTI{I*2wd#1!&>?cTS&F{e16QjY&C540N*#KF&>Z4pT2*RHJKy?^Xag zFv)_ffGI%7wM_#`iag2Ay42)&DQkWN^|Ye<4TSL>N03!U12sBnhk>YdAS>9Llw2&- z^YcfYUL828C%H|;C(p|wv+~vah#{knY&que^3#|q_U=Am_<4^Iqm=*2O;_j@s$kmQ zv|Pub=0xsfQ5_^#UVYDS)~K^Jyq{_JtSG<$3LS+IL<11Zr9VLXW7GJ@x9q|<0qgT_ z&(6wyizin(bjj?k3#SH68b;%mJ2CnG(o_zzu?j^kP+F+4)S5BQ2HmFu1XZY8l}zkq z5Ps>nxwu)|CFw9mSo`6qMJw>N$c+wdHBNAYeI{gWtMPHUqXZ?yh8hfw`4!D=|lR4vhv31cLO{7ai*lYloUa1sUG2 z`!v!$oWD=MHXXTERG=_K0yDn4y!bh$gOKh8<-SJ{~-dXL%XTNld*cee1mG!GQd1x3BV${$cd_{nHKr-?y*STU<@FitKdjz|&?N*8!~E;E^0qE1 zOc!D6@s&r=nf5Cf5P}sa{gY@!$>P>O*F#6Sg6ML3_VfoUbxJGN;5L{2qt?*-ash@! z-i+{mBD@*RkUyi*8MR<%pVV**XrM8Fk8m6^3AhBtsZNm!GF~!WLiU9y7l6BUwOe`X z#(dLtxyf;WRWq2;G{FP5GrYdO{E0#mJ*SZ{)FGm(Mp_{j%k#qVrt{gJ@$wj_y&X*D z8rE3d$0ckRJ5Q~L;>}A$u!P=qY^8yiGhFJ+ZWO7imoLa5pnAJ?ZtiU8*tM4ls=5CbZWiotPP2=xJrg3e!O@?N;S1#9>2PGg|V{AhCa6Bksb?5jC10 z!zI+k%_=ZAup24HK$CWbA z;<_SmWh%YlF&hBSa?>4N6><&oFTpMwSdqiVly?VgY@;W~Ac!hq@3T_#ankdDy)}~H zX7jW4#N3IOCqZnfB~BF34Dsg&A#UBgfcn1ykn6UOOg)plPP zja1yO%+32I}Lbu{tVxSvEXU{!QGe!G)3P%m{L1I&kE&G0fjjxKDA#uc>l!A7K zFaxV0Cq^Up^V%QMje;*4jbaZK=6SPF7D;Tj{Qfmbfu2*YqPxDCfT;7#Mn?@6 zs5On#Z)D)!%aBT-S0Uo~Xtzzx2yyg=zoAC9w{f+<0#Xjj^0jt@=dP@tK-mD`#5O3c z@L2vWeXAe(y-R!ZAMAZDy+F8<9L60@keCH~aupH~)`{&*aF(2} zgVUUqTBjJsU@J4V{7wWaWZxgyCAws(*U3E}gp$G!V4HHXxWb3Fo2_=_qDxDfw;~)) zInJmZQLT-MB65_}8W4ZRSIj(z{ zhq6}(Pcja4&nK|kau^*jkJNZzel5fm=^287%tY=7k};TtQny%4sn0ZNA-D?u)_X5D z9l6LnK1fs9hZpYlcyi&+7^1Zuj zTHuCAD=(!6>%2vAGMmV2AgBQ2uD!@KP`C+ML&^MV7;%+m_0@{@$OUYUznQp)o<8Qm zB>|0q738agYS=u;{Il)aW#KOdM*aGtic}mbh<$waQbMej4s9;7x2*G==z}aLU)R&(UrFVZwg$ zy8<#zd>gyFR~%7~!u-E7Ny^XIbZG(KZId4o5eCgHy?0Km;4ufX*#RI3y>G)T8Po~JPp8v?)nIYTI4gGu;w(mHxxM=;;;f@BQ$x2+c#1as z7BNS3E_SXMlL|7EaoCXeYJjYUX@jb`!szL= zoggK{6s~;sh4)`)E=f{RRLDs+8_f3wykiTYr$?|IdK|jDRKBJAk1)?1k6U2~zOY^u z4YO|N0j45aXQ$B;y0-M2-U2n$qP>R zS2Ky~MrWv%InSLsFllA$coDxxp52e6kcRT&36}ToTWHXge zPsDStqqTnKrHGBGg)9+Mh-o>ezrrIRmdFv)y)#zoRSnhU{{>A zZ#w2QOFA&meDZXNSJKbj!8GB)%oeZz7FsJ|;D$n!-@K{xRnP1?*Xg*tUCUiSYV%B& zMR1dol19G=(y76iK`Q#+Jpfz3r7dE^y9wp#8bPlWgO0TRL;v?-q9|XWdB<@nPGzWx z_HjlINuUN+D$5AOG@MScG5h?-+hkr!xV_#xA5i$oWtMjZ^jA|A6@t!QUtIF5#ripy4p!D>`?y|Ce6YvJcNh zFK@oeiShklE2L`Qkt2N>Y^A z=>~Kb;D`t4M!TRKvrFdpZ3?jsE%`&{4EsExv`Jw!SuUB44m8e#QOhD+yV_7>KzTyY zboOvo0GU4%Q&U(z6R!@}E|TUfA$6LEGo|ffag2MC5uc4}g!;bN43A}ey!x#E_NG&l z@;vNo1aF!=NW@E0Z&0eAc6mpaTT@w)vYXLsSL7=ApA}9!+tPRxgQihzm0Uu>j346L zeyalRp_<>_4WRd-@*j^NGr?L*H>e7_q^Rz$md(ARbM{6l`7CeWc^QnazWp%ecy$fN z-<#6~bZ0$UCmJHnCW4iE3oAWg{k0Z?s4mTey6|2?_X*ktV@d)NMZ)5|F|a!j1u?~C z-wr;H?+InAqy@z2c`gk|P92Genq?sS`X+CqKfe@? zPY;!%&}@JZ>AOn(*X*O((g342tfKkY?li4jY4@Y=79hcCE46Dk6Z%QV11q0ytPvnS zMDzZHX>5ip+wZA1w)ZGvlA;1SejWa)fzq5-5`~(FxkWma(kR7WHw-yW5Ik9_1ZJe` z-45$y!ra`4)A#y!ih(fc5d1=iR3b?9j2;Gs2qoYTNn{Z`tcChm7%NCZ7FX zak;X449i1?jTlaUte9PS@O?0buS!Z8Bnk-*l293Vcmr@|D!x5Pooa~x%(^fupquU)A$mW9=zlYfP@gTod!%5azEp#CO)rp^^%2Jg{{vL9<;2*egYzasD|D#Ys z%#pVv+7h@mpkLmsciV;Gqr0pIDu#b5yA>SPX;Gr>4)HFf@DUt=ntsg}7H(@c(#|1; zp`ru6ig0vRDnA#_qU+49>MsWTK>Eju(N#p~Hd-9jGSWv!_`VfU_F8A#+pd@1gYvxw z`7!p;f}TJrD8c9D-0p5d&0iDv92d;HuIoiYf<6P2mNd4MLcv-ne&XP zVMmgk@WO%Z&vQF26*-er8m1i0S{4Y^jGuN{3}O~1=;jx62eE9erZi(d<>dQTZB>0O z(KK&m=nO@d^B-wNjfBLfjrONZc7iLhZVofNx^YHV@EJ{+;3m=DiY~VDE-GjDWosDT zvEbCW31O~+o>!_$@yhZL2q{!CEhbC?bCnArK+PSlP{d-FR+A*gib_1R6e}ynFh{rf zGMI*;&iJfXkUZoo94t=xoaPUP5y88JGSWg__pDbFMlx4u6+PdObi+S4>?rP zu>E4(hI{(x^2p2R5RD8jkF8zZa#2oazcokAb-X(PGyp}35__B9fMPDtwGk9A#dK(t znHT!VT9W^XrXg0Koq7S1A%-bDW`<4JlR|fc8dWlMXNyOasm;P4?v@ z@%b}C7O8`Pi3y8mCL0Btun}9XUXEiyHsqUDD0BHjIl0vddF?37Zj!08Z!v$*G7E%= zA8l^XeIr-iE3%sTGn6>?s+XMsQT*T)>>NjI-D2jRIrAhl@Iz%?r8?O7=#q4Y-fUS} zR*K9qC7TD{e>JOU3?=$QNGcFKSmW#7w6@RtKtSGH2NJ)>S3gLTdy_V~m$twZ-`#0utmSLx~FlF9j}@ z4$**(WMH(C)i@%YTz(R|<`%(uDd?JWP5X+08B~fqah}!bnVc`AB@u~wPRY_y+9sb# z{+Ds@?TPV&kBJ`1FJ>$TA#j+@srco=;R0DhUG(>}OE6{jm`ZUZYZEetj+s z??r{$QD!G1Vhj$45;WV%%3j?ggh}?kCTG=7|vgoX?oh z5mLsdL1;FRNeB-B0=-oL64!=$n?2&edMFne>Mmj%IX3@EV5qys445G5@9+b=`HUT* z+o-SL7ulx($Zy6Q^IR89z{+br$ZvFYU0Jh_FcKRfSj9L37Z!MWVRDM=h*;ZnrvTZ+ zb!ts|2zxx|#}t6ABU>9_z&cTDOW|N|15WQNcnM1ThfGXHUJSnJo3uZTi+;V-T|bnu zuPR~jLkg&kV`aY&HLE5|=20VaILf-~a@!t1yYWexuEb{CJbi&oTY}mL(=g4;BD^k} zQRf4)g?XIF?CjjMy;IX?%fKpTW!3PsoZw=qO1gnpZI{q=DF7OtF@H%*`qF5(qcO;o z+Wl*o!XWYeqfuO38ga>TK95|8*+? z=V~vq_Zko_sm4cTJki7Sd~omYI8aC&FRY!g^*%>!UsZad#b7$d?OTjDCBlb7*Wl*P zux~j8i{<%4!1_*@dtd}YoaBT`rFFpEae#wN+diD{gr)4MRH?D;wYSJ@03XLH{7*(s zT`YcBTuelq_SW-FP`r~c5 z@3nh{IVqUpb2S7Y#BwWq%T|;#t>@&rvR%Su2^5u*Vg8p9@56$Ng)GqhGwEL;A$4fV z6(UmrSv1|z)#(cA0e~}Au0Xkzav?e!Ekw$hlKl_-Uqw;q232ukjd=olfMKs6I5~;Y zD=>BcO(}^#z2O@O`X=~J0>?noIZwq>GS-v1WvP%(a-kyof2_(!iEoeHj-2fYmL05Y z7bLm003lUB^~)0R3e>9~V@x+%N&g?TeBJXG8Y0O2Vzx?Spbx&PQpkIxM?NNoMk0{?eU2VNNzg!9wxD5uYgFgemvR6G=q`YUBY_V?D_>h=sNfy+| zK5#e0IB&l}AmfsYPBtJnQZyAs6l-{g!qSsb=dRrJki}^8s`l2jVH#3F$oIgtx5Iir zX}{i;m?k4h9{K35jw{@@58xewWo1Wkj?A7N;=vxp+_%gVuHqo2QxL`BHV4Kp1GF!k z&@&5)Nkmru6x| z#ns=5_}xIp8G{e@I5E?JmwiEJRt9#|ZFiOQCZWa1?cq+kbCRY1ouQX5tm(b=kPRe( z^Do=4du3ExDi=;Nx|!ai`UO<%jj+D$Py!NXZUSEuDKh7ucJm8gW3Y3KBRPS zsKBubRvWhzhJKJixnVZAJSU1oiJ>; zX?>MR!PuAcJ0D|`41ZDf@3GsQ)&vaMb$D-u2C!qn19f#{toEkO;}cM?)Y|1{G}Z ztmW`Nk83$pI8@7DyyM4Qp(s~<>co^0tPl{DcU;@>(SH*y!34rxnB zM}|?t!~|ZHPjR4V^KuTkEY86M%rUdQxyRJfQ93L+eU9AUb+HSAW~kWtQ%L9*!!^oz zRtj}9n#T<-smP)`J}j;^DvD~px#2b^`yPV}MHk|$fv7TFACg&N?bbnH{ec#3g1C1A z@74oNsOg5D1}O-<)<7|7xs`}MsQA`Qv>C<`v$_a5yO2o>da36^NY)r*yarXi8E(}0 zosa$P02ibi0VgAwk9UnUg8LwPf`f_ReNh?4>o+FjKD;G*-tDE-;Mp~D5YgJhe~s+v zej3Q^nSzw+T>U}IYj4~qGq_>*F^+rDR|3ISY0m;j&2vVc@$;WtHzF)VzqW&rw=7r5 zYBJP*DFJfs-Dsy3vJRtTem`2oAq0zMAv<%&B)UJwFV4V$is>F(j0=e_&tETH25V5S zN&#=qr4wrB4c?B3vThl;^5W-5##1M>oscXr3oq4AD%V8ltp1{&0~pQ25|(fW;fY4$ z_eN6ka4=+IMH&2h-ie#a(j~GPd6J$H;B1Z=3xpPPdJ7t&`fN-BL`>M9M8*ae?cxcXQ>c@X#vD2}I&`SJQjf!M*qr+A9h+`j#A+?yzw|8Z%AR==?8uPL!rA)jYwN7d7gLiCPwUem}Rn zm3z|>S(pSY+r(0ZpZjQY%Kl_m-?ionXBFd1M9CV&3*|ykuDo%l5JgH zLf?qZTts@4T%rtE@iZh*O1QKb&Y-HvPqc2p&4g9*m53V8Zk^N00+ z=HK(0VVL)Xo+bt0 zpeEKnfB}(J7F<20uni4>!Ujv}g*}*sONxj4yIEn&Q=cR=g5;^d<^leY>c0@f9KFj~Sd$U#Z*L=Y znVM`2%TmTH^_!-BFyV6^iuJM)#|s`UDSffy;-KM`iTG>W2!Fg>`1Ak#zZZ`+3#|Hx zMBjEVy6OC8)R~z!=Fd&bxh;b^D1l-!j4~#w4)$ptaACGAudjn3=t39aCPiLJkR81c z6CID>`t>8#-&sK~Bt@Cd8@_hYP6k8G+-D*OiWb}e;~YAwOPm$J68#jKa8&MOht0MY zJt9&{%qc+-Tj}8~YcT=(^(tKX1_cblEVrJ#_H1WxEcaK(pvqfG-7e(oXK75!sfu%9 zKF<{3nR~V*cRlj%>eNOZl-k-F0{Dh+?=@LESTEg&%G=sLD5&`2cM1IJa`U=syZV9=X4fFJ1b(8XZq;z2mZ)3E{{PTNC5lVU zrt+4+E`r9yP6Ts9qlwQ`?UBsMtdLkSJyo3RXGkuvf$}bY5CM*}0@}*o{UF8F9%n|S<|36k+WrUJn+X_LE;unW{n4bL2|AE;t{4kT9L8k18kA0NR2M&~4r&wF z&Ds(mp-1!}qA%uHe^(HODHC`UjbOcJ4Hg|82Dm#TITT$=4d@j|)~ciOE2UlZ4|9n7M|^qx*vS}2da;PR zZ_oQPybSC|EOG%Fm1YgZ`;T8zUTkjrsy4vF*H8+Sl`u;s0gU(`kvt00FiEAqfnNR^ z6-Mi-;8z?cf{}zYJ`(AYrxC=E=g47@_!d3V22QPJIvQ^d-LN_8unn*b&Uf$K!n_|C zx}czr$Nr~q&QuITvoRV6$Z&`bbQ z>=t8)G)+3M%zdyyos*O0HGCtdcN?v2hK42Jc)QkUsO-Vp46pG>q#1#gEyR-qOIh%s z-ZS^eLD{A!Y_pSxJ-UhRQ5t7`LY|9UVU8%1HB*t()bl2Pvn#7v*eKpql8;2soaw`W zTi)!Z?VexnfJb&!CCjMh_`N8GqWyfj^-=$AL<5j9Fgoq{r$z3&(=eH$ubxNoKO}h9 zpImZNOX^AQRy}N8)*E2(2049kTePkN(7OA)sK~Nwoe9^UWzC~|*6r>Z0N`AV!7nYC zm3KrA*ysHVy{H_KD6#O=@f8=wjwIlOUW1q!BOa^xk2-M+XnP=^CE}U;V4}zY7#Fgz z^e}o};YcNiU;;7+7xn<_oat>^#_8{(eKWm3-$n-ZBqJ!`Afs<(MHOap#v?~W_oV*R zhaREnRhih#v~KwyQ|i`uie5pkcJH-RRDr`~(Dq8a6@k%q0eSWYWoI{R6WIC!5rGDy zusKO>12m*@d8rA)sdBLpFmc(^L zHmAuKNX&5<++Tbk9+=w-mtUZ!AnO*LV!Qp#1Qn5XmrzV26ij_>KbKm?$cp*bHn3$d zb+=k|HMalk6tN-lnOAbiE#bFcINIcPuE>lgCL56Bk~E+*VCCQ5MF0G@QAAb4%U1O1 zzFyeOQET?cSYK5<9nJ6}HC=+KQ9~F!MziVYAP#ORTr9} zUS3;iOgU_>n+}@li?2$dq4zKRMaY5#xZJs5{L zXzIl!q|k~MWzh{5h!9Kxb*e31mHeHO2DvV=svCg)b`3awx+zQ+WutJD7>f2R$LFJj zm41cxxg>s>j=B+W`VGVG=Lf3==I_po#21*{47?t@L)4}Ew=}rd3HU#2k$0Pfp-ajw zWklYaGvcH}R;IKT@0@tYq~Y~uqsqGztkZ+d8v02?_sT@e;>*}uVqb%%YM3Hj_Q98$ z)`sE0<eKVNh$b>{M6h|ZpZnKDumId9y!IYEE@J>6jr zQc$VscKq5BD96}Rl6Rc{Qh@Eik-8?{^G^sPGWH(?QC@;dhgA@DE*JB1I4-1o#llCqy+ zrIm402T~+K_UHoGHlH@nMi{kH)e^jANi5!wy)0Q`>VW1aD~4d(Zmi!6(vFJa&2RW| zWWN${*JP?0&RD6VBL2J3p3WD!o6B<`R?60e!B0)NT=PwSc{vYIOqo5A+el-;<-ZTV zhQi~M5P!+IYkAX5e({<2ZS_=F-W1CWHhQ7-oUjiQHeKQFJ}jdP@8mg3v;#oI=&jOc zo@16=J7tHr())qj*^R{hVy!IyK17))kh)jBRFX#a59x-VEOFC6B>R13YK70v)EC|< zAW%=1b~&#*;De$`wU$@jKRBt}pCEH#A$>Yec`$DM5)Spiwxr)E!T}xBiuRmT+c@!lV!Gh2$~CwUKosGQyfo+RVs^x?4R z3wyqo3v|v^zkY`ZG0E3<;KpDXV7^>4x*fn{;}Y9CUQb78v&TFP zM!kme$&TBwOd|9?2jWRGAS+IMA=ia)?E30(PW3h1ex9jmPV`47bh@!@zl3V;s_`KQ zbgf*YGFTfSyf1Y*Ms4j~3Nr0P)*UM=Zq6hsPnD4+9Gl>swana&nM=J++Szc6o2)wp zw(Q$zD{AlE>hx{b)w1^M5#EsIa0GF^NQvPZJvgIN|7f{IuXzkXbA7`Q2JTjNaFsOd z|FY!rfda}Apa$vBX^`PIt>1uOmg?ADwUxU0!|upoyvG^3SnAw)DspNdN3@nBAY3xs z18cDQ2>8MDb*3l<-i8Ex0wBZv^ZY9lniZj@M33^@O;Iy5VpYznYLQoyfg31evFo#5 zLy$yW$k%VUjf=g`&WW=rY6TBbDS1idJ|c@cRfVd<#|Pz7(O@%i^k%Y{#lD|FAO1Vbqqf$Zr&7jLATbj<=U;<+7rW$;!JQWJ0u=hf(8grVto!HIrdtLj+ zpX-)CiJtmG2@*1N`)#53NHs}bA<2p3l21HMcFcM;A|hG2Dh`3YIZ(lMVG<|b5jdVV zWj0B_dN`#!suCNFK`~0Y%8d9{(nz{qhk9qg1~IpDNvRaO}j&dRPx(&e?zkuQT?b?g#(iN%3(z+RH$Pa00IqREdO zYI?!ViILNztr*_fYLq?pFj3Fjy2GoJn{*lr5^q*1nLW=!G`{O|VuNCJlNAGKk)^f) zj~mp%{-Ap9nGu}s)*|)9T@*qZs@WmmqL!17$FOM?^6d!7poZUG)MPbW+cx2fM9-;V zHs46WYH|@qJOGJhv^?gUP!47fY2SC(luQw#ot6i9a~B)2cP>=O@3x7l0z`8#C1qik zGnyUjn_hgIN;8LE)GkPZUHg-mN9@R0xGS#+t!p*23kiJhfxD#ju1dPsRjN^rV_k+b zS9p-JJZy8qR6$+c zFsvznRw+RvU>RjNPFk!_fYUB-=K48SOf9}igB-FKh*M--CoF0O>6MGzb#Q$5=ssz; zL-#zQ&_J}XYC7EsvlNqn)KyUcFQ8^siJ1Nc zvpd~r^vqdxd8MN!p+SEC(!4odjX7tw#uv(*k0d)@q)GWVa#`pcR1llOi`Y3Y3RKQ$ z#jkhYet^^7JD(j*UrXas5!^h^yNd~&7_Ip;wGt|aCF}V$sW=istCkA?lIqv6ei3PvNy4Cu)?(^x57o?Sh8 zf0z7&<{JikE1s_H@I9+Xh;sE??Od;fMJUj=&ga+*;S3>daFmnv4$`9L=21}S9uXs( zdF#In*PaMx4-x-{O_;T`eUVlzT(PddS459bLk+aYr-g$Ph8R)YQoslQl4zX9(W!$Z zUOAqdERLuG56~WGil8T!btSW3s;di~&~|u{zForkA0IwPeXiIDjW#^@lr`!z1GV>Z z7>qLk!&IL-xn}iH&N&PlIR3x*{6B)7iGMPexu}O)bnN!qS!w}HsWwJo;~(@Qo2OM% zkKbYH#t}!U=4Oc;gqK&DJ zjx%-nDR1R`2-EV>F&W)ql{-~d*2oAyuTAx+@JCu}Nt4W0?$00E4eCU7;wSI?#MADf z+j9U}?FcpMP^JPdU`WM4g$XPev+1*Y9I(}1 zpXof<#6Tr=_zYAwvFYX>Xd)pyMxM3na&%Jb^7oe-oO=@f(Xym3KNezRm=uBjt*DrM zS;5^C6!WD;6SQ$olkBr;BxYV`LMR*(29)(Fy~?Dp+tGmf2q5=|#gk%BD=%0$_=xq9 zLU`pIK(S$?B3|S;OO^#o3lBq!i0loyo6@T7fyP)G!ggC~#jdc5d>m|{BE(0evA_*R z^O4dOaWKz_xbsiKqr5GAH4wXxb%^(2+keO77rhbRIHAJ;4@iqlBW>A}cIx3JH=AHI z)r>vec2a{g&V>}}hFI|n5#v~AhWV?u^)S8B6H>ixqWA*5z>3B`A{hAJ3`wsY9ICU!tYL5aRN274& z(FyMn&ha}CKz5kL590>?Ki`hc8qT~#_jVThNE&LPXLTpku|A>@q zP80#V$ut97%+vonG~6gL3Q~EG>MULBlGA>&M{?0`bNtj{w<~2sKwT+^o*f;}6IlFb zmmX$RBy>LHD<$e1GF0)VuaV*sV?Oly^Zys`9U#DlF?xoe=Nms3hnBcuMX0r?piTzFV)<1@AHsJ<)eB4J>W{8PWX&lyIZiSMZ0;58 zV&E`7i|6>d=_@Le4&URgBXr-d8KrP^`ls7i=yzq*;c@0uzO~C6t*d&TnH$7ybF*Kn zM@_NI>p6mHb(dy}@n`zu^`MLIr=Ho1Dslhr_|Y|Wf~4ey!-|1z&jH>BOA33*d#RhB z8b3U{n=e>toqd2;CaVz@#bdrduBu4VAgFR_v$o~PRiH|b5xaF6Z( zHF1^+^=u<>$l{!laaH zYi)qrJgE_bx^3pNchzQ~5MUyO)qeLlEo|}15|PmzDs8T-8L%?bV$3K}x$)P>=TUvb zTL6M5cp06T7lnLgdz!wXf*v@?8HGDbl_=EMbYbEH^Ze`~8EW_Sm(y}abrqHZ#_FZZ z8V_b}SMuCfwO9}7#}Bx3j}cor*FX_{ZDj=^hqrS)n-u3t=r9ug{dfA?$Tpm*+d(Mk*qJ z4xQ5i2y(2fJnpUn2N(iz3BCpt1?E{qmQae<22>2X>kU1al@ZEZfc!hF!68(!wwCE| zQvV)SWQxaku)Ij063Im<5K>6a6bop&GF6#icI%Wkd%% zvF4Bgwg++?WyWZs8YxwMU^MYu5d5c7Udgoao{NafZJWx-Xc!9W$n~rL*Z3?kbwZ># zT4em*U3nlU(O>nbj_yizMxlI;QJM7dBVtXZp8DAxL9%k(UTSN~x2Fetas881oZDM%_=60Ht^Yct( z@Bt~Yl^`4^L=WXAv8(OWnaei1@y4a5ImPS8xx)ni_ja)`Wunm7<6*GUDO?qu z3*0G^!K(^`NI9D>j8-b-8m*@4CB9#An}{-qorUb&Igk%f_YYSp@N#gzwR( z&MJf*)vp4c05Q>~a#BCR%-CyMYRt@CqF~ff^WQe7iOv(MK||T^fMlm+`WVAJ5VbWo zl3W~$+h#KP9l)=xEB0T4qPF9M9nM&XO&Tf;NIFr5A`|EyoqEELMPU7&w-KxTRLD+m zu`NJ93SkO|LGG=U88JGU%$K8^(TV*=366*VT19fY%HZokOlM`V!_9;nAZ1bmuNzei z_vGDaj-y6Pfo#)w-IymIH>uB&YXealD{ScZf;+Cm{uV27P zYjvm{b^xX3PgyS%(uS#^gmFhV|ChJD-{TaD(2KeJVIqaX`~0X768z`@EVuBv#~)j^ zUEknNVt)}0!7tPC_#Sr0`~k25>!E2+tkDU4PjP3cBnuB1e(j z2B!Tygw8f+hdVKAGjv>w-Rxy+9LJt9*j5b+vgvq6QVUnLA3ma;y?Do}JG&{3hP>Z5 zXE6J{!%`j=!|~!hU^5jTsdggHr4gh&p5RQudDyb}x&02HT2*hWGZq~Ea!wLrB#@8K zhcn5zw?RT^K&!j)3Ty}6){o;Xn`{3~=n^9#FTx8FT8x^{hNj)RE)wfjt@x^2jj6%N zR`Cod*g(i*d~$fpoNE-L-y4q3#-3THR-;#Y){%N$YB!kQW&7{#9Gep|{KpW>?j&`~ zD?*)P>xbkD!h>q~7hZL%r=B5Jw!?&Yal5%W>L)OOp#7|?*a^O^5`fjOkYbrcw9H{y zJJzh?Xen+qu8cC%_jlBM%jd?H=-TpiO3mB2o5_`G8ydeDYn)#t>OS_w(TFIy27%Vb zPcrs7cGL>9ksygxW)RF^e$0EwvEwG^!<4BaJ?|BNF`!SV*QYXw#;CQeE~na zlA|bu5ujJ!BZSJ#1c8&BX?&bU9t(-2=?YHH7yz9Y>97y8tVX#7Yw_*AOk+b60fQAw z@JJhsWs1V9Cla9=i|UTH-pT2L8KML(=GOEp8A!>Y`7)$M6A-gV(ILV=czFlRfUuVm z;$dfnes#aD>t1462?38rqE049_O!V0bb@ok`uY>!BTtpYh1oI?B-;j^PXzlhXLNZi zQf02|15x5td;Kw;Y&WYnF<_^Ul=CFTwnnEw zL#V445Bxkk2`E^>9~&)g?D~yej3U{AnhiaK4a;*yr)git%{1dEGx>})QE!)uaODkQ zM3b2lBV`5}9cH!OSFEO%_vTe4MVQRsNO&#h3mP)BECYLOA9%KY7{_` zmXAZQbqRz5WzD(m%*aZ)lR7Ed6*qoD1VO}M6DYmbX4pjMs|`tD()ZtbbD_qym= zOYTR&)r3zO==s#p&Ws0z-0PYIKI+U>U2UrwL5`_0hA|FBut_R8k7Q>i*%=8^1s-m{H1_cG97ru|}1G3})<& z`jZ5KwBS^tOjXA>s{ZSFzw{csD)Nr|aH*@>(Qq2qN-8_T-(Za7>lydZdded_eDH28 zLCPKqgG9%G41kHNl&e(OJ8GdH`+ek|Ov@~^%A9H>rWJz6Oj5szeAyU$9h|ohjW3vv zf}0}b(o{%4eCfNeOp>6s_JZXQDr66}Wrm4FAhgvz^Z_3rtf=h@Oy0H)q2|y9+mq_g zHpK>EU_%l&#q)o(xP)1tq&#?uP9#i$A_wT}w*!1r65&jr#tI;Ao(Q|fd!q0EoVT@G z&Z`rp(xo!QKdEaeZI_{O`WOi^mrQIPNf_XX@(E`*QVn;*nRPE=+ZxytZcV64NzE@1 z=*t5pole9R`9||nyZkIxdrtI7?@X_FY?kjrQ0(W0BlaktWF--BPVz3dTFn1{X*B7i z=m%UR=s=ddY7u-v2oA6FBQ2e=QKZ=4ew2-0i(#OzQ|*{>oC<%`ahvOfXK=VE0%JG;1IxjE8`Oa@Hx!^^qbN=e!fg;@P-FMkxe_9yR4t^9O! zJh7CNUK;|1Yzx$xN^;+N35sLSB)?$(Ia-1lQ|quI_toWd=QGD_{&^}j0~72j6d1A( z$PTCUd>8}M-HG_5eJyP$B1U*NC!s}X; z5u4NaN6cu6gPkeR8U>=ML2uX3_@&q`g$?6D4`;bA>0#@d1P8iu61?HK=4S2N2rh|I z?h+`LY$>g%({ZQYSLN%r+{U4NOGW0lS)x86?lc!1sgx)yecIw*}K7CPN?gaLwnyoKm2 zEb~t08LcK{(RW1D+U zz%h}PFobc}Y&kkLUdEN2dr-nhlpU6MX)jl)vHXg`#F+7|Z_taiN-kZKkvw{G=!&%s zw0$K)h$jL169(=nqj9mooil|T#>)`f_v$gNmD@2nC(_rKpioH~Fw2uC%4RuWF6cBx zvuB}3@hwMbqXuti?fH?y8PGh2kc72ba4TX5kcec}bci<}a7nr-%ijY6do)$N8kQi= zX180#(;oM9?5Ur}D0G3B-M(x(Mc`o1_Ulc%7};CTL+^PoSGxWbFQO3;8fVXY2o}Y? zm@vgr3dX5(nkX7L;8e?sC&(ImSB|P=)6FXOqOsU~qJQ@?b_ay@;MO$2MO3K8ZI-MQZeoLf8IGHrWx}UzC17lo&CJN=c?v$0V*S_pDiX)*Xr) z`9{&l_z{QHZ2|LK;4=a+2?_I;aIUFN1ZO zBM%Re;G@pxlMo!QB$ujC`!|YICTJ1?gkwmGo8qILaV6AE70fV!*Ki!fUL}29C_1krck+T83-7y8$ zwl6{Qoy%E_fVUrLZ2+OziI-VJ4eWuvZ8AwrUSv0WF3R`KijEfCPcZ1rp`yNr93T=A ze>$i@j#+oUE!bFxa+g1K!!?=W760pOJ8>MawTi?ePkG_cw-OJ5M!}Qwb8EBEH}aKLvqL)TuN!&4FEaA?aA`>q=z|;S2HCYlcGZw zxPJLJc6l$A%{PB?VVbn@p1@6P>(R-!lV8Zp$9ijS6)?!Ic&-h2_8v$C(BA22IMTYdHW|FB&0;ve;_#KzIP^v-Ny}l>j6VNU%bIA$WiGqDN9;9& zX*tY)Ho_OZ$;6uoDZ$=-U%Go{?LJz7w9e3CTU_(U9D_KUi5m9rAMDW%(;;gDmDKR+ zSIvrh6?pIL%~cKO#vZIH3pGh6Dbx}AmQL1xw-PdANn&M3QF0LMayCigMGo#i;j}I~ z1Fe(d#o|VRLJ3pP{zhIJGYTMB_HoO;<6Qb*h;N|bzI7MhS&TxG{5i>)yQnd#&Zpc8 zZr?7|`e-~X4?_}l65;E45-NfK8YjhYSxE;TS}=;?5^$huWrNe4;Lv|b>Sj0EZ_=^B zbhY?9A9~6jNY;C&2JE8$bq2&H0KyM|Rtk!9iE8@)>p>@`zWp+AaI`$+XXSzItyRI zefaQn6R59@i~ma&VXLaYjNB6{1a!w~kFH{b7zfxREJMy;cetDzD7AR-P|P3$GnXV z88~tk(4|M*mYToP2udX!1%-j*RM14X-h!bw;FzGIZY)pdzLbvqETHc@N_J_kT=31+ z>CXyCSX8yb2$`K~XNN;=!2XcHQxa8%%1QLJ0CB@hPJXA^Qad2lD2L3?DXDZ*?GT>shKK`l8C)DKLQ6Z>__Kze*D`rNbhSlZPI ztlq1Wj|on+z%{NIK%x+`bjxkTr+$q&lghA3nxnJKFll#jb_h6<9&e-bX%zpH!d+%Jr^IS8-vQi zZk5aBZ{bds^c&PHJ>;gvLk{CIb5*)W$g)BjJzA9C+^U;UQCR>RFQVnowx5=Hudvk( zp$X#n#RW|LsBP0b57?+ceGK7Qe$qIzh`0cOlFyiKN~5MW9ypFM@aCT9lzG3~{TQpK z-cIRAowy2G7{ud|9#)~#k(Ybed)#C8z5UXw)ILee(yHey>B{B z3A^?Brbo{ui+i>KeC%62{2jpa3oe^@r$3H2tx+auw5h^Snp(WmJT`T%?D-f&2Yuez zp89uf%t%{2an57}h?ee;8Y`v75Z`^LViB(0tc<5pu|oxrV@h|rFxPTbrOoM=Fq#92 z-vYdHRKGx^wCqKz0I!AH2AcDhFjoqhEkya&1vrZ->O5q z%%NG1+r~@NS+&`DJB4Cf%lOk=9V-NdytGBv_B;U%UC@j(nE&A1v+*gSGa!O<(mS&j z;No-%CT|yXfPng`#>F1d_%cNQD&qm#PtW$pn_)zuY_z}rM7%#7gNwuLt4PQK4!kFA zk{sIOL^n0q?Rb0>1ry@|#A-3UXCZWXXDCKp)>%hrl3eVBXat;a6AZEwhqScXf*R-f zy>DyM?R|Z#p(IV0uHg8^VSgY_g`Ekhq9n>4$Lsm|H;2LBGN(&+B%Bg>IBoW$rAih6 zFI!+@dmJ9M+G7oGnPGki_FLg%40)8~syMHkL&;&+FMi!q6!7kO zgUOJUM!$kGIUfuoH~9$R0kA0x3=wSaaa}Nu#%^jBb)vB;3lBI=&+qXHrx+8dZ|Tq_ zA5qq`_P#Y#!G`+%#BTkd*7KqBsbA$v(xHRts6U+$y03Fcjsvx~)F^<&>4Xm@R6)dO zK=coRgL#qwnu6T8*FPwGWU_LdcZ7o-iT%{%7tzEuIzZ~+k>WzO<;7@H00Zc=s!tzY zjO;E`oV}Y(EA=^+qE)6ZTQSkt$w+4ZoKm5s2HZ4EWce2paP2m28OF;j4TPo+ciWAj zp&t~rkd}KWhW^Sbr(W9MTUyCBqey?odBH{bZ9}eJuD2Xb^aUeug=2k5v`8|kI`F>1 zgy|RP5Ouv5bf&ak&bKDjJt$NwhT4>$ah|%eypx#&_%4t`EWi$9O{{t2zhjhZ0g%d; zBtjVsG!eTQyCw-8;809pE!^x6&-G}~OMmSY6q8z*OR?+OUNVz}hiv+=AAs`>1?x5XhCDkdT>D7c{vl*$0#XZphM~; z!Y%RoReldmaK5)_u$7(w^`MENm$7HXv!ZfC9{{mojLOCb36lPnaC5>%OK8LqJ@wVT zZ1)90i&0~S`pemC{ze|{Q*o_U0)I$~>iV5f#{hpx%VRGQ{1V?p!W5Ezx14wXN>9B> z!jobZsuq?fmffF5vx4ERQgDCEE2|T`XffG<1DIgmzmHaY1I9nPn(~0RVp7Wq!@-kb z-HQ;Evf3?3Tpzg%#6LORo}Wu1ABI`lWvEB~6#8fOh~pjAeGLk1!Vnl`W`Z7gXkrlE~Lf*Nmm&u_K*VPVmH6=R}wZ(yuXY~@=ZMn=&NQwyYvtIfe?teB`}983*KOsaxfhgJHk>GI$u{&_u)| zml2yb&YCe>zDTpD%*INW5oOM#<5`2mgGTh?vZHQ+bLv_%a z?cX?;hv*&CY0v7NMwxdxV}}KlKtX%5E?l4-)JVegzL8bGA=|_>pyq04Fn?CNptRLC zR0@JW?k?`QWNlA?I3}@YTjx!i30C%+BvTnZ8?eQrCVnSDMrq*xVeH&Uijn$3w}Wo0 zTFTG70KpWU2pkehKP7PprS0Z;o277I22CGe`%OOK}pde^&zCw>3p2b%@hp zTuK@B44l1{JGsP10T9Sqhp(W`H;XF+;&O+7Yu~oVcNOKNH?fZMw|lq?8{i!Lxle-t+~-RTBW|_Ln2?y zCNb#5{sGR*ZnErkIzjTqdaW*bjZ~bm-!dkU2C?49i&a--!ZMZmZN1xV%-&<`eo$f) z9J0GaC+ShIBBlaCh=`*`IagH+9%Xo11yv_^6KYD%eOtv!)1M?dH>L#uauW?e*ei#F zs_w-}A~{M~)WIL5S=O8lY5-joFnrD9{!$m0UA}szQSisXRPZWR&Q3-e4A{1T+x0#C z=_H(~>xB&94)W1TVyMpp=C1rfY{6n-AB=a~Q*->Zx` z#)idh61YE#<~?lkI(*O6s~WS6#eSfCwQ6CxKVY66`>7-kv9wJ8hLv{$@HIhjD2UKW z44hA&Hl|0kb1fA_r{X&$JISYOXAN*aSb?B z{cft%Nh!V07$Sk{sdJw+OhqH0oIlnAZzvWeWEq;qQl#D}R^!J5vAC~SaV+jtL6v4izS zqmbCM&;f}vGA`yi$0T>>xX4*$l*P#sKULF;TXEPq1XV)?SLwd@W?Iy8B? zV#VF)Y5+n1KBFL{lSMuRox%G4d^B*+<_7xmkT-s|PhImBtKMGkdLYB7Y;h8dVdW>gH?-5lRG~#o3 z061_xbHQq9=<6*92Ax2jDWy8YSv0$XTvjW_oH02#XXLg14A#6vM#niS5o|Lc?0m3rdgW70T-=*}nDH6t=Fb)~}j|w+3J4 zY-Q-9>t2X<$6>H%oe8HReg^El?>U;xQ}NY(7QY*@Jcg_42G=P1o8i38nkXl-B{t_! zvcD!=zqnvI+QFj=<4b{_qg1pjok_Siezo1xDq2XlU0Bb7>|p5J?yV2K1Je_Berc&wkjFG81e*C>|~VdDTGO_(5C8FvJ82x(R)A0XH;Dlb1mWMI$_^40YshmJZanntUJCl)_U&Wgc%Ok}=-#zqi_X&r})?nqZ_OmH2~?k;M3H)_~Q$4g`|IkvrCf zN;K@I2s>b6zw^D2IPM!=XcythD_a>Xajijjb;z`J2f87|q5n#Co`b;7#RtidJ2EE( z>S~SDn>}<%jl_yi1p(qm<=703LHiTW-VR9S;!5TkJ1E}8g3dTYcmEq*$LF6!;-%=B zNE%*Gm|(7FJV>g$uM!FlX=RvIUkx_1i`=$7!SM9okJy9r6XD1Zi#=7T%inGE# zSO^0Ni(%!W-i`X%qBDL9RSPq-6ADjk<~NsUhTgz@v=?Fxq|YL+4esi(ZT&T`r#KG_ zkOLt7@LXnWD0g>~pXWOyqd@}TycG>oIBxNobNEb3t^GXZSe)mww`5UcO9hfJe6#1zi z28C5^n|g21Ipm9(vC(*yK>b)j#DMhKLdJCQ#rVe@<7QW_ooJ$B+VKYqs%t@tdUG{_RxQCP>^xPL6Op&>)g>0wXj zT`Iw~E6E4&d6tSha7l3)>COS5XJoM-C|`&9h*`{#9;lqb+n!zO@Lp?oB$GLa8O~!O zp3bMeTon~%{BswVho03a?l5!f^Hf^NCw(q*eS`LCt~%uG_O#7kkpR9pCzi5NnmyhAed=*#ce3xdu`qmqKXee?kg*#a9% zNK0ZD$y5p}ZYz}>U~Fy8o?NT|egL?xsdqa`ZjfHx<91s{a6;i0FfNd~%WE4~*H7RY zJ!2Ux{MV@Y5r8Iax-(>8&0b~+mvC(;S7{w+Zv!Leea!l=zue&8*Y#E%)Au?^w!h&# zGzg2;#K=$TjN5|`RkCE!;*?0y&Et%rDuiiX=qZR%hkLqvRJwE@g|J&R zzEvaV^2{>e)b2dsE)BXBh7tCz;I661GU_HC`i4d$5Na_H&N`EED->PjEWLp*g}Y9u zEV)&1XAjAp+xV2jS_4U@?ce(QrfnpDScsgaAaI7Fhu$wG&AL)8F$R^5C6k0yN$kVHAvcs!8GMvY#A~BR zy*Qh++ex$+%GO9L;3pK7J^Hq~F1?kwz+*xcgoeTuP1zi^hHm^>&kd`4H?wVhBH%?f zTY6~{J?(A6X(p4EKS6_iO3R*8JJn8>;0`xvU4MJXx1TE*^xM{zzE=2@pph0Yg8`;prYVaF-G3;5$+H|=1M$+c{LYrm$>|>3vzNAf$Xb#R!H0($N3fs)*<+ai6H*jU zM6t8!pXH9(xAJ~Ni`9XAj~jeH9r9RBZq)rX`OzRY#t?I73m&TYLUU(em-WQ7>f5`x zak(rDi}NaFiWXCi<-WE|LB}SzHpkiyNvf$ZW+pY>oWX^fildo{A9Vi@X-NqTQ~S(+ zhmgszYnT7cH)R$R+$rw0Tn5Nl8|M3T>VTJZc0+GVO~ z19;s5Y2dF)88Q^}mDxkkNl0UK0-9?%SsfTk8O9nJcc$?rZnfpR160a0AAtupB*-AY zwG*}~Z=rz68%I<~nFsxJFdqlbFSAZc8L?4Xudl96yFx5HAE_}ul7SrvecTf5D7!%~ z*??H3pZ7Oj7_3LoWrTMb+=&)RFY8Q2A*$f-Fb=$olzsA|{sm?^Y~&#_huh?zL)YIy zVV<)t;+5Qu<^VPx2s|gHgG%La!##Cg2>&}^7U@Brf05$#7hT|+%k?|9BBl>#?POx1qPs|Z7gd&u`Cxri zbPfb~3oU&D1mlz~OmgQ$1YX&0=K6I5yhH{}-KFgbbI$M%nQs9HtlV!uqSKg@5C_)` z-IUS@D!E?ebtlyh^c^&=z-q57hVH3Ss0f6(zGj|Wq*^5Z1C|f2*ZW~RYi8yzN-vF( z$SXE>`OhADGAl-pu*|Rt%BwAmj;TaGclb|A!&#-)`VGT67x3Pjp9`UJONUbt9PxoO zd+tEJ=P{S2Y)XPAUg_^{@v`>Q39l&*B`ve*Q!7@?hn=}~jUS)PT0pDx>UcLV;XtX4%m_Ui%lQ{q73`yB#f?E*^E_y@qNY2bh{%Z)W!zDW3h#mzdAx4wE4?+uq=w_3F5iilm#OQTi+3 z?Zmp%QD)VX#Osf5^wU>)lC?TBy+u~~-A9#rOhEG6m@R7!{G#Emz;H?N}zmEd2{zS>+9Y&?XX2Mr1(uTZ&q%Qu>xIQzSX_pX@idj)GkhlX>z_cpSK4=ow zvw_r>P9L#Ko^e)}`qgAXzB;CGPo#Iu1&H78;6kc77k;!4{Vj=xNT$mdYyD`NAO+^Fpz+qsEcgbe@q=&e6 zg;`!0{*_%OF62})`L6hwL+?4h3dm9J?~Y%(efsgSS*dguGjwt08{YNbXas9VzQ{@V zUHNjily?53&S;n=EQ4$VWU(T{Q_||u z-U_IpYTAJ3Y>jL`{0?SI4nTOuRZoY#j|7GX>FWfqGeX$`n=k~!d?;`d&IXkBPZJa7 zw^cX_pR#BPfeYAl9T?%B^$<9>v0k)xU5HCnDv(PunbKtplFI^j(G{91EFq_VCP$u= z)pxPi{croK(2pWO&YOSxhhO;_{z`W@B$)(*4csgcUPd<4jtxa-Nn$ok3@1w0Sg_HT z2HH7x-i9D=5O*(p+A6I^bxN zjTE9*KJcym6V6W$*)!789F(vX8WJ0xR%>B=&QmpM=GU@(@^%^=9fs1sx<|TXUQX#7 zq#2SmoVwFJGr9Kr=xm>hag2BR{|c(X>`6|js}(vkuZgh%r7Owc@je`QcXgVWsBvt2 ztt?{II+QUwR-HAxiO-(s0QYN+>GlJEs~a=H);`Fc7aw3b|7N1|F?oyflEwXIW0s^~ zZAC^m3cj7-*rE{=c*~uncypc`XE>Hn@s{_1op}CBYnuxS>OCi@OU`DbF@}~&(kN$0 zo&`sb_hUap+=Hk4_s0VBI&TD=%oMlTacUl*-G(7Qn?y4s{Ock{CN#~EdHP{VviaR! z9cOI}M74NG5;&G1!WtlD1oxs=w;*35#-Bu5O{V=6;U5MhMB$LUnqN@QJV>!Aks*$U z65>I)p3&5)Ukzw)^s)V0HuqrRUFLQiy!@XWtWXapV5#DyehORG@gm@9SCL1Dnm9ptd-Wk0618RuzN%(XO z8)9l0<&Dky*+&XR(M5mq5%eRyIsMDt4cGBY?d-aRhG}r*f!B9P>M_vmEvr0^I4(L6 z+@aRGu>F!kZ ze3kNl^Rp?H2a5++iZ3_EJ*_#>1NcF-D3Xd(peF)+PcXUuz8(GHIq6(5hOp1m*UJtT z?03lx%scE5h!@NQsT?Rc8A03mOL7%}!<&_2ympSGXQ0l2->(lAKVaaWgTI7$+H!9G zuwy+9lMhckrXcU*MHG*atG^_6J4%&+H*8GoKx@zmUlLMghBpwz7cSsqbI2ti-B4JP zVl~Po5-^hiCX||j8*vIKZ+7F@*wNl7OqAkM_9v1%fCr%bL@2vZw zMGMkO*Co=WfHe`Wi$euctJtQ6UedF?<$i$LA>?FfJENq?u)VB2WnXGN7tD^%#^$;A9NO+AWLitQ<0rwZWHuB5GC_ zR=q?`)RR1Tm1USL(W0{xAS}WpOR#;Efvz5XiFheZd`m3ib{ur-alo#}`{r2$e!72w zK+vcxcLXNXJ!uazX%b|C9w*A?)zrg7XTfSoG$$EDR3vu z&Hfyd=STY8e#@P>!R|()Y(3NksIt=cGPYM#(i&zSJVkCt7eGaNxt!3wKRR_XlDWn@F@Z|C*E=Ez7`2_w)LFs4Ylt88Z!HT|o*d75)zk(?5 z(TPLb4|C`gr^+_YfLJM`bYWs+ZL=C$M0|n$Onnv4Bxc+l1(ONZ;6xptGhO7gF;)%yEFNJE#vk{6{)gXdqc6*2m7^cd zXp+GY^R5n%Z8x_GpCmPY1E4}Omv`JO1!AZ*#91e@(dlMT6g4G1PiDOb1JmYj2D=O z{;}`*aW%`0Dnl-?!&1c4h02!DvPumsBRtv3k6PPdoCj4?doxIB zc1Yi-P2*nESTl!CP;sVJy4-Wm)yy}(V0(^yB*;326Q%`8W14%R_jMzEk^eqzf>DOZ zF{nnwlHf`Fqo2!&U?8S^SEO~>-*CVU{H*$mjD*F^B^8s2<+(&o@|sG}Z7qGrWpyL^ zny+~80=VND6XG*X%R!NtHE7Qwh%lHDsq=U?AeV&$?e{2$;do`-CEA1*rV+CqomJTG z!_A~V7QIkzIGJY4ily}u)fWZ!f*#driT7{!PfO8fx3#TZ85eY+?mlY_&}k_VPtv@s zzWX?wn0^(pz_@@xQA=Cm((O5Ri2-uu6f>3wA>497>gC}6Xf`!~OUH30$^<6et}{l7 ztWS0Su?ByMHRZ978)V-)tfL$O4}9pU4Ilp!=1z89-L1<#>hv53ztA*wenEk+M#v4^ zK}M*@e>!`u4!1(eQ(oTw_tqcOD;;f3AM?9c7H#-xla`pPyv#4WIEsLAOr2cl{m|}N z5jN3M+Hu=}d^?BmAwh~p27z|p?!41&EUvDku+^!eN*&Is$$^+8kPVcV7+wmk$Q_?te=`0jVK8M@1&f~1p91he!vXYo zh1J%W_BxSL1IpFX2zz#N^|k3>c?L0FmENzXOg||px%4DBjW^MB0lL=)o*bb-*4*T# zJ(4l>$5sFRfdIaQB60wn0>Od=0KBa2-xfd)1mHF`7BL}m7r5w>2~`PHTF%Gaj1;P6 z5Bo_EWvof2=N5nDhT%(pzsrK?zuYY*$wH!j1e*SW8JhL?3)v92=96jfhFSe1z6PwN zohz0+D#rhnJlf|hSBx_^58KLIrtA#*UbJTRJNXR7?_J;_RAIF*#(Rs@QaHYaKsTH1 zAYB=oMQKqG3cN}Ad)bRT)>8w}eie~8$=zSD_p^L5$wKIQ+9A7n;c7PF{11d<`?al6 z6axzH!!BnN07XE$zaUdgvycOw1bdEo129<)gkwQ<5{IorzWV`R6lsv7mqY++vA0Qi zf7CO1*6{?H45JJ;P$Wj`?OZ*8^KK#hSH4Jp@=N2~nXEYPDsbL{LBUKE; zXnB&EfKZT%PUE(eZw@Jg#v?zzBU%5p>o{mlLR>*nKlTswnvdS0%qI{zzPqk%&iDqiU0~^ z+BH9F8P_)vOE2aN0+8SY+1jx?Ya}i0lq2?O=k6Pd4QIHJxyof0iB^^DnYdsdV?Mr5 z9q~RFI%|FFO_)?Nwpr(l@$FhDmU-Ii)?Z~KtDw@ zjeEEBkJ*3_b$qeJy{dP&V*UY$XlhK66qX@kpV0wGXj`Ya7{eOoN1Jz-rXevhF3Uds^nLkD-4koaAa%Y!`aPB4 z4sRC*R3W<%CDxbm8$-iKW%vD$=R#muTxf`Q4_7B`1%NFH$YFpF1}w) zPV8TCn=?I6MAWX$2LDj=%>a!w#dw%b-GNw|ftZ_RlS{*(gMfprB}`Mz&~%bkK&xfB z@=hqQkz6cP*5ur|3k|G04>0P>O7DtA`u?Qp-0Rr`1*J4%QtG#x{$4T9?-2xHoC+Hl zOkCJ0?rA}^2b;E>z899ya+p_O%M7uef&K4GubK7~6`I2Cqn1Z$wQ$)%B%f3TCbu0$ z?~eHO<(DfYI9&~mkuMlJl{teyd;aSAUZ6Ei3Lj5+XYP)bRyc?eyF!=w;-pig?437L zM*)0=emslJS|GP~`;Kjck!_5dg&$#KOR%M@0Ciiy^lx$5Tt0b>zh zR2>q+TMx*U^fsEqzXSF!Zi`9cneft(2w|VD&5&t!n%h?jQF}$k)pZ1i90>fLLof>) z$=*p+mwXd&O6DNGRE|PVypl=eWxcXV;t6;?;phet9S;Sj^pJsxryHgBMJ6bV`; zbf<`4*C+vcx+Inp`A=h^M*MKE*9rY>=Dg1(^%485R2x}Bx*@-dO5qMs4YGr=;>K4(l_#km`&!@7lef$=-M%ix9C2H5KOW~fJ8{wF0R$| znf2Uw0hF~{?E~`Y<;h;^h4b+bFf?nxVF`A1{&jVbY4)iM%`XcwT$^?xJ9?~qh9vK$ ze+wbKMR=qnVL3KjgxHuE3<}Whgph z=kSONogvzILyN;FmgAbCt|nKu6}NUMG{yo?_q~A`-e`$sTOxstDc0_CZ#SZ>ME zYEhU`IpMtt&r<25C7{5Bw+0r+Bk;B_PSe6Pv;A(Q>nLc{%Lqq>^NdXFwx35qm&orm z6z4fFnXV%$c7yEK04S#M`8rs?-|Foo;z-aDA3&V9gux|bs?49eofgB?MJZ2A;F6@3 zX|fnL_j5wv(Ph9aS#iB^9LFw@e=pSLSwCf+Ej*}7F4&v$s=)-~jeWd^$ct|vxv1!| zGNSyfg(3^HCLxu0krIhGV?KhVIOSV(K_vvNh!_ybL=|<&&u;IhvvQIH>CTVUM3Cn) z>S?a}gLi(aiG2dTVy0e>B+(lZ=+G#oDFqn>mIz|sDyLcRvO0(%_9Hhkr|IefWXkZL z0RG8e%1B)ZzFofrC~wt_+pVA1&3IEakO4GZfb4}*1m$)u1~XZK57#HbK#X<#Xg zz>L>!LQZ`N_W zqrZ<|NC$a<79K(&+2O^~Q8R4j-2~e7bjT`lco-tuHEMD{%A_RkE{xF%#P=5=SWEwu z)(;7FJnMzz(>4tFJMU6;0FyGB_WVIGH@Urf&}e9cq%AVP#bsTB(W_c~eDBjm{itSb_3&QRtrOhra;j~?jIA}M`ysJdY0ekKg;G88E zJL5n4(`$Hx>xP5tVE=hrGI8`k-QoqRX~m7Go$7;JiXHZp&0zL>_iKRv_o}-4XMMWo zae@q<;k8Y!^~=_T=^3TL+;LQE10GtE50!>L`tH0@m5Sz63#WAEZ2&&}7*~Ur$*sAQ z8C9|-TTPGN)RQX`1ub-g0kuql8KC*uYXxquk3~&buus1@^o<)jlfJ9*oXjMW0RMz7 z!UHeK<_rDgI~y-5^bMB{iW{nrLJ`flf@MBr%&}A)Jsk<>$WaVMt-=APe95mq?vtI5 z<;mpWbxTy&q!QSL-oiX)-clu)1Ip_S;5vwKni6ciiU4?zATewnw;WfW_d2YdZOice zDe;JE={c9kY5GEEhcp5{F}cH}w1QOKY2AhhN6W`3F zctv_3yjF#9oI)f5o^`eIxI6ZeN>H~|6|?lvPXLWcH{1pdXQ+ryhf>eN3F;}+;V5q&CNR~R?mUO-FO^I#zDp`a4OD~Q(O5iwwB^F z;m2hWUm!xx-4hV}T5W6BxAjMd`9XJkdme-@=sP2?MiDp&vC%Q>dVg0;dFNNR2VG=f zjiJ&oI&;tr+F3+6`^0#LW&9FW)8WrZEDDC4u|QvewY13dfxMVKCJu8%plvg#_G>1z#=j89PP)en5fQvjlq za$tagJ%tYfqFH-+*6f|WB71vYuA7glD>dT#3i z7bQvTJ|0W_+n^1@V=nHM`Z67;M5*|{$$U9I$9V}EfsGRr1yu|@?o1A(bb(IGwX)N^ zn}x2zrFbiZcsprRJ@98zfBfx7!>#PoV9onAs=CkI0S=&~ zPC4U49`8NtgOf>HPF5-&@DN z`M_3mt1w%ainTlJvI!PA){-KSxInYKHZha2j(mw0CFvZBt-8)(>If=NveyVSVUA0tp%Dd{1$r& zU)JDfdngV6iK%W#igwDD5$fE`rZuy@@c#f0~y>uu4Y;_Nt)`SW~ygHjTkw zEe~Sv8;=;kh;fUU42$j}nAEHi@th`S@og(aCc58(10-JueKPu(i`#1*xJ{@Kmh2 zE|Pof)k^5tCGM&R++c(wY|Pa+wp~{es!$_qQyFgTrvz8_2kvMH&2Bc;noeTU%Y`uB zQqc7&=d$agU+1$%FyIHrFPx@HJv*6=;$Szbc~R!c=}vkkr|ZMh#@&_D1NkX7(e3?r zKQ`o?jd$3mwab6?$lY&b)b`v*4(m@67!yd;OF1njYw*Ohp&NLnN14;8u1dQNxHM_d8| z0ilN9ii%$m^2390_tLzlQMMZEJ=PLQkDv4srHtcbIF;3VlFAr3@a!K%r<4 zfCnBG`;0?lVu2#6ig!Ds(ZMLi7$!ARcoE@;}0v{bE|Eq7;>bTB(VH_Y7 zwi@IoF_PL)ZbWhfxZp7fJ3vMSvxRLtFiz`G(-+n`Go*{2Xez3+`tT`REf=g>9Ov89 zC6cGe%+UaPA%v=lW~m6SWNnh4gM7C2;pq<_JMHEmGLmY*&TWtj1Q!eOnSJ1k1l=Hh z`n)8!WN0qBt!=(mpHpK41ko_TeHELM&9-Vp;uCzeb091le4`m%InVtw0jU=A~@$E8_KJl zl(1>yiFUv~C)X0a3{$^ULUo52{}e}r<;Sj*d!!>$_v7>N64R6I7GWMMaqDS({}xcr ze_98op`_cXlnH-Ppz-*Ffn%1>tImBH;MlDtHpc{H63ErKB1wR3A#+1}xZZ1WrFVm@ z)r$5X?AN?!qdU<3o=$egaV>}%3Rl1+4Ry;2O_oHal#C+lo1nrq)*2g^!00^&+#&9qhJGVFbUkR{ zL#?JN7rstvzLD52DcS~yoHo&trz7!zi%TRxI;&>OGfg`jwYOLelE*iE?8?@OjY;YS z=ETFyMnD?W&lZ?LW6P1Q_{*i99%CI5l6dy(1M&Atv6>o{gPUiXdp2ziE%5_J_-f3G zZ9b@M#RejmFpcg^-jp`h{DGie(EE5-2-|j{k+T1$&(O zZ`h_v9|5;RQ}S_0Bn}iNMq-GEst58rA#4J0HJF(-o_RpZ4Ho;&C$8?LFij0p)2^4_ zsQLGnr}2^sqgj_7<&l)GfbAK9mM}3RaVNt{w?zn!PO}!G6SJK$qD|AaTWBrh_Gb^g zyHd`w`7b#=mS?S+zdplE{E3qn)T&yIx0=fw!Qe@MXAlMW)I+s%nX0Jht@50Gq=N&t4 zE-m$)l-(34YLLTNjjTvlJ`A7$(DDI0iXF=eSXc;o|G;Cm3KG><#4gxNI(9|qX)MqT zT&oke%_?Dmw97^&P9^ck)wCl9_LodKs$lfc3S~NVRNM=FiKY{qinbfPgeK3rKEPkNxKPx^?0ErCLB-(lo6JZwky<-=-q>18m zBj<9SMlfvNyfQoupl$fT#4p!5s||W;;ynWET1fBVhs5?CB%@{5Axlz z!MyaWI_m1uzTXzb0g@JDehyqx=pqW>nT4T*Uw>zZ2}cAXc=IiX!7tL9`%?adHf!?5 zfe}+;In`1W6VFq#z%cMA^JyiEQVjjH$C@m~1$3c`N zRc;94(N+5=&gQ*Wh1JkAvW^1qLcnH#5*w8k&nYi(p*pUE#o>Lg%dI(^PfbQ1kpLj* z-;wOCc|}}FZzylGX|93u3OSutOO=ajR>f@yk}9T=ff{yLAatX86TF%DHj(G_f02vq z&yr%Sr&~z?tbK)WNGP!~6|~kOi1QD)^~c#-C_ex}3S^tnaQAtpch?lGtz#PMM0xYefyxfzC#Y10f324N%#vY2i>g0mdWo$%Nj8a^+upsu+F83Z>Xegj{O&6XqcjSyWTWB0e<7;>Tt$ZG?Q))*UoX97$lM@I9g5 zM+kuvkc6^>Gyi~v(n7O=etOOr(7+-fHDZBqebF)a2-nx>-8okeHvWP`L}x1zsob{7 z($e*0JlzyWWPG|$vm5@2^=~yi;DcsTH#_n+YWz+|ILHLb7FGcqG}Xz|3A`a!J@OdJ z5I5yWO9C2BR^pHgcW`$hR2US_A8}vJQV5R?LA*T*7&Q5hW1qyWCLL^lq8qa2Duzo@ zKUcAPSi`*A4IJdv`=C$kZa^r66GkMn&QrD&Q(Cfj3sAQ$U}L)g4?z;Ak&)!Smp%ds zg4mHb1n;Qtm`GQJ7Nem9?yC%~o$mhLVKKw^IID=f6a=iw)WA6I-;FnNc#JsZoa4QG&K9<)F!Km^SDbo7id zwo!}aE{&Im{5&fKMJhKvLE*S>foV8{`9$Wr`$$-YKOHJ?k1?Fs3c_AWYkKpZoLS#s z7g9w+k-s1MT&AjzUl~u$Salpz;DRVExz3t!`-u&Bj+|(|*bmBr?UJmZ+#zH&wi$BS zjINPCzTsUt%~3pst6?w4RTlQC+4e~~sC#wlnuo0w#4ad(-cYS#+_}~r%|}j?(<8IV zkyXqxe%9lVZJK;Vi<8Fp{30Df;dM~qUGHZ;fd*i*%&(x z`^{8`{Y~Ml0{V>Hd6zzCVU7lx*AP^&_o9HYBF?!maw;C~K(Q6R@f63~;M~O#1yiWE z>#PA+Ef(mm{Iw&lq&zk<4Yok(ow-l<%lQUKuoKTA@+#GTQlwR3_YVmU0}`uL41z=Q zG8k>UI|%UoBf_7fP0Os5pIXvImSPw^*8;o-INMzl5YlY8zJ?smv=qwvbEY>#<>qmi zawf2PT6Ei>UXYAOi4P73Ag3;h_+6P2)81X*_r4&0Jd=Ozt_nN|!HIJrzM!ip(TbeG zdkxXe-r(x((euC=3XSir=|T%!hW`}8Q?f$V8$=+E2Uh26tHssfBe~; z3;KUcf8fxyZo{M$tOh69injec*V1>nu*8b&v=aZ$^~%IY&QA)ZNKF+DsX9_?w21>U z5XbUvaYz(KwTop9NwGFZWHl9rj%FpgvZHqIcTK)9d-kB#e_eOA>Dh2|AS|q)Bb@Pi zm*XIy2D``%E#ul|S#1|0X0IQd(7ZJRMlxM{P_fb+p_+6LnW=RnBR$*Lfk>c?8CYbp z$gxKAFixW0YG?(po;em*Z%TY|z2d3L$B1LbaCJgz*|?7ezj2em6epHx{=C%=43;!v zB-PPs0Uw~ypRC@T0!Og^0rF<3uqE5_{27wBn&+SY6;d8AohoLFi*=3MDv{!e3wQq9XX}IRU5|5&%dC0MQryBQ0Rv;)J6>6;v?f2wEVIX4&hD1tjJojRG z@sT(xC>)i+9c|QAbIdwqK7`~|Vy!+`i9oM$nCoyR&G+MT<q? zY&cG%UJ7s=7e5p8Az``KpXsF5E)!e)I!oXk*^8}s81oiM0rrr{HS&?axJC!le3_qB;VX)~i5}$+-4+32mYPypVle=#%9!dT5xE!gMI=@&9LM9_d_2 z(vR3vA3$b>?FVAo{uUQEO!nFZbY0>WsO5pvtUCC&HEckgMKH9{5D5`guIeksQJSw! z7UE-w0~Ny2dgmMl=$AP1qo;G*&IJk7sDXw8DZFm**m4G}S{6DQ5XyqJ-cakKu6N~f zA#?A}>#Fg%kff~!{-D7aRXVG-U{#6+Ie-jvQ_5`0=uqH7blWLN+5TaR*A zz+c+Yyd_~6$jQ?ymtXH6Z9gJUB#!|ia#nr=;!pmeh@fAR#aZ~25ZZsEez|veAihKZ zO(t>hLzgo*D1N0o6`+~H-1?&(Y?wDj$`C*^N|3T~q^1HfF5SJ~4o7{`mESiE@#;Bn zBN#L%1WVT*;ug+>v{F^c4gGQ$%{B4Gx>Tm=pVs%lRrGL~?L=rhmlN{%H=T;fiUEPi zJ8p^#?KXWO9|vgN&=_iY0})pG&zf$oA+jO;QBN@6w&c)oa5%&42$rVW`;0nArayiH zsGI&Q>=~2RM6@(XnB4B9IG%5|DspmGA`!JjZCs{K{38u|+VR)X|B<2kkhctV;+04; z9p4ejxA~+;G|9sP`74GiOedq=UNlKC;klI!>HmTfC-QTSH>VO%JJyErDl}>KohZ13 zrpX)PpY#=HfH@%bfO8!pVRB4`+)1^RN`)h3MKp`HStypTrR%@2O(uM}mc!Cjp%^i@ zXS^RU^~#w(hTS7^{2On|`DV=WwNzq5<6X;{vm&lm?%F(eABii_YC*4L}mM3+}BOHbnP`dEWQBa1r^<_1ngR-Oc`ova-PS6QQU(W8GPj+`0h zGuIsdoTbs=p|wnK+9bUx^#0I(>kE_=k;Q+vFlLQ+3C(z~0cefEB=!r)eWYT&3oqLs{rF+PzM=Gzq6Ym+|Lw-!J zjBWU#XaVhhpE4}AFEo&2sq&$fb4mhXt#i6=oO;z(iNT0i9v9~u?Z8!ypO_$Tmc;h_ zL1MzCXL!~$W3qV^s1Yb>SMOhtkwb;~Gj3dMVuv+D)2$HK`zttqUDvi!z18E+7BG>8 zM?B-vYi#GdqoIo5xVpmEmHr8X`x}6s(UCjD!k@rM6(?MhAemn%=75H`l{LpVK12`= z%BSwsE<<^Uz~+Rwa0`;0nfD#Dw+O%ITO&D3PAW@zOzE|n7KtI8xFW1XHgHGqnO8xb z7b=V^739DRJrOSgYI%y$rBY+VNDX`7$b_lAkb$f$|JBMe+55(^{2?*MOuY>yG4(Bz z+V*>;vr^>_!O**kP_!ELsjqyjJ*E-#cM%yukNw&+hj?~>rBuilkZ~uJ4 zyMV)1CeW*LxDG4oZbsRwUIZe7VhI&tj#VlIU=#|RsrLKEEUF9DR1cgwX!%gh61mRY zp8Jh|y2Atd&LdT1Hj|eT@)1p_T0P|Q;o^AmebQV%6f!I2PV>ZUq{drlSRf z9jsxasR0OBm^8-X$*I)N+l+p=Ja+LIzOVx+JrNSy9*WIy5|{7tH$2m|(KUYiPyjSG zMFEmIn_9UoKNR((Ll?b;F9lQ@4r?{NWF7Pa`2we;0#+IB$l zGqpxRMQGrIJ!XqGbn<~!%Qj}CZe2W%6Ga?C5!i93Vc~wIK!n?uac9~ze3%b}?D1w& z^tBqZn{>~=pTY8gX_}MxxVNnkt3G)trZgN1-t+L9iS+UZqOp3lx}M06wzvEI(YU%o zN58zZ3?PT*l_R;)-Lg6Gw16buOZn2zf;{{HB>GG z?v8_Xl+1o#I44d5qD6+3w@W z3@E8oD2wl$dm~30_!e$2s^2HRosu}yOb=dlk3lFTqjJC@EasoyKJ2n`gBM4~jrwC!7mq1{4^H+C=mX$oM6e zarwnaKp8k!BZDlRB&J$f_`jmvy#M-mURNG`f&V3A^yLz@vVId*Rgt0>{VP;`yCdOC zzCPs0L6>V&`^eqCu`!d~nL5V%zPovOkO3WKv=9;N9{e}Y+hinjKg>iU_a;r(A5yeT z?*AK05a@jD0rW$!{PmM7K~crNu^oUEyC7c3z$f>qPaLB^LN zJ=uCn5B%>9d=57#gbwK#p8wlKB=7=>aOHNyMR!m}}6uvOxk z$k0uipZS%$6N6z(I0K~WmY!Q1PY{LmT?Gz1)!pfs>7mRlG{MJm63K^JSPoui&;XjW zrdf1<0Nu!e##gkqf5wljS5q5Awyh@sb>URfmJC^mLnpjO2-*sa<%rET@p}jZedQsq z-*fF{!6MdLpwtfGtb>5!b;u%ONAx;7nwQO7XAGkXX)@}&%U1s^2UvhrMmChV_IplJ&r11AG6H@PqRl&(^ck?p{KYv z(M0exx-CNx?E!9_bU-@33BBQU{knP(qoj2{vlTZtycXhQhVb8f?Rzkll%A2NyenzK z4=Jr#sl#MEBwA2OoiS=L<8X)fUxr~EKsd}k1NmXNgP)~y$|h~m!EFBcM7c;v3gHW@ z=?FQk=t-H20*$Yp9K(E29LzeY%Jj>HWP#Hxh-4`D1P+mTE>asIX;Ow<*2Pp1oUBM( zyew%R;m=#1H1U!K>I-2*V4VM%RLn^wac1#IK6ivDZKAIi?g)b$HZ`NUXEPy;chLZq z^7%Pz!aZrgcs@~Nc;1!+E75XiZuEk6bA%wxUKnZl?yTX=nt+zUwOIrni zs|BBIDMS7jInh!YGH-5doxoGGR4|;JouRzDo{AA%|_;`2VbrtCymU zZ6E;jdO?sg4=!yEhf-SjSznt~MQRbKr5=}vqWHe6z*dG>@jL4$rr8?;&U>kb5 zVT9_4(*|e1{L^!xnzTsB{tI0{2y!-ge($gg`9jPYNwzW!d*jI!b4e~o*OCP&v(37I ztT$$qM%kW@+XN`ihs@iMULe-LBDh6@Mvrw$vT%Xw^O-#faL9&$zlSo_uiC1X5`(I3 zZ-7iiJ8iI<*@eBn_iSpxNhx=a(k?F6bOjM->xl1pba`2Twq`J#)2pXXW&I;MJ|l@r zf}-D_odm@4%+d_y)kFPoh5hzQIi>JO^}KA;I;dL9z2|M78zJ50@@-Ia@V;&~;&8sV z^q3$@b$b`A*@ZSiuZqYd!ZA!=UJ*R>iC~2Yg>0w5ZKHrUIjQwNihkN`#JXbyYZ0CO ziP_AhlzV5h%|YvaLu&@K%ZIMn)E-zViKq3znw4*$s=+~~8%EfBsj8nD=<7Ux*P9$9 z|6R*8Bm@0!K9nd~LQRNYZUz+QZeAvF=xxS18dxmxb(!zGRW9~+ll8T*VIGIY<-2pV zl1TsGt7fHO<^s!-AgB2%$)eEg7dEm2E7k5(r^2s=8E+QgWO9VGA+c8iS&ZmT98oBB zDPj_gAf{=|*?nQ5R?Ufn`gNclE(U^AzU4M*Q|*0E8r#zi78hYwiU&(U7gC`jRee+T$7P_#T#LK zd8~YqJLl^?UcF?Of8z?wlp)z2a22BP0*`gRlhAoao?+(4G>jG2bvYT?FLC>*a$~8h3b-@vHtVNdWLN8-3;53;5nxuBnUSYu%i1f4~$GoLyoDu7JF_g z8JDwc?GS^?QSd>7ND$ZaS(+vT7W_QfGa1O%`1aNF?cYvirxTeet@zMYW8GeKY)X+hs3p$#EA z9ZeAhrCUUj5z(?Tz~O};B~V?n@4l<*#hnNr`Ie4Z4Yc!Z!?Kd_&rC0HJ_=)hB6Z!h zh24>1DLTT7Bv9~4=@K|e2Hs=62xQT%p2!sJ&#MOKJ|^^ed zg`QQ#@*pByrbC`aZ>ICct+L9V0vC=3KKf4F6U1Lm99|l$wWO)83_(qUa~u6}+HiN8 zCCUp5_*;HyP3)}|9)y82(pm9YBlGc@;f7X({ai5sifjwA1LB23{?Awr*O~iMTv}Iq z&H0ozi;tt1b=18-r;$2fS=YtJjw4Peq2AqSTCZf~(o}lVOIup2aiUkp$kgm;r)ZUj z#ZvxNwrZD8D`O=lr3&_Ekz7|r8I$9QmRsTn*j|k$r)*ldex|ZfbRnaP;;h3|a2M04 z)m#!-k=iEWVS8Va$@U}eZ&w>;-?)MfdhcCK-9&6Q9Lpm_(@iNCP2C3El}C&NZRR>(Yfe7u;0b27hM1vUmzu#%AODI8C@G8D`D@IC9HCghhUopK4_(`hhsZ)rBL|?rPk5P=4dbQg6 zEeoYVD)KhM0dTrAB*z|cWxLQ1L3Z~At_0TQ;Hx<6w_z^EM60oSZFnY9W**wgFgvEX z_if=~(&*WqB&#VV+w%f&9vq^}Nf>E4w>&|wwi^*qFn*!nNb{rMvBmbT-a0qO$3e5f z$?fvF6*B5!JF9DB)JsDHOOz8k9I<5M$+pjY>55(L*Re2KV!v40SElT*pFoCU(cL{Y zk#+j|r;C8{e=uBM0PQW0mcg!<#iU7F37hN2p7w$UNIu-En(HH->suEaY3 z`H7o+P7DiRl;93wn8DVGMeUDJoAWh@+obTq_LDJ|ivoMIS}iT~=xa}n`h0;ajI`wav>^`%ALiBZ;j-ceQ%2 z{>3S6OdE0gF0J35k!&>cB!&S{O5b_}f7k2({&9;-my2SADkD_I`f|`kC*X4CS|~Dj&j;ZZP+b1nE~(&3CNklH9(0a_LkTo zG$V4(N;*?vWu5>sJBDK@-6YTyI11m18f!yi*DHn383Tp1TFjMyXX$qfxQc7;mt6vE zDN0epCOCXUQ1#1m!&s;xM1%j&0e&Ha5+_4_AEG7yHH{XhkP7vCwuncTP#U!0v3e%G|xzm1qGN4QNn&hf3o5yePXf4 z_ZuZUlLUH{oo*_(OP-vwsF^o;B*DjlUE$&+m8lc@Mlh*@nYo-xB`rRjdKaTw z039Ubm!LQ<&84|oX!x7Ldt-UwZb?sVq0@ufzQrxj2)m@q`ZH8PDByIPO&Vwnc)_}A ztLxh~x~11)dgWoWAqc3fA3cUv>=x{blG_^Z+-SR4t`nbregPHlHHpN=+MrNs*k73u zS4rHb?If*&d7(3EgSGgO%e-(gST)a)hv64w!JmjPGyj-UY?eG~9zNvcS_)n#H5PMv zAmk@ve%Z)K4)dqoK@J#M!B?sO>jbj1zsr)Std#-4g49|~J3KC2HJU4>=QrL^Ycg2Y zw@GouY~_CGHM z+P?VnSe;GB=)~gpgRcy#PoSye37#*J-0;nSA8^+xnR$yDgf@}aq(`5s{1cXH>X`b^%q-W@M=$smvF>g+}y&Ul1^VdH>xTtxq;d{ zgW7jgV%B)9+=7^Np-5lOthaNGE&Dn7z{}I>J4(yDLQ`nu+c}UQv;5Gxb;0peauXhL zmaL@gITCn>Slz!;xd%9hiLV-4u$iu+saFrGP^{8e`#W5f7@VZnI^!oU`iFW=o3Zka zp($fiBgt8KRT5;)Mtf|iADziwU%Zlel0qpS;#r4L_&Sz_RpPHOTo6- zSDZyatLF$&JRI{Ay8R+IB;k9ugziW9Kgg6JFJ@6V;J}0|ywU&;x0Qt$b67;?0|%`m zO2p&UBVvmhUKf!ozr|E9#UY~0^%`(NHi>ixhYFec$B-qlL^fM-nu>@ivY%(u^niS( zD3qiT8*vIMi zA`X5is0AQ@JC<2QJxfd(i7_ILm<2=<9Sr#@0MHNsnQmGZ z4R=laD}X~gm%lA^uptc8%>Mh%Gk%-QG|GeUo%6==BJRdGRqikSfuskQk=Hvn^tNfCwj`0^pPZ*(ouZ}?xfXSH1W z{n(20q}z%~Ze)q4BV4ZU!w0!PmG=1;_}x{T<1?^c^&l|1iCX)}yWpJ3iMyoBJ{jwc zZhAdPz?zwsd@G)s;HgsRo}i9MpV2kjEjI8`GCG_>UR`G)tXT}dwsCa>z8sMKos$p9 zbmx+I-LysYESkVfR!-ic=XFKPi%EQte9TcSGJkYXf5WU&bu z&n)|yQ=`AX1+eZZ?#H@b_1U<%TegH3HA`Nj$O=%$+DQEK8kyZb(98qal=AJZvNl0e z+3?x+H|**PGkC?S#4|ZMwNlRuhyL;CZ_c4KqHs*MJ`*}@fRUvpmk7nUPNcCE324ni ztK7Lxh8=pS27*>}9bZ^{Gank*aY=ffe<6RE%G_qowuYL2M`>T6J>(|PLU?COS)jr&^cbag`T6MxC&@z`5 zs^Pn-3OOuUpc2NQchgUI#!ltNtzc?Ag%D`onK=c7Hp)n*4yg0GJXBmE_%yRD;ARnD zN8x3KW%Zw&K`8>Kr7C}5VE)G|f64VNbImvc5#;-pf{fUR##OI!sdo#_S(fcZG#d6I zU*CG*(Ec48P~qqYH!vBc*aYQ%6HT4Ya#qg#k3_Ox4*p2>*ob!vO!7;(U!&4XkkTe$ zDWx+bI%5JQ5;?`O!<30*F{qP*H`92Brs#zW1!GhZR|3AJ5>kPzYN3JY6|`IGTCp|s zM(3ifH!|Rc@q;lcB~iWY7i4>w~QZ6Y-=I7c0Uv)RRV8tS%;vO zs-ocgy887Sq+C=S0%UzvU%+hnMm|v5>f_Lsp2RN_`Q)5A=wYH#9-2n(TK=a#>w*ib zK>wfXL2I2lhzljlIy9b8tSB?lOPm9_nEZwyTyBf7UgbitiS+&;+Q*16t*hJ*@GJ$B z#RX;_P>AU#pQU&R{FeKF$5Mx=uf5<(Ns;GyTb^t{mZ`a^~M1%`KOOP#9Q393E_(@YWnyUj{ zQxYs(RVSBxJ`GHweST<<((v@!(NI*na3NIDwc=dWt+uD}dXZ@%LlnfyV4+8CA{@lV zRhIY;KDWx-ccFRYPE(a&Yn4}HcX~_#DdPyePON@^mj>X0M=iMEMPJMkpuokTJ2Y>J zkLRqHNV#NcWXfr?I1fO2y|~j&Q$kKmIwMRap|%df+soC%Dozq4yZNe|RMen8n1RP^ zw)1C|=xvJ+V=(2R4F^Pho03&77t8WSA7zEr==Ahy$}NSUiix$JT}J@CjJKM_A3IgE zO;h9Q7#fLEXtbNlMsdntS0FMr=_FQ5G$2bHWK@v_Q6OpDOYwaiu4%qU$Xqt>2MS@_nU19s9FEy zf9BE+(UeWqscC14fN7j>J+0>6Hcl(z>`rbPd~->}rkk~XIDdt1L^;~H+%fB*s}HR> zM|=38!7FLdw~tibB7I=w|M$=yaLD-QpwC?za(mz~G#98tw54iOG#Q< zL!B%Z6xY-%2`_!LIZGtxlCoH2-;<2?6V4ZwctySUY+1RX&gY{pj~E`-_XJ>rP;W~ z#IRnvt@d2OgVlv(_1Vui`I?cLtDs%z3_*}-4ULruOP%v?5_CH}U_d`V3bs@nNI>5% z>BFc<57m&wh4GF8QTN|9Gj#$H1+~bn`_#x^({e;sv8X^xGPySCRp5-4=T(}}K+VV_ zPnH;;?1BKSSxQR4t_5#tSH>FmgK53!>|Z!5WuHu~hgh0dm0ia|W30>@_&WdU3;t~# z&!s{sL=_nY>Ku06rMg+b#da5hig<7z;9>>PaA`Uv%SFlQV;$$76o~>nx1^w2iN02> z?W=_aWtX5ec*?=8Al8|O#wQj*D0qg!+||5EBgkgwaWNRqzc*20c1NPa}Wa{a1r(?gyBF2GbdW=5`~ZH_IdZpw_I;4lO>@ z_z-YH+hi6YzRo$fdkSuDzEtW8zI#ngU2=@s(ez$o0)Cj{jGmNVU>MaDli zz{@e-OcZt%g*-tl3`B|ZAUMS4sSN-GLwCr}xnoWmJ&y10eI|GFNmR7MW zmZ`3ZR%+Po-7D`&=RM^I?ftzL;qXKFKe3mH6VekpAYkjny&O^$*d)gGc4|eU83TSW zm?vFTSb$(==El(QYtaHY}5Vut`8pG{$xIM#I%AH_|-B$^J_>V;5~r z>c)P?o_(@41BZ1*_*)dA7GW)#Xbg*>Ky5%g|q zuNozXOGSpn%CMkh7Y0#yp>FyJ^4AHCooUBv6@*QI7U9+X2Xzn4HkSgsiy)3lyB~&Y z(hNM;X#d;e*+|0==6pqcqy&_A zqDMBh;J`tmtQ_snR!Q*<5b%w<8%zECf7FOY8Od{3k1VmtjHc}M-xfG>dvU)K-dYgJ8>iznprh$2?y z`U>^MpNI#!6kyN3()wrol{ROB4Oh>^shwq#QJ1 zH1mfFjMh^L%0e;~BnIDhgVAEiceyXb6`f zSL$=XdoI3;@(Xq!)S*Sq&d(-tvz*SKRdZ5C-WQ4jXSl{Ono?+2QJxq-t0f=g@N)AB z?1^zP9X4x!8{k8X1S9k~-@U{C6V|2)LWcVSMJ%m+$-yvoXtwa~x2a&6xNi^i_ z0Z2JdZgghrWa2mxmQ#)qc>o9l8wyGs6L{Mr81av#0SV>RXnIVLsRRLr50qb|r$4UeAUB>rGwZtyG|iF9GmiJ%N= zo`w!AI)>5%$yv|S@f3~1#X_pwhgYLdHa^yHTwvgHb6t^7vPDF>e{Q_7?`&o4n-W z#ouo!AUeJ0Cm9_J$m7sX*Oe~oWD&#ee!FkZ`;3J%@Ogt+GpA@E7yM7(K6P6T z%8PaCE0xIxp8s6m6Oi?@=K^(T*y15wEI9XCdP;@KKY%eXa18Qc3ChH#)oPe(7lTF1 z;=B7+<5>9Y&m$2b>8iWAwP#PO7=P>7rUVr=9kRc zAq2c-a8w)3O}E@kf>gIvgZ;5qf6NIn&%M6}_gjYSd%YffZiZ3vn2@?CE;Miv z_P>u0JEI_}dIpu)W%akszXTDsa)g<(fQ+lb?r_atzF{dBhH?>X6W`5`o!nyXRQmhS zwgbB!o?aGO0rDBFLgzK{(->o4>4ti>J1b}cTE9cgF17|r9X>I=2@%fM!x7wFj~s9z zk;zq4fdiXK2}2MjZf_seR3~fe5*n15T)Ws(uU~>k=J#ch{5==2^Ver5zaQ7&U1h3- zGr2Ky{2YhD`$uy%y~AF5izdUuis1yuqr_Ka% zXib$F8Dv=0bg%sK*D8&Thg0MVo?%!Y7dCwkLJB-lYh2M*F?({}hx*bGZ?^rr_PPV} zP|{obhJC)I^Ym%s`#vdIipb5&!~iFOA$7}lK`5WsMVron-#`bSW#g#O1C6MUywbpK zTp)`&*14<#GV&J|@M?3g9k+b|t3=y+GQ^v(F`3!^#iU3IaiC58~k~r zCynXbC)7n89N&SZ1?Ova04;9EkDmbqY<>VJCJ}!wx9p-IdwHHoZ(Av+^23un))0#l%{FXwQn`Z=qYRUjJ7<5|@ClY$)63T)!S-#BA zyTydU_Cm=DLCBiUBfF}%(_N|p@^)yD;l7VtkJsdW#!JEe5G!8|7-hjBg0p&>u;j#* zAll1g&UF1T*h3%PqVhx=l?UJcdxhy$BB{60)*WHjgb;u6zP5k`gDCEyV3mwcZBIN! zw{Ybk$>eO}kROyEx6!knc|zD^6b2l7L-vVZlQj>oowKZ6F#fS|QfS4mpaXLLyn<{_ z;KYsdq;CeWQJD9WFvD$nZI|X17r9 zG0|3gXoDI5$Gx8$5m%|RvtnAI|4yV}YS|!G-BUS1sxE7l*0*`kWjP;D>!fEB(I2|z z$8w}d6AFPg4*MIn3BBQ@E{l7+erB;G1$*1^Si@b$MlpGVvQIyp$8$IMbv_i%XGnvR zSqK#{T#HNS!A-#?vXq^xznH*@bsG1o1+>jymIzrE*ma{@s86cjYER`RAx8VwHs-za zK(;*hOFV&qyi>c?DE*jX$mL8fJTN5>vxcAi;5$*%UrR5xAxXmq?JA3zq+xG{rpw`` zP+hWGF0dmq%p?_cM9ryDJ<`rKPjJE5b=r%CV44IEZ5hVqe!isxc2Hj

jFy>(#mj ze!IM%;T45alj)(OBYx|nTFM8&5}sz^@m!2uyfr(C5G!ZA;(!w1iXL|!Z`6T=i4*3s z(+KJ~4worGBgheXC5eN_BY&}(CMqP!Lw>a{E@JL_`ih_S`G1^1SiFDa;qw=#KAgJT z0u2_1j*y=-)Tq5aSW516TLwTZ&Ru6~kn87;6)~3Wu_;pMDO}dDpefi99+b95}=Y(~w-S=2nF?R(!LT8IGxzRo=% zpO#%5Ct*YJRP@(pzWsZUMel8WZlNuoo@tIW7ybY%*)gx~exnr{XGc8?Ai5)e_^Jkn1C;D>z60CSC@LyAKKyfq&maR&P>)1=Hy3-sSi)A=*RAanVagNQ-S7 z8bKg~fpU~mwd%$RlY`Z3<*2r!F(_-SgvC?rB(qheEEB)48k@L z=qjFM7SUPXUtQLB>UzfkP9X3jN<#E;X>!gnS5I=Et&Q2g~2G!%k@$DrZ+HIEj!;ck#jZJQ^8+<2J7Xrk` zCYJtb;~7JT_p|gW~}EpRf)AwBPiouwuLiGCS%h6@%Sb}egJd;==^*k2~hMQ zW>)+U1<=?fU=f@|H+S|7jo%Qhl@8(|d(i0G(P+^VL%ttZ@n}q?3ZYha zy0xs(T5Q2=wT!my{3WBD{g*5+Y83Z-7y}6J(=t-#XzEvOG^7bPE}2^ouQVnPNY5$_ zh|M$vvc5;X*Mz+=RA4rzND@z4hM>)Hhc!Stc+*Z8-c{Z)3(yDzI#Qe8ea9r)SJ<%*JmheuzCIe@EUBNcNPpwnz;qlPVF5A_x!AC-Mcfsmtkw=l!`^$$HFJ5)bv?no^FlFV}vvzFYt@jQG!k} zGvSqgs*3A?@HDl-_@3#^;Rf0V*T8A0j6Pokx0Yv213wzu3`xGvsMV{!a6)&74X^WK z-_BHd^M3+x$)sz*mgY5Lk1s*jqFa;ye#jswW-8c0V6QbN{|#6#^g}sW$Z2%KjyCaW zUT8PP05=ype|VBiHQV>tmP_5@9m&nup6&qR7jc&Zzg)z>g?&1V>R>JoVYhsHcM+E6 zu_V9*MvnH-vmzOxE>w1Pam>@;^?_-3nC8`vz`WVZMY}D;uNpv~12QV>=@R_SP!V9N z>%fGM;OW!_88WsL;HKaqi>#E+6awy}q;;Hp?wBq)vBt0J&LnZ* z%nR_uy+~8?V4#n*skcHiQ$C2B0@Fyb0YjzlI#sf8xB3Pg%~j5U9QFla3z_noxazzh z<_C_?!fzoJy|0R3peB&Ss0xRbIc?9Tts!=cWH~cAYaD?@z9XU4tuG0!2$Sf-m~3&6 z!eQer&gj<@C6%g~L0(#eRMklNf0n)s~YbJLXM`>3$yf+UtqR6EvK5Hbl-7 zg&A%%**K|(8X7yQ(>Z2;0L)iMfpK%p8BgeNF<=>ph3|uw23=A9cD;f! zYEouXFlIJh14rTW7MNd6LeT?B#PS1_|?+E?69!~{z=TNnb}rg;ytOaJS({sx@I3U1MkaN=_B1}<)y24f*y9o z>$R1@|5ci(P4<;JWD$@N38tMI_}NLasz58&v6V}(5&{lF4G4jGKes%R`3_s*p4oUR zUIeRCsHxfo(!wR5v)(q$;k5vNR6lSfxHoI(dApJb{&hyp_>&bm+M&_4Ba+ZN;@ylIgfXoz0YTj`by2c{(#z~L3D`OFUFcZRl1Sv@wn?HXIav_Man z7aLHIWY#@g@2>45>sRAy`*+We)N4$OV`Jwz z=7LvY;45=F%5<^!D?&I+?pxK_){g&TT}8wUcoWN+7`a}&>x!d^T&xi^pT+`83iFJ1 z=JS5;K@nV}SdAJyn{>mf*|-yzB^Z>j{&c6>^PM@p1P?jQpECpUVoxkbP3O7KZ^~kc zqWpnP?`rU95{HNngf+~w?j?|q((#(_?@swJG9<*8xNT7Ai_-0(ugqH)9OG%5>CXv7 zcXs-Uv{YPp-Z=`WpEZ^MV*-Jp1)s-mwd4{jeBnZmm7o&sXi}xAangjFqD2ztPgG9K zSlD!}es@ebSFQ`oYqc494gh-mB@xTEje!G)E`yHmqM%+UT;dca7v|~+1lSR)rmy_( ze{|45hvc>7VheTn_s8K)kAwH1cI<8P&6XY*etYGBCks5EDezcFFCN3psf+FjvCY6+ z^y*a?z<3e2pY$sA;cEzkOh+NaZOZBtKYUEEFIVEc)A~vMTi%8*E|Fd;@k}5goamp`A&p7q2HpFpO46}lPo1{A{A`N1v;WGdai)x z5mq&xJHB9BhEJBfxhwJe!N^iHNXgE3ikR6?aYTGh@3LA^x9^#HI^<{L*?F6(!TRQd z>s1ZJ0DjZJet0>%pHo-C#b{VP-opc;iDDgKRHM^RrVA~4Wtp|&(dzE~%AZUswdMo^ z*^|6wahf7dLBn&5xK&sav;#+%9$-VnKmCO6OD&FXj^rtVzWfzWF|33Sq+2|e|! zz=I!O(8Z*q&`p=g9L=N~#QuIoe~c}}eGf$Kk0V8fynq!{Dax^S?@ih|wZmK-6}KIx zmG26BkLqQ>(+`xYsv2;$+pQo7Av`@tNH`y6voRe8-*z>WDhSf@qSNQ455w9H7)(i( zD5_=tnNLfEHQ7;pBFzEOvv5u(2@-`fv5tzGWGrzFESf2dt?F%2=!%)BS4)e({%)cq zT-hM#I9MeGVtZos(j9cs7_mw;M`<)m?1ScB@O0ceJufRepf0B5bfxO3gNq=>$vNI48U_*%>`zmggL$!FiS z@Mx@7suh0r^>aY#EZJ8{vB0s@mXNk3P&0aVdKxEMezmlT{x|FY4Bgq$irYnnbkClh zJu>imos{^>sgV7#@~zhsk9NW>?Nps73t5w`9ve3o$qL89ttB`oD+opR64vpsQq(Q!W0N* zxFmhsd!re>Ys(JV)^gR0KL(1ywWMN>)S z%wMeqxxx>DsI3JOoTd@YaUXIl!;ak>eUYA`*duD@IPQ@d*q!{U8P8CYY|bx`jf(?E z;~KnQeP^`S>tv1n31QF!E+51nnSMoY+OOlH97UEnIGUcd2z{K+4}|P_b**DPS0GwR zrCs!G<7&lsLDNDFp!her0ZATdqAm6XcC~ApA%aABeNnEeGF%6CFo?nhX%Vx7)clHq z&TBO=0TKD$EW#5)wD->QPJAkTE5*R`N4e5(L=Dnk)kZVk+$7y< zmYfTa9@xps&VN}?;mVQ3OhKN1irqz-kr|@*CLFwiFjmsYP2G!REa<1J8EZ%cmaoiSIgD`HLu{H)o z^hH0x3v~v<^$O(dtg`?@o->5!PyTJHEkVdXVZTO-Q3_Yfu)3~uzzn$Q%i9)RJw#K{ zCL;ylO#kcAI49jkjPHJW@aJPO0p>!`M!`UwLbqk&#>9jSz_%U{>sYuca3#c( zhe=8_UEBx3FCf60NBRkJic4)4&qL5jFi?4=f=u?nD)?uj#zh)baKp9S_=Df0O<>tH zwB0B1<$-)c>t%b65W^>;HWsj&)F^^MndSv}r#891hZTUO(o8HI#9Ij;yw9uS_#BoS5x#?S;=ve9hjDYpZz7c?kFfYALA=^=Jlr;su~jQ zwc-fK!g%(hO-I5xueT*MI_ZDBPFDNXTsPNzlBYC!QHgU~E;_T#xH<23%tS+to?5~; zR}*8%4-u)ex#5-5;AnU_+bsmv8N5De@&ppm&1TF_Q?mg?w=VB#f!x2rEBhMZrHA={ z$8K`A_IHcj2J42xeRo?0YA$4wic2)1nyCl3cVVYr$?Q<&de%dbjMKli5&guaqon!3Kvggg&rw=f_PvHBI^S z38dL`Co*W;Rl(;1eOo7|Hzbti$O)jT6e4Aypct@aq6unU`Yqd1ZE!PA{eP|G|Y>eS+lX`mHDmIiF^&tzj0%K7}#={X$7%t=B=k{j4w~2Sg0_)RFHxGO5p@ircqku*L;4`EFS9Gww&r zp>K!EpXDxKVyoejU0EmS9lobBqGx%!_rIg|X9+Qg~IP9R&LkktW4N-6=B9AxOW z1+f+B{AdaJe$lu5TSpkKdt>~TV1L*z3N9Rw&;d=z)%(*!tp5E(m8(iLV8Y5m-mK%D zJM6QUAI{;oq~CBIoW<`8my4;)fY!>nq3-v`{iaaLe0t{ys=;LH6~yVkstOx?xLyyJ z6njC@2baPkxyghM*9gQO6Fx)ZfCR@IL| zDy0EmLM9kk*>dQ`0w!Dbxx%P%W+ns@81{^!143-|6w-*)`x!lJK10k>y|`^PzO|P6 z2eTpo5r;PV5IZh4>aYW#bEF@L^Q!Ux@K)=nS)W}-RRWQ!enTfHI;q5^qGrcpGXZk@ z{47@u+u^kcTKimCYTMmL#?Mh)oTNG`CBt8M3Gh<*q1+9^>WlmPG>3+mH3>xpatm1~ zg4H~OSC{`U+LvS*HL&zr_`v_ef!MO_q&8ogbYul-+!3ALS2vyifaf=BJ{mv%F_{lH zlF2)h!Xc_1r}yM53;$MSD8O0yZTrRoHBTj&IQ`{$eaAPo`CtoZnqZN>dK=axMU+@{ zpj0)??sZ%aoVOabIr3egErmg_d1%1VE>?f<)qf`?VRUovl4qjaMAlp+h1XiN>`*Am zty*E)%W>}@Qo-y&!}~D2H<7l8;_Yf7Jkkf|V~l+@#a+`Wp@%w&JoKED_c)BY*@a^@ z5Q+OiC%AgS0PK@0F!Yo0q+sTpKFeftI(f&4>E#PI8{Kp)4Iuolo^)g~VY@D+($U?z z2r!@Pj&-sQuR!e~=4$~iUv&aVySAJ0RNE{A&&cxw9>@K(3^N6>=^tr%)6uVv(LKb- zijND8CAx!tf~yI^08Pa$?9qUk$Pfpj$NmqMx}_k#)#P>nHT_ASbqdgX=u=J?&4`aC z7Jjzx=kh{WYxYm8C1)Mg3daN9oD{>?-Y72S*&YHOc5oM{Hg(FdEFrK9F%muUh1I*dNS^feTC6@#6k&YfIN>gKgby+mB40;;oobq6Iv=Y8|23kLD^H zp5;Q)Q%(n`{?LOxGO)APX$dUi9S#%V*FucX%)Y@PVJ)b+&<1<9F5k4Rv)tcmi|0bu zbE}nwulaZK@VFzUSDFFh%l5omA zE-?)l_VC7Kp*jCYC6J*3zN>e>)c3nD$ztPE((Mf>h}tfK3O50cqB3cBiOd3KG=dr) z{Xu#*l+GQojQ8Rg(iDjP6o;$k(o(npAT3w#Ic3Gno|?XF(4t8L!;Zdz{(Z8y-hkgG z7;9+kV;k{%W&)N$_|Fk)>jJQJQ&h!>FO)N^e!@I+npCy~h)PAPTgR@H0#<`wqAkny zk;vM~W9p=q)qgCnH!-y#7;0;(UJPnX5BNBOu+9if3gQ~BjR7HkE;84Ft@abhZKi#{ z#foDhJP}I6@DkLXY@iiby^(<;NCUH+xFlELA1f3 zuMkTmf#5X0rZB3S2=(7-qQP4wU~HGPf<2Zy74aNEkO%*8*emSQ*IQfR1E18z>mi9- zRh2sTr$^7t7Su4@0NoCP*;%_v)}j+B<&#JgQZ~!6RUKDY;cG8$GfMS}%`2qI>7QR&?~EuJ>4QyD-Bbyc1zPl$V@CXu$NUzK7E65^@=+w?5n z1`!MaVIV5$fX4I}XYFElmF!gu=R<2%VA@^Q>_$*yq zyy@ymS13jka#M(viX6I&=i}RjcHQa_QA&S5D^dI3#?fJ#2!8B9UfPcMhT{w91+(>u zl_-6+g^;7@7ds3cei4SrvQ?JBRRDpANl>m!BC9|yIMrqEzx)(oj_w3R$7H#isvTh! zbPoi=%k!-Fv?f!r0aBc{-bF9tzDY2T&Esc()j+2*zhbyV7CSr;KXut!0B}%q1aal3 zXBX5u(Ku-}h8Fx79s~Ae1Z#BBNBM)d?HCapxTipPRDT7icdlcXb-(Z*LvLnRccs$W zzU0s>8&A!Ccqa5(-CgrOsf>pRj|`l)x02D~FgK*ho*|kQpbcN_Gmpup`)Ujm4(cz) zUSN&bq53e#nEY>dsKbL^LJ;}aKG)g1(2|z-@#j|Pt|4{hgOz|?M)vs3Wm9{%ui}no z6EPyn>@}aOjvaBBx3I=jaRSP4Sy=?|FCJbxozj%w($TDT9{l4p`Qfu<91Q8wuXwfs z0BeDu83N|IrZ#hN8#5osvvp$HKfI-ID($f+{kQOxD2Yxn7j%Wf0k7D{I(z&IXE2+uxE7us(0z(@L7y(h4QZD}b%V~~dwPE;BNA-R4MCVQ zXZf8i^Os{`DDOK!l+<_1CQKO3;xn04Ln?ybs@_JrDEHbnK?bDQ=W={OXwnC|$VGM$ zxFfJFUi9}48SGAFRpK7eZDnID4~~Md``*m5D?L8ej3Lqe&{QG~g(&3e)UA^Dk>dsC ziHr+{BeBUB316!UIFw{3r8}BOXGvt&nKG)N72db~y)MgqJx0u4(y%~ANxY%HL9?0! zm+x977TviWU6zwb?Z8d3UF@UpMIWlTBLDCS4I<{%*=Ek}Q;fC`h3qix(b{P+g8k_0 zGr`UuopI04KjS=6<0hJmKc+<$`&^;x9oJZ82{_I{j^?*@BEj`!aG;V?+l_mNFKi*T zx`))r4d^WM(ddGv{ko38p}M{j1{85kh*E-R*%S^L(T;3J^CSzpAcQ4n*~E@L^Ms)6 z33zmf)!wx?ztLwj8UdUAO@4O8Jpj-{V2Aa!#x=(R`&IYcy2+|I+oL$6UK2}%-Y0CJhvr(zgbH0OE zK65Y$kZwIk@U!r*7$T}f%6{3Z6t4&+sxD`mmW>TeGA%b)`Av$TaIc=;nz%hirsa9bOMsvPvR zHdvfSYwFJu@MK{rPoR_xRTvp7g~*o~No^faEqyw&ujLt^!{}2#se2A&nlD=fA}#8<`Vp>A707mpuvR%kQ@0k_|IIBmx_U$dP9F z4fOyAKkJ|#1{O-%l%Kl<1sG$OLc#F7bYFlG%w=7NknJaLu?F+EZiel1@+(ni$I6hurWk|hS57~>58YeSB$G&Kl6P`ZD(VcUyQx3emLLITeUcy;XY zjxQ%Fc+76{F0DU3qv|RR9@=>|BrEUHpC`f-0q^*t1o^V=ESk97SnyXXW)^*+mPisx zy+@KZ@^X&%a4mbSNJH7M-E)WkHdlHr~$|^ ztcBN_M6Um+KU#!mayJhcEyBgHg?+|WO3^5|KFJ0CcQfQu&N!T;o%F&7h;og;Kw)mz z;wd0#1PAS0kp>mdZ8f3+uJC9RDM#`^%;aP^rZJp^4&e*-E$0!F=x_}0>ry_-$JtSy z48h`|-_E@qpL25+wq;zwTK^)Cr0U+wVBg;Iij^=R+OJ5pKz_1kD(%=;4VfKdXL)&m zk_A`4;l>+NHv#xdn-*@b2BNhzJ`)&k4vGk=_u#%CZqL=xz{bf7&g;8rxE_5lq= zzf#Z{@fN;J%mRC=gS>K7_0c&uOEMW2`CBa^83?xON)l^VPM79eB8V`8dh5)N6!l^R zRsa(Q*9inoM3wp@!Ab2dIea6h+H(fg?d z^|<~}pMF4Svb4O9WM5X{IAkfWvf+@=(@Kcsrka|a{Y9H}o!De=k5-mdieW_ZdFg9n zmz}M9*`;mz$Z!y%+-Blo``0~T9}O^OOxd;yiJ_q0{;5eqL(+L$vzGp?$QRNHYi3z0 zV*tDq51o~cw>smRJ8{Usg!(%1F(Ul13%>HD3sVZKudY5gRxygL`R8&@#gCL~DG2k^ z?*k|c=66sSRXIVlk8VdT>#N#yVgsG4^XyKtz$1Trhk3A;n3A47$_FzJI8Nzd6U$@@wNs8kzVX zq*+YL63|4LWKT96@skztL*wFfngBkxj_9)%w>{)wKI5Z)`eXm_Btj8b< zl)E{}5$j83xw8g6&wnx(%3i)@8jBij0AZ+xY4neYx1*>#3{@b*r9{!U(Umu5`Gcz+ z8u2oJ#Bf-nA~e$tHQZ4qf{|gQcI*F4(YpW(oH%_H=svdmFqlbj?I8(bEN37n zvVtoJv53kWMTY)SO?|0O`PedO<(?Y=p5_-|hM6YHjh%Ku$9V71j<&6R397DO@64O3KJ`!IR_$lTgfSF4FM_WwKx!48kH>321hxDG! zX95wm@XXaoe=GWYSC_u#7L2nU>`#~^jEQyR;dDr}emwNELHh%<_Jcah+p^`L781x0 z+`qaYgo&@e0?1iP?X#rE={m9}N2|;WU2;D*<5Sp1T?I!Km5GzG$!yc4&G;>=(d4AN zuE4~|_)lHfHHsLn;EMi*u<8u{hRNmTIRpc%kpY3qQ==Wfqr}-)IjgFZK$R38LXR7B zfk}(v`qxd%0qjVy&V;;CP`9Q)fEs%mIv|C4+Qg_2yp@b$Lc;= z+HRr1?lto(aEw*}FUl)+o!J#|H74lX>+Z*zn)ML@u)H(spwEE0n=bqXkUwmBoExh4BwNx+O0N{#_4%!g0Px3W#ITved zM4V$`wbJ?c0Ym&-CVY1srFtEAjciGZM`;+D7M0gR!WJJK1l7;@^%qf0h^9~!%}V-Q z_YK4U{9c07gj<|}9cT6j`imrxi)1F-R0;1NL%L5^Z(zRt;oK=C z-hlCteageq6gcc)8wY>7P5u10)BpCpJJ9F;HENP9BQT1+HLG4I<~mLet)9+{lSl<3 z=jF`a(#H%kDKDI6ccrTsKJzIil@pjAfS0fvh;4yBI?5( zs`ZQbs_NBRQ-gM<%6_OvMqI}Eg?w&3AWgX4odCEQ8+vM>vs5BzK?3!ib>Tf_f37%O zq~eDHd1hqQ>lfhKA-;-R|HIR?dbHu@iOAJ~-xKHndoc`k#(;ZoH;}583&QXNEO-ft zYuSPaDDDzR=Rgx(e-Z{w)+02^50z{7Gg3w%>pTZ=53I8*MLeJf2%yLBX$j!iO)awg zVnPuoHlil(PaYH(!jeHYpsEOn-WF=sS7%ASUnmhxv<3(c+ILhqlOp>vsh(^S8+hpL zr}U?@9Fhc3vrjy71|{I0zMeTBEYtB3ihITvcLZ(~z@K;Sf6mTz|Fj4h z!|&!u6uBY|GxBHH%(1s87R!P*C9#4l0=F~kn{ZoVj;rP3Y@THY5HD1Kr$=s5xjJf* zr#0CiuBHZU_sSZ|8jyR3gPBd(Y3Fm`=RnBH?|B=oTMqLeiTHY^wuC~e`lZh7k2G^@ zA)$FwEe8%B`82R}!QXFw4w|xEo=fd+e_Lm*1(IAZ9r<%!9|;biZ5k0(nqawOV{Db!?@(EJU>i3mf<>|G!702xUMmf6RkeexKQwN zZexQOjv%c@FiiBn+jakUZvOkkN`l*0+d6t+t#)YeHrJVlBZRS@u1_JS0{G2^l2aO( z`af3;6){CAb%T>b*f#Ek(d70VMBBIK*t0*zy|+HO1yK_*v>T>D{OzDIuSE4abFUPj z-V=1`@XZ`vi3bRmGHE4f&>sZGLY;vTYi@y07M(fldgx7-J)Y^GP+QXlwT&~ZHZ^Jv z^01)kTy0U5UlgJ7#^pEsCI$jH1RN(U+hXe-WQhsoWM|Sbd=8960dVJrb^6t;C7E}? z0m~dfV!q|k052VtYMfy+Bd$zB0?+wrl`yo72YR+IjP`Uw{(dOY<7gUy_HsjL_puKN z5AZ=II6tv+caehAcqR9M(imtlgv43{kd=AKv>Sx;mhSY;Qx2BQq^pXrPUZz0LoD=W zYGBupA@B#>G_wm3JlP5^+@iPD_$M24y8ZOctWrsC2>M`@0C-Q(Ss!qse>2E5!c7se zK=S=&d~=^y4^jq~hihMB%#VJMDhsP-?-}%dvwKVN$Eh!0QYaQd8`;F4H&w@&+nx2Moqbd=(`Ki zN9uap9meX-iNWLQziO+k27*t|DUag-%f%~TlEY-$)@oB^j-?S7ee{~*O&ac-MS~_nx4SQ)JbM9)5xih6*_Yzf!*TFonl)bH{Jk$kx6^xgb z;tU2efF6^yH)<@Pygrj}3!<@I%Fa9b{43L?#w>1HA?E}{ZW2?mDLQ6#ug#j!E-=n^vqGtVF zm9g9`*#;MEX-Y53iA?{0r@CITRoSO>%1QvyU6=r-^Ecj;-PG1CT(+r)Q2B$O>c()V zh*?$bX@4xQ3~8zQ`>~CSCA)X90ccdo3yDq59niJxs+@^0W&EZaDH#RW!Elf(NDBc?#O)is%^fsiYXRUSr0l|e*G9c_QbzIN&u=&o zz^i&&^x91YVkN`bA%3ql)ccAX8H|Be<+rn#Pm%3{p6F2p06y8p%*t>oBrNEyREe`a z$n6>LRTeXxRP`A;hJlK#&Ub_fx5un?6i0d*->vH_4O|bV(H%eSaT8*9M>5SdLAnBB z>H5u|umB39aQhUuS(zH(#6 zchv%K#f2KM=l^RM@N-&zf7Z@`>M-jXm4jB3&J?`UA~8}CP64kv&X&SPN_X3dO`&vp zncPQ#%6higBPYh`v$NwHnbfD9QXzIk%Wy`|pphw*VOL^EE@TA-NmEgZzVHn5bgi}z z{sB83Ie#gBSpe4ID_;B-1rA4O{z?EI=v7SK;4F050U>!zjeaYnNY-DYknT??vcUBA za!$432!~T!&{XIu);M#e(BrU@APpc-k;3NlIbf#{o~T^t)`R#6=2f4#UTQ?L*t7Y) zeAd;2z)pWwWX(O|2C$Hx*EfK<_)1G!#lLNFr)Li2ol(~FwfT+YT*Xu%%~fgPSAzf^;iu~9 zj>ylc$#*`@kC}s6FrBzpJ>IXi2m||k&qS=>!7p}no1KjOOteX7rF!wYivdaOTHHC+ zuX^9dRNhHLmrQJp*jX*SDa9(xG0+*&TV3B|PU05})Lpg~Y0xE_wlhrE+DXWTL z_%(W3qH?PvhjBk>L9L9}Ag5*NY9peI(D)E`IpSVhMq{z_D(X%7z;DIw=wsF`pP~Ym zO#b4z`MDNh2u#sd)WM_TSI___!y(H^=p6bl#L)k>&Ybp1xw3P-F)Td`C9|@6EkVSL z8D)p3pjR+5J(>Xnns#AIdAPm@mJ( zvev`5PF~J^oF5dUGbLP-) ztM5qXUKU~-mN8S5glwinn1;j#y1M2NmC#-SOp4?h(B>CGUKbJgqrDaO1Z*o25|?_# znv++3n6hUcGmBxlC|PMLeToc9E+kKvMUg)jP(!uRCL^&odstJXLbS2{`M?cj2w10-8l{_aUhoTgZoC+bJJ)BYnuAT{;~DsUtoW`fXd zW`cQ`(3td>LqBI5vo9W#^XqI#7oJBmt6!iPK<1HAQf7#s0pka(Zay!eqVPH4*mUaYo?|?Et$_mo>Q7Hd- zzZ~H3+|&AF?<0l(&!f{(N{U?jZG9F=Ev{b@8)eBkeqX?=(&Yt3^{h!Zhd==p)bwSa%kb1}g| z=@H0L>PL4DQR$N-=hWycs2CRRVtdxk-dgp^=v`|~70ZP$uEThND8EQnuEkdobsnX0 zNLAnY;n`^xFd3a?R=XjKA8@2^q88VBkYXdUJj_)1$!=NS%WmXlWQauun(TiqcIo>af-3a_Lhc z?7p=!5E+)V;BYsuiq`}z=t}=;?V+&801RIgjE{H6zFF;oVWYY=2lt73d^P7hKya{^ zy-}V2{fZ;oD`IS7@e58!iP=#gg4?u-T`n0Hk7Z1*xo$8>NMHRi zo>u%6+LNd{pUiqO#?<_HQGZN|m)(-UY>{->9)gA%Zj`7gad@bXTGkR(B=Mjt_Q$vn zcTM#8diGVgmb_skEkd%2dU^`S$qcD0nrTF#2^MaV=pE1_TtHSA{^w#ZCF7{(IB3mL(C4?OWz zoI&k^(6K+%24I9vwqG=?E_K+%Q;=_Rl`qUJ{R))K+67n{72bW~ktbAcx~RxnRxxf3 zIsZ5^;UI{NO|zI}`T%O`u)s!-Y3IG@H-I$cNw8ldp0eLGb1i z1AE5(oex4ASVQ|o^Sxgcu!hb(z9i z6O#WKd7vR_fi`#q{iClTWIS``*)pmM^R-X>JG*Td9rAkP=#vRbWqZ|ki;l3Rk13k` zKfNE87wCh-!n-60H^tfNWBF+%;_UPBcrCBxQRkb9?U;8jKDBBr&YOv8)MV0_F?~;S zv#|k6UeR33_}_o?T<(N>{l2F=fW8^Ur-OX5#s`CPeWult>DjwG>~+mt+DGP%;83~t zWDjK6u9Tk7Icyi{gYXRFo3S(nkLt+#I{&2w$VI~lIcEviuM36)ft&kZz8~gciBq5@ z918Mc#R1DT;A(3D+jMK{e!uP%RR8W;@qbXw7iGlsJ0>)oc#Jg7!~UtSo56p{S8@UM z;z!R>-Yg>VR#Zr$NiA+}RJh_UmfK}5_3fJosID~l07Y)(C@9LBWaU59ab*sa9enF* z4SV-7>Eholzg7~lZL;L3w%9z2w*`_3lJmqoU~hN;oG?41xc0c6RL~3zdxvae$(Q;j zC?E!2W%WV<{zDz*xpb%f&>2Ej5r(Qrl0}y;W#JDmaDl}HWrQxC=H}4bEcc#V`bLuQ z>`Q5!OwJEeVfRCUJ+V{Fzev}N*2bVK?!Vh;jD}6EwbsPCohm#@aU0EkGLql1k+TQ8xPchfo@0?53-T za&&1bw4%DRKN(#QD{;|+oodwk@EXxER@eLXJH5t1mT!6cguIDnPhE^NDh*XMgvXL< z)oud{xEmp`aYYTQm1zXgs_scdX`zA>A7V{o6he2h!zHri3!?3Uy*ghGgJsLaV~ao( z5opVM(8F^MaS`Z%HgYTx=UOYk5w%F?KN}Ot5Bur&R;Xfof@~~aI5?qgy^An)^QL-h zot+E*14=uxXlO-Ld5wj$>JeJbg?svM;$`N6SH-#TZMQonQ|;f^+~rq zI!Jy%wq`F4=f!_JX&^*`|CC9V~`pyI?5x$L@*p>*ePG1KL*`7tsmnP@{WkF|qJWHm|{@7A9!? z9r;z)K#s_OQ8o#(DlWXKbeTNx8ziU96`-C=%$-{*cE>qmQ1~sqKnK^Sb>XokzDrVn zIk?;O?gV^fRkvN+i1QFPg5&g=w;zIim)`XDY)j2ZoXE5aGp?_yyz zU9I?IFD(ivMU@WzW_)rZ^%>uHqPFi!v@lA*NplgrL2Xjt0jptT0dkc*=t+>8%2f;? zsfr-JAygB{s3nXVF0Y>s$ZY-yA`>l#&GEohEa@U+bZxolL+~BZ$eH#~u5iwSV%Njg zk9#;=zHE9l{T*54nbZFQnIFRZN-7O7CiTOJRk_jiV5v0_m(Fg&5E=N%u;Vz=J-sU5 zMI(~p_UYCj!!w+qNp_8VtwwA^`V1TY#}_ECql84#4r$uGn_l8E-++Vlr2L0dCwzwZ zVyf^u7^8idcjT=+fLT<)fd$= zaFRVd>Lc_WlM3h_wd)5r8lp$}oWc{pN<`Kl7!n4^(# zWuF<-zI@T%ln@inq!TjuSE?CSL2g#LYHkQsM-7ny#;T2MACsqQ%gQN&q&Fjn$I8RCnkg-g&mm zc*i!pswRu+A?l`>7>t|%Z_iIyz~@%g^EXO;Uy_JA`N=vAYw$uyU94@j$&vkek~EV` zrbc}eFQvo6y%FvsF#)Dg!tV@!k3cnf$2YGtbLrEoqD_6rz2ZUv%~fmb_5ud5R>`JU z3rS+riV7b9IPJ|&AznWd%w~y_&Rx`v%15f!gxgyu4e~WouN}6Et?GBZ;wl^e?jhfV z=zeWb%0p}SOcz2Ol%$_7ha~#BR1BoFrY>DXw)TmBCNe_i%WgS7vTF$8lVJFiO*nGH zljlX!iw<2x`@He}Oke%qXT0g(|G%|uRBbRhcbBYMr8}e={`=lC=8FWqm>@xh)N#>g z*ji);x5y%QHBYR6%$zjSus(hZl}(=_4Bc5Qb#5gk%vb+eQH_QP|HyTex!*v1~x#4GRozdh4nr5eaJt~eMvkk>f|x`uUH@5{s`)OU}B_JQm*k$}u2!d?~mP~`ud&(1h2 zWy}_pnV;)S5rCNxm`lRg z{^5A13IB({4ej1-Gg=^|y2w%8X0#f%>P<KVC`9^j-uUG}{O{Fpm#U6W zCkVbb*&B)C*lONy&G_B});(hJGMiMXE=N_kc_M{zcaO#Ch3}Jo7G!K{VM*sg1WNFp zP!1Ohx>Nw|AbK&@nmFcTSAS$mm`Op=Ej3iwydxiWe!apWn`WBpuOzwLSd6xXmRi)_ z1SbkS>@LDxg;4u)zq?67$4FN0(UI3H-UoA=tT)3INH z8gi~&p=CIildIbK4XRUCu(+EOzQ+wbQ2hJpJkrSzia@;|NZ+#}etrS@wEH$^6n^K7fBZyD8l4!s!#sV_Y&MAF zZh=!oY5O4t$SE3i-uTtM%sIpsWZBuYb=Z=&&!r&p;?LbadAdgUmCvT|jfXs0V>rLN zOs*)cyET%9%%d)oLd%?|_eKo!k>GOO=j+yrb}=H|XUAiU>Z@yd%H0{>OMyeSaQz^+ z2`Ngq^hdHi6S}%p(qC5#h?>`Kz-q1)`)d{4eHl+~((q@VsJRCY*l&!^`{vwDb%Dx# z3uW+la|jx*ugoPr5XMrET zlSXP88)}mo-WB;3Sy=Iue~VImP@KIZ-lB0)>eVO#ygqeN_L2%ezf&$jUS+LnK}gSV*M;G}Xn<)c$3TS7 z&S?%IYi9Zrs6#(+Vju<;21+&FuDgIrOER(#rz*Jhp*U+>rtLptFA%OS;Gk%lAmG`b zQb5pfZk@iWq=vA^u?TeCuUrt39{iC(w07o8r=atDT{}my)`1kgHg`KH8zk#P7T0!FcJbL8 z4Bn%ieuS;z+r1kIYChKq3nA)(?re^07SRUn@kq40cY>is?>|{ml81?@a zA_nFSw+9iJKxBRfq`Zsm{ayYEo#WLqR81h4FoMepN85P$RR+mw`qN z)pLV7mXabpemce836rs@7h{Dcc0ah(O}-pZF(t+c26+H3+nT_|&+t4o~cAF1tq zcyb+;{HQSa)-k*SB&W#&KR&~Wauha7cfjcPGKcK-fyYVsgeSPhwAe|r)1Dpp=7zhh zRoVqV)cQl<+aaS;&Vi0Sd5CL*=Nz~SoqO3p^c@>CYYZ>9I>&bqsgo5BnKM~G?xh71 zPZe7`8c`oIzE7c)nV!3lG~7LeGsklJ_tKH+`};Fe^OQ(u7R4FJ=vTcvv1lvo^?B#S zL2_qe!MSCfTK71jk)vCwJ>An_dUtx2bJvrGZ1hb3RYU$v(e}LZo)+9`lXtBykaCb(I=3%EhOy$=45@K8^5E>~ zkWcJSGvlYLEff6ApM~DbaXABWTxb81N@3XgMT$Y^NsYsQnS$s(I^92=6zlF4qAvl@ zqPwhtw;VA^Ql3D?B<=O=Jt;CdEzfz9)wa&#Dx}j}7At7Eq%PwfP&3#mwZ$t>OMC;_ zxItx(6nu}fQ7RR-HaPHP-0A+4k#13y310Z5WtJL`i`bv{U(6(Z2?qLPz=&HZmbTAP z+d4>-(Fu9_C*|Q5)vB?>;_&cDc7~Uz`!8W(#g3Phm7bCZhIRezIZ@p>pjHDV*E)h5 zyC@k*HC|w=tc8Q*sAUe*k}&~rOHI!iyse?VT7EKSz{X`~eSEsx@OVI;oAXz2ByfPT z2J{&~@9kj-I&#~^19DsA73VGhsyV1PeZWmj6%zMeto+z5zZZpMi_W>Q{ z`~uf?M2E*WKZ?XX2>fu1K$2tPUpREbngdL#kaYES!~wuBK&pI)TU=?YPJ5Ml+n1Zr zmYjB2G(8{=MMleg=-bW*fHkKt?8+*ZH^Dy38MJjZaN$zL=6VszqT$L-*&cq+!RHOD zAp~i%XpCyJVlM-w@egi~**cfTIi+=iRYTBFU;T!cYM}b}Y_hT?m~_cX@xj`o`UcB3 zh>@9)Tj4u^9;KW!J}}np%g=!-Ou0nV`?=_)ZTV0RG0&IM51VIZ^ZHDn`y=Kz~<9rS4^;nhzd?lV7imeH)Fc&oPa{-d-Uy za|`~{NdDG)=`!kb&G3I&qDitfmx70S>-v=`kl*_iOnm}tu&Dl@|2{<q#Q!?kI8kJmEQM^FS>-Gkfgx#t?gavJDO$Lv-z^?ms+gtGf8xRcDNQ(<`E9;Qhg1R*6l@mn!l>(_ZDtgL>R!j9D$03!?Dz+eF4E)7cp}#y-CvG@afEX*;Wdmk)kcaln~CV5mw0(R*sgs%?zbBvwasZCR?)Lko#a#Q zf%xGY2rWga>W&h3!KZrV@<9u4Ohxf2<4w)S3FR>JSyFZ-o@7|z0cO)g`^S6OKDMSp zLUn>6t(kePoisVz6#KaDUIQu<8wfViH~pY;_#uyHU2;+`h6cMagHS$_ES#4At4HoQ z6juI&@5;)QJ8Pj}XU^EBG~FYiL+)*H_FFG(N_&N_OVz6qo}$9TSP)tDhdE;6ft*zJ z*X?{Kd>L94Ay?b%UerFLdOmqK4tWC}8P_`eu1*i45re7HO|{{6_S)tke&~UsqgQP| zFxJ0_xJ8(J&d8EK?{lxREFOy?k08yzpu6+Dc13YBDOg)Fc(YhTd-n&~{ttx}-lqnY zB8NtIj7}6!vV=-mRFCAH#vFf^$@%opQ~WVL%z)0XTdN4G`5A zw!4RBZ(ul)K_wn1m8$G~|1IqEg%C7ZG-gju$qSzV4n7&O{9ut4RKQwLcyAZRqICxN zGKN2DONHY7ksOnuo!)w7Yo*H}{C}==)%3;VyjlNM6O?!)+PvrwIo;=bUU~BDw{^d) zZ>`Y~j$hgN2Dn&hQSyERu{LdTZ+vJj6dk~Lw%&ZVhs?K_l}B1EnFiZSVOBM5tPiUX zy{6(vAezLKE0|?M$Ez5vtOM!DxyD?d5;V(g(!oHd;r=@S;hmoxdtoYyM=UWJ&csZ@ zjjvK=9rna|$f6^;SWZ67@O_Ihgv*|P)Zb?NqqoLbk9_ zVNWEX4Q(CqI}ilK4eAS^DY{E~F%p{BNzgx%c+P9#1}~KecNnQ1ulr@TK}tSQP&@@N z>C}YJ#u@B@FjV+vOu;`l(sAgoY0djd;ObDZNlL|@#h&|s)M#JzO>oqyZ7Jqwm8tFV z)hc~ibtkL2%e8!1wVma7&g0APeU||G))QbJkLG~=^Q@dw6Z&BJiuo8aTvPZ!1@c+a z1zraC3$lb&^{{c$+BFHi@P?YiQ5o-OeTWss$M-G8n_%%{Ao#WB&c{kmEdbcj&%HP4 zz`*OdUIQ@@U?B1M{mC-H29lOHQx#Bt23keQO+IG-W|ncCS4___teh|<3#B?gB)D9> znSrJ~opLdD1KdcO*L7|A6CPwU;EmG~=RBvWf6;jD-aNEHI97;^Jk0Skh(A*Lqo}0} z)zTJ^S|9nJ{Ei$IKVq>8s}EqoOd~`&fLUS@@)BkBtA=4aC3B_e9!;iR#`XMGFl!-^&vV zRpMl1>{*S1QX4pDiIq4ocf!;TA{gAoU>~VapAR>bOGe8cu~mN9E;xv6%~vqEtn2MK zT}B>qro5u~TmS=`r1wQ^NK6yFJj;E46>B|N`$ijaMI7>fm{k?Rj(I7U2$X=8FyVFD z^g{X~>sC4WaGs8twf(MVf`__EDh;vw?0j-uYbCUSxA#Zqq}gKjdUk^G+*51I_ys6% zV3CGrh?UefJ&TY2$9kVM8)n-sZr>$;EfHz_(t)v&jt;a(tV8eHS6uM^ANj`2dX57D zQYa92{H-tQf0=srS={pU(eGP9>D*hcdDDvyYYZ6CU3~JU{5qhY0b3_^ll@X|!ky#E z@&WAb9bw;4wsdo(2sATq%r841j2LhQ6Xp9=@iMGV5#f`;K|klYOFiNKiB9%6O$|w~ zVebQSZ&E`#!xNY2PY*;^m>Cbf3d9a%_4r6~Ky(wW6P0k_B<$TS&6tE}N6G#lkKiuFXsg&+){>Gw{BF%W` z0*zlDsFqiUARNLj1%`$xKdm^}Lk{U$2OhmOIM0uTQe|HnAD}^!%wy*=GuZG6Ly+|x zQ#QrYMtA*#nR#&tpRAa}NbEP@sSNci`J5VX7aKORw?WO*Kr;m>2$G}RDh~Cf>l)pB zt(;|a$(GRXp7A-$Z@m4d{00!ORYbpOm*@n;qMTm8unZ?9Sm?^a5mrb8-819~FpEhB z(n#XqD;V7E&mWc&1m~dfeD!zZW@vK0M8b|OF`l)LqbUi^Y2MV9p9yROB@X9az)p%; z>u!F9LBAo!ghW^qnHbsw`R96j==Yz4I^cIod>qF(*tWYNaP%w(Ow=N^2=QmNgkTWO z3^GiSu`pNn*@iq=jRfnz-cUjM$S1omDZVlh!Ae*Xme*SMIms;e1UvfqRE!56sG^nQ z_}0|s_kZr6kOFTHV%@x(?brZq8{;QLD4rgJTe3I63*)MP`=_nT)PHatns_66ua3N3 zWTw9b>-*ILX?+JwW6?rE9Me^ZoqY>s>`iR2cR;ua3dm?y<7ihx&SeiPQ&zLHf)ArJNVEaTF3C)Z5 zd70i|kCeq2j6xVpbU}qVbjMwr=?c}E?8e1mDmcvxTO}2Lb`p@n-uN*|%OUh{9Y#+d zLRfagR_$PpT`KGKcZ7m6f`#thnhYFLCk8zVqP!83eaIcQ`_D379ky1EV|7b(U`E_> z7V${w?3Q@Q!`&kEKQ=LL+B%5P2Ad;$L3>lmt|B3(Vl@)=Bxy1?=ZepMr)rFeYEbk7 zdRUX`lR$NyZ<+>ulDW?T*x@5@=n_2IX?UZ-b4)Fk1?=4pH+5W+qSyUTnM6jCW=m3* z9n1s<<+Lo5CQ>=)TH<{3s7)6(`i&O_>8d#qMS=wI7P15TY<-vc7F@o!zET`&-#GXE z**zjIJOidokW)lbf;iG~x|;xiXHy~*gH(i>dCXNXuNIyEaepO*ux76Orj}jg#jM^y z2qEJ8j+bp4%cmvJHp&>c)jQ7fYy_Z3h9@J(nAp>=901V;YE$7a5oGVyim2~gNF#|r zYKg}!AU6sV-=*HHPkqz;ph80Z#x_3*(=RT$cq}y9|0WmXhMs1#H8q%oO(ffnfmAbJ zVY8eiHTgWXw<1BZoRDHBu&@Qr0^2+WG?Is+T%e@1Ag`e|_U-tjCX$a&bp7jZhPBl! zk~y{Gnq8hOBPqFrU~i4ws0v3@5MAkpi5T>!YJCPkC~%Oc3(xxQ-vr=q?s8HPQG_KBx(UBm;`c_CaqS!dS4(cMrm?JveBaH1@Sbv^PhgUNqrD=AGU%M+*@qd^a zuP+uQzU&b@mC@mL4kA7vAC)nfzR@l?QXp+eA>|o)vs9&y-jXIMREFwZ?;$?jMVf={ zDbh^hjs{U4B!cFJH38s~T zc~12nK1NF#NC~=PKT1EL0*mJgMlOGrwYTa7C3NLmRMS!`+VeGj!ymIy96-4u&+r6H z7dbuhM$Zd}tRvYFGQK9PnTZfBljT$Dw-@Fd;GwMX<->~5ID_amRj;xdmXlB7bgaR8j2Nmzrz7}Ei6dfX z>uM;nmF4${l5^POya3pB_#x1T&GJQs^YhDM08HL42B*1CQ8S^J$UFOVl8FL*m;bCx zJ^c?V(rUu_NS-94*Er&t%|Fu^O8N*Lyp7A_5*%peX)lHjsQ%dKN?|QT-dc2Q%PzYm z%eDfUC*V#+(Qgwa`?AI9WCF7iqo7goM<&II=cF@G?yzx$GBUX9{9{(ImAFaB89~z9 qkGKmxUJ`^~@fO8u?A62o00030|NsC0|NsB)FAD&8Rx}c&9yUN63p8c` literal 0 HcmV?d00001 diff --git a/tests/inputs/gzip.bin b/tests/inputs/gzip.bin new file mode 100644 index 0000000000000000000000000000000000000000..52e921e4dd55c29036c8ca87a224ba15cdbadcc3 GIT binary patch literal 109 zcmV-z0FwV7iwFor^dx5h18j3*EplaSWnpt=0CVvS4hiyfiuZJ}4NWS|D=Fo2fr7MVTtNZZGXaE2Jqxmij literal 0 HcmV?d00001 diff --git a/tests/inputs/pdf.bin b/tests/inputs/pdf.bin new file mode 100644 index 0000000000000000000000000000000000000000..c8891322b190e628f1ec02dec76a9ef226e95aba GIT binary patch literal 245715 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ΠvuH*SdER13M_=Hhw_QDEw zlBHsxznl{dSk>)gs_Z8UMxU$cT2PCt3zsgshD3i$Uf%6xSm%m@OY6n-G_4t@9s+uu z-#``8dcrBc5z*YPo?>P308^jH@XJ9L+@YYQxLq!um`ytY=%R)bnIwWJuyn0NRUohDV zPm|Auf*3SL1$@LHH~z7~Zq@K5EG;4`k334w(~z%)pH|EXY5k$9;h>Bacrfy!H#T(P zf&#U(eGyxJ5ea}HD9d*CKrtE$1l5|%&HJL_vBvuMSpqb#eF8MF)1Xc3Pz{GS5#?4) zA5X%+RtO@Bl}#t=?}tY9o4rj__ota6>(W&mXMZ0nzNZXt2KX%1xM-$oz-fiFDH^dP z|8ZqS>p`(JuDptspAa~q)gN4MX?u3(z%8~=)|n!oL1*Witx*Z$G7RwFXKOHn@AR!K zr}GsS{FOqSv<|-iQwsTKkZYE|9l8GBpF;kJ$n~F%5ne|p2V(#oB}M!);d+7n3F`t~NmkmxINNPTqT$ zj&xwiZ^1`rhkH}!4dv<2GVW3%p0?Ll0{NVd(MgM-YqbuE9WX#{D`f72FwL&gMA{O{ z^jG`%BFYIMzQ}mxs%+AnVz`n?-K4W2C?!7S`KOn~4p=3YE=Ap)f$#RXkg0+DC;2Dm zb?vftC7Jd6aYgG2qt7VvoliD8$c0A2>OrL@uElGrN3Aa2xsJO(N`NpvwRtsL)ZEtk zRYoR!ZV!9kGi9!Pn_D)<4ReSPp^?VRvg)Aip5u?rXHNNH$ccBvY*)qHz92|D? zY`T{wO>eG@kcR^3-n>^Ukj77~dU8Du(vUwLqBeFc@^#OAe)atlFJisOs7DJnE@*t) z?n0MiE$PfIl_syC{dOe@j78+2!H3T+yuwI4L5x=#+!Q<)7Odf)UVg z@(i$Ar8ys^hNb0CojFz4j# z{z@3EW7G~f=vYF_ZuVuVr{N>};RUS1S=R@tdc3EKEE)Z11X}5R2w^Stfw3kpw7MoB zed6#AjQFeqk*d_O26V#I0Aj-v0CJE99RisWN^*gxgxzNNUrJ_*e8W8!&b z37{O$Pl*)RUwP_gP`e!38>`t;D-Rn8foewu{GBMdB6*)8TR*hoxk47zbo|#xoM@Nlqzb zF4iDCw!~|~vy|NrS9j3k&D2kh`*Je2eqD~BFum3sM$6{*CMg+Csv+`Y?{QdpkU1>% zb=Pk!aYYUQ8bqyN=67%4C_n^H>*5QNu!0DeYVb>rQ6q)Y5qfAy^_H+r$ovSHBp4gx zmXhMxQit?30Ko%d(9ZsksDOf!S@+In|Gtkh6k`}ZN!Ty~L#N9IgkC~sh)@!;1!A4m z$Sl>V#npybWcy2@hEIOgG<#5ChlHE!vF;BC?K7#J-HTJtuxJ(HhDTQL=qvNZ1 zcam3$#(^oV_JIV$LQn7Bk@^pr`TBI2qrEFgF})KJY)qy#IoM+t;6$>ATIKrL`^CZu z7}%-2nLxtA9|-<5AwdLAUqDd1-h9<_j$(N5 zoEm5Zl`WQ)jHX#{uGb^Dhi`p7vGDhT)VSHRm*yjig`4niX&a>Dclg@WccQHhSHX`mX=yV|KvCJ~>A{QZ{qpJR^AWWtq$h>J06KEbSiAk8LQ@en8dr@g7&92e2e?UQp( z({nItqh~c~<5$(FYc_+;mLdST;A4~{Lkpg{DkTp*>b1-6Px>JE!ztj~ni^2>xw#5S zhetY;=-(sM_$jnzE*@`c)L~RJNTH$E)#o6es%$35S4;Q_DBe1OGe)-5Efi)mmkf@J zIilmJc8YLjdfiv#O46^Zx@2tea>kGP!!id;_>;p_A3Oip`?*@zv=U4f zjApd=jeBjvst3>w_?#X?l4_}+0>$L-w{AHiw+f>Iy1Hy;fxV$G-)rTqd*5Fh9e^Wb zW$I6YYBI=(F?Z@uD#a&+F}Ji|71wGp;KgU`2OOHakuCR}p`lqbwn&?!Ni~m-2v1G~ zvl1BuwzFP_v_c!*-?-7%dlF%CwX;2cki*bvTm5ruW?rH^tZKnPVYlDkipmi`LMt4m zJBx+s6jt0yQP^ql?rJaYiq5R|QwlAR>&P$`9=Hv#@n>#sO$J4No|J9sw}P*%KF4WttxCPsWyE2`#fHpdiB43E^DeIrch<0M|z z%jeEd?+eKEMkGy2G~yKRPj5eDZwMwBvH>73mHiOt)|)B!=8O;O9)JeR_qy>$9cCo&_ z+xKZun!kPh^2Ym_=RVaJ;pe7cPb>{uyLvo=6H(tHQ^dRoNO?C*9|vOl{l)TYH}6a5 z#6U-9#C;?Ffb{1g^qmRSQF4p3UfTR_t8IlTf-Ls}c&xns`7TApo;^xShzk0VH}YjY zMvTB7D5Gt|Cb|YXu#IoUGcFR4_^d}HgQnPs((~RLvyW;-8{*?m0KL=hr`fZcBMs^B z0Fg$h;WM;`KFgtsZS^4-1-iwVAe8*fRba>1?Qt)(cWq2-*In}*Nb$=37Iql`H2-2k zvE_(L(XCKi8w$qAK=AKwJvwrQY89Q1nbd&W9@sbk2qh z%L;o}fT@-TVhgXAS1UfIHc>LZnVlfb2zG#iz}P+rDWjPD=2sO;_VQ9CuNZe%JlH_9 zCzG7TY=^ZE9aAjcEMwH1GM}SvfJOBj+fuJ4cHlsplwO3Ujc8L`d{2HAk56jV920~_ zA^)cZp!7f2B8^-g-=GLsf9p- z_8zDTVwp&;?`beq&1#=@`HcH@NS(;pQFuOs+gIE~@W9u@Fvm0o2VI zsy61r_JNF%HgsHMjoHvkV89owA%$g6;r~s#h}6Xq=zbr3>?A$RBBPuJK8ElqWNsryY%=0+{;gnw;THL$^xIm^HqgM z9+9sQTXD5UG4)m%jPilosZ0XS!<0lN>X*@Hh~_*;AZMfN9tLX(cG>sRDUwF&5W2J> z&;_TUy8``a2t+{XU@rmi>-e%+FUZLKQ}GMv;VXQaCA@f7oc#MD&gbD4XlQHZ^Txjergd zn!7Kgb1k6?Oxz^PVqGz7r7^mj!q9_3pKpC;9u156n__O#6VV&mZ#9aayMm>Qfo>;kT;El3e z+srfWPi*jcg-?DBuvN_4)pr?S9=8u+wBwg7-93Wb9|8UN{XlB+wSoYFV;X>xu+O$Y z3_@FH{)(nq8(@{S^oU18f$C%wX!|7E-$4#28?6u?$SSidWg?9DFojL+!%P_`Q(db_ zCUrYN7s2K(UjPd$N3>!c%*>1^%oYmOtKs7@lfJGYSn6QTX5xLIXDT@%&wf<&X|1I) zf#Z~x>mr6_cA}#?*29XD@WAnXaNRLbhJ=bHA7)h?wFqzPW{Lj9j8~-6<~H;M(|vYT zs?BgE3mR5G^zGpaUhZeTb67{ZL2)zfPU{4P#gLyDT+U}SpJJeza~H**8;f>@lPoa- zqYbE9C@#RNip8~XYSfx!*R3z$2so*_r>A=jN@ki$9;xb-{qIz zg$Cd5T5s%Z97h7p=o12l#C*g03?MKO3`T-M9x0hYA-X)h;pK557Eg!Q*C}-Q%e_0Y4{+GIVNsc;-x{RjvKQh+ z5+5cAV!tKE2S1aqhx74uwl9SAdkEHgL@wUHBDRTN0?eF&r!VQkQvuU^ogaS60=;P7 zBW20E2HYO%%}_D&o1@lb6R&L0G&FG_)^KFJ4AB8Z!Vkr-lZhEI7>lnff;E7#AJ7y8 zGeK0_c}(mY7Mxh2#DM}JH)*c56w>;xSA`0E&fo3=-JQoCsllX&m}6#qx*9~$3)X&5 z`D`50OD5JuYjxfO{Kav8vgl_~-tKsuE)O1V3aY8Ar!HgGhE|#v#@2qWKxpLp` z?ni56K{j-J;_7`C<5!AiK)P$zh`f2FPH zI3K-QHdhgs6xEEr3d4@T!h^y@K_~l+yJE8FijP_I5)J`lUxyZrZHZ;&i9EOaUwD)Bj zaALqglx2I-M@|F;S)*CwW{Lqk7^TJJ9jq!h|H)m?+p70SKHM&4@|j z%y~_p4DyN=d3VJRIGccp)B({tHJ&5LzA%0P9B<7+#8b$GZH7r8Q-0s!09+>+(o$AK z78KEv>JxGyaa;~c^RVFBIiDNK2AFyvz#Iy&k6h||(6$;ORjzXwO7pP-VO1K6>XCbT z2ANbHbtSZft7YOt{v3i7JJp8LU>E#O7xGdpb|8GjP^49OOnqIBWhaY#EYuW7Wz1YY zPz-S6V_ktj6h{*Vu#owFJZ|^d(yN7(Cdze;iXXED%KinpLkP+; zur+;Bs0{XecHGY`N1;g^SWtwH9B zV}+FF0#q?8QHE^D2@8X+59d6tclTXY2d+C(-BU8>mjF7 z^dZUP!sVS|aTyy|*G~;7nqwDLa5$cWswNs3G=w|I8gi!DJ?76=80lIwqF^(kZHG7f zhJ)@T550-9fPq7B(}SjgA~*l3K^~qSf@9gwz`4tbd7s6R^Sev>gxHO@mIjo&aKb~; zHlcuQr%x}Wnmk2Ht!ZKlvbqhue-Xke`4Xveq%B{1Rx_r;M7y( znf%#0`jJT^xAc|;$P zGIPcK>YGrU1CeSMNZJitfk8;nx#at-X>XYY=CGMxQ>wn+5U|I@;2v=ob^BmU-0=Bp z?oe+d8^b+x_@xP*YuTH729u*qj=WCHoU|9W3`fw3AAUpr;B`&a+YL5RGoDhLu*dC$ zLr)^Y^agC@iq;N0b|)zI+r9L5YUa#Tv#W80*i#;=fLY7+GJXqR0ei#g%xn}DvuMK5XrW%g;qdjNBEnb zZ7gBMKHcO04h07QPeT4Po$=RD(`^5FYWlzEBqb9kI~PYI z6DJ-XdQo?0ab;%%XOr*u;>rvJjQ>^F^qmG1v$J*n{_y{_L-{Ysi~aq`|C*ZSWc`PL z|KD^*p#;*m&QQePJwWK$LANlbOq9KPVj<6N_;Sq1l3UqnF|+>Rk#7C!MrGNHSM}3_9XjAk^v1{a&vgMOip#Q@nfb!S*L8Qu&Dzuz{{A1t-YX92bheN| zCXG@9pjjrE0uD(7w{)LRlu(PPZVH(G!6!ORz{|=$hS#X>M|XDLp=|MwVu^U${W!M7 zVEwDTBzQjCJPg0HlYg={uU!)$2scCpVcPXg^*hbGlzK@hu% zEz(OB#Q+#TtA5Sz8;tl|fk&4f+jX;*U&+OBH&z zh}M0+t+!IX`T9L~t)CE+)iXOw=~F*|MR?#6lqNW&JO4w|oOE?+p9gT~!y#+NQ2yzI zBT`A#{cR+1!~_2AES*$iBv8!tOC=4wkc=7f-Q$bV(aDUa?}ul3c8z0ETS-&n1)W?V zsk>dwR@FGVjzx047Xq(Is$-~{6r$F#kheq9D6T`A>TPI48XnWy$;ydIO=`V;TARD2 zzv~0ehBDl(n|Q`;@HxFY@$Z88kNzq@LQECd|{Onzjda}MlM#* z5?qw@S25=|@2u%6CQhPXx~=ehf?$sy7aC_$J!bPX4*m>M$}499zAy%+m_3r4a{%yF zf(d^qzA7SBju5w0pH}Mmz08I_MGomR_TpITc88nll}4a#$)RR3`5BF#a^!(O%nSNa zCYdA$U8u6=m<`MfP3)S-sG_r|-V60)V3cDfBx|W(N`Wx*H@VhDFLfn~@!$f+Bv=ac zW4^DrS9V@K;lS*u+EX|Y=4lP(J%P{zNhC=_IL68*`oFs6U5dQEJ4Kq@JP~)X$JYwR$Y_lvcyhdci@t= zS+x3@P`l$i4V*WzFU0~IvgHebJjS(^Gk=;WG@VHkV~D-6NAuS6YeDyChyfL-C6vi} zMMVQz%=&s*DC!^4ej%-p4n}OsY)#fmEu-B`(^yKvOJjm#B1b` z&I?3`vX1*1ZARBl60B2j5YqRzCqP6ISCrMnRM=!kX`iyLhGC$XO>7??(NxsT8Y z33m*iA~+4+uRah*Y%3n?4>E}!UrcJFa?uGttdW4yJk^5ib6T=OI%-ta_6{R@ObN&H z^LoV^UgzB^hw2J@RVk+m;cb%^H0iZIQIhk?VU)-~XG&cFhZf9s=(+)fe{zk(7nCer2`GdIPK?@(z%$p zYh>{}5g~y_-7KG3Ug?`RJWv8Ez7inX=$haIsh^XE!C6 zG5L>f6mUk7r8bGVEPUz6(1)UBMa)@9g7@W|7h+tHCQ=eGAsm{{uo}?~y7E8{;&bgk zYSKmcB8e3Y+TgrCo|GndV50g|bCMa|m}{p3-lvm;b;G6@bq5#n=fu%J#P2N(M~S(GN+vcvFv*UShVU z=H?KzS7pOnlceW6QdkP;(NJ}bc4zAUUAX^N`R4sb2)FqdI%lDT zsHRO5wK*fT_K-{rE>ZtVU2$WjYU)=Mv8Li9EnBpKWg=Y@KXvww>07!EO}51{+k|(I zboPjgK|uaN8NBx~Uj=a+@1?096axT-io5kckxOiU4SLP?pGU9%4Y~AJZ~XiFDgU)X zV&h=@-^X-W>e8{_PE6Ok`htb>YkQ>gsG#Y`0KX z58a*B?wNQyNVJ;)cydy3`gs-HBhi;y_1D};I`f(xXndJI(nJ)MYbOS+G5C@KE_q{2 zVD2gNF3?~-nc)5K6O3(mJhCh@Dki1Pr)Cm zS&aF9*2+VsqtWicZe$;}UXANCjUYE$I(spFE#ODKIAwV8=0@=vGiy>_W2XM3*Gk^Z6xYr(vpIahJGs`{tJN* zQnxQ(+OIdQb>79OVQ?Sq%S{CcQy zT~1DvOso4c=04Q$&leVK>F&MKOTL-`7=Y{pma12TRdC!aIMbnD&d@DK!nBA zcDin=(oHM@qxZt_WA{;TR6!yrq=c)Xgv(N@^B3E2+C*wf?Y@j%(U16jo^gUi$j%S; z!lok)=eXptte3eMfHq=ah>(V|kCZ0dj**NTD-C$m`4DfD@T-&FCrv{2E=<)yI*|Mx z8mNe@I!A~c?lANi30U5h1n{gmG87MVAZ=U&f#`8g@TZjwLX2jLE>ic@UvE3XLed=6 zgqWO9Qoyxz(rhPup#E4e!!98T!aNqSatEz5(M`*P9V?(5?4Nkr1TAbMT0mB8LJ=6S z<=Vk?-k39mRw_U9kB`y$Du3S|W5u-1!?aQ&}aB-0FDH853Bz=^e=|O%_Tnv#9HG?xFV3AFNBWyCWEi8s-lSEklaHHym zB+Dgp!t}EK#35~B#9FCjw*`;l5Ez(cuRD!(2se>$^@9QbgT8{t=4~F+A<1>uh9uLx zV^*#e?DSm2teE<)Jt>G5k_CWh(HlyOSeItqOeL+UGW>h687dm}SqpLH8ThkZaZZjD z9wuBo7KRFgHN#DU#4{sBB>c%(%b>^!5|X(~DSp9t!RoLO^r?b~Y4{B1mcxja+LGBO zqkp2d^%VLP_Im%`hQ1&;cY(bt=3ya-dnLQ>yPa{W2)Fn-{Kq7dQhPrt2XVPVQvqw# zTNf&9w1dnam02Z%k*hAF*7T?}UJ&yGCMi4gpKk2Ao226$Qh(AXyV)u{-(A0~#B!O- zzqUGkzFs~$dW1ZluW&p5++a^I#Jb<@qwDY~K;E_-UTM$h@|eUcB8Lt(Ocv6@i?T3l zVir6YS36N8oSKU=2*|q^t<||zjdIaT0As!|QcE~nu2gvu3E-qR8Zca*e%YA!+Ya@M zMdfwwo?i<1)4nKf$L?OmuUCs}@CgW)%muxZ-HP~Lo7$l;q54vEIil{Mh&U1X(6SU` z4W-_0aA$a$RN}xM@L?*0k(2On>h~K<>qjz0Rp6YL7fkcUoVyjsW>Qux%hzX-KL)wVt0n#@VzEl^*f6!G7+i{R~l1Wmk=)YlrVs1bS%?9TLQ8 zlxL-S(q{<-V&5}xa}M!0watp>8m4nj7-=!Ssv)0q2$02UiGNaQez4gs0p!1J zWr^7f0Z!uVX+PchPuO4_j(Ie&q^6xSBS12t z)>`WeIg}hmj)+ZfbfnG^1_!mppI?RlHd4+u3xxieGWct7Xtw`64*hQ^ga4C}@|U+J z{{8s>QZg_xu>Hesz`vO)dn<5XQ#CikrmQn0BpoMe5=o)oZo&#lwr%6{85OO?C@uj7 zq{;jB^3$y(P-E>yPw24`2da-Z>ocFtP8 zhjG(-hckd^vm}!v%o%);Z*soQ!X+C6PRIW?_hfnLaNw&ZCVszgMaEnk7rP*HDObJZ z)b;i_rj2Z80CT5^y>7$OaJR-TgG>@uoUK5?rj|A5=EjQJ!>Qr`7yURWl+PCj zJUI#0jmXePt$7HUMISqL^5@Dzpy9N`LJqN6tBe* zD9j>_6PhJ<>^Il`Wj!15yq#iGnJDrzEu8sq$Kb5`G;bSB$xt2f(h)of7LW&4>ZbS2 zDSvsam^4ZkrO-Nuoa9iXn&*l}!kTE4&xxJZ3MaPf<)aPXYz8Lr(Pgg#H>Ybe#s@z% zU}DPEoePS|uEM4&=3CP;HbgV`wxKS4YG(2}Wx|YK7&V{H?rTk(a?NB;{W|jT;S-#^ zge~g#*B~CpGO4>5A2h|p2V<&(1@oqCGn18GYB%WZ{ZE{ugkFPU@n{?MaScr@v=LyL zOAgtF>=DoJvKc4~+U~r-)-1QSpnsY!Z99-V;a3Ki7mjNvHrPSB$cP+exmOcQrcSD5EFu`x_b!O@L@ z#alG))DrBVSBah%(FUW>+Euk2?Nr|-BgR@~5J(v7W27;=?#pqqBV@;Yl?;O+@L5$U z7{#P&>sSUF*kvzIxhR)LrH-a)UI+z##Fi1{36yqZV(T)c2!xk4S`@Rap=t9C)%`3u z5O7_oGK^>i-sxuAsej-!W2T5mD(P3lH1$nQcJC#jr(88Q!bj*QQ(b{HqG9^PL=$Bx zj9pTh;@sy-N9tiii_%-tRMY;I_ioL$i}ApW%jDQw-rLm4TN4x_xEcVd7WYQAr_B|EcNB7hd8Pz{rT*#cOV!??Pv-e>RKy$<( z?exMy3h^SRhy69*4Cc&Og8)A<48Hln3w9nJU!K`Hyx3g$4C-W)dq{+K{t5C#<%Qev zIWDByQluub=$gtP<<__vMOlMK#S3OtGrX!@97XD^VzT;)^qR3fSwxdJUk~`*xv|*pPmInA%jkWuK@%=Q^CaLKv_kh2f~JS#e3kI^pI|w zYljOt0I-q7^4&Pzdf7(1y3d>pW9$hyb9r&EUD)64IDCA^oo}Ljw43$@j17%6iwY9J zXUY*5%beiHG@FilgY^nXeuDQjX_umYlAw`3jbGjpp^IQditK_H%k+Wd4Zq?^dtE-j zL+|6r8wy~O-wA7BzCFr!1D@}>|G^kCiVJm9__?jKxD^okM?mi)@@5C6xun> z8A1^7XcnHga9zaY}8=8+31am+^+!&vzU$hbG0blOOc!QWwN6ay1$~ zm?38yqoRVI(mb<%&KWXg$bXsgk|*4oKDhYFMKBeq+V{~eO?s$yxA`#}?H;(AlHnvf z3Z4KmtUKTOm5?`-)z{a#*}ZJ$19BJSq#S0*DSKtx8|F_Ef6lbxxJaTYrh7gct{RUf z$Xc@(Nw|7?pYIYtuc?&N#g{kJzU`fTP`Y4H3C={(J|!5dK0}y`Gc&$qgqc`Evgo`~ z^QeQvetVhyMphd$%T>DT$P{-U45bLlvzc#nuEDZSk~i05Bo-!!GJgiM0NtV0*b_n) zW1@JO@IX4x0%_2MCq#-A%fkXORt;+e81=%iEz--b9RpjEqV96TpLgKxSfj%tX-YEs zm44Sxf^wY!u3V``n!xv4@4oDdqFY!N%=WpLaDy8Wh5fO;-tVC7$&c`X%*`yz=f)=4 zwF?RI{A~bS!fD2v&B>GX8_T6ZJQ(_TO7(9g-2&S4heb695xih(fWP6c<#Ik!9?m z+3F@|Ki;Rt*Fx==xkYC^-OS8#e7-|%7{Ro-C)56ZTFdnuevxj6d}{(Z4b|7jTpj3D z=L|)k_KS6z3t)xIU5zq0?VjrlwAg(%=Y1zljW^dzkKX9TZf?s{*r$;De&g-Gx$(~1 zw$7j588Be;T>wc=`Swb;mbiH#wgLEUX&~T#G}t)=K;iKokf1&7Hj@9n&MV^P% z-jHAE963R3Y@_S##Qex}vERkaTD9JTWnFUtLq;cCOD^AUHr2kw)8Xl50T4gGIpDLu zH7;}UWXS|t^MvY{xxaRRMA*;WwTr6J-aSX)!>x{Lg4~7J<@HE}sF12eNik#-KABa@(aEeY24qz8>kMcll^AG>A z2MfVOEuw&m7Tg;=X>bGdO@y^VTMQok8PXt|`8pPr-c$q(6KghFs7Yq>holownz-Y_=zQ9n8^AD083A z{a`$W*W14ZK@7!d3Of~?#gg^r1Vg1Gt{F&fjKK3n;R<9YXI~PDP-0Z# z+N)C-*eY$xvyJJFTrj5sXB*Ci_K9E9G4e>-bMO{)MzZ!;DrHbcH~>~-gQOSAc{`K- z0YZ}vBhQjK^yWhNfY?nPA)L+f_)^Z1cWTpqhkrdTM&Y>l)kCTfaK0}s!0c|8f(M5l zkXAO$NG^Uvx)JvsyB1VuId_%4&q@~(oSebl&+$uwXE?Ej<6OY!bMFnu&-Qe5A96bW zU|}R_cVv$xg2IH^7;}m68xr|g-=o{L=5jh8hmfS>@z@o+HboC;xG(%qYyhClZq}} zI&Mt0s)q{&wtC;2)SXZee+`!`gH)K9Vj1Ok8S!{5BnYAye0fF1TBKH?1R7@hHFRez z;n9{b7Z7A4`D#xp@PYU~rok`4uq2*#eLF}Ubw*T6)W2> zGZuDG?4zTOIB-Gk?}}rM>x_cGc&f=fh=$kg6NFqCeXCTWdbAUobHygEwRwPOK}+91*I<6Exx+Ra)z3>5xx#s6LR2A=NgNq=giN zB9HfLjq^HOi?nTgH`C_Pt8~oM6|qf$ve8(QULaj{ES%PR9s)~vn}L*+bhmY$QyWUeX$kq=4C zATNc0s#*%1j{q@gkX%fv_6Kpp&2TWyjvXlge{ zkCKDSn1il5x*PEJNMdy~v>L{F8nF<#mRU40Zd%I_fGVKnHmyQ&>C4eN{HiFLU{dNMVGx&wwf(e6=Cpc+3?0oZ1>S?-i3 ztTkKTorUQy&Z?U%#z>c@Z5jjIa-4E1j31Kg1BhxmV?FdGtBSnoR4Lq)>>hVrbPmgX zp1D$(k+ovv7UjOYhIKVi4+gl)s^N{*PnobqnyUw95>S%L3lKlb&2ygx+*IUNHRc&R z$Wbko-Y2Jmq}hO2p(P4!LLN}xb5KdfISNwt1zd2T|1d>Hx^^>GwT0}C76<$yz{IT3 z0&-Kj-lw<*-uR8VfOR?UlJa~W;p3#IzvONcqGh1A7=7}RPA4LT^&H>LR<$TO@1XUe zx*m`!N>tq{WX5S-Z&H`A^cD0}q=8&24yyHN`utUJB@|UZW!YDwArwpD`EbKNCiO4Ry@+pQn!h4Po?`kGKA3pfMx!Kh!2Vt9|Pq4uo&7D(ziNE{+UP z%8NH!#LGw9WgTjcTXi{ciX>D61e??p@z0m(g=F5kYkLB?7Z3e35A&4C+E4#4Lk$Hd0yz;g?fp;3E~)3$s0Wttu|Bs>+g zffjh(@^b>bU93FYX7G~0=IV7sv?oC%!DVY|2JBx^zR&{ZZD|5-@Wr)XmZ1Du1(i22 zZLF4|z1^qHawuY>0CO-381RIf2F9NpIQcK+V2NlIp#)I!`Pvm8A#4;xilCpy7&(d1 zek+!T6-~(*cB3`We5JrJf);2LoHg2MvczjZP6o;;sBRTBnpx6lO)f@mziGX^fjfUc zJo|V)KP1%M9o#mq!i&+}j5=dI7@@x&Fxn)z!wy|N5D8GU&Fnd@?J$`;Nb=BdPmR7c zGT`8vK_nF52&D>?;+B6xsx3hyC7~~2cc*-4A62#@>y=S85w3&|!c0+?^IBzqLT`V1 z@)o}p+Pe&MynrId6o&WhMN4;Y@ZX#P3Z9~Ja08ueQZ`5PiZ9Ou{$mv<2$F-coD1kVN>yA2c9rht*p*gn-tG)ld48g#vz?{ zA!Id$6Qxh|gSh8mY7}dAkkx5j$wB;xpvNv9_SaQF7=XzW!pnJ5QsKFx7Jed^oMe(1 zy+NsUz!1t+%yuERSkUeC#1Y*w9zNoDivgVgtpN7=$5n5&5|3U_%@C;1{*_Z5lIh5F z*EIC?+^pOUp~J9XiIZUeFYsqBqnm!bsJ*3>NQoM$EFuws4-;%~aX=3nmmBrku(=&l%_;7?8%WFgh}#uMfj$ zI7EbG6K;^Rw@=Qg6mE|+pa{nrP$06`AyA<8uF3@$_q#`x37$ z?j`hu^v#(bvoQ}tiWe$hu<*Id%yBTwwGSl7m+KbA$qjTS$%LnKpe=Y{-y3)YcAFzj zqCu(Mme-CXYMUe0x?nLe>=N7buV@ES6oUvJcB>ZTRjAqB;4+W?*z9L+M2VHld<_mx zWpDS9vt-7%SUg`RS+-=VTc>j#E{&a@7#FXd?KCjHWNDkx9eo@Q+5hwK=ii1a|5j!0e=mCf`+q;nfBlMz z3L^pIUs#{}_v8P|nFS*&=RZ6L2Y;uL*ToRN)5vM!ziUYokW9*1VFqGsiX@Z^O%YHe z6=(LO3`ygGS|iT??v4iJbMu+IK^XDR9paXv6o$-ST^bd2a4~HEi(TCD#!lgzIwkW+f zWCZ%&&;Twi{@f+yL6Bc|Fg$A152#)P5zTVxdPEjU2tj8WN9nW`cQAZO(p@;cheK=q zvHQ0bnxK%0(Jv(l%T@u1>?6!YwAzUG-!oV!t6RC)+Dn6jHWct^N_~Wn^p)SCRFQLQ@#=txf!aB6@ zo=Y00qL>A~YB!7z+bEV5G?eNqX^h)-MIFgcI6X3BfufaP)Uxna{J97UWt;rg(sx8P z#0{b%Nq6=PfleV;Jbre`vx8w=mWXT{gd1TPPVwO6&cMA;G|6PqI*-#${t%7d#SZGT zZ~%)*`;=^$<|g)U5fI>*ZrCsfr7kEIXKm@P@Hs#WB=!(gthg9jsHGk25S#`#Cn`x6 z2(o^3rIHv(SM5BsBjzJrCi!!kL4ZTps_Y%ncPO$@>O=e{uldJkQNv!{a$o{8-krFF zmsn*eUyW~7Nv;w-<1*>!K%*YlIXM1?CYfScRJl@Gmul~nbj4cw_KaslE*;8qDbdVq zPSGE9OV{bv_IxFo$0I*@^icaUxlq-I+MLZXsq+=#p~X4k7c<-EeIs%6*krgJ$B<*4 zY9#h*%mbj#_?~8u6ns*t3zP-MLS#ZcWUn?Q56u<-=wAK$FS?2fkHq}Q!yxb2JCC`2 zA-*J!HcvpF#j#%bbW~Y{X>mnzrQIl^!Q^rZ-3Qt9Oggls;mW0paV;X^+g$q(*6CNC zny2jH$s!X^j5T-F?oK=dh1wVD=x2QiEf!T_w~bjnco-s2WPd5l{;2he9L zAsKHmBaVV2TTg%o)xJm5hK{Wo3E{fS*P~Esxo+NA8(%V^(<`aApsS5(meMgt%ek$z zFJs)JednB1yrIsZKS7Yg!xvnjg`d4JA-wJnG6qwydTvUOnjdr?4s5*1QBjq8jGko@BKIq$ zUGtm)$*C`|+KWO>2?o@sv|!a6dMYdZYomAaWwhp{x*2R^Lj@NXQ+aSo(y6ITVRaRAfZ3;TOmc zQ;WwATI99d(`)PnG&gkLGqB};#D}|y-GBBC zSJS-8RK`E;3D~jUh+5Qp<{%wxj;vG9Yo0rmYe=#4b${10x@K%PHJsoA9Dnoa4*oZc zuqJu6^iM8!_P+*GWdEgFKc3K zVeo(bhJt~kiLEmMBlEv~u`~Y7!&mwS5WaICf8}NVwGQyiq zV9^e@`FyY`kWW@ntV<&`oWm=yz>56I*57#Y4HBz@w3FeBtV4PrG(#M(=`Gk$I`n%s zp(SR60JK zpBe>TQ!vw^ZR%WOGs*@yCgk-4oatEj^dUfp(U7EDD5A0bt*Jl0(`chAicT7wWfXJ| z_BO7_0~lbhVs{l;khe7yy^*H`k)`7S8aHf(FmOP^J4=PCQGBgdQkSfgvq6{o z481c4FbhrgbJj8Ar*q6~fqWw{Z+!?_4zuA#CP<>1w8jt>4qlsgO#?E6oc2e`$_dk^ ziMJBjT53+B#jIausOn@*wXJ6ardK=&!_4-{JYu7=ALd$mp3!r+m%q1Ps*SF0u95kn z6MFZO${~lwz!&Do!TI{oA(?H;W8MH#T9q8RXpS^BD&Y1M1=rdNb3BJmJl&(H?}zk~ z6U}0ptFfLjJTP)4gC)eyM&-q5$qc8<1~q5M=N>VowSODirR-#VVs5Y9>k#DE;KYaV z+@U#mt+O!4?Pg(}|ARJ)f6K!S@$QO4au>wy&al3y{s>!24BWAI|DDaix-TJQ1VuJ~ z1Xv2zJpm-dGKw79`?kvC1s8_1!$BK-VtVWYsTi}I0C-*?cR^x-^vpJXQQHJ@>f z``*#IvnC=#WehgR~1Wvi~RE zoN@HkP4{qGe4tfP%%{j2c6?VQi^IFy>j`>2ScHmM4J>5r4}9-B@xku#qwE(Jdiy-c zo;8@akUu8R?<>PBZc>#UQlDo+F*oHfizMscBx%xjj1b*nl^+t{K6rP{zmB1i5%Ykk z+6R5`OQYEAV0sO7$BdMc1s^(4g`+h*3dO_}*|UV}QkU3m#y2RjiX$H|IP6x~t~va{ z#yI5zW%GK4yB-{R?MJ#vZ@yWEn@PTLn1pr@ zO{}aCe_=|_pi-ftR`*ck|CrBG^lgQV8GHL5o4eJ7yw^e2_}47MtJ3GivFOpf=wx7V z@3uE^IL4)7XBSr+fpu;-CAcb4J(m`6V1nAXW%S`^md?T_({1|LE{)P{3e9IanlA26 z>H5jZ&a)u2F)#MId+YsZi?tWdL$d`>!9LO6w%?TFPcxVlX5{Nw?Gzq;MN33i zoTGA9_T+QxrE}{U#O6b_IY1wcha><+Ie|&vpk&yRbiq;&#uW%>MTFg6MWcP#!7WUU zaW%s3fb$^;(oSV)P7{A}k7YA&UCh7OxcF+J!L5V!?SP>uX&NBXhXDiYV4;4(BWr4b z!`L+?uiSk)s^ILKhjq_84MTxsE`x;? z0A27@{2t+s1RzG=rB)pU=m;iif=%`=uvtzLIK)tn+#Mz5*NpsHf&a3WcFFrw@6roP zOks*jvKVHD3Yf4>l=n+rDkxp*oL(;jpHGw~V#N4CENH;^S*uT0`Ibu9(E#p+L;gDE zfoWYT;BWf*==1$YB~MgZ*pHR;_ReZK7>(*T7&g-h^mwS-L)*r0mIE}RFKn3=Rypg? zl$~Z+mAnG4$B9U4<4L1qCkFN?{Wg5^B0)F%Fxfn?qZ#Ed<6S=B7mwWcE`6F{OiC<} zYjYGM3R2Q0Rvw!2Ov6C?14l@ttNOz70#WQ)vXyvbYvSee?(%6G#%xjG!AtX*DgC>3 z0|&+e3iVq$*?3i^I}}`h4YMIh@?Dw}MdoTyL?>H~qhxM8-95sx8(uj^GWg9u7`X17 z$jTjw@YaXH%pw#aNGHz$(xDlYcyn<5-~2Psq81;2kSD9G2N47p>-+byWlnJ{ z)&)oar3JYw+>TwPu@}MWF95@^Aj9w8YBx%MAm{-^08$YC71sS{98v;MiNFwVOIX-tLXs;6k%q2S z2VZY9Q!|PL#q|Pl=!DM3MyDU%?npA)Sw6TNvew)M%hVK^O2)Fs!{-4sG}xy@))))E zZMn^MEdEbO1ibLR&dgdtyj&=^>o)_CJB#~`CJxl*0}*fhVEbUI zKc2^(4{^P08VA9S_}b_Ms67KP%!{@>`}3ymypXqanqY*eZ?0qJc}7(< z#`Wn8)azAhUil|5G?!MeDOPl0Rr5W{Zlw&?R~Y4;IcV{2XOtUvvfM&+TO;wBoqUj) zKYqFH#e4~7xv2N8m}$gl+Df>v&=;Q!7yFVsf%OIU_0OBvo^s!xQq=~|XONlgr(1|I zGWDe5lkMjnrV&4Z-GomWWZH*{E!tBj{Zo-%%P1`ePW3Z%Qs|XzkT!3ifwy|bYsw{K zTNxWCJ!D*A+Qy!Lgs-v54=RQ0)M^?`IsI&s!Vncd@z)rKmOCZZ ztE`g58<-k)Gk`C%cFyi`Tb9v#siLeb-(}_LocKO;=nF$#kkf0LJYGCKVq2%9hUe(; zdiw@SU+Ui87C!Ly@qE4?hcHwn=xUYRt_Oc|H+?8ne0+UB>IwyLN_R3oMy`lN4sE-2 z2RdJ{(xm-~TmSy^su68_oq4jK>>CSawvuEOQe)Q=n|y00Q5mMChNRrOZZ_FfjgsmgiKQ(LCMsptqqBEXFjtf>?bz9K~!PN#)f0V{D9R zib*~DJIP2!ws$FhNmu*KL9o)8w)Ouw4~L!!9KFLiwOZD7+4LXRxUK2d3$e!-lxWF` z6ueAR>sOlTgdk@HT0u53>=Y)ccPM9#;wG0NPB2cK7AhwTeHyN>s&Z8>axl<*D?i1* zD+s>-uB6Jw>&v*I9mZ%=M3gUCl2}<>VVeh8#pBrVP@E}(qv`vV_-t1taFr2H2kVGm z0a2l!xyNdC>OOO?DVv{~^n4*42g*Dx)*o8ATX*h161PCmkLeeI`o%#hUXOgLAMA!| z70Ny}E+o(}f_sIOCaiu2FFMP#nX}|-j`>~9?$K98+BI(2WA@S8u!4tKm*e4Wj;(;k z*92N4OyX<(Z9SQ@yjw^s}p)M@-1ooY!ST_Gt448`dFs7!KNT(B^@ zguDQ-xzRQz4@*=bD}#H$&b`?@bfHK|w)f3GTLg(v04Z~}7x`Kb`} z7}aNZf!^e8sxsqO`$hErQFgwDILT{uu6F=b_Dut;#Ki+R8es_9?Raz`Y*zPOY9Mhv zTX;>TBwusY?L|@~&{VTYpJ^sQC{U$dHWn1QOo$97&}S`AI31^ zedm)>OPS5-n_%)F$<3XFH8Hd^vpxh*bg~C`s@RU^E?V1VUUm%1SUwj=!T9% zX`?_Z;BssCuQD=Nom;g5&5X`SbMAzoRdAeTx{v@jo1o-inHL5WhAP#Gai#n_E?YEP z)L+%|8id*@y{K1v>^Y#Kq;gn73|yQd11mAQqxEKo30*C{Fj0IP?)RmC=TX%OBfbBM zZ~il0CfmQ?%ltR;&3`0}RTnfD%U&wD}T2oE& zU8oY@2nkU&(F1oK)d7^KC!UxqmAZS<$BcjEp z0UK88tR0C6LDXf`)EH^66A|a3lFnCH&Y)%dC5peR9)exe8yBX zADduzgOGyR1?E}+Zf2>Fa#5ThwKWtM0Xe10`Yz$9?0myGnY_26huDpqPlO!ps( zRO<~hh@;e)tohL<2&D;BVZ@P_xhFAgYd1WkubRc>Bek4uU4|>?hK~iiFP_}s3!M{` zfKSmoNQjh)Bj_w3G>cu%0wZzLP^!{g98&2sa9_*iBhxGi`ah=K%IlU8-v8J8A$7{idP0b`V%Deki99>M? zc`nMV9u!bt&NA1WpQch4+ZT~OooA(qI31wbj}?<|Vt^m53|lN+URH53%dmB$$6(|@ zRRJp}_KDR2)Q=CZ5SxujBK99CFvnuGayyn`LWYfM7ZJRp=@;)b{bUBO5ft9D+w(bcRU`MBtC& z6Mq%sr$Ik9D6QgNv`NidJ8U^7z=Sb$$B;BuwKt;dp&6GAn|5JSlBLzfJ2`reb10x zOUY}i?8L`o>!cZ-riH178r$K=^Go%z>n#V3IUq(v)xZh$o~volvY^-_+iD#pHpD*Y zf)Jnl59pEKAL~0Peg1Q9utbz-dJL1~DD!il*M!U+O15|2j0ap-^ccN*saF+7dj|lR z+rXAIxHzHlLTUCT{gn6{8BqXv#? z;Sf#SG-(b3{ku_R4|P)2K%|gxlilg!E|cpPXa5geeR?RY2#u$e2(=8)-Qbdu;wAxmmc9u{S_w|K z$cX)N`K034xDUe(U?|t{6llh1ncCYyuOX^1t8WBZ zY~4f;tT$3!f4lDYv7=F^p7HV;lu>xIPLO`=Xxjxve;_@YI^V%l-DT275|5_jphK+X z^54N&@G+&LXW2k6+4gbuC`g-ob4W^TW9{xU+#!DpDGS zlhMIi3;*Mr?dEAg9+EwIAv*6OVulQW|9U)}?;fuiRYx~i7wZBL{1F*tl{(RjJDK?o zofk)HGRN<5!fupPFGBAyqLf4@@ZonI1T7gF*wz~0CXY9_CDzTGOyW^8SIB1A^#E8# z$Fpz2_5Oe4A2et(`+o&n{~6bl?ceWu{@26S|4RI1q-Xml*!o9b_9%k)irQi!x;Udm zd;thLkacY~zPKNtDBU01x;zodV^}&!y64jyrB>U7gf1&+W?NS^H8mBrY|gK?%r^cX z?pKEPkCf$)$3<5MSQpmzj}JGrn5jeC*21SPgMHdfe7`NQpe`~H-)?o#O8Bni&f8D? zARUG`7tIoj1kzbf-L_kO%|8q@3+s0}?-3T5CFKVPKTM9gdoh@N z0>VC=QiwZlHlG=#w|_b--$(3V7j+=6v>=x*@XmUIyAS5JiA{9A&P0-p!OX7hP_fc- z{=D5>=N^W)`fuUd!_$nBpdD}bhi=iG0#FnO-e$%)9_!YrM>cPvam;X;txy`v#kS?AYi zwv?0vw4Y5bf0`g`b@dfuQ#Zn&yZ7$(zquTPESzoXNI|`=y-cP9>)pqU&Hx_uNcpqqn%GaF$<%>1mqyn+NVCT;qUWE7ea=BXQ>`RyiWgels1LR(}@;rKt4V-y=zcJA2mpT zinH#qN5FwAT47q~`;;lC7u_0kzP|cd8*;CT&%<&rcrb6PbTbeMpd`+hG~nU_viCB75Rsh}dpQUT7d!v&+F@d}$~8HWL~{XQJ>{QYYF}72u&LI;dJ%Oa+oiZx<&W}4a2-uKM(;(x z(AU|=r!O48D)ndG%;Shos_|f9c0_ZN6VTEXA+0G`wx|l& zU022BH#g*4`H@GSkz4b=k}3f*5sYD&OaJz2HFOXBZd23WG9FP33k(aGOaHE&xLmz! zN1Mt!d$v<&xRpE+S=^|GA(GaEywW z2%ANX%+0dOdZ>9B-6{@k1yez=WEEB?9n_IVS(DO)oBr-n66cL4%W|Di5HjY%WyY#@ zsu}w;v3a4ejhye`4)Wx$iS^{^S=39t-#hqxfvg?P7?-Yv4(_sHP{E*U)KFD>t4T_6 z#+rmHtSn|sNsE)hPGriYWwT>WN9M31uW5rmr%?u|5~RJ9Lk2y104E`w;i8%{`54Y- zoaI2))YgAF)yC(pi87gF4oFE|h$&mojLePZVdk>C&xkYLxs=a+CLiKNw-}`*P?*ST zhkkqf*&I7Bkla-8oFe}RFOIJT(A-pNPmwj<}@ z;p_WSS1LA6`?a>+%iSxFW7D!h!~J~^f)vFh$@_y9S};iRt5+89fOKPk%}drk?VQjG z)4FS_AO0lSEm;PRqdO?Z4&CCo#Chf2MtMlR`gxMap0Whq^-dQd8ch_oH_qFyT{0ugAIm_xiBkX1B(pT zrZvsqC`%7fQu$ZUcGYqKV_D)|CeEbx3|udZi|FlMR+zLE^weq>G|J`mD=^SZKj^at zk&7iYV3L-0;5t=mB~?q4kb~m8BMWEbi)R?A(*uibg35R|qK{>*9qoz2{`w^*dxuHj zD68$lll76Xb*HI(JLd1kfmSh>*rzx%k!8#z>0RSU=t=69N7;mSsz^!!P(Q~V5K#;v zwiJH&I#ehCpwbE}IUOnWGQwYH6c9y*BduTAt79xPY|fqYBS)RQR!UOmNdEbK4T;^n zT2v_BE7j%REu^EI##h_{e#QO(1g|RL@Hr6Tkx0|pqhru9>CHt!RXACc;sPT{gfq?~ z?+UCo%dV;=2I_SPr$V!OO3*QpMRu0*6^57YCqGI<<-#Vs&`DatpgL>uxs1qmV)m^+ z3aTAXL~@BlJ*Lw!&I;qOYo+>>cww%L>~%5hmF;5Mw- z4=$NU09nW^LpRiOAB7u@3>X5oxW4QJT!k>@v6poMpCfl(HeT|B*a=LqKJ1KCIBvrd zc&X|Lmctah!!20oqbvG4+Ywidl(kzA)Hp?fMTU?@TjUy*O~j}e2+%w&d{ zrLATMd2X2kkZ<2Ce-sM{Uz7xN6|Pv8qcHC$Zz(g8yxc}r$txL|%41L*R9S^_q^Yp) zLB+sfO>uvz#~H!v8-1@Tp*BWB68NIZ#1wmRo!t_YP^c-w2W}^cR6kfx~8;$GnN+FCFC$s)hL-=@7XK{0>8VM$MY4%LE*b z@8_Wo2=4ssf^BlPW~Bht&xx{f$~{V>qDZ}tF#8o|1vS{<_r^lI7wMO&*{u-Q&^PA2 zK;FH&AGEEPF43AtG*E&G(f?q3@B3HgLfSL|{a2v&pRu&r|NWNs|2s$g?~UmF$C3XR zw_@!71ZqWU7j_422tU`o0eIDfuEO2c2SC6vY_#&${vsHNAME>k_;NY@iB2hEb%=TRQ2%&{^0TjhiG6*Xp8 z+(rhx*SpL2bp}0XryV9Pn}I~O!-}hho{AC@+wNu}#ibOIs!>*!V`3vWDQm-hO z?j^dGb8n^<9hM3v-m%hWozJy~W>QN;t}y;~IK_bN^m6!Ja*xqP3+5N;`5>7Xz%B2y za1Fg>A^{x)wjo=nY8@R(Vk7yhf|w88(dB(l#bY&L#+FE4q%}br4~sy$-qH%5+%fw0 zK>>OTQdQ2tsAIPlG+>iGRcHq7QEyYXtC8yx|$K zkSi|CBd4<|RCLxa>EqJJe1!&xoa;C)qI6K90fTBkXkg}VcLYFg=Yn3{`5iVsL-$x4g34c18jOxY*jT#X8B%Iv9ee5!*wCLmHe zPN-rW0HCnNASO$20d{Vck{UFf901(^d2z&2dP(#e0SW`)O>cxh6o&!W$yjtI$BFLZ z?1$Bt51-)tI2mTp`e+ol?sT~w?$$bY0k0Q z%)_7=E!zz|!B5|<#ULP2UnAqRp<0tA;1huGm5Z$3L6gajOPcAgz1ua7*%|c#NmJhI z?jP49dC$|hU|pDlvoRO%vyObQmiLXJaWFF=ny?lu-QaE2jH6-NK$cJFR^1!3I?M=g zH!a9$vJ~8qzI#T)aKC5hTmW9MZ|Ej)jYq$h`IUUoYcRDBY9!_$Z~*go)?>izfGKg- zocNTM`M(2JAANWD`Zj&OKgRY0<3Red`StlBSkc8dI8x{MZ1&JW7)rn)G+CT^wJbIh zur$KHmgP?jt77);TYO5jBD60EVH4V@1dS%mpy^J-B@#MRm_(YTT*DSLG{K- z%s;~&beCH_3y#rx+|ka={dZ!1dv$j*t933&zs2D&Zp{idOtGOk7scFP^IE~~y?63X zeq<>L_jNe0T~sk1a&Ls+#)HPjhY9jQP&+soo|Qo0ae8bphbwIsp_2b>9{nn@duuTe z3=dF!3x{HQ?tP$YLTXiS5>&F~*%ShPp0;`--e_U~{+w8JKrECsHZLibe>8*$^)}i!te~SmY-Q zr7;1?2F5pE45=Q}S!<}vNcjbwY>(ksX1!%nbg;72WY!okZ={;D#gm4_vp!w(?22Mj zjDQ0T8_G$`kVJwe)45Y_G!vv+Z*QZvx6BrGL2gu}{XuS`_%e1})=YWm_OA`iA#XLB*oQb~jUL-*($?Pf)UWmKo~z2eu;X*y=@WO- z{PBaIve9ku*=WQ81iv$`s6~I$Zh`hr+Kl;O%#Cl_($5!V$Vp~liA^Pg3oN0+Z)npi zH#jAeNpREE0dxA;PXy?K0UWMnx&V|v#X3WpCmGd6z_Y8%CE&HPP z)W+k^i!ff;3ts7Y@GDc-8YWIKksi$$Z6@(zc^F z*%;8V62-CNF6OsrOEYa1(?yy}%^}iz#?@Nd+ICA>AVaFiL?yDK`2YnFbPjYsirePJ z9_cZ41&3O4c3b4j0&*>!5{$1O2`?vlriQBi4jduhu!pW0&}(y}jD@jD-NLh0jD~4u zzXEDh&?S|X@`@_n%969G9@yv3_G{Fq_PHQ-5oH|fNT=IW();9fa@JLPg+wFPYI#A4 z@lGnD{0acGlJt@y7IqAsrq{*1fkjxNLS%xWzm+_uSb3%Zx4&!2WCLGSs5Hz?C*h#B zS!%5A)wT6kZR;Mk>3tM%g5Gq_oXOAmU91nrj~(3U=A2wV+Vb3ke7_7WoIV?= z+BH=0jCYqk%w5goa@X64wqCGY*W!sWgbx#@wHqW2_RDdv{9VDRf-9Ukh>f`kceo0= z)v&c9^Xt9e<@Bxb#o4L}=v5Ct@$?~I#$wnjMLNxTwZ#s9`j|W6nt@V-nmw2O#XSP} zInAxEEnSk&Rm$>;DH6#cRrTJf0MvUU5A?h*Lhpv8soP(xiaZAi`MR<=NPr7gj#9Cx zI5(TbFY&bO)x5p+Xwy;f)^BD+S1#hftnsn(;$e^r%_SmKTcT=T64o3WuVIYzl-$1cQ z5y{-pjyOgE!+9WL<-gfq*@^06(17CkdWPDkp)m%O`ZIdlOw%P@xz6o=ej%r60RcBI z@FBTxh9xiT&*Kq6H_&OQw_7h1c&Y4oa89|zs>d2f%UZ?Of}{Z8I-{cs-GvOK~pQ|5QMJ8lX6so)#||Ojgy6hISo|dl?)P_L5z+-6wD zp-KnqJQR4{$+Q*yra)C1iE`Fck5-c4|E&r3@$S9Lc#uob08@5{sqX6NmG$jcA-8XD ztqH(sXdHEgo{!*&1#8~SeJG;ZR6xFw^{Y{ox!U@{kSffYRCECZX!rn!)hqmBaG9L$IWo8w_S%%d-pC zb{#(B)I={oYQ=Cg&$GxPLLFu*(2qAnz%7J$;c+kIyBrl;g*%n|yCt(VKYd4k<&@h4 z$Rr7Fn)SDb*^BH962~qEVxw&Qa02!WRe;9rq^qTA%Xo_2iEzo=yx$ z(>z5A_=Y@~YiE%VPUjg;01=hWfR=eWFk}<(ETLM&yi&@{kX~b%K!Z?G@^bQBpQG7T zxR*XCuoNnSWt?;*q2r*e2?CT|rX?V4kHLk*T3v*OisvF~f}0nTqsbO9q;T`6 zdnypp!M4?{jbM)v_l1E;-JXA2rMKvX^7xVtnc6`WC{aHJ1hkW$_RQ@KS&lw zW3BRq^lJj+GBdS=goWU;&|%rO$$Zpc+Jp#rV8yYi#7)z391XoIh50*v(v~--o;MI> zA1HAw_vA`11PQ@M8Nj%p#X0%F+ai;^(}7jdU4`VHBClYzlEOseq$zIbsTHE+k0xRw zO+ypi+w2)+;Px4nK&8LEC7Iba*5Bd-81e7qt_d6;()82r_LKCN%qEVYFLeF#VG!{T z@yO7M>7D(rkDVAdQ#0s4697!R0z_f5<9e)Eb!9x94N@$T@$drY3PX`!fLsPhSNM%+!Gja^E+^`8s7#(GVil=e6UmQ*Yvpu2sYu=CC^k2ij-ryP3S{B5M# z5V{P5vnO{AKlhGh_uWmp;&~utU~8#Lc4VBR`Tdm%rcARUiV3;3@Pc}3<}MtM zQIvsjX-oPf^|X1t@FYEEsdkSd2{!w+=v0t{U!IS(e66R7+=4Wv) zDHC)#`->AfnOBT;g;SIsTFvI2mj_OKxv_jUqWS&3>F=zbpJsEH5l$;7#g>n!cXYM+ zoK1xzQ=l(wc7^ts!{zHjwnmTIL6+5><>%W**E5b*(zUXe*p?^OKfSn&}(f=6> z9H&y}KHpL}5-h6dVB(h5(%GZf!b!eX-XPMc4Dhx47HyfFOOcl`T@bhN0hrRr*X)kp z?BFQZPVRq`XFi`?c%OwA@bQ%IP;@Cgha}h7=(v>og_&5X`U>%s&p+R7+bL@I0UM<% z!2T;hseXm$-csbDi(25OtD!;zBX-$>wiVFTdP$Qn{jUwW~>N zdI%;u$q7@X@%IKJ95AeZdknz4l^)s^{+HtkmprQBMFuWHqc)G>p*h9dXjjXK&<`wb4r*`8<=r;HrB>~+H_SPLQ*Rn;_x zLK_u)$1+<47e%s=h6KAj5;v-DoVJm6-n3NNRYctnH%?VVd~z_~Ig27FmWCQRAZB(#HiW=K#qk$ zT`7p)r!pcYYvE||L(OPS$*8WGt8kXRxl_pfN!Jvr9rx+&75;tDk!~Nu!5E*e zRv>4PHo5nL7-9j+msU#QOGaM;rCay~?!zQL~DL%yJ{bh=&i^*#pSxmLjb2opT zrUn)yrJY&v@$&KvC;thI{NtO4t|1>KO{31N9jq9Vo~>cbOcfPtyHkUty6&Pj$P}8E zvYaYysyTC1jyJ^ML6IeZ$o=>{hLsyrc4*+v6=_z#I0FR69M#-=OWQyusgf?r1_AO zi(BiIvZ2$NN;{pe4f&9@(Y7}sVI7^zzh_+6{-n|z;DdJ+E0rS@Lyci#RGa3s$O=v5 zZr0iNsyDk(|93m@M)%>$Yoc3~U}U9CA_uKq4S0iqlm8!d&^|?a{`$V3ugJcRM}n%?3OEuuE6m6G0dn?nVC4_Rz+~epb*c5W}E#Q zOz?*cmRO=kRPIgK4BY~#u6rl19$JJVGv@uk(*yNNr>z#pJoL%iVrH)*+P8R3b9K92 z!gOzl!>vdzGXu|fHdMan0+I*DSe_65=q_8oB%deS#T+_xr`B|?!Of-BwPI;rpx-ty%N04fK+qy?FMkb2}a*8kHG_uEihm}zo8(IF|e z-QYlC3zVy3i5GFD^%wDlzj++Jwur=9#7cOs6C9e4Z)ap)(Mr@xh)T3#inNBqFH-jo z{5?bmnbb~(DOJiUR7=BS$*KozDYS-&hzxK+P>T=#lJKhrzdW+xcQ&Wa&@_4yQ~&Cs?WDm6 z&21lHGh`NW-tZoqt0h z8&dvzd((I8(&y!ZR0Ew`%2tn!W&heRFN6Q`*Suxz&J%7BJNA-a7f^od?g!v5RbFQs zSO;G8HS{YQN>vZWqg_%rGSIB*{LO>uW8`15Lit_|`&VT3pApX4|NX-Ge?3|Kufl&B z85#e7?U#D7=i@NGCrYpJ%20n-zM2FLIXYD;b1Um3WwyGKLw?*rD{K?hz8GliT+4a%oI z$!g^))=`&mdnzM!*WCea+zq6ujr^AK%Lu5j=)~>6v`u90Xn~w|s}bS!&nrvT0xHI_ z$Z0GO7;IG0Dg@WDjF*;$m_l~Hte#f>958;iGQ`RdHF}}{GHQC<*d0l{Ap`st;u$`} z4(1&TsQtM^9x=wvziL7$ebw9N8~&;MCYyLmdh^P9o%2F2b?-|gHT;9*wuL)7=_-fE z-*3kAe#C8!lGy=Wh3zEEMS2S&Lc(Nl6x@T$9-I4=LxdO`KKJ^X8DC+6!_zrU_y>nT z^Hq>JPACgl(FW}I!&}dSC*-e4lMzH_&xB2vxB0ymM6D6_)XjEv8@$kHnTVxa`uSQB zC%^ZG8U~;h@3=qH)qi z$P>0{-sbP{^FN|t$fP8dV<48TOwwlK6H#M?*{Q+_D=e4fD(Nra7}gIRt45mR1Zh5{ z^9@J0tjK#Gjb8eoD|yp(i5xzruNI66I30JN49E9?p~!zfw_=CRbmg2lflE(?a`?;* z;m;-Ev@}#aJD7waOCTrMqh#ekYChSI|IjHY&I^fzeC}ob22J~`FdTGOfo7DcArr(+S#IVzqC7_8& zeK(dcb#iS~4`OqHuFUsd4`-XVN#r-%ng0c}-`C2}*N#i-UWxgp=q^>2y32tnrbWoZl;1AZi?nD8#9Ga)+Tc0zd zi7BYNHxAE-)A}-rvwm#6z%LYSYcpx;6KUA94*MjVsD&GCZS4U%1g%y3>XD|Dg@f&` zNP{?nDNC>yt3`BxacC+-9OAnHgf;LAMtHf_Ihd}nGXhZyBJKIrGINiV)Gqy~T1qsT z7Gz90sTdHVkdBBF>p74y8!(=gOk+o+Ocd;JM@{X_Vbcm7VNw?)5Xi==Oc+K!JwsJAz%VBAOCB!f)H^WI$-O?8VW`ow)xDopBq_CUVb+6_i$f8{-m- zeqB4l9Z!8zjb?ho+?j$74%HKAwA6&5!LAkXY%#n`bz>y`icH1z>oJRkTFc@ssWzHV zp|?I`BSi&b$m(Y!JhXgwdoL>XHZ5x*5g=|3qzYy?Gc{&%ng=v7V=v3V4R0ZOe?OIv zi2*-v!il0w5w_tuEv{kK8mTIiW~`ks%w;LjO9(nHXT(rnnol@l-LsiSeFny&mz9)Q zE|^>bwa0F-&Ske;J#GLtXCK~@p^XKLBF`g-2%MFFj;Da6{>DZ zdXzoAQX%!N5G>|B;rtbMdx)}Qg6dH@k1LFT0N=!+>Qf^wwxph>ynPNnyr2e7@ld;S z_tXGKL3b;zOcwAJCTr;0xPD`ShG8%rKkcKMBXRJGixG3U=sPaP3$Ex|!`e^QOAD%E zu*1rzUO~YUQ~Gt8Hz}&9Hn?0XVGb{6$!j^y&p-~CMJu=4?48%dieOPzHEL*V*EM9O zF7f)mTYER~z5s%>;6~mb%WzEL@*_~Ut#WggIYy?t@lqgYFpX`{6SJvM-#fqy#OnX_qNbcb_Z)rmY@BWsc>#^WD{)((a1@MJhy(~}@g5LPYPmdh)|$WNsGo<7 z`@S&DfJ|AicUHop=n^c>GFk>L5nt%A5+P8as1n_qG{+mvTtsP0!u!t)1F9@f0^c-P>x#5l!ACGs|WX2 z2Fr*&0_Wr`VbdI0YvwG~5ZOQfg zY4#d+xZ^5!Gz%_xk*iA-i|*d`HK-sHgYolY^Kux_w>7YLs6H87(_i>*Og*MY;c?ZC zJ)PW(8>#YBGIow~C>cJn2@$a-|U(|3?3{0GO^vqsNyjN1>Oid6`)IUdUX~bk9nKY)Fnxi>LoyI~u zyHu1k{+1PttD!|>Z9d0uf-y9htvL!Ii-ve)*gX!FGH@hyr0KE5YEhp1iB&?M+z5`G zabXX5ya8WESxWdD7*1JMf#3NsDc1Lz*L&*P@}Sc%D7$LWBcZf4cIE=w5^*PJLe5L| zOl8D!-bqXD(Ku*kuJMyw;4b^!`(v}8>WxtQkRc45I+Q-*Y8vy>v=wUc zzyc;|YRg}a<@btky$%NT;gka z?Y6ap0#-6ns%#z!gQ4h7Ki@N<`pFV;GnjQ8s8W#U&(Iu{K!esu-J4SmZ%vbFaX?Wb zZ_%k=d16J+MkDh?^OOj%)Mi;Xkof-J8gSS+qSJWZQHhO z+qP}nwr$&9ch%Wn&c3N+@7z?~)K3`6_|Wsby|o_e1h!ojf8W-?6e11x&GIlI1CcBp ze74nMkg&6(PVw`G7J_bK9iQPA5%k7`uZcslBZh4dQI2aFnkvisw(+dVHm@6^iUqB! zrc0IDi`(kf((vZE7+DmVhkmbd`k8?hSImqrX~Uml6W3SJ8OqzextLeaq(qNPeG2U? zn+@^Mn8kL*>Os1pO?LuZ5+IO$ISGRgFdV&BwPevn&o%}79HZfT7NrA!eZ${DdmRg$ zFw+NqBZK5ZI$K=N`3ekA0{kpsX3mW}zZQ_;Zr3mC>tqhj3|5LwKODt19UO{smznNq zn7qEzeA;p@+Vr-iH8bsI&7gHOn;D=#o|!?4SxJnHF@`;+c%tW7P0$8Nxll}ZCA5#T z89zw&dnKr9eW4h3rb6jr$K}{Asi7?jB^b78yp5&XdIf+wZLURlq|^-$%dM91N=tD0 zUgw+969mwt_6Z~qRlY1 zAOplNYP)1<^rq=Q5)Z!M?^2-Qlab@v6F+Q^u*-AT1h=EWMjWfb6fKL+7|XAs%c3CA zoY|Lfp;5O(KcXCesujugbr6hpY+K!n{y&I#Q&a2s~p`gIUc^m!6%DY^U0 zEBEfc7-jO_m{+p^w-O#gXXBgLWQ%uTf!|X zJfLJ1qTJaCm_l{gBQik1_yUMk|2UY0M8Hz;=q}u0#B?S{vTp&;u|&bvx@uS#~@{A zVqBtPva_SDHe7`RtUqtZ3Zz*-3!6%6`cR^W#QeS6)d-rwyDqVWREw2UJ$S{Q5?!*6 zzo=&}TbQ_<50QqTQ!g36aU%NH-H;UGN_Wqv62a8y(3%gUqE!8Y)}FiRGwY6z=d}Uy(Hzj}NWPuYO%7s2 z-zJnW@IkiLe-u>rE*p^4ElXP}q2pqU?=g<@B(yk}DyW=;oGqsHJEqf6ra$44ew5zI z+@HJ-IdmpC6YAt*)2V4nmDFu@{e!9pPypZF@Xx~ezXzJ&_}4=d|2RSa ze^T53|75`ZKcD!rR{EM zDm?z$L>5-sis*UE=vD$OYj`!C*Vq-bD4UHgq&zaYn)|?G3)wi6>>RA}K&D!g@fhAq z@mGw_aBIjut)CAW^6(oy* z)qh;=r}3Yt#oFJ0TT9MvZaLZ(bSLGc=HW2u^FY_m8wxr-SuNJDgR5~G(mSJ&mc*R2 z#26@xZtJwnfz5k$2tTrFRU7ZR)XfMO><_T^QEDqVrxXk>4F8EMJYNmoLLnQwkk&m> z7DGZKCkRZfPa&;bAv7Xb5rM<; zKJ=OHE=)>vuP&+dgqxHSgQjq#@4cV~mwAZFc7r74PpMA~q54yq`ogBf(j?sz9|jn0 zwpl1|K+aeOe}_3_rBEX)3rsS>_EJ`hS?`{_98=X#np-Dhg#61UAupP@9P3DoBVr{F zz{CPkwB){V-i-lP#W%)=kGY_ux7T|ML8vQ2$DH2as*ktRVXKy5(m6EgduY4pkPt<4*0a($vhm^=az=EgZRSrIe;wkmYznSf) zt`8P$VK#Dw)-*KH7SujYN^fu}DP(A{RBn)y*QW5@q~N}2(v9|ea6ka^|B)!nwBQn_ zc$%?;<4TRueZnAAF1Y&k#Q9rlxXC*tkT82KATRUhn#8v{V?r=e-oAYyR=s5JpFbI) zj9)G}V>;@S>CAyFSoNmA&twk!M#~L3ANZ@Mkt4M!LkN!sv9Ob8jTaf%O6Tx8pppM; zDW;r+52P2RjFJm8jI;YC3+S^J(3S&lz^xx}&sW?wg3Fgj;@Apj(hdj+Z11CmMQOekPj~-{Z`0?u*o(qGykCt(ap_LCp=%lit^H3zqCZ zQj`?Eo|oli=RI3juqU<*tr|H}s2~nA8&g{=zP+OagNoUq(s#7XZ)D*&MVM6U30s=> z=0%pYGzFFp)18A9$^P2`kh%Bf5lW`2=SDzQ6_sv-Uy9yLnDGVU#U>x@FXB|U&upI_R{*JF^hK) zYb+DUk_O`Gt6^10+LgDB#lwUHRMM9I-n0PvKBw6xKv7WEgnnUrxI0h1MQ=1YGc2~w z)ZS*VTg+POL|W#@%aH|YAQNQ&4{S9KM6;`h=QYK?{uITd_01D@)+Rfw{+}DDE8Sd~ zxJ ziJ4u>AK(r;Hcv7ex)5<-lN!gcid;9;tD<55l6u*0u<7O2&EX{1xK3}jyQOLEM`)C< z;+rMq-|U+%?A;4zW{9ODP1t$!eKlGs#E(`1nE0%_y}+ZAhGd{?pa8(Iq%XQS%Z>6^ zm>=n6`94E0fjW|Op3?w9%#A6pt&a)+Vf|Wtro@pjd3rO7(r!3rdPOv! zo>gtT1sl2&JVT~G#3C7sTpR##Ee}Lh7@AEpEbiZw1dmGkg_We1nemZ92qWI~6ljek zIHNm98LVW|TA556PcW0+Z4~-E5%z(zL!(uEt5WC-f&t(?bH z@nPhDhXb&4{5Mx?)!$2D<=<_ce_RR`hvC=^3y}$qPb!o(aGu|2swoW;(?V;qahB&bumr;az%Z9^)T$CTer%TMRuSF3bPKVRZ*l(J)I{<26Fr6x{28v7p? z_RNLVOviL30vOXt=msQBag2g&O2?i0Gn zXzJ5Ofjc5n3D@fjn|4oXy63{byhIZ^XX|Sa$%LNmB($z0Jz;l9eWn1z=8PfI4UnJb z(*sPH;$OGR@smQTig})}$~+}T@<&c{K=VnGb;u!;n!J8Bx`wE(cymXMBZ=7KP^TUWtVRAC0D2OHPY*A>1)(r83oHW|jD* zX|tp*S00ShUK+cu(F!EkxfOn(<%;_5rDqb^fdzO59*fWUMgGN1HeCFuEbtMsdq04n zPuLP3Tznt<=WE=mk~&~Y!4zIU=Tx=*hTz@>f8MVM5KfSi1*yUXhr&Vu6LJiv-9E}P zTQ@uMV1kQho3!~xNe8-S+Op<{tr(Xl$*ea8QRF_yJ_dy3TT-4W zaG{iJ@1gn+KTnd2s{rGstSVaIY9-;T6E!amd7&we$`G^cEeB%c_){HtsRb$4TZt%+ z4REE_RLt2pXk=;Hm^ldRiZu`59;BpETP3CaJ zxJ=-h+G>Oa(<|3E(i}G^GAE!+wDZv9iv)b+1aa~nt2Kv_1gM(pWLn(LPKQXZb{Gv4 z-)|1!-Q4U-l?{|+pH;LECF8pEWJF4tHmn?+Ksxe-heq0dG7ppnFlGQVC;a6em=YPc z;IZHZTu$jpX~!kik1PZrn}W|7t(reM0Q$hpe*Ff4;_=18S0RZ^2?c%j#XkE`Psw)s zR5i?x=yp^Qd@L1#?Y=eE?~y+s<9~lS`8wHoXe+%@8jBL`Cyx~o0Iv)HY5>DZ$&!Uu z1lp)?=}Zah5dMk%UU^wm^VMrX3SGe`bC6HH(d|5l!R9MUgn%;t2^AWfuPxa8?mW52bQ>pj?Z|XUO4vwPxf`L7?ynd;zbfe(?_kdc$2I(tThLJ@ zP>3Ue8F*ia5$dI_^$1-o3;PJLf-H^7$+8X~bI3i2%X7YWdQ_#D>po<+8s)6X8O$E1 zSqGZLjl#evS{y_vWlByHfd#`3!nK-kAKtStQ5pl4DfnyLmdjr#{u;6>ulT=RW$cpn z^i%i98vGpzE)BXZ89rzzU6nY;I=Hu?@#>uPDxwJ-aoorhK!XJ6xX(`UrGlzzPOsSfYV{@-c2wJqqL! zy|b9bcuIK(iY&cpytvcRO|63RT?9}H3RmUE7&MksVO5nhiWZfIe9EvijW9fJ+xmSr_C z#$O$f-ye{Xd2Rp~Vcz)b`>j|v3e1HB-#=?%dI=%GGrtx7npw(=L+nDX=@Y6gDXPG~ z^vN*IuRkAqQ+i#%CX4a&KJA2QRH48OF|q(+b9Q3|o4@AVZ+1L|w&9i7ViqZB8~_>~ z{9MaA#`RTq%6YsN8l-lEXyu0mjzxAlH||0ZeQuX#+<0lSmn{n>CJ@Ak!<92CEi%hk zaDjde>z76}GgdSadpaV7OxIss^^3WirI9LHFojqRpU0^P-vGPUG&q4$?jgK4*p&S$ zvsu3XjiX4pfMv4V4Pd6S)5Isjf)Mo}rm)h5R<7OGWYRl3 zL-~7uP9Pfsl-=otlz)NjTHvt$h33b;l6Aj?%HwH>*Z5Vwtp#H~% zeV^Lh>9$5-5jEh5D1rW;l##x-v{3+?W@$;|>!(4>SG3+Y@fd!Yq*Yqdm<`nn-qG#2 zstOC&O@9N>o%~h9Wf^mG!-AL?AXJ#JW)bR&Lm>p<@6j=?YLqfd;9~JZE@Ov2@@Yon zm=~k^z{|#q445ojn9CKFi}>b*8s~T5G}U_7$K^-0>~XQkLqNs@6KI`v(Wn{(0ew1C zDS8y6%i_$F$}5c0cQBs zsAa89W8`IW1Oa!3SOD>TUUQF8bYgk@H zC^pk&PkAP?8$VvQMN^?7r+c$%6IFnGlPMilTFy{AI}(|+tn&VNPa`!;O6drC%jPF3 z)?gZRzNg3>+dDCK)FI!rA2 zKGfI)j34NBL7R=RaR)sJb9GpDOrF_56A~;&Hb?4}|B@ytRU6*09U`DQ!a!`Mb^(df zpp`}Rp@7s)VV#Y`I1Q2xnQ5#W)@g&G2?$F~;*0jPX}uHCzvNg<+ekjzN0>fX|S^FP^p0 zavG6#YLC9pSms(&uo8d0hylwk9|5mWmAAW@|oyDBbzjnOLI*F~()n+Z7&rF(Gs#Q1= zXNB4I%t|U~bNaFew1xIc*9goog_{=dt(vE;olPZ=RMcO~)uWWst96gy=Z$Hrwb8gp zybfMoX>s^sEK=1}V-o>Uw(LP_5Z1`c;8t;|jMIT^*27(JCb;Qptmn}fKhKJ}Ux<;9 zJUaoTIUhk_;;`B!Zki!q^PwqHy`i&=_e496IQ)cypb*J5L_m>4i(eCEwIIS=6OEBH zINMU?_shdN3~s4}R>x|BMksV0od7d((VAP^0V#g@1i$A8XCwy6X0|Fdw2wne?5=z zA0L+fcRT{aeIWV%n$MsWp z)Y4%q;ZPd+JMkMW&po~Ri60V7rdTT=YvWVwO^}u10B|qh)RP+gwXgU$L5Z!IQ3KJ8}_C!$wUj2EN$e9 zOdQK5=PA>jm^V|V5pA*Q8dY`<5cAqisZ8}olTZDz%t2w9HiLCgSQ;$HlW}J_L<^X5 zmiPO~oo<~k{Hg(+u|H}Q+i~6Lsiz}qYzLLkl8!lJZsKzdR{OmAYi2R@2SU1SF2v#r ze?Rr+mIu@a%t?~gCVGhV(KVWjomqfwnE|&GNj|XT>0Jh<<6>jwQD9bw{+9@_TbSvM z*0LY9pPZ&9Y&{HB$h=k3-a2Vh|8Gs_YL0z;g1xQN=^C@mf||EBy<$kUy@2j*wQRDq z&E-l1*gZxvJBAh{V=`X+@n5_}5%3iKck;^2yJadR7?W-zJtX!4WfU?{KhkBeai#05 zs%|ZlaMU({C9Bf%)((SlReqZ&nbxKeEF2OxH5L~zzKB1-SCmAC{6xRtPmV3oNND_2 zw$f{X?!1-y{E^jy@)h`ozPbVUf>BZ-lti!@;nIRC;Z=(I3B6}>3pB##TN2ac6zt#g z+wT@t9ww^G_(}rUNb{yJvDiFdAVuo>rLPB zwhuQiH#IRr9)}I|bNIT`u*4~=yuQi0L<`L^1pb=kmL}&a0?W1qv{HJEQ6`$-l_FV2 zE3S$8T}*$1pTnS2hkM5Mjbdp(O)oykGQT&kE46K;Rj(d+vmCrA<*C#0D`gT&sniLV zRUe5_VR>}@v%`Ti&8gj`JjYCBjMQ^ze}Pe0ibSy-gDR>|)^C8WR+xIs;Lep`UKE!3 z1tpt?`pvLK*xq`~IF{W!d65yUeoeTAs#62PT##evkZ%mG?milq5+IiI)pX{pW-rfy zP7`fz^5_ZNHwWpN!7`K9c136({7&G$c`@!s?Jw1-#E4Qz-^&+)3noQJ_+vP4-8~Ra zH?>m8hU@F~ltcMQ5|fCpzoX_X0xltrS!P?eWD+({1DqA5FKNNw+}$vgsWEA}!+b@% zI0v;d^psCqpFth3nX|rD@rHL4(bYnJ562f1YQ%hCfSE-oZULRQfa+wn505|(Au2JE z-|v^u5zvM(P{_{>R(a5^hIm*0b1vu0J!k9E&J;KQGtC|?*oeSg zJmhT+7haFx7cB-db5<_~gJb^{$1u#($VoPpXFzfp3*5o#vL!eE_-oR}lab55s_n5S z{aG2@wI}^T_y*S7cRy~RAM>>}Tn18_yUR%_$3v|3huP1y2Qo042XDd3{WbHlgyFTq z+oJoq#nq14yUHoFh^X{HKOCpk>$$MNby;>#%C@@YL6{t3wQ=i%yqZCuP)VY)kT2eC zi}5xhSbD_4$8L+08v0@i*n+$a?9Vi(i?~z z;tTyM)!Ev##U=QeO5BrN)ud2+3cCVTepw5`q=@IGy9}O&fR?ri%l)R+)kGJUzH90% z3*1}UQYikQdblTxq8h`Cg84wUR3XWK)~nN;<-{z zBIp}Q;vwV@S{`cfP+K@?TwN0S+*@#R+}%EB5~+lpJMp3{p|6MWry`#yOMWAZOH0YA zi3oRkz{XScD{{{K;v^v&@>&BZt}!Ik2A&8s%r?(MzuJZXMlPH2T3i=(0S0hQ0dod{ zh3?exWaN}+gT2vtWu2mz_BV zj~I7J*BmDVwha{W#FJ3UGmGH4NfCwuIv4@XDivEkAiVb@bjs-;y%soP1zZ0cOaj=I zg$U&MB?IuZqZ?I~6s`RGsCY^TH|sg9wckT)4Tf>Npp9~8%CKXFCbX@BiEIJyN&xY@ zCrQ{?&XnhXX6jF9z+Z?jEu!-63!Ttf-YD~bPYN-&XCrgEvap~KyClNOfWiv4h$Jwq zLswJi{3FKh{83>1*hmZKB<+J}TZ=enH%m}w*ExGm2W{f!k=d*i8tw?3f;q(#a|*t| zeJoqOSMurT3a=az-$?ktGi*>NSUr&I5<|JzuJ#Yf#_7fsQ6Q+~wp10)he5{@@b@W# z2S9dzUNlrOj$Y;ap?zu<1|f=N7k~%Y%IO7AYyk}`G#RVB2liU=YGXk&Jh^|>sGcQ) z4kD2WDS&=}X5;GG#e$utT?(D0w>Sn#AepkT;IjzN{g#qdA4bI&q;>^rqVlpDM+gRQ z8}GKWuN@=1zF_Hm|A)07B6jHU(cQpp)N0V>vKOQe3NO+fo9EaQij-%c8J5~V3~_o zv=M0iC%cWIx2A@C-X3pVBpjIsVz1|ykE^x%7&R-GEMD)&kS4DDNwa_Y%$w9g5TUlO zOnSGyp%V~pq|k+bZK1YUqWAN$`Q`>k(og9(f@V=Gu4&XGRveC zP1w5T?!U6j1fUdK2cjbFF1J`tq~eN{ey!sRKp8`WVGnbJxj9%*4Auu4YF|fy(T-wD z?c!XPd?`Lzdqx~2%yqY*W2jix0K1Z^Hdy>6ZapnAYmoG$`~z25|E%FR@7?(SjD-;&EtHc zQ7)ynb$4(bB(f+fzx^f~d)?zk8=r~PtbGGz^%am7qwUovL~}EIjtF7fY-stC*1waN zAv_HZDl%zhkU1D;j8Vlr#MjC*Qi&&R_S%#g5e<0|8PNe_^?#1HWfV54mP`j7RYOni zs*BMM!u&<0yiZ-2o?|~46cLl2)W+SOn8izhVJd(`tB_RqRr2AR4b{x3yAQ(pk!oS`P*+d;PkR3a4EuQ+t zk*eJ`=B6Y9J}Qm=*zZJ?yS!vT!iZd}Ek>QL1x5H_SfKZ=C}7wd3zzG0d>VQi=t)g` zPL2mgcl;-j)p6MXg;2VT08PtC6z-Pn1`|o28kgB&h-wp#Fg$jw)KNh?~6@ zntjPI2GAaKRO5$I-?*Bl9n{_c_Kb)lWv2{e-43i)Po7v8K1qV9K-HGortC>`6L@jD zp(2K_e*dGCaxj;ii-L}Nw!A=eJ7)e1TQ>f0FJo_2&Qrgsy2}0)oFo^`XRfN{WC~dt zN?Xow;N*)Q!9l2^b+$4P4fV|nDAA9cB=hP&zE8o%--OrNpFNN_h8>7vRt{C0gNk2t z!$3<(>xZwL$l8C49wFVlk@nW%e@f{;zM>3!M5h4SGE3U1xTKOr#B-`{Q^yT{e@?Y` zs1tqAz4>Ohr^StR8YHjKdCMb}`}1tsxWd z>wXBDB71t=AZt=VYh+N7b8vOfpP)dRj?Y>C6UGkW#UP_;;1ZBWLTT3$*tj2^HBZp= zEje69waP`wMPtHM(yHY;=PmWv;H(h-uHXVxfRTFa1t`JChxma4pxPq9*qy1ft82@k z#J_3`P`y4REb6RIS$DIJAM)4%yT)u<#mw3fT8Oy?pY=pox8jJtCy+Tzj zXeW#li}h3qM#-+ZGpSQQaQfJS23#w7P6=nn%X$SdvS-(G7llnf4#OxB1A-B*;dd_C zQA@U;rhgh$%u_Woh#{Ia7fAI`==hUWx%;DhkDjv1=h{qhlF8^n>X(GFJi~4!IK94G z#}R!~31*gZ&I}8>@J)^0RSY(gcN``Qsx(Dz>Vl!YnMc)jsfVgTZpvw2GI77Uz}Gsq z)M+^x#1>x!ISro~DIfR-FG1teVbE75sP(a1+0+YlSxtooONShuVv>_l5`rV|*uwf8 zbkNyU|LlxdRE!`fswDd-w_3QoQkUAti(&UD1_IT9rLteWgexdGgh9zqzl~8(i*qUN z7v`>oalf2N&#?n^q&L9muZwIi!8-mgx7RWYLqTjy>s|C%I3q7beE;z#Dl2cw>R);z zS)MJoUvg{R39B=OxUPH7eDGCepSP~ovCe@Tt)SqdOBZTYCTfchpHS6m(Y3p>P&G#| z#kst{TeB<8f9yCqQWPZM)np>sj>)M}O-zv?EkA*noioBAzy+70pFW_^>@kIZPXzSy z5y0yZY}!MGZBsvkks9x0+^gT_wC?HFTBQZDDxH$Y%LLa~v-wAc=?HTC;+hb+DJz*D z!=q&()ro7fP$DTIo<6Uk`~8 z<#L;A=)2Gce=F@@O6Ui>0ef5PQmDdha9Yf;b8clcn+JV=tq|nV!exUNoPcamgWY{NJ>&GIzi-bX0sAc=N zG}SDho;rcr+|8@Ou%+PAMs|@Av9MK;ykG9|QoAjNds^qZfp()EIbjoPVlk1Q7kK19 zsIAm0aOqGY%ayR0wIPr&8P1HmU%ron-2K|KWH*sC7%wvZxSRcFkBtAGwl@R) zzrODMU#GbLTu1(Yee?hL%*e>Z!2Ew3SF=8 ze$>aEuASD@w>u{u5S0nMWll;B{koO|VesNh$9#>{@5PoXWO8q&lKNW~w=I;NeAC55 z9zo7HHABi=&K2wRh7-!9>BICH(#If$#>g~en%?sT+lKtoeA5}Y^+KFBb}MN#ZE|b( zlOB#3Hg-X@A62?KjCi8@n)UqL3(!Zm`A+Nww>2Lw4D%^WrQ?47!x*ApTpk2J{=K!1 zyGEQ#@a9B`*zWFQq(i$vE13lQxrR4&+LSB&JWiWqcuBgrlcoGX@@)MufPM>eUf0uy z@f@Uki^Ob44q{5^WV8;i*#c<#W>gNW_$L67&R{&liXVNtHXDI=1&o)GvS2wkPi11_ z=p;=QRcVwnO_s53QCX4IZdK6=WqDXD->po14|6f3G@vh8&*PHzN1wJ~4wKW`Qx*#zoR6E;g9TJ(b_Xp#>C4mHE}cg2MLF zlYMmt^a^8&RXkpF(nkk(^4a%L+A6!ukIuMN+0WoK$UX=rtQ4=pJar_tA1T4h!F>@JKpruL#r+=gj~=b>iY^g8t2 zC+W%@qN%t7Tzb^svF`z1d_hKL#9YwMkl<`#J4>*;gAcH`f^RrltF8WiEz593M*C=H zEVb_1GyiuIRl{1k?>SINskv$3v||Ib5BB>tz~G##dgL_ZQA9Yx8%MG+?_FDP@B9}} ziUi1Vn=1%P2ln4de(LxYZyTEEyZJu|kEqeTsRpha<%i+C5Ar+=p_j(To3?fMd{swq zbZTTv$z%X<#spA(s67C|h!l3@Y{)csZYxxF2A-Kn+p&K-V5#@F5;^>L(qv0awwgGU z+(T33q~shdajO6;S5uL;2()IT1MNUBj-sAfMbhVwxB*x4U*>Lb^jQcIu+s@eMC-XW zzdmV+Ku{FRE#JJM@RRC+YuFDpoDV?vFNB+8Mr7V&^erRY-I4ih7=fAEZDt_^VqJ14 zZqQs!vD|}^e>W^Au?Q-N5>lNV)2WJ~bW`W6qWi*WHC`?_0xAYHu8gji52{PDXTJXm zdp1hMeU)R6`lv$fd_nXfXUDB>Z%;l6_I=$Zeq$iJnQk9v!+;FlG@dmevON3IFa?J0 zvz*9q)gh{m(B!JeKY8`=CX%OBtU!UnP+LwZqv>`A=BA!z}I2 zi>*!}&mC5dUt1am(uGk&q^J=}oW9g9zmutZjNC%Jd zXS-&5@fh&^xSD>Ip*KmX7m*RgOv|S-0g8< zb+o}@OR3R^q@@28A`Y11+X0%lAGyFxN?F%0U^Uc55#bsL#}Ft>KtB(e5t-ToyO^MJ z4VMgZ`%1hXnYU;#REp8{9;!Bnz4E!oOX#w#6<6CpdtsGC67@ukinGfqsw~$+v4D2Z zsW7^tCWqr3Powa$zf2EDgKLG-=?E!navN96AvXP;NYqGSk`8x=s-ncK5;2QrMNnMR z-=)KVB9MxCe@CJmgY!hNgpFu(1v7nt+UytWJ1rcV!GmZ(@TkSF%afq!kpp)EA_+!SAm5P=Rugnr>T#d5$7DaY*k`3_xcEtZ{J;05KA*zs9yBu(8u{xIcL$ZxfrM z#zT18f=4zN(W5ZCM_|j<9>C?-4_Rxt35*ndSo=5(sj^=oCJ4=phzIL?zx-A~hdFU? zlygZ5OOcZo<*Y$TaTR2c&v%B5gl}P|Us{YobK-$)bGlSzX?31zpkNv)o@p!w>_R-HPZoXZR z6#^**N8dlUUQg116>YW^?;v`XaTs>P_4(-!qD|i~>T@Tis}eH{>P-qfQnJS;kz`Xg ze00MGW@rf+P-(#>k>q0}RSt<;ilQ54;7$Ss$?iV&*p@9Sl(hdeBxcvt;^`7oi3Dl7 zBb}+uo}>Rl-rvCb^iR75?+N2UpEJL-whfj10G!1ILG%EBR$g}Gi{q-S=utO+%!ehZ zPU(>jq5N$;LxPT^Q2m+L^cg%&cm{cQ>6cYJY@MgoF1($f;9)_^T{0Cz-!B)z75`B1 zE7l@cQ{x-TOyP31OF+)3(&qYPJZpvo(|LkBC*Aj`VEF}1A*0^urvdX@)ejJ0^Gy8V zpM+Be`hQRTpMm~g-~a#5PpAJY0O0?U$d@tc%NJ2(G->ZKsBZ?Wo+KWR@=Wwzm%}dj(|%y=@X1lra-VNr zD5Z3M^fH)8lyfMeAh+>NVw6&l`b|F0?;w&6gH3kj>e037W5Vn#fnf zs~&?BQQ45skWWyYpSPb5rmqlepzkn!6iaPj+5U!zrPX{KB97W@Zy+p`QlAvPY>Gxs z4Zs6FV5cWiv9h<$U};o=u8B)|xBMVPVLu7J*hlDc2uDu!GX}$UT%JGbr%EAL$0t+5 z=7=JsuE7MsL1eOIP*ZkgDz8&_I|6+)I^R~~FE9w8q@e4rX+&?z zy^Ya|p=&o0&ZB|JK&CNxlwIBwQ7~xMHkVg$7{G`CMoCJJ3xK`C$IpySSWaL?ff@hT zU;<+efrr&9I5mZ>8X^NB-;}Aa(7a8m{;wo8QH>u+z}GTlphn~=N=dgOQ_?j>4-0d|Yg8$BO0ZY0;P)F) z2YMv|_uR?-;V($n{mA8YC@tp zSv{4AJSz}7Iz$4yjiyniBbqx4pSL!5+b$6`2Q?L_JpmLVj=o2gxL8 zg+Jzp0kMp@BvkH#W&!ANVle7tUThLj$hyah>T+RYH0DHvZ?lY=03E+E_kcyKsdh1M zq924x#8(N6*M=J*w1}G^0wNP?v_0}CEQ1jHMJ;a4Y=#FYP1IrX5X}#_6P_uh(FH^VUt3QJb~&D#9!6e<$9IOHWj+a4iNi=9|G^=_Nda&=y~a3`d0GbUfpXW`911|tAEVc z->OP>$){k1NLC^0VS3;&(YAX)yGh)@@4bp=dbv|lgAvRZiS{Rfp1m&^uS@96W)z3w z)pREHFn7?CaZ^e0CVxf6m?tj5g2Z(-5V$<&?pkU9YyC3!LNH7TYQMbMCYI-;Cq_Ck zj}}yVGd8~`yhMU4@&d;AZNJzlY~Cjr@CfVsYaH{tEoq-z`-WEgxm`hcRCi~}>t(ZP zbB~7SxqU8oPfTPe6B{9LJ#FdEC!8X-$mJ{I{2P>XH0Pj0g=Og=FjW3I@Xz(zo_y`) z;W*bKZC_FdhRL6K^v50JtZU{it`YBj(x+nS+2)(|tC(@8QqtukNVGzaC@tYqIp0#( z+Oi(rZM@xI z7)*a#Y@0*}wITM)0ahofNsdH8Z3C?>UZQaqYVJjq*duh33ku>jT4xw**Mf~VnNge{ zXbFb`7cGahrk0%(TsS+85^s|dR<|eb!zE}As^S`Mi`|qNye6q{Nn2}N3||O!Nf%Bz z@Mya7d;5tjCaF^*u|R=jrK=2rmZpZ9JXkAO1uKHV%J$R%PK#HG=gOPCB3rfM?MC@9 zh$dVsR8gE@mA52%a~!|S+?MXNBG)n@*rH%6&~Ee)78i&09N6I7UucE#sxqWU1W9S# zyYcPmly9Dw8+;gP(LGu_);TiF@sizHL}FZkQyRB7ROygkc-CK+uiYHGT6q}dDzYF!_cX0=6uhM8!$+&uk%A7WhAt8br_y( z&e#6UWKC9&8_kox&s$&rfs6E<2FPtVBW})*UB0hLvZt4&{;ToC`jn(ZG<4_M>E#f| zWl`|=ixQH1Z_XE09{_#a5z0T!YX2Twfr0*C&nx`rXSM$ou)s*q%KCp_5~I*9Z4bmB zxOxltMk@Kgh6Ezwu<65XA?;e2(#>w19Qq)8fU)#V8`gDwm6w-Crl+b@Ae>#Dm7TjQ zy)s{<{P`rmYF(QrVlThux=gw3sXbI(!zp$yc9w^J;0cRrd1CE&^mXB}UC$sb&ETjv zpM^Vay*nACZJAr70kK{&;da&v0@*~(re>XwvnOrcf7Tw-YNyX=6W@p{2WOE&^S_XbgXxPU`uIc5QG}L2 zcL^;Tg{)nTaB`ds6%ooRk%8h@8btVUmL;LMKt+Xno+;gi7u-7Th zfZrpNB~b8S}8Au+^NObG3;J zK$lTvhL_y+I6X^JSw!p_DQ2IV>Q2=sQ?;Y(GORHLJ=|RdJ6W9lmTJuvBD8lw-k@OM z6`{RCo^>d@Yxu%{8*yc~mhYob>Tez|w6M!haKH$3QeYOv8@w@G{3dJ>)Dvk<>h5DI zC!?Vh8shA6+*-L^W1xd~hBKrv^?29=w$28GD%^5h!vCRh1iFV)Y~A-lCPcUlHl`^H zBekfaf24;I|F#ReiS6cRIR_-l0?w~EX-JSNL5qJQe*+?`ih*W>g4ce4xDVuuC+ZGwF}x6dzq<;7ZJe^E1fDcc*KUh6S~1M zbnAUUQPV(6%yUCo`e_JUA5*v6Fd8S8wbhVZrPN09&575URMmM6&QTY+j>mEUlzJ=Z z-e%SM>jf3Z;Iv#q)WM0FaC?|ktm);r^K zN4J?A%(&QXe3+}h99Cx{!za%p=Kmq@9fCv)!gRs1ZQHhO+qQAbwr$(C>y~ZXw(XkR z^JXy}(J}8Wx>vI}k$KK8BQj2Y`Trkq2mXW~z+W)KrMCCL_*p2q(k>d&UYsm#ym+h| zJeYlrXtg?|KQ}5#3cY$lA0Z9^gglAWDm?+$ z+^8OHOq8zim3dGPvWd3UlEYEUn&Pli7+!~0VRmZPD~%CxD&oibmw1Mb=UVaSs{Nt1 zBk`ofiZq(&GpVZ5pbWXvNH?mR>Kti5sg&l%s+dctgRK`D&8TU=tYG6$(3opwM&(I+ zfajELS&ERg(%w{%RrzP2Xw{~xQd`bZk5LR?ve{NH*T=iF!#IhlXeuAJLnmRjC2q~K z_`0~Y7y0%Rn4SeKHTPxMRN%8xDR)zV!PU25QRQ-1!@NEnYL=^lB7ohJ6`#RZ5s`|V zCNpjjyiK1xtn_)yax_tE3R`=I*n-Bm zrG{cpMFTQ8HU-dM8Qnz%@6-aOR{{d>MWy%Fb6tRdgr7FI6r9F~lM^b9LpPJm-}$Yn z0Zg@td3PSPw#A6E02_ZyzCJZa#)QGPC`&@~z-Kz@7soAkCLAOZZpVwXtwH`6Yh-h> zSmoWH=Qc%8{E>oiqy`Nj{dyd#9?|u0M?Tm?k+DB8Xv*op z_bJq_WE$#v3Erv6ae~x`nSTP)g&AUm4nX2+jdCT^(h2H)BT5Mu3yP--hKcIt)0FS} zXwJCjUNy|MQnD3=@I4;xP)c4WN0;ujbwA(EP0r6n=2^HzlUyRnpo=Uyk^2uczwiPe zd615jf)OpLi@@r8Y7ZC`mmt&etC4yAe+Q9eo71N}==`z+^--=#htTZtl_Bh-rTZj@ zc>*y&zy7Rn5KnoGomxv=8@MWo(OsZlRL<^XK)DBuW&Zx`iKx!V+|?DNrMv>AuiB*Vk3C3J2A0(77c zQ-K{&yyxr(5SAEtS1|A91fJx@A!PY)DF%-V;>K1nsAckiL`8U_S3Azwkj4zD3XA0} zOfM$pCI?Rh?~~;+wixDW^I_5160{+Q54@|O68~v&inPw-$m>f-srQ8(X2}jg<|~~? zXTdGdcilli`K^~lX*#+mJc^cguaxXR4}Fa?Lz+4@LX;a2G1U|z#p5 zsbg5UE(q5*dj^T%^bbj9TC^X)ujy^eh5r_PQ@?ph-=3AD z*#P2$@j}d49ITvakby9>9MKte0D-ek&j4)nW}5tsIOlNcqMkY}-X#=JuuNjO! z&BX2Fz0nuses56vyw?0}GPy`hRy`@tE^&kM&*Xf?ObmsX7VE$+P4Fy8Oz;mv+)QFS z%UV`90n~@dv_7|T+e_@qHl|vH*;%%X7hohC{v^n%V(OhH3f1A^9$tj?>@(zy6>{H2 zfW|TytHKy-pb-uBL#WFYx5=jN2C|zVh*7Yx6d}4&+F6C9QYr&-=!S<%0}LmsUvowh z-HSp0xCjd3q$BAGP%%ETstOgih6S2+&DTI~++GJmCaSfH%1nE@jZyeTte=g7N7Gn( zO-y^=M0bR6I*)n8bMy_P5gTKUU3(#wu?&PEl88#4L`@tIM*E4i*mTL?3*&8^@IW#Stfxfr^_1^p1~Rz ze-viz7}9R89kf(_ea)xTt^F+6Ggax&_gy5bl&25K7SG)vZ-P95^uO&&FWlgqp6j*B zcQeY}F`CQ&WGDbfl`GrKaSk5SQ909PUJMz&(lfMK#=s{9?3+aOe#nbklX+(^oKGp{BuLu~d!)2*zGacKPK2~z&sXX6j7@;~HsZHZ!;@Wcz zgZ;juIK6VZDLM1tM1VNssVYy$wLYZ-Mh1Vf=QmKU-)OG}UEwmAm=OI&3xNKjnTv31 zZIc;xMa4Geq7|OrxgP}}-7H@X<$fU%K9mBg9`d-PFvM4KL0)92``}LqCQRQFbeF1+Ec~*OfiPW)lTd%1SUpT^@tnR zyHryq(*dE@LDIk3}+P65fy$dO!xt`-#i)e2I91du~NZY|fS(idAMqBY)Ik;JG z{EllVUqnm6TX7g$iq(mB!4&{U{1~V639`Cry)^ zMy!M@_xudk5bx%=xjUV%`-Fq^T57O9$I89RvO_eU9 zPZ3pD-VK_jU)`8^6KAxyH)CBhh_Jgd#&ta>C(T^X2f0lr-w)5*-X+h4aW%`TN{J#- z?R9Y}q^)r|#<(*sttMQO_^y^KXl}IS)Rl)nnn173*S<_E1yzL_cGsK#k5E_8%htV) z#VPjasHr}QeHE0wutbtf&;(k(K@z#>l=_OwJrxB^Zb-chph700~KNJ z2?wR&c=n@h>lugNkp5h@bRBXC!fzy%?kPoxXahjpTMy~)9rB>FvFVXLD1H?yeR;9I zQ0a==q-MeyDG789fqtQ5WngijXzk?89l;vA<0x#88L~jxj-G1#%UA?D8hN}%^dR4a0;6Ig^_Ne zLnwDHH*g>j2#c{HOF1nH1V3+2A9;@Dy%f~!re@~UJ|QDvNt2RJB%Tn(S*y-D=oHLD zbwBQ{HAgAG5D+9L#geY7WbQxXr8^%$Br4D-ntL#yR#9jBN*N@4xcLmsry@e#YL*A29CuUyP)$w439oxpKF>O|>d)~i!{TTNOukrUv(@=JNyNTR$X z9}XxEK37(<;dkmLvHy z7Q`~c%NEf)QS@hHzH13kt(Gxhse6L|RuzbkJ&l^X6rp#*u3YeQi?=?CX&zL3Pwxa5 zW(gSdDmX#TG*plyzj3RdO?dmvR~^a7%qAhMvwj=};6s`y3a$uN|=Z4ZRJC@he*am5hEV_g{V$K{{~^jc;Lzf|F>lePL}_4N@uHX+8weX z_`Ir58Ec3%QbhEiKm)IDlUOuR1gdH0TSN*qSVo1DKy~)r?Yfystf#s)z{?J#d}k3b!9 z>69?~(iJLJShhu}`&9+{FCC-n=y{y}m$V$qsYRo3#uJMIiw z#yLmM$~3u!s#&7bT-Tj*^$nDsiF zUE^{pCq&1%!43Co)Tex*z%!Poe1QOpm{>QDeqxP9P9T7M^WTHtgc#3KwuTdh=MI8U zQloGRI-4U2=~fr=_bH%ET+3lZa!XQ&X}_d`}D^l1RCMo*-XROB_vS!oH2AK7E?n>(A}xP&Hnpf?Pw2_5n)JVmsHd(m%eb2&ql4}Maz zuGBfEy?vk6IY_;fZa;u;Dp5iwx(=bRnmGYdLA!72E9cp>OuEG}$LCY5P_Un|@#wRNwXJ{3*i*^OY1wee^ta|I9q&xY zU%!@nXmD>Z1rNh2)y|z;A1+)^*m7saRycg&&$$;-0f`MCz^vlK#(7`u{>3)&F z-7@3hWhQ%WbfxebIr7-K9PP5|ip6NnY&?!)36XOq$TY|zGHCF6bfcfLJf0E`yt2zl zAgT(qsyB4s!PX9k4>Wm!3A_FstwjIIsn(o|#srfUoso*IJqZPJAM<}d^77dlcBMF7 z7#vD*psk>!_;{EC4uScS{mYm-+6k3Ob4BorfQfoX;XGvv@tKM8be=#W(LK}h9EO|e z^6}VMu+?|htDMf#M)7#WsnMJW^?GW`7C+5$p+dq+8A@==nr)%%rjRe+C3z#q$oecP zEcC#S3n&K*>n0qY4x+U}q+9+NTTvE;M6M+00Dgb{Pyn$5{K^PpirGA*PyZkr02mQ~ z@cdW*P{#iku~N*^#@W=7Ud-lS`BTKy*xtmHUdGhU+}VPFmGwVWD|MEpBM$^nLic@Y z3sbkF$TGQHVucWFuEEeB2RWPo87Xu6(t|P3cfOa>>dpfYm(-0@;K7yNZ|eD-ua6#X zjrH*lk7jIFqwiOCN4YwcyP9=dX>=A>7Dvn8TYA)lQ_F@&M{Oflh23tN8lB(cobTCU z;9r|gM_d24m+AjKY?_RFHGD&^YslIfuw|=_IBlL!vwG9gEt)(vr4J+1 zwJ#f$)_S}}=f@Xz9{%!>l-Xv#XH#*(sk%XGa!kO(R_`erC5zI1+;!1*SU=bKtsSYR zxjP&t>Mqf1OglsM3ejs?J;U`1+i7||V}HT^$jJdHIsL)=^t!oi=%rr+-Du*~S__1` z@>gpujIp)g;?2&LgD=}{Y&%nbq0aP$?=4#&q-ln<5z6W#`#%`6YYbY2%BJLI)EGAV z*1@LO=J5C6pTOUMzX5*){QUX*JVI zX64xhMxkQ8{q|4TU;mq-cf=1hinK@Hi|xzW@b(n@{V;ZzHb)Nc)kAOT)j>vl*qdkC z97HaxH7bvMZ4REUW`OzgA3tQQm&ESB+;aa%{8L7DCKitWXa6x0u&^^S|0l7O_ll1@ ztU4a}-EBsPn+cL20zK)YqumJ+OZY1UQbetr;;q&LUNI!PV0oHz8XaY-!KASAkaRGu z;*vB)N@HVWqh4d?c+NkTmt9_%D=K`g$;%eC?C0za&+P4v(@Zv}`APOHb1xtuLbUgt z1P*hpwaVn%&8+668%^S(qY@6@b>1N$5-`hUdMkrE=GWQ}41^?jHDE?8CTD=|?F*om zDe%BH=6Vz}zdOe^Wbkm)8W%G$DK7^x2YPtV?8qf=5-UgvTMfWRSiR@lRQ6VvWo`*; z^-k3DdJ-==Z3xcSAME=4$Yp6qr3W0sDj=!=V*L7_iL2!7=oWCUR?}x)f74FmnJ*nD zb7rP4m#j$NN9B#w!TP!+H7hA-Uq$kB%-dUG(a`FF{^#=u;B=$ zM=%-s%f$pxqyw?xeIA1q#}pU3g^|Wg{9^xfvaGNs$CRG+wf1VD-48(8^^XQ5a=|?y zA6SrQb6;MF%jtJ%oS)zO4=Fq}wlIG&2>);akOIcd3NnjGGYCPaW`m~CLR76H*o_0& zW?`>j!N92-SoWHLbL!))CC zHEe5mU`^kevE9Yg=W?M*4kQu9@uDW6>k?2A<1L3KweajA+7qab<{gt;s5fxx)60M2 z+y@@J#x~u#d;RqX=ue^FTE5JD(e(%L_h;`;->JV?f5`mO*l8qFStfxdp{vZgZNB?I zMD{`y3UUab=Lh~61~TZTlO92|h2V#v2d-0y9}TA(rDKr3ARi7Z8WnO#${;BZ!#KpY zOXv{ZE7g-oXQGhHCN31?Sf(^fZqT7h{wDaQ>WvjRrt^s4k;*5Qjopqd9+^Hcb_n&5 z?xy)A=Z(2QB@>XUB%oBTrAU-yEeM~Nh)@HkfS9%)D4c*&eRU|EwxI}fTZkMH&k1jhtcX?(7MzVynmC#yH z*vjtaCtEc$#}s#4!r+P=o+EHY$L1?rP)+BrJM-y^t|QeP2t|d5k8QoqFXopK&eHM0 zKRWKj?#S)z>|opq*k`l%bB}1Be7CJurdhDO};t)0O^nWP41rj z8U~OqGtDX)z_#Hv?9~5|2tXK_kqDw1g&+=y5NeJg;S3P(lkb}ri6n%pF{&gF;Tick zgmZ{xQ^=W_Eey-d6Vjz}P%0!A|DjaNq#%{nRO(SVV{cOSq~T2 zlOIbv;&yEL((oObLMUli&{9m#fG{JA%s4L_TFM$%O{I933Q(GwN~X$VWG44BCR4B- zm+YZW(Q(SY7@QGd$B<+=YsH{^ z*F3*yUYM zn?mC|doWAG)(~xE&N*s?b>-uOoAQ&qQpxA?UfZFr@B5k-JVM>|A)T=~tKC6FmzK3x z)git0cRS?f`9{aB(W~*(cJ=i}!VSFb1kR1tMR^uz)_YcG7DqmoeDg7ve3E&Rc`)gG z{I1wTiFZ7=7~BJXqZ@A-^Ahtm+O^xc8$gF2TUTcndr0$?>)88->uTd><0Q|TBx=6a zebqp{+B)9azpB>>?sB`$tg9-_DZ(jm^5oLg+gOLShlMISX+*JTYR%T9v2`nxACUDj zx*F@{+o1l+Ooo{Z`!Kp;#KIV*3YK{dU1=JDc)@+~%*L6Cq^Ns-;eG2J7rSlCW6NWx zW3ywsV729-HZAn#&NKH;^q05|73rh|1 zw?fn$Q42+yUsN ze2c;0qdS_PAZ~CG=8hook|;vr92hM^ki-!&xSUBLu$UnTSP_3!@QypOy#W=O0Zyth zp-%c}F7o!;Ba!$~q&J(&69TU$1GHg5HDXolvJDJ2sb^Edl?z*p?1(2@F0J9?I*#|0 zS(EJ*acitkpIRe*eU49Pjtw~X1YDD_4gY6kj=A|gCHJsgJ(FvUt|9t8Cp*U}npq=$ zM~wQZe3Q3c276x`Pcrx)e7rE=#HtYKk|2z%hnv4}xxd{#tF9iOF~QFYxZtpK3kT*M*QBjk>z9vmZ}eUP1d3?k9-u zjNHmLb`)V$@gd0j8V*Xi2<8KB2R$8xUnKNlQU^^PMAL)H_J4+9xX~)a(_;)wF*HRz z?Ub=tdSa$UsqM7BD5Zk1+x1uj5G+_2hGOyUrooYe2k{(au~FCuUJkn1sHf35#H(Y> z55w$YZbe}(=`QUq!7TzcMIRMEcCq%1%K-4Bx0PU?Z@#fSnn#n&AxG~kv{oeNg^H|F z%3~BvS}|?OixtkHnUbS(4bACt`N+p`93inqAP=^x7YgHLp^I)yh*kkyO1a!8 zm35Ux=R(h{;|&i>4ORtTK{4u4=R}XCMzk%$JuUn{AcPr&5Ca9?2myX1M6^i=@M;jl)GQ)2I1pke zMD|FJ2+_CWV`|R=XU2rcokhTu5@K132{5nc;pz$j>I_IijUhq}DZuvYFv0=P!uZaj z(&nMJ=aG3Cu$dX4neVwu4Y__oDbvHp(}RsrjCdj$(25wr>I^Z_jQ?GK08b8ms{3@N z`n}xKDy9Zl%uEfU6-y~ff+bZH)so0jW85WsTr>|VKkY)ZOe3=jV&3(C9)DFg;#H8O zxe}e@Qb-as3V5Gyc-4q*+#X2cC6Io{Qr#EQLE;(ODvu~Ri>p*R6LGkP7e9hMp6#-| z;4KN8w&-0XVIb9!#sHiuCQ@J)`fSYM-h>}337Y*$DoKyqEdRXIUr3Qk`5r$@@P2S| zihYIS%MxBDvtX`BirE$a{KNr*l6nxa^UT_ON{;B{Oj> zM{9^pKPw*#PaDv;*{QZn8lh*g!oWhpIXb;m-qfoyYbm4h;#HJ9%kHn#RCzA|q_n!)b|! zW8$=CTg%Jny6KsjkWBV0$@t=&b(tt`e>qRvgIAQu($#GWpH-yg8$B(W!xl#Es^Hr& zh)MjI0>Qh1ms11|o`9q)p(-(bY<{aP^gU1^uK0x`D~&Qh)e+`W!54dFS36Y9A}-@% zf9o64-EqD1uQeI64XL1Z6nX6{k#2T?7`s>7RW(amCM`E=RqVlmkovJe zS}*U&G5?h_E9WtedOYvQK2-ChNlnr%tblH2T-vspj+n{)i!?g5XXCABHJ_g8P)%o< zyM2bqXB}5U%Q)2WS6BCTi;M=o;Lo&M%P@;$&c2gb{U{hr>pg7r^x7!8-H6@@x{Wuc z_r4jL@zhQ1`M?HbaWY28mK}x{Wk)g;FBbhD3sE zi!D*fg>>5m^X944@DqQl;rex}1;#AruW8Tk=Z}+_88BFjwMPZ#$$aQLF^Q*mBx|V% zZ62=n(`otfM#C{lmxzr@rA&p(m0gzADx3Q(Mg1;E_8~dA zARmz;8&pau;hk*G_;%*jTMdYyExac_S2EP6*-&~$Q#J{epvYe=*%C}pV60=y7)qi^ zih2WP&R1Y=mL79e;tzfPE~RD_5hVo`noTtp)<56)5+`V68BL`eDbldWAt8+;73A9Qi zbHWFSBGyGZ>`&8Z5^TLxtV?z-;}gV1r9KBkE1i{$looyGh>s1WG50dY-b~p(Q#@`q zCsk01v?`Wn3sT{47do(llacitz$gSz38{lpKr zZ#4Og+n?1}V5@M<5kvdByBT-^q}lo8%%ZJ*DU(y`F0F68!HNKU$Um@o&{Rvl(j~`B zdpF$1&K*EM1`_d;&s;(G-*-nQ?FjepMC$ZgyW8D<1rN{C^gg-)dvFjxkA9%wL4duJ zv=}g+IoX%_4xpL)R?O8IK!LpC?DK!mnDSKxcg48(7JQ+14Nxf@1d`4qy`7xQ!ErbY7-0b_fQw2| zfCK`bAdZ*)st0(2LgVllynFb%gR&Rle(y?ACo zzKmfS-1^rh3|5cTaVnn2$6F}>@_JAnL~ycVnNJ-?Ebg|y4Dwg2tBZ@NRb5`zp^2ky zJI$6V&CdMYetdG9fqmOc0{aEgyE&HVroSBuH{4VZLKp!gJ=r1@6u#S&UEThoYSPK< zbah7)BHNd(#0K~qFM1_pGFhTn1zS548!0HJXg#PW=)(ZV0uoff0WGD_oXtIhr`|t) zoE_67+d&d%zhW*mn(Z5=sHyOPOx@7uIJR)952a~@)>U0eZgveFG>FM~E>*k)Yz#~# z&SlU9cEX!G971YeH`fN@KN29w3h+P}XF*czByBlIT%uPeQk_u~UEYl91iT)wg7Mj9YGPY}JRMo2Q(SwHzNK-;M~pws_~apb#_sGEg3FK2=_tW0U#S*mI3z93~h z;y8buTtxUA(bCb(c3{jqGjoDuF+qn13r1c<)kLcPB`?EKj_xI6M!dTN;x=}MTfl`q z{tRGeQ}Du9akwxR+OZ^2(b<(r1z_R;J?u~)K!V01pYoZ+z{yI3J(t_9qN!eKcl7a> zr?2huU8yH6O&{VX(_$1$Q)&Q!E&Rl5_Dp&m6#s%d#!Op>FkyR-m_6@`ls z;DW5VrNf|Jm8aqFmc45@^Z1p@O4f}&M&EATZ$((%i|i5T;^gM+Eyat`{&0$OztOO| z<8Ed&N$TsB-a3V_10#SDm>>>Cc&KPl*+Q*jelKBlpixX?r0hvGMiy=@Y!Hz(76oD^ zZd^l*8t2GdanJfM7_oE$oA$1S>3vxw-emqV>SMa5FDq99vP^3`O13uig}C`@i1g(} zuX*ZUTfsI~riDp^oWa?2Svch|(s!L1b|E8B{XOq3yq}qf-xA3lP9K+>Y**kW2e^>KjVMfDVAaNse_Kw4S%;>;iITuK;KRiy@SNHGh!9sE{ zztd^o$@Uw|^0&Ds45@klKs$Ju__#IRjkqCCE_i8~o6K>YUzY*FzvAJtvfGM{v>VKd z-su#bt|n+*^_9zp-XV!SY>kEE^I*$|hnl|{=RUAudL2McJEEmz(2)Uumb>=Kju>!0 z`Ku$`MDGUpo;zHaGIc-F{B-@m^=QcN<#tRQh1wA~gKHK=N%alc z9zvLD+E5#Ro3;9~YY*i8o>4t68{SRQHz1l{_5wF^N@N5jbD0PRSqNOI{e<0G#o1og z4!pkpZK%UuuF=v&f)}s6^;l{PhO1fP6jy2#nG5@LUM&{B_r@ltRYU;{lofiua zGtKubRXn<>MBxWtmrm>j6DcWM4$+O80I5Zu!XKKc!|ARGMc zbgUD|gcX^E#x~Ou?R{{A*$G_pYAcxnj$HupP{l5_E!whL*^)y(r` zOUB}A;ykxR@b%)Bz!0tzH@_s9vt0iz~cqg zx%FT3BIW*-{D)N!I0+yfV@(+{UGaj+C5MQ!k86wALh6*lGsg$h*3e!B;B<$?t4S@y zyZ{QYkl36M1J`FW4(=Us-~QE@|GKPVB{1>H11deRu+L6Y{iUO$vT-xzw~pgpg#68c zg!LH)u0sr;+Rlm|4|`0-^J~E}VZ4`fj&<48PS$>MsLe}HIBX3b#!lGDX8((=R_NqS zp?r8_e+5LW5|yb{uZGk&-F!Y_F@EasVDjM7NQp)a36a!lK&Phh8B@_I7Ogrqak3}y zMV0F6F`nm>4XS2j9^f;HiohYIt<~U2S(=uRLci{vdLVs!vj0a8{@2Ej;B5RN)$ z6Y~x)-3)r%lC`V6Q#X#?a!c}8#qW5WIBZtJ&;Hh`=v4X)cjf18d~np7GW$rG;p7Mi z5sm%6Kk0ezoCF^*GGRHFm_@c$HdXD@a2%Tr&rsFHW?&If(j`j7+$~U$CXt)AkjJT?xV=B)2;sP zXUCZ|0IYk!kgygE!ryHE;fd`f!?Moi(Y z_?dmKS_k=l znKFZ_Z2Ck+6LsC!F!Zu~?B$V}86CaQ_-FrLq*>9|oaQ_5;LpYuya1Ntz!0gCQD#@c7R0WB16ZG_v48j`BGy*n(bsf}nAJeo+g^c#PIn&Dl2vzg@P|A835dDxt{I zF%VpP6CyNOgS;vX%Oheey0YJFx-#rHiC3{FEL~#CNBOqf2tuw-`zIY@+7m2#2C(4B zdZE#=<>>YjP)bpygc31WKeR3THEb(#$bP>3wrwI5fFtGG9bx^8oGd)L{O_`OwOj~Zs1B~M#VDZ1u z@VLTjn+}b|p<>JQz<4l493bz4gW1SO_T(;@tE7Bcb+Y`9lCOPUXNW!-!)Gqw??~!G zra=Vxdg%y|0JBrN{P#*{5fR=3{o`j&y4Ce`zDAt5{W=ae>8F9w#+EMP?h&T^98wmY zXP&$rbP*(lDD12f0W6S5U<1P?@ZcT%!#^g`_5L=vqwgPU+h2*1&vAUZEe+^_4(`nC z)E=vYi69nCN=n|@$g1GhBEp(TzMcQ%{TPh~aiWOPJFcSt&HAQAU);bvK>Gn+l5_yZ zMXkJ33@9v>U@6xm|B_5gv)_r{%M$+mrsMeo8&~-F26u&c4nI%%ph;xyopc!Bs;AAT zHQ+|q&%(Kam+#hq2G>D=INq{B^3o{hrQs_TJE%pnI?+;GX_NnD8kp?3+1g`cxN628 zE3QMM?w3$-&lxJh#50G_#4!1{QWww5Yp&lkBe2#k7rd!$Mel z>d0Rj7V8DsuRKO`>ga_*&#nGd(3zolSyZeuagY!e_X-|pQxPHpge)i9OQo+gP`8A7 zl0rM9$S%msCRuK~=m#XJG3f6?Q&vr^4k>FJ2|aXjs{e4BBQZn!6ZW7ds@;dc88RXU<1RdkkhB)*NksEjGX4I^5Rfgjqxi2`w>ctWxUrYhUt zo+&!$m~tfILRcM2v(@0_fQiup$`q?sRF#e+jKq94Jf>Z?Br#M)kOgk+WCI3W!-9;*#WwYeEHGL(i!@|N9{^73L-3LFQyKZY0Q1q;W@@7=(5 z@;!-bN7Le3#6R|(%z)oZ7%FkxZ4+;{1AUr?-NAHL!AznZn$h7zFxD@=%a&@#3~F^a z;;9N%F%BQ?PTpGx5*vL56R2h#%$^_4nBQIeXS43hK$W+C(dy7P+RK=Hr#oxxJ#tq( zSC=fY$fI)COAUuZvm=l$M(lB9C2|{F?AA$as`zsSE;g5J2+f&n!TvFX{Q#`g8z4z5 zOb81sHCkg*Qd&pl4wIb4=hqzh@kJBLm`PBXtBKh_B9 zZeidpzH9k^5ki8lhJ+K}Vr$4n&>m@5z>NQ1)Jr0&CLV**qyFU#8*rlNSu?y>a(G@8 zjgA`oso>1n&bFI*t=>-DQ`}B?m0J;SgT3XZSiEHcNu1vDxOONjBcGc?wcD*F1J1Dy zbtCa~gZ=2*k4~N3VO;4kq{fYe1G~J=A)a58m@5ToqM2)ASY`!DAE3(6O*NJF*wB^d z0wv9F)j*CG<1ts=eK}L{rON#C%%R3wh+&o18PvqQ!N|q4V6B{N*ZTr>l_dE2$-MI; zwFlI+uYk2n>K4UR4%nh(U)W6)%~xJ|Fcoc(KI-sN80B5SP+Zr{OjjPS;*~ROQyjKH zgnCP+F&T?t2z8~Ws5zzhGc`5kldAT4Vb)SfifM7)EO_ocU|<0ck^4^lBa^mBf?7wf zLiaQwM0%NGDv1`e1+?mQY?921m$;pk^JVgTJ9GWBTr0Wd{xW^)u)BOgJ;xFrg-84R z&ZMu`g?&@<`o1RPOsKXJzw*=Rx=y+}7O7>K%CmJe5+bFpV|i-kro-;b$lU(iLGCOr zpde;Iqz<{v=Bbv!p=@1JiNFq}WFlf`9Q0r;|dOB{fBT-N)@& z_Q`9Tk&(OfAMF!hLSsr|tRuqoGE5RAw3z04bLpQQq7-c+QrZ7iogw(n>UL8Ia(uWr^8 zrl(Qbj!tY8W)Lu$?Asw%%TkqSV3690(4RKwB7E-BgaTJ9D`?)W*{aGaf?|qV&Al_P z$w(O9()uA$?zg+Jf+=Nzw@BIZQHS^;r6y(uCdOQSe~g_4nZ1I@DFHdk}Qom_3p zZP$1seujipJBu25%9%?m(YU|GST{yVuG0GEPn%0eB^9dvKwX)We*|A``HnXXbVrSSC7_`%Y4^v5)A}IMKZNut#a0hibx)`GJhC4=W3b^40r{)B$~dhIC7zg zdC7g0=PR-e=Hz0ZK;yGnnEY&c7CM~Bouw&4h@7z{uOXeUs==_LaR2VuMd?}IZYej_ z6^dCeKA}HeeO4ev{ltozUU%9g#*9QR6r@_NQoHT^Y*z%e$?|jh+-+_aSi|!cZi~gu z=og8%@D97?_(J3iyKYO!pa#;YPoRqRYp5lCD}vKc_>OzMy!*U*+n=oSUwz*bH#MJ3 zL?Gu`rs*5Ywg!Jy`jcTdR&7`$&Npvb(Z10fMD8JjU>KY1c%X2*MvXc8=2whg*R=F@ zyk?A=|JqtU1oOi3jRJPCCKu;f>zBw+qFD>Z*%onTh_^Tr;De5Z{qMN`_Xnj0Zk%h#i{v$dq z&PoLH|0s|8Nu=5lT@P?n0INmGBh>wYz&&8hmL+oNles0Ieyhp*iVD8l0_}*6MT9g4 zG+>{D76IUo2ebnW?8EY(HMhR^re>HqnWG*e%N<%<9HQA0bsUHy0pvako)&;{$Gk0* zjMW)-%H;?NBOoRrw+rL}ojQEAzeue41$_B|y1AplMEk#Jdkd&Ix@}t+LV)1G-64eF z*0{TCaMuu=#+?Ac-GW1q;4Z=4-QA^ecYRIHckcP__|JRy{Ns%`Y81PA@3pno+|{G0 zIoFOv%`IX98nW<>t`c2X4Awq{(cw^(>0v9D6NwOfhIx1w)RP8j*o6(W62%+$sSem> zmywvz-C%kw-S8Aw1~pFmh{m32{tVe@4=zt8xM3gDIB$IW~xCxzf&lXF1Y%MXfv>l*Lx>*Pjd zxF^^5MA3KLw(;ho^#h-OvkBiSWs85+`U>TXVVR&$KgJq_*pIS#*S9ntab)6Aze(K) z-1v9Q1{wJ$>m+HsQnESch@XFnqoP36X(8S_WmUGj!>3^Fzbh54QWp*|$KLaFYfI8Fd zvmFO*`?QX>&w56Ie5IFWDKi+LL(M)UtqwxAB78a=p=e}S1Qr-On?0<`RC?$$^&j&i z^dH7*`Wn}FZrqrjvt}e>uK28wl6Cf&*^TlGdO^72o-6m=toy;twGa667@v)v3ldOq z-kWW4p2vV-24%Nk#r;PmE3~_9^e`w7AtZm1Op4?o-#*28ea}6o7rF!PrQIdWI~RzI zTr_P~p5{IiZ977^+WLuDt=-kDRH_?1Yi4aZLe~#(hTbJiV{P3iNv?blmcH4km5L6f zZPn0)Y#W)}a;n<3^+OIi&8(WlAw^G+(B@7x6B`0MUA&;S(kR z__DEti0z$rn?;{hs0ZIx$kuVsN8vTQwV3DU)Ch53mNxD-X%m-3;DO`Hkzs1LOJ!;+ zP9h_b!IHuVRPi;CPaMh2@yG0ndDrekP@0V$(J=ff3A{1oSD9ZQI{@w>SE4coBeMn> zl1(T+iR_(DC%&^b;>|&ra-kT&NFOy6L2sh^TGX0N$lYR6;cB@1_bD5=m4Y0fIVdmp zUA2a$tTwUG~w~gVG6K{)v941;Y%_F+#epU z4<#cKQv!3nA9oh38qJ7Tk8kE~er&?5npT9ru_RCAW*SSvd+3|n&>61XBWhp4GH^bz z_1=H_5y4fuDUkYk+bh$6mz+F=9J z&McD1qYlG8>-QPR5)YFD0S{La-p}q7TjZM{xS7L;J4>C|dnv-n71=BH#iQjV>!+~> z4!{C;QEK^PPpuWH`?6)h`UAuD^S%d5=D@&Rf_|zjo&Ex@1wX;}<(-IK9XLaMl71vv zFH@r*JANOiv&GEh>S+^1DrOjsn4qBdRBw!dW7|M zYQ}ZP^1@n2eF5gUL$qcm*W7?kIQN=^?EtJIHt_!`b+7n@G16~i--@2B?;7$CaJD9GLZzEB^Pf` z(*2lwHcK{Ff{q)yM%-XIFDjax2aG>DWb;iv#a)}_iUEy1b{vnhl{URbyxAw7oiDFh zT5fE0L;L4J6Cl!l6|%s)8`S~Ku6cM)!WcEJJD+X$ofeOd=BXbNrB<8zm{y~UFKzSh z@x(dtVxClzon<+1kedXVJ3M{n)WhXGdss}9s%Dx%VvKs>BXCc@Z5#p5pMV&k&mNOk zkHF@;lP2>bF^11OVdu*l9%{+w)p=L+?WI2UI?4n#33mxe2~yHYp8P$7ZypjXCB-)T zn7%Bzhp_RQ%xp*2eCLR=nE9N2@)?xL11mYAZTOI+X#)31T6n%p?HnV&t8=CRNF%SwfiJ9?pQ=H_pEb@HrodIZApx6p_O8Y_4YHJb1i zzU~40^&*p`K^gu!&EdMBQ$B=^9?nOXcn4cO{Yay|ss!HnbI-c)I-Q_iuG#6P1Fz7s z`iy(NVwUe-jTJW2jmOOq_Zat9!lop3`as;6eImmap&pA&FRYin`jVL7XoKB*td>xX z-W!d;bc6;bJMF8@-b7^CbFa%OK`wXP;&rTBCQs!gcfv|o`pT|re6HGEI8vxllB?0yD@Iqt-dvj`i%cgAv;;Am2I;4gpH zuk>!2xV>D`zL{4d0JZET0qbIh>*ISQ8^wV1^4a{&zn0=9NFOL*s!A;nHi64YOY?U2 zW%FjZo(SXpst!eVFTl&fhFd&4Yofac^01Tq!*eA@%1ES&{a!iREG-f`<&NLt`@M8VR5^Ncq?Rx#Ee3uLOA5 zG%GpKM0-!r=Jg!SZY57m%}{f+4egD9cE5$YnDJ z@)>?`o#at=C4QZ8J}uJvDs8eawLmNpY3_4N-eQSz(<(?wkm zWMibex-*?hJ3-$ylZAX&>ldgKlyanW-{z?TU9I*9tS6Ef6v8YNW2Ku06t3j8UEJIr zFUeJl5OS8W%5NuKx;mFUh@nH?LJ?~FAwI&Vsip23f9ztoKb6tPlFjV@j)ubwjJ>v05^T^&8qop2nzcg0w? zDPYqoY|9pR((X{YrxC_U&MkHCN_bve0T=>Nu{OChIR5eUB>DwXc;Z8Vp;0p#I`RW z%Ub1FpmqMXv|TRktj4@+QOc}5hZBLCzbEN9mU=1hcuocn#P{QoWO!NbDZ}N#ytQ}x zlQX)j2`;AzlAQ_Vi?>))az~0W?#a8S6QhNj*ld}fJRuc74=->|23%uKt~$K;aTd~1 zwQMA=W(_DTm@jtkf2hrNEU@q6bPYtWAogFoNhIG87Ep}h9QJ%HGx5ZZ;>J}5A!k1z z1+6+0-C^Ugxkr$7y3ahpxYs<$REz5rMOZvf@^y|$GuI{z;WH=I8gB?QbN1TeqRq=_ z#jDKSf294U-REcdAdiaC#z?MAu{i$`DkxErUDCc!6qYmNJ#pi?mz%H~x^h+850Ny7 zBw8v;9a8L%BrW*)^4X;sLY#0(KRHrx(EDgAQ}^d^sd$}wJfpNFG(J5oTilKKbH=r6 z_1w*St$Z0#G&f7rShOPs0UXjn!g4W^UYqFjR6qC?37;7T@!NR_jm*gQVoW4dZlLz9 zb0h90a92%&4>~L^X0kWuhdv8rbRR-3ap(L>k=KE?%qgbGzxXbhmv~U-%dV71Dwy^# z9CaL+>AcOiUvxXegsrG*4SzM5hmxPZ9N;0IaupUiia0a0NHQ5E@0lFw4E$Dwyo`B+ zbZ_pR_VA|qoY<`JCO>6j#Xag&TNp$%bja(uPV)S|pFBVnoLI7FPvwb!hAQ=&AenrRt^Ythv^lX7#7(N3;C;t!Uca@; zexBB7WVS^$cziUuyv$Dy@wZ>ihi5r*o5-9bWf=cKPv!f?AzjauUVO@tF)maSp$66${txakGO(+ zPmkBtoS)gsjH08%r<+Sy#>11I8ow?VEaR*jW!DrM(x)uFRKLp`>ZSZcE6JiK1)074 z7aEAej(hw`Ghr_8o7-_eZqX>+saer4JuTO%%K0MaV+YlZn>^_NQXQ^={yEox#tYQ* zZ!u%vFC(75HDJ=sS>$_AKG!eTx3AYm-r5o>8M^YSV!#1AEwaMhN zD5pSDhNIr|3^!|qAuK-Lpu-i4uU!Hd7=12a;rDRCk0_y?%A^>6em_D;RLh1bwfhHC z5F{#cTf_y=1U;ve%xjL;Eb`72LrbO#R3FM~O5zQz9H#`ku@rxOA+~*3tilH(1>$gp zP4ZulJRaX1)is*wt$H;!wvJ@y06!GyNt%gn@a-1St@B8Q^fthA5-g_7>56%C-YwZX z&IZ;5Ts3#!bUBq+q1Vb1-)VN>CcBg_003jh-+32GWH~Ip@_WsATsD`ofMPA1FDb`g z9u|6ZH@coDVn_Imq(hY5X&QU)lGa8&mzCX@M<4F!Qyc;%4o5xqk!ZkbQ;F`@dN*2n zCqIL0bGS{vl_YW}ENe9%4n~%UCwi+Yn<5_Ynl~y>bWvlKIw2$ zU61#?j_hx04LJc?tk3(que|&ss2;uAcO6W212s5sYpYS*SQBH+9>ke1MgJmYQzEB{ zj_)G{ANIzsa~du*9td0rT2Wdd`;L+UDt(ZpUTl>O`OgWS`TQhVUV4jVOVSU)SJU(! zZunk9=?a~vnMfo`g%gD@r@O4wPF4aK-DgteSv}JRH)^Z_~F2 z*r!MFsan<9Gj;$OMl;T%T04H)ptxdGYVH^gO0rzFU;@UdM#5T*S~Okjdy=Hm-q;;c zMXrp>#gFcO#owlFxd@rb;J%6{!r%i%~4KD2a)hh%dBtgZ~|1<1lJh*f+M1+%fG zCrm3;Ln$b7sPj(%dmbYKL23`wk?+0hiwVmpR}dMCPmD{mbOldDgi`I!zk z7K{bhPqIJWp%Zi(@PzqR9CO#~k9Ej7!T=p0X#*HKyUWpQW2kJShY*RWc;DcyyZnGJ zYZv()@W{1=x8*9)DLIwm!vmAv-txBI2XIp5KiYx?|xcbSay0m zf*x_wjr5q@!BD5hTu+SR2bvrZJca(4^5dp$clfHv_Igc_TkS9@sh!yv8-do&n@})xlXIX{q%;8EfV0VJG3??6(c6ELAW|Kz_XhTN z)MLGMgiJ~#HdB8D`=C7iaD|?(^21P)<0Rkh?EL> z5t;t)pWX-YhMW~Wtjnd$Tq-9u zY#n3^Vmc+rR2}8vt(jUnYwBbKdq8vfJ|A4H-;~cK%vPs0yq({hTR$9f9vB*gQYxvH zs^KH}p5011U9j0#lq2g=vn9Y$SzcxN4sad+>`Uk#f|Dt$*XnD%&~bw4ntV6WIj+{$ zxeI+;lt$wS^`p{8G0-Nzcg@LS7M2v7l;#kxaCV*D2|095Gj+yHd54SU%A@gkUpCZh z)$m#;#Kxj08+5d9;Qv*J2HI zP<+olEhFh9ZM>v+5ARo1uj9zQr21rd`tjEIGLt}tNiSyPaE|gR=Y8eiwd@PtDFQF@ zKuK9{EvNYoruX!$aw4bFNn7L^btB4D_6&ovX)#SP%GdKLs}byA)R6j#Cw-Fbxy6FE zocTJ2-@KP>2a|5q7giH)@!{@vElHr1;dH;mH4sy4$kF5>kxCcrF+a<+^)326=I!G4 z2)imL|2^{di|9ia(-qIeVF6Nvc=775t{(d!jn!RPlZ8>3tfr* zyX*!m?nj@o5rPWt(droPzJD;K?#Vg3!#GoBsk;|!JYl{ij)gTs2izmFqm>{ zHX|BYUMW4>J23)}jbCPOQMEjLCUwAIH{_4jlj#j<+H%T$gFf>?YTNEmt(ta51 zxA)?H?Y_@HLZxnFGLu{p{1krN{!{mszG*?W?K2MtOdix-yK405yWfG>D9(D*{T3i& zT`rygC3M#(#6WD5p@_gB!5kk3UeI$qsz#GX1pX3*5kF1ui-JD=_^4yNi=hsE5~LEofO5K$ zZ+KjYV>WF?6xq9Z=EC!zCmEl7C0dc%C6Z{_C6fG=NXaSa(2(ioX(>Ob4QwZ3(u9%9b~`&`Tc#&<%)Z%Mow_xY(9cZ7jk~b0=jLJzFXO$rDQi-FJkF^pny3bi?|V z>TyRwShY1f*$J2D`89OJI#I#-N&O~x*_IY@);dIVRoGvuU6suURv91s?=25Ds6#L2bE$^K+ko>9H`UV3+G7@-E7@Q z(_`&oh*cAcT!{wSvh&D`Hy-rMKg=aTSk4rVigM8a^Th3#*kaaxvVLib>@5*oYNK&E zlbV!@8cCW0jhu)NIj5~s(+#Tc%MeMIS$*Ag`)mEW7Gi;h6GWu zJPTiD#Sx|YG_^7CZ3dvdSlXiy>)Cy?3H*Lg_wSj=mDcUsjG|90;i(2g56{-4Xk(9y zHdETi-;_;%pNTPOH7#ABo`ia@HnL{pWdEK$U>eD|Kal&EB=r9xg4t$SV&c+xf)+gNWX01cNvoQRf@e!xC;CAOT+97ygjYQ>^Stb zmWG+eyTvn?cGL}0O&^z^V;T%I934BTM4f<@^0wM_2LSXHe9k^7+@rF?_G_R%-%ELZzx_i+~sQj}y?q6~|xB((`0yFOl= z&`MPF8PXA0z8fCpG>q^gw-fJ5a$wpC!g&D2lVf1-9XN`VEt8BmaQ{qsQb;71n^$tE zaB!M}Ys}USf_3o}3ej+tUQWPeBmXtsZ_YzsKT3#8!{*yNMoh&V%21dZK|bA*-tUGLYzMhq|l(@ zLRH8#sfON*y-UjB6}zb^*oZJ$PsP=pbQ<}7G0p4esy#%!2dtUqj$+5U$b^A;I3ZsN zA7P*qY(oY?c|Ji~IkM@Cce?g=Kawqs$8k^a^vG6y3*`C1Jeh~jI6ROlec{2{E&`+9 zutU{sG3E!}%xI!memMgh9A&Buc2mIdp|9bc`v0wL$KS)c0F6wn9Y~m%0E`U62DTC= z=4M|UNZ6TJ8AMF}QAEeV!t|;nV+JH)VP+7sv33x8mC~kTW#uG!EhAxOVFvtZK<7`X zn1PkKrRzr(1v(jXYYP%Vu#B7&^*>6?Elrrgmj8&<_u7)2ft3k^xTds*kOa+N75>=M zDVdl#S{i^AY`{j!4)!JvMqe1@Z0xNJEdOMw{bQJ{jEoGD4hELyMuOI6majtJ$_^%0 zsw5m7{}A+kt^GO;dvjX{8+!)zzh=kA#Qry#Z>GNmW)U&~n!Hx}KaNS%8Z4+|Zf(Y( zW^OHL4K)9+&tm5GKnLM32KN74sDJehp7kH4at0ZLzf73GnkdSSh7Pa7<0|%!CVv#j zRct<6o4?BSfbC!9e3bq*4{&eB4qt#;%*-s{6@S$=``5t?0Ox_v*BoYMRuUG@zf$ns zVdG@}kIvV6uji{h<6nOnNdWAuBmfp>utPAuIt4f%d;(a(*8mcBMsTleueR(YfY%hj zOv1tXn$JYS4qzhzfZgIx3a$?T3$+8l`2Y^^H2^@u2_6}Mg@Xj}XIcJ?o8uqjXJZGq z1TJ}Pm5q%PoB~K*^H^A3duRJ|&CJXO9xM3zbuGXt2LL=zu+3`^f9iqjvVePGV`e5{ zVFkDITFwj}6$=Xq8+g>O^;iL~(y;%34rZ|ED+}Py2^N?CFPV6zzsc|am;cB}sSB&9 z|9hYQ2e6C{tQ}rm4M@TS9_8z;{x3h0GzLS`+`*Mj;$I#Db`!9S{lDCU`E}%fbC16d z=v7JfF9A5gzr$Nn1gww`_N-U2J*EE{?W}*G_J0X>@T$Ld_Bzu)VE;cY%&XD=Yq0-K z5BNX2S;F8&a|MET6-jGT8}QowrTZ%>qGBU1DI#lN%ka;;#UP?a0*)8Y_-C&F4f+32 z_WdW=!7aW{^cC;Se}}gg%PY2Zz_g97ULpF5RVPrN@d|5p5)L-4{{XSz)nU>C;}D#_K1f*p;E|P?Lkj@l&|zg^ z)B^7q;FS3_CE?&?0sqYSH=zDazgXVh*u);ZhkyL%-J@mzKXS~04)(4e1;ODTOsK)o zv$eG}v3h+vGXA}lze!d8?`76lnEoEcE1Bf(nDb@yr0n+P<)yRD#mDz!no- zGmfrfSeG^{B%_>wb$Sl%lvHcHDlLGG^*UL!Cx!(UrxZpeUN0n$6KoV%$1Eim(g(uI zu5Q=w#yBiBwd#C#Sz+r1Bn`{l8+o|k-lw=~svME>QSH^Wgm^Be4o!|uKhNhpSj;{} zfaVZCuw2v^Y}h?!F^JyOaEQmsE$TW=-!>6hGi;`hVxH8|<8j+XBvqDdlk?{sN( z-!deO_>a)0!KG<{KNEmcPA+sVpu-1;9S+QG6@pUCS>)Lei$II+n$DVyg>_B4BioYS zPPZx^TzD#Y7+e<)AM)L&pdBL{GLON{^Macf*HO61M@Vz!LT_?udS`aPsnwq3&5-ovk?Ox>`@v>kGVN3ZO`keai&0U;_uZL8N03W3uNk$AqlzcyS-><)l z@7&4UU#h5ZQiD851M@uYHpXLK7R_7cJXVsfL4$`EBO%;({Eh1D5dpmq-o)=W30R0H ze>Gh{ak%6eu*;@C6c?o2GNClqvTT+osck7|mgw%IY*xZ(as8q_Wyr2u25SgWm_8_#k`8p;IQTe8?)N zJryxlqw%o>BP$CNyDRG2NFwNGINW!E23=GO1AzdA=x-rDz9F}YpIW@4t&?{%1w33w zYhu~5ih59k0t)E(Q4|lF7 z)I#lke|SEmNB>B4M+|Z4c{J54pVO~g1Lxy_cW09-$H1WK-BS*Kx@}*Loi3Fz;!zyB zEaF8hFn`v~lGNR9)9lkw#s@2a`7xUz79@xOa}P6|)oXty-SVb)Edz#*?d#x2ViV`} zlmP|-!ML$+=v`~;BufwqGkagxQF2-iV|o}M6fvMTzwUj~BfOpUsrs%PkfwrQTHP9W zVfFm^d)&h%veIbB3oxu*F{lHP;xl~&ORcDP^=0@5fvZd^+`Eoja<>OcevgR9`gNLps4i(zUz`Z&TE)Ez$#f`-wjMatsC{|hCSXORcjBJ{h+Dwn z{ZRMXZ^meBe4&yt7^>T4))Uaay*>1OngiKypD4g_BNUZK6g};Dk8b-Ra(yq8+NN_8 z$6dhasc47|I^d7*+R-2&3dyp=~VR;Ziuf5+=mmU;-e ziq;p?(mWpS#yMjik*A9O4vIxVNX;6gkhhNIkDcvDDufeJCg$Y>9+FQ^L>F`!^8lE< zTr4lg+N0OMh#&@jgM1lV6Y$ovkq5s!bov*Ey6(bIfYGrjXEw&Lef=B)W3tBb-S z8ErC}v6&P-ureAI8>E2;y%+eFT0=n5p(va-M}@_p$OM88RHp$GlHe;VZHNV<-!}b0 zNm;?AK|DRMFbod2k&xG4!c!H)I0lW(-hnzLG)E*XkzLha zgF|`!tDi>zswBCRJ%ZLyYy#;|v}*9H?7#FG&rD3h$z#%EjqIq&77nj-KKYg7NzVkB zG~-Eg^fPsukghtB-_%=}{*bLv9jU0lWRjf88K?dgyk$SyKV5Rp_hH~+%#JCD8caFh6=zoud_a2|D>+#SjV*9)X zVu*~qtSgs{p{@9c?cHy!SY}zf;c%qz?RT@qmR|tN%0nYsn3D17xt7gM%rw6j%J26# z+hDK072D;R${XLYr}Z-_(#}{(#Xymv`8rU~N~~;(JvhL}a`X?rPc&xNinGwj|Kjt; z_h!vlNJ&S^+TKdNhg+^++DTj_LON(m$qV7*w(9_G5^7AP2%FB`kH zEadyX8yf*Bvm@+CNn>Sv%!dRO-}1-$CrSi4t6;yd9#o?BPe{&4k#mQV?shydF(v+z z2T@2U-OSng=*o6!Hvy{EJ3iNN(P6jm+vo&qD1CCjMD|F!(n%p?2m00ljfHdV*7`+p zyBQ0EoGWyrNIyu>cE%vyD3E+OTXHFxevbGs_r*g~sZnQvQd#Tw&lWRfwV%d#JxDlK zHCC4@+kv0GVhQK-_B)o4&5>vXXWo|AkrGG0Fmkc|RX;9FEaf=}dw z;QGa|HthKmA42U36Avorx}*RTk`l9V_*&<#4hfL}Rin4H_`m`Z1UtC1JOE}2URZP# z^X*FB;I=}FFmB{c6mq=4Su)&K?T$rXnWMr zp@b}?hH9N%^mP(hT{yyZZ$s9{HLIDobX3K| zF4lazR<`HpK5Rkwt_yTPG@(zYzKL9DLp0&SeXSr(H^G&*Qd$R_7Bk4QQGg9gm?rDE z9c-Uv_O;xive7`zthmvj+*c+U{yDm*BH<}opl=T)<%Vd^;wxI?p?d>zz4oRN(+&Lz zI@8;!tfg$zw_A{EnGqEOGWFAMwy~r+zgQ**s45SClNGI1Rh~U?YAiz4J;}s})GS#+ zUZL%2kP^v0=FQ~dwOL0Vz(X0^8O7_GJIxwj>oT@sBtYw&j&;j&FKjiNFuQPpZE(Jk zeClN3b-WZ`*QcPkmPJImb#sT2q1|1sYUJJBCHDUL+z)vpk}<|(n-9kn_#TKkqXS`< zSzGCm)njO$|1*D#mi0#=%V!gU)BEA1uex$I$tn7%ZZG8uiRH|$=K8d+0>$C3Mcwz3KK1c zqG~}kePIjH+*&PMy0kgy5qzO#5U8G&+5m>pj9G@N+`~h z;3Tu=x}9?*?J~v)<)G3QGgeZ#DHm4VYn()s2UL&V+^EKU5ciUIQzN(9-NA~L4oz-F zk}n`MCr&|dG|X|n(GTsnQc{N{F76U4C7i5KVLKV3=Sk&#HtgiCPf;6=Bdm{-JQ#JZ zO3K7lKlq+X;VZ|P)gl%POJQ}oqW1A!6XoPW82L7%1mly`VTIi@;{9e<@Tm#Li(IaQ zZ|hy>@Nix@V?gs;DC^AbRuG)5qHho&L;yV~N<}D(NS)eERlA_YCO0RXtWHfxz^Dse zb=}}J{#p}1Ao?v2j_d~;3Tpuwu1MdXi0Mq1STD?l7toh|!%5h>`73WZF>IryUDDov zO{~dJuxEl-#E6lQEI>3UHx*=57git%*5-pf5~2tupy?}b9coq96|?cYIB@YK_k7}F z{>l7;N1z4S2QRP>N3%|4DOw|Ay4Iw-1-hJ|mxI9U4hP6)ElPPMV0?Dm)5K!hMRTQn z28ZyRZ)RUaJ$4i?ftP;KwY~`Lk3R3X8$5%|Xi#y7F4Ni+Ub+3Pu?^Qdyu7W;?bgDO za&YJ4{rMoMGJrH4_WMMX%jm{Ukk9*=mG?e@%!yMujUxTWTlleI-MpX9yW zlRxC73Q5^_)xHZ?jkn>e&i=Nto*@+aXyPC>EPi^w^`QKcZ0Xw%DFbt8PF*U*FRPa; z32BRe%*WdES#4>06-OJ<$5<6&!ZX#;T zn^1fMVI5ng0~s3HtasZMKeCfUHBU(t2?>?YMAhBh3Ts@HhcZilCMOu7QRgU8^Rj_a(CxVjXO**FYC8*Gt%X1dRl*O2m&tZ-6F`DQ zfU6UMsP-XBUF_s%f#qoJz-`-`zeURNBe`&l(h$ETDVdK+ol1PCK~qxDc!^%QNQKv| z(E?34zS$TtYk0O`XFYrNl~$8icVNbzc2RA3=c}ixMQL6*Ls}X(YbZlnQU-rr>W_C3 zgm`GI2;ZE91AD&FnT5BpsrZAxAqQC4h)WgJZ_{TzFBviRDKh{$9ce%aRZIAPE}Thz5TEEnyCY;dizg_YmuR@-q9IA;i_=S<*Aa36-HH- zTy!yQ$2Jb6jfhH7+z`847}k`LbDuWX*wD;h0}(QM&#mKo*njYZ&Ms?=Q~~EZT7!jf z&b)>6rt8rFfDQfI7avo;HFx;iV{#!;Kjx#59}@IdCU7n?=1HL}(ZkYaDVy(N1Nc_= z&xR*GTi)H7q%-54;7O%h>S=~yHR08>?PbWznw0oPZ?BB!dZkoVzw2ZRbn?yR z`sHLx;UyKv*UFykb_c^St2ITkvuS4N>L%s8e@DS+aYWYUa@{(O?%e&v&v|Cs@A^#H zrYwXZ51H=Ih+%>gJ5`HXJ#QnTl_x~M-R}I-6!}sO`Qa8d9gA*B?)_FSo!S634p3BW zqn5#r(xWXtr|4;|8+7gY(y^jf`nYx{+V-I*9*vcYeDN(#n9mXzJqAt z5wWogl|n$hEy5lsTcrBi;>S-^NC!a&L!T%NXOuYIjP`hQ$Gf9%tSVKb#w?S#q0Qa^ z%ydW9A~El>&h#^U?kCAm^c^9Iv{64){<^Z(-#vFc>+Ord<3U;Ed@Cu0p}XPh>*co- zr?@gTwIx5V=UllYPB&49M&iX;T09)b(fO@ zqAnQmoaxo)NE^B8_6d0v`pWE|1K?!M#(L(MbM?#PDzI5Pq-nacPz&JTrgpax4GPTT zs?D^7Z!w;!;Imc^*4QQwnz?aYu0(7gcp1-s9C=plwS_eTLTPIw%DdCyaJZo)L)i?C zt#TDue_MEC?VfRwW5?s^z9N3xwTkK4mXVSu5?$d|n_H7A~5Tp6-&G#>y)!oC$YIuKg^aXGs`!@HBD; zh5k(>N3X>_a`bM5bM?esr($@*6m>a7(0<9ds+%E&UUlT4EFLrEmwguoNRbLoX!4o& zhWHq7J^?3Pnsb`GR$zgj*>WtoN%Cb^XQJ*GD1xYem1X8=lp#mR_fgbzq0ezJ^Ic6toi8zx}IQehmra&ZpLF23SfR$8ekKN#AYg-%dLrJ6R0JzDZMdX?sM{d^ zX9&e0TY@^&EdSa^?*dBe544K1KuAqB&3dz!wy1ua5eE#|Su08VvSYgY9ZkcgjP(Hgf#DSIW8MvX_Q!w`#r3_64t7G*S&;G>L&>73rpsH3Uo#Z&#Z^lb@L&Z#0gz zRKr7zNlejJ8+6!?2Ut7xB5fv;`)OscD3ThE)Um}8u|L#y1FRMC2z49D7rt64lVz#T zEx`>3JWF7B)tLzLim^YC$@%qvJw8#9AD>4G&ZNdu(JQIee@`-L*55JvWagYL>P$7yYqxmlHPGy+ z!`28JssjvJJG51)a$nkm=hi;%*QaZAe*g~pT|R#5Z$3ojeoOwb%FHBmNne3NaFEuK z4^Q;E7`HHnz36yt0mHr)$JoNiV#-<%>R{yZ+T0X++|nx8ZK|s2?kTDzR2t={s5wg) zFKJ_bSK5*P5B+GT3F}Dwv08~5WEVRVgw&=@2&8E8u<@1<#D;3A@| zlUbFyY^dVm91q*EuPmLfB{20l;h!`j?WGVN=_w z*r)CM(*_GuG1o(;ve9EEfEM|&!i1GTjq66R;uVs2hFnVGrPWhCgwsHWQ{r1XX0ncI zjUshKF|8ZUlZoraPl@xypTqzQPksz&8$; z8=KzV5*TWawHG)~bG2I)7RS=Ny;`v$)cKi5LnZH3sO#m&Hiot#4JE58q82O1kWE^b z9DXaX9?}L!5cU~N507iK%kDGu%4uFcVp&|7e^|OnTw$qoCtp!*-Sjzx`?YJfkG&T= zXyyUu9a;+M-e$K)TpmcYjr6%BKe47d-=HbG8)A=ozr7dbN+R6}PjxkK_4DYsfnS5W zKM@hWVk;jECh9#LXS;OZGxnPSi5=RiA6tto`yJu~TDfR@S;VnscQ>Dbd&%X{1BG-@gQ-+8?iF2iAMIbkcm?xwpA;8fHH$ z6z@}0{jwDk2HBW=cUZVGB7X23Mz#BkVu1KXvz=dp=;7uaOV=BRP2m0BMuPh6jBiDJA)=u8VEuh+ATma0Hty*4zYk}r1%2iT zs4xo_bn(IPSCc@yrhk{>%W?W?MLzaTeF%um4n9&?Oj2;^?HzM@*lMd%wB-}|+{4B1 zP6T6Z4zc7ekVLjEPQy*i2ZIm?C8{J-v+u0>FOKCQH)Q5Y#CPxjOO7fg57=rhb z@Al9$>L%uWBh&@L&`ZoM$92M;N8+t`D$-5qd1$j3;RTuAu*FMUoi+y`H zi9Ys#%C8l1CbLRK^yn0ZrSE+zAK6I^VO_^@c_ah_{fA1<^MreRhkDH~wS-BrYjWDb zp$naCI`{3YrM|-*dh6@n8y9)u7KBG}m(V`85jDf_L-zeHWw4uRcj5__YXoI)&J6k_ zk}lkQPO8@2aLx&AgMm8R9+W@$SzgUturcP+B%SnXK~nw4BiF5I#%FCFG0Wa?G4oWO zurb}p7psf?lODRdF8FS}L5TPn?Y!QwcaU2qeextP(8!twfu_h^q!->;C>w~Cb0?^v zAZa3eS^z3Bfg&H(upwsaQyHxRtOOTI5-GEz&rKqYnL0HwNgTi0DsJ6S3k{`VdM{yO z?m_$w&L~unpB9BZROD!U%pLsZ0W#$%O_0^GUYJ&b*85c&O4p3AlBJZzPqOsox2AT` z9w@i(Ip9)Z6AJIu2KK!~sE5gBmIQG6AgM{0>2%~$_qcr-bxVR(`(*m%<-@J>3&-yh;Tgp#fy30$y`KV@XO zBpd~5I3sOIX4^Z*{Rt#$dVLK|I{`)|cqPJdIcgIzhdkukIYR@(+&I(&l8^)@u}>i- zB+?J}4J9Aw}7cZ>Ug3V z2Gs=)rkRq=6ReT^HTxzLKGWi)n6EtyOwV+q^P>cvI8-p%6%|=M;$ij=(h0%h+x8{X z<3FMz;7b(}lY;NW(6*#=t(DIty=lzh zWllTJ@w0-I0Cwso#U%nojo;Gag!cFglrzX0U3_r)L<)u(mzZVlVr6;G>@gy>#i_P(=IueFY5|)t$_M(=tt+c#zyk)pVYY!Clf^=o3sEpD6$@1VL z+C!DAv;yC(k#aSB+qOA(FfQf|%=I#);LA_SnB_1t9ER&j#y{_DS$+KO9(;ng^NzyZ zNU!uhw2!iJ2U6CHcOvv5gBPFLY)*?(Z?&`X(=foDy-tJw(w1dr?v+N) zW3vc|>9j6axp=~M_jYWdRxsbTlx7@hz+yZKt3ioqlLLxhmcC_TjH3MDCx>A8heqBw zcx^Ly68Kn^NT;k7Hryg(^%srY`X4lM+_S2wp4Ez18aY<=xb9S*rB?GCk;=iE2OQa&OVbO@IQ6JSju8-#3IgSTw|O^NpX+QX6$SPozpflTmv~S z4qQ*Vj3FGd_!hx5a_k(sqVUmls&K2g=n(j41atUQI!QKK6scnVUkO zgswk@*@p`6Jck+^b)8KQXI}?#xp!kgP?}SJi9;9F$3PR{R^2O&-0L4S^6>vgBdQU`ge?Qp$dzX9je3?OpX?70<-;6*oO^8?T5fsf zc?UaV)uW~;dFzpPF12h0joKxO#r{PjH#?6p{6ixbHDlNu?Rlk2AT@fu~amj$T+obhsQd+3@){mT>G^2F?wCSD{UYGVtBWDBC$OFq< zgYJ)uSt7g|%m2{G6JBZLVy2|*hCq#&V`vQ9eEy1^wLxa*5$IbK9(j@YaXC-G=WFG7A)1cw{^JUv^ zm?y9D9TK@N*i2lys_*j~Lz1oxAGk0hZL4&?*3RXVdV5OgWK!nfg={T^_h43 zoP%S-_H$CN{tz@sJ9Q*`e@Z~Rb;8`&hnt@275wG>-P2P79`9`9u`BTTsrum~K5iK4 zT5(r4<%?hcqQu$5*40cha(%n-tJLdBc?-#fBL_F?-|^@j@_0w5L26qJ1EV|(^WGZ| z+19~u+o!LNA+`ISck{h_aK6!#yqZq4Kl{JCbnj4f#59Lm8~c`abV4E}ke zZP)Wf*CX_dYa7(wWW6_Y%k|tPXKI*QkLgfef8-BQq2Y~fcN)zo&9rZPw|#Q!m)kDmLhOF%Kvcs02VIzJR`LFU@ z6(tz6Dy-vkd--s+Gkf31=|>)SyJXw;W_eJXD;qKml8s*8Id-sAtY7bt{{rb?|1*g( zPjh>=deOH0kt~1pzT#T`^_>bIIR>WIy!OR@K*fC1Yq8tX-^T`}o}2jAsO8&HIeVUO z_<8jDfKM??_ILXjIbw(I`mf7JWbw_u50Ts$({rU)nEFd&BlQ7^<9aja{n0n- zrP*|QwFfzqie27(i@GskjYGxeql45wXwJ_%{I%^jdBA4V@8RWsy;q;vQj+-dkVD_I zqg%Pv$P1WOY(8s2=bCfsrESEh&WBe*O%OusdF2R@7psS!KB`0~}V5i7csE?V|1YjnfYA zm|1N9?yXk&hPIy8AN)VPSe1MI@)PkX3%mXMj_r#nI{huLeOVrFRP!z-T^C-+ZYF-6 z<@e(9h5?#4^^dPVyr8)I5JC$h~rJn1ztwlj(+3;--uIsp-=}@wu zQ^vd!?;~B0CT%$NYJBbx<1Zs_oSyS;(SUwaJjb04Q-2XXx}S6XjAfR`<33e9nQ^r= z_et(XgPF?#(CrxS>j~1rsq~+T9Jj$vWZ2oF^@rFh}7eAKAjhVJS zsZL>p)8#2=Ehg*@yivaM>YOqg6R)D&xSHP|jomo)M(lwPc9PdkTFByte!99S_U?o$ z{Z1Szy?gJ(lu6@mXbR)s2z>fD*{wZvb$C{n#JKxM3$o)|MbTSsY_a`FTK02xl{h`=(k}ZJ&Yw2Vp|m1 zcB%KlwBtM*v-u;2?C2s~u|8ehd67d)!@^GUH@r4_kuopbujh(C*1P_2>vE*!_u^A? zD%@+9YxWDDUi*3d(zUN{6ga)+OFAF9(Piz==$E0}4n)R12>wy1|GMPZ`vprA0u2KD z+gxZr)_BCK-cuL$^dHpBNB&)3BX{D(GnZuky1^zXDOcN`nDfQaX2E;4&M`jcEgE)? zS<@hUyV$2+#=uqc7e2BP^2dJGwivWRwD9=lDW|OZ%+2?$|ETea0T*`&`$z|-=;jDo zr^Gu&k3Bsn`esV6m$jdVkN$D;8o$5WySS4F4o}PYe)nP6`o=RHlk(j+#(92u)$Lxr z>*tI^qE7Bq3tboDt==bcy`|bW%PF@yI5u9@{Nv}6Y3GK#dEWD-%=pvC87*7uICW1| z-xd}Zk|_7fZ7`}%uyI72YlaWzp7h?-f8I>%!uji7yM>yRS?4uhtv&wxmj(6DjJz1( zG$^9j^n2{i#;c-6EQ($Fe6vYm@)^^NG3n*JGONJUZr>?A-JRx4n7wJv z?N8esj7o$Dqe|rI+G&p_zyEU9NalUzxXX+;sgLJrly&h7kLtUu!;jz_a zOk<(V&#UQi509Jl(f#AKb=1x#d6ULEmDaWs{-_zd=E@j>G-7X$_akHaw>{XuWB%r% zgLmGvl2|{vW|G!ZaPg(bhm1a{+umxwm>N>&<%RmLnPbc2o<{RB59c;NnbQBP;qB-X zGqzuTw0=ORBNGp_pT>K)Io)FU^i55)N53j>eA8#4r@fw!&Vizox|e+W_u2BMQ@TsK z-oTm##j}lCw>@+H`r?tLjkY;FKbLv_M>4_+hL z=fe-nIG%jtap8nvVP_T7C=zgbzve=?(M(c0_h zrmwWkv@T4!y|+|ro7;uCnJ2gK4=y_VS!cg#mu3T+@FId*mvww6e%s0^N<-VDPj@f* zj}A9~l$=gq6E*1g)Y=`)I%(YBvg~$(P$#*ax0-bDbsaaWNc-KL)*p*{Uvt>?&pmHW z@AGM*)y{i*cV>U86*4ZlBvobU3YL|LJY4LCSUQBIOG^*uLVRZ8!2bLMz2@?lOZ7c%T?CCJ6zFPSh zsbyqtddnM&4U+eyX>PXKJn7Waf#FB)2+LDfw7zv{X7`P0X`@$Xw@ke?_%<#la`;qp z>ZWnFo?iN$<~&?~RW6i%)*PT`)69&YtfB9kkZ1d8wBZPcQnQLC;k6F5>$hC5-I>M( z$NKX0ckNnfG2Z^-5VO)@;;6evFB~_C&2l<1V}Fyd+}B4ljwPE<)D?#7jXCfoboFt0 zNd52@&vOoy7^l_iRx$gF#cYFS5!zv$zL%Qs)x5f|W7yi#PC}#b5h?R;OO9PRoclV= ztc^ooha(>2yo-X@rIfgxHBfhoI%vBv+Uh~-r*7pvTprxbJCaf(ZjZ+JQ!hHH#dRCE za^NeIuNIf`_Uuo4*Xl>B@ry4;MV8cvNT{c6YZ&46wfeo9fm5L2CqaQ= zTLeFM+kwLKMvdo-n@@I_b}wL~({P4(&Smw-ppKA{;OkcKb z$;2s!4c*UJjJ%Q1Cm^lxVe^`UH|m&qI{0Z!?K#O#%|WxH&l?>Z*RmyL{rpdqcmJU! z)jlBo(R=L%{htk2>^Yj^my_OXY5%4BSAV`5ZFVH5;zD}e9cM}-zE7}Ow&KIlLOaAB4BxGB)O^C_ zGK-BruSAUB{N!|kk;h$~%(XM>X3lxlGNkr`1E)pl$KIFb&(|x{t#`kJQRl*f^=ECg z(kxFEwalnd(V=65i#kuA4;oq~EeO+2Fj%*)M)qib-4(ZSP~7 z_w?Fw)5=NSCNt>bz-vBr^Pc5I*UJ04`}w>n#_Bnf`<7WQI68(`SEJF2yrvqpRyYiQ zHfN0d{jBEu7rq&PBz8%IC3W+@wRM{}Mc6SmxnA=V#~pt@Z2!lzdQW|2?SIxkdMNNv zb&lQKAKOo&9>dAe&u}Y-P%Lc8$CVIBxljV#8y3@eOPzR^S>T9otTvU|?u9)^LBo_Q#p)SBx!x zV>bHAo0vUG-PD(@AEn>VKX`Cx(Dr>H;oDDd)fXJ=I`DeTo*4HPH%rX?zLljLOntd} z%=KOCtUK)9*K7Z-MK)_}RS=1o-s5?aMLlL_g`CDRn#`Yd zx}-*i#e!ZoyKZZD>DtxX>g%-0S9EL5{(g2?KvrqBmL6-}&!g|0 z=;gxg-A+x*e%E>4QoqyF&)wZ?C&_BQwInspeNNi01v7e{oqo`IRlU~5Tjtyv6W{B( zjr-{{HSg+nUK>5$!qj5z^Pdy$Y#w^E;l(XyKIq@O-9K;Co?CTqjk-AVrfVa8L%sW& z5vPM&EN`ZMZ(`2!)Cz}wD-1{exYX^?h(+6XE&t=l_DglYYP;)e)tcE;Fu7^ztdpiD zZRW&$9q7!fv;Tsi$+S14J!~B{pQ(xY?{!=HbnZCE{&Mq~o1(qi_3Zz=F+cVA`u<&u z=gj`GDY}Fw=^7d${1Q_ZQ-7%622rQk7B161UvF;sH7mWiSo2%U_hCzXira=ZE9`$; z?|bm)r4{C32@!QGYF4b6zAH5{wIn5G?PKf1Yx?(Tz1MWimY=V8#CWt>zfrF=I`5?S zi=gERXVYtJ4W8L0?4r-qF5*R*BQ)iki`F`IUuv*0B=BOo)PLBrNiUAncj-IBEW;u+ zKPD#UcKz=rcW&6;*%KbN+QIUAQCLRy&8Ho9zI~&=P&Z1m>19jNW?i?3Lq(e&E?XD) zvVG0bafNrT?{@nv%(%19?7$cQ9cv@r| zFDc z`@qgvaJiJ&+-{EMobGi^R(+lGJoSoEpyy__ysxy`H6`Kij&_nxfbWTdkTZn{yS- zRMaA38&kEoC)=B?#nsDo^mpm3H-FKIDm!hJN@p#^21NxRxR;_^|D=3Ms|2J<7;zPF zn`^NhoK=90&;&2RKdGR~mPn-za4^=wE^R6j+osuzt3dcqDyXtsQmFzV*8{~UV0SoG zAmS>(j&1y^GQfW`1PsZPK!no@I6PD|9-G%#;e16e_}EBJmGOm&0TD7ht5O|n%%6`q zD^saD#facA1S(X_0Zh#GN6ghAR_PB%7=KYgCCM2W=qUjV8(OIX>||#zt^(|`XTSbQ z1(fs8dLZE{ka87BxeBCQ1=z)ldVYiGZ+k%C{j&?&0=C`X3j2Op4`lzO0?P7d z709>>O%H-oH0q)J!!RN6`5YN*6m*Ap2 zir$QH@pcQGg1y}`(XXBVW6ei!m}2e{=;-Vi==gi*r9uA?Uq>eo?CGD3z02N)+Qp|* zwYA)x4Yh5><~(y>6PGFOX4Cy$tf!B(ahmSoBzM;CZ=_}rq95Yr>xI&^LcBb^1N1`- zwH;~8vp&KUt*5QUk_37fYO}r2T4T*EwM=~cU9`k~CAv;LoSYz)_vMSFQjxTemVn0> z>+ytoLY}Tbs4wE_iv(JVKW!s5gbe(hUG=R7nJTKoFGKAqfq}mIdV0aZ!F_{;eSQ4h z^!ReQT#qNv69{yXLN_4PJJ2yi*E^sKS4d?!l^g5beY~}(T*t{iL4k(a+Emf6KSjU1 ze1BEs9nhEcv9FVlmtF{V?eqKc^!_4~x%uB`^YZ%BoB@G@r=cZ^p8aWs0ql?uE0+MD zAb%&9!P6kVy8Kxq0s^gEego;hC<@8{v><1vUk&mN^7mwbc6QQp;r6u$01Es+?Tc@f zF;c1?ACO6?_iIo9a|580zKOq!W1!0*{5KNt1Uy}yT$d-b;q&!{0)3&lH&3R|;~D6w zr2IW-tc*$w|BF(jRZCGyt6C0@XK@YvuS)ryQl$*mA0K}kA0JO6jtGW&1NYqBytPbB z7|v_;!1*uEKEVM!tMp5eL%A?>bN!*-0fCO*PA)?S83hHoJL~g>5?8*fP^8P3N`<;2 zCn--?CKfvDiUndEwIbk)_%1S5ta9FJ|(i zx{l7yQeCMlAN>$bmI|e=l{Hk!U9Ds*7jI|xKv1-ar(-~Xk*~jxkE=c~tun95_iFjg zaBhQ-e<))%zjy%SI@T_J%CUs5#5O$L8TasY^bcSs?-*)VQe{=l{#_U&Zhc25YNe5r zkM}ee|3DXK13jhq-wjjEhU@cd)a<0EF-D!%Wx0{QzkzQr5DyR4cKhIu;O90sRcZNgvZ(oJ|SvROo*mbOXkK_1%9HEfJMF zP~Jr>o$Tc7EZ23Fi=?^|7m-NU(NQec{-l^cs|^#esub+(;_4XW8CVGjm9M`Gs2sW~BUEL)4V<0yUFpoP zK%=Vk!l>f+rz)l4i@v45k8_Zdi@yT>EunUdaG&h&=pTynboxRBDJ4?LY~zoLfa0c( zo&gv}N?IAENXa2!6(xkVmy3mp1MN!hmwJUCzZ5jU$57iJ>eru5vvJzhFBOo<9k2zG zUOfislPu-Qc|x3ZBVb~*JCE1Br=CJOaYxl?Rg+8;Dn-+To;~%$l5*~)JTAZv}KXA$$PMcFM4>|#zV5C$pMu-eJDsj+CRO6&# znsh3slgj8+I^{UIgeKc6adMjVDaAGVD2@}vTpDomwPNi`Tq<-%(Hkjf?1@Jhy)SHl+>K&lF7nMg>pbEUT6RK9As0SqU* zk#agIzuK6~|UUF3tIs%99J_)y7DU!~RrpR}S!1 zivuZCt3xIu`$g3{a59^OOaaPqP_?VY33;mHi+R3Kb$t0eF<%wO5hqgRSFj1t35F{5 zV$fA^4K@RLwYH#nm`p3@S$W?Izhk*)J`36qD z6I8EPCdT=Y%Iy6O$hU1`AG94=QS0omZtxP#iDpI9OzDO#o))vS&o+?g?d15lE zDwPLWCRN38F@Uc+zG5*>LRHNx7OC=kSerzuybf_PI!so%UZ93*-+KL-;Yq9E zqy+PB)qWrq*>;ukO65E{L{lY>PA653lZsUPE8~HvRnkGVAS1O>c|hH2aF+4t%vF_i z&c%jXCBp)p&#)XrPLJa#1zeL(-@k?#eNis_m1D1=V067Yk_-L8-ss z_SNt}4y8sFrg9uVs|qW*xH|32p>kF0hghyEkN9#4uX=eh5b*Ez1^PSUm}gO+?~BQWG9eWMXV$EHQ;(7$}h%^9Bh-Mg}IL!6p*ZLB;~P z+(Zauknup@z&zu@JRX0LP;NvARI0%?3&4ea{V#i22&UO zziJy6!8Xj3Xvui64a;Q$F|!Rz^muYTz691leIZ{TN9Zd4{f*wwGAss0-<#IVjG?uwp4uq|9@s1{@YUiZ`p=jFcX%!@a4Lbp`7W8_^vSF@?dfj z$|bHcxt!-Dbd*$DPO8|Il>r93*Pj@5|FsP>?(?s0nAZEM+l?yCMp)7K*EakY3j+Vz zhAYjw|JsHX=Hma6ZMaeo`ak*pEfW3@*79#9{|LDMg6m&!{UZqcqs0GW*T3NUM-cc& ziT}l}|83w>T^kPmzrQvt#4@v(Cx<F{Nuz5=npUT>hMi;MH$rZB;UIq+%0T}iY)K$jQ!`}qEC4s#c0cgMd?VOi-u4oe?O ztW@^{VB{Md5;(*<5G(Kq53$AyH?4eVSs59zyM4$rSKxqH&aan#;LaX0BBB@@8%ho% zC`*o|btl}pWT%Hkbv+xGkU*IG^sIcSXk1oijooh ztC8jwgOsnEA_xR|DXwv=a@!Q=LHy5dn<8s6b&f78qsxn`w1*9dqCJ0oAC7=8!zDVn zUdP4JtBIP~!X>tLJ`ZIY;mvqIXGh=Eo@_Skwu_~D(Md1Y;N06&>>Jm+HaR|h#J;<0 zM9CK)M)ZHRd{rN{4w>4%Jz}C>r4>&IIdy7sou9IA(}IqS_S&)`JUx25?g8(2M*NaT z_PKASE!pn;C9qYa4Ql6I1|}>?_m0TV&5h6r-eaZP{(jTw%ZIf#9=064Gd(Q#!rIgy z(}Rv^qzbiH)ZW%-cJv%xJ00g>9pkQ3)@<);HYKy=i*Jh#@j{zi9+)w|Yt8nKkGuz+ zIC*Y=+Q6HAh7H)#W81hkwIAQQgClH&I!^UwPOLw)P9wp*xOs82uGL9XH`Q8xWmAKc zZ4J^sdyYEtEK+~Eo5lIvJvPTJ(Jjh6xT^Qnp?w={`}#Q|_-E{=SA7!v((P+6k6UMV zMUHzM`tt&IUp@)X`>FHi^ZOrOmGA;G`~5|qj$#G?VY#k-8-e@ zGP-?K*f_(LiQ$FUL-#h=s+BIgHr8~`I{)?VpVU83tUYhkilKupI0s}ry(`RlS);pF zSk~-y&--k0$|#Dwd|=P(p$;o6;?o`G-j4erUovF_Z&llyU56eW5p59CY~Z}$hfNx1 z&$YO+r%ULq8Y{~_>`J`it?8LjxG~{~aJ$$vpl{EX1ruKR_Z{taASYB%`6M-r`+is|3-NKH051++dVEOUf!3Q^=U4g8#Hg(sOHyCx~*;AF6n2dbDl%R3wd@zy&-qKLad6MFEmfO z7vCU6#_g&Pw$^&NVi5@NDd{vf^3Ar&8?!L!QiUK74}qd)ZQF z*IBIt&FzD_)tJ$EpZX;e+%5XlqwblV$=w3#bgw0Cy`nZXqk5{v&i_JzRz|R-~MnVyK|kn zU6yFyP!BkB*Kv#6x|=q(i{;mn-ZZ;=+tTUbg?ZUc%&kut_G&u&-n*eIPlWB(Z{R;T zZuiJuPLB>0X-o<5dcDJ7^_d6#zvjI7^xk@6$DunPv^En@zA+V(Wb&oaF+JG}*u z>nxkwHt%E1%WcE|7^wZSQB1SG4MhW<#=Iy$pLtH)@{#+fpRpgIOO$XN+>^GF(XHrbsaJ4(18+CA)(BbM#zl|BW{cCQ2tG06O;fsCpMkLHR zSoCnF!{k8&&UuxX9;;(P6 zVY^yNbGLZ5d&7Gv8PdK#u4&lPPCw{#yMVGnE5W^cpEFbV z8!eXJnVL6t{X0wCI8|r(sdqMJyCQm9H#*eR-}~t@O<-2Ycd|v(b?7qI^rJ+v` zTz#;s==;_P$&DU;Q!f+nnqMmifYVP8H`IPtET8 zF}h}o^#M`8g#JGJyY*N<=%(+mmbro%!&(mfv13RL)96m;FKD!oB|iRoWAgct@3UW- zeRz82e)k0V`xhp{s6CrL83cDN;q7qDXstbCo92rXT63d4oCaZWAxfaVx8;jL7m@|_ zO9nPGe4Wr=@>BG&-u*!neFFzIs^>ko>A6;3t1DcWZcQ1`aGRD>t#j?%H?-(j7(8y4 z+_r!EdDO`npRhQwfDB1aGxzxXS$zsTw^e`ONyp^%-h_% zTKx~UuJb`0@uJSx>8svn@>=J6ZK~CI${!{fb;5-M2E6n-YhpQZfJd8{+qbT1)SOf_ zIP+rjhT-#$)R@&}_xroYn!PW1g8kNxM*H{f@zK>B9GMX$jNZ~_$g+BQd7<9M`?@z$ zJ6X1-{r8k_-(H$FGW=njzT;<$zMYo^Y5CUkvz$6}uKsyX^}8{*md2T#oxROkEje=d z0UK$GbH`~jeVx|1#^*$yYN%aMvzc@0qdw=CcDF2=U^Jk}pfFy~Y;8>Xw|JeXZ` zUD~lf?opn{8poa;p8FKOJ^Li2F#nT!vj2fynw}%B^*z4wd+k#vSJblJIPPtr)V2FP z-{@D7Bj3L59+?09+@bLsm+qb`y>57g6XD;6&jC(S|x6A4F`W<}UKYDMf{a$N!enF_H!`IIaryPuC z=B>C>?(@Rd;o15-m!pkR+Wz4alv;c2vmBo~n(dz4XcF!4wBUtBo8+(Sx+S-m>rrFD z)4`M4p1*Lc;2nR^q?=QEOn>~a{^3+@8u+-gnURL6hOGaZ) zbego%se5LR?1^8CTYp^BRKqgFY-GsFl?V4NTkYOm?XlN^EQ3+E+IfY(@fpLn|N3Bq z)=0AxQvuFO*>t{{R6cUrjyuL*T2HM1bmJXQyMTl{wxJWP zLsFVtXcp|LvuIZjvw-K4>ARzHlAYAT?(ewiowE7m(!Jm8KFFJmSQxy7w9NUn z8++FeePL?+?aET^N!xy2>)tb?@6zvy`yFDF^GB^3bZM(BGWLvBLAT=*AMUr+FsU^x zzVWcmw_Uy@cjy{#xXRe#M$=w6fosk%y%xqp8pwq&)EfrQ@zq|~vf+zW={=WQYwsK| za^a?0@^1cW6w!3~yye#K%3D1y_D}NsqVqa?XwZ?n;_UwIAD>C^+5hzN!*<_iPqyd8roC#?)}r@qA~ghs<6skp18)Alv>38_jh@68}5EB!2ji4p16q;zD_)Q+&_!^ zFLB$f9cDUOLb1diS7NejJ7soq%qk@Czu?QHmA8Jv>yIzABS$)RvnO^Nva5XQEk+`_ z7TgD`-1$lI_{XIdicqH%8{Oo%Wmkd=Jn6<>+}z8q3B^6S@YI4YB;s&)EAf{UAY zahWJQ<*@Yx@kmecC=RYv+y$W2Lc~kp8A&(yk{5^sL?VHIFI;4C?V zTu!y%zQgj-O~LSyKpgJxg;xm|=2zYe3jYzh7Zin(8x*4fJH z?)tL7Wu7^Uo82DV7DB=K=VpKn9sAvRzEq{9=V*|ph`_6=T1y*?P<>*pC{51 zp^Na>v!fc}!$lXKQYivNO5_+0%;K2yUh3Krt(QdC6lij+?ZH&-}uu}g|s3*km90#NCj5QB#}dzwko zVxJzRAa~Q#rL;EU^>Gfi)N)J_eeQ0&L9=y=RzV z&j&K|3Fz3?$cLXCAEQs00jEtnDdz9M2zx#n$p=OeW?%|O_sde)9^QcXjXRzRC^B3) zi%t{fh~>xwKO;Wf6AdhYn~)v(qyZCvzPJmPVF<1{!z)hM^KO;2Wa_hh2s# z0zU3>MSX-2*b#+zP!7f)b4fcIcL~z5Hvx?>PUTJ5&)rr17jIAo)k}Sqz|W1~K$!ZU z-b6(#-(S5!VQhfWH!*z72&Sx`)!+64z#k6Oitju-q_r2oSM7HmA>fBWCODw~R1T;X zX^;=&!ia~)1?WuQ{_HKpc!)7h0#F4}IcuBBTO#G#3ut^4Y2dHKkehJ?f)U!z`mA`< z^}s}z)!!U35H%6a{(7T6qF*9ur8n9|V@i1R-@J(f5$!V$1RNkPMD(xvrhCa%>jr%6 ziPD91t2hxE?lZ0|PxW0{KHP?JpE7P(2CfsK34!Y({Fd|i_QX;|z(FE5eB*GH;6vO8 z^g+IVguf_*5vzpo5x<3e+*M36fpKOcUN91jG4K`faxL6n3|J!`^dy2`B|O>i7K0|y zC+v|RUv6RoR2KRCiwO@3zVvXU9%R(1B9F*v%S8jOw7OJL`d!bHTb zlm;F#K7ssFzztrM+#T_tKe{&_y9OAJ5zR;dGkD*#e1sR|t4Tiba_|R|ByetKl1L0@ zNA1Ao2QYo$DavNB2V9sGgJc4m$7Rs)rDKSLfg`3t4z+~5$cSsKIii4fG>4o3SS6B5 zVb_yj5U`gK4M3%=(Uk}%u%|1u#Uz-Bc}O@BEFxqkq{Jo{ct3&=NaTaKfP5l2gVW{% z3gaXTh#5FXqlw^=u!*9bU_>Gi7Ob!mj65#JhRCnvY?WN0k{bV8sv(F}mQneJAfzj@ z#poH>8PKtktudv5$c#|A3hA>R5_<;Z&~mz_oNGDh7#v4rkd~0RV8eh&1xx;2S!JOL z9!V_|lC0oK?MY)H-*LiC32RN{-+&M3rIK#`>aB`( zzeuE#RQ}>!$x~I{_EI@W5PVijJOyJ!aOYzm6!9-?l43do7ABxg!~YrHr65w!jf@8g zMVyYfD@LAFH4(ga*_#NEv=Mw0$@uozI|Dl6R3+@0L6~Zh;Vr^{a5ZocqB9w|FN>#} z{ul}Hnv^{9JttfyK1lnv z$X8iHJPoyyOppjf_Si^)Z%|RGMPfM)(E-nrh|qMX+cGe18GtI2^6UutsBi$ro;JD2 zsB(ZoCWQtKCdtx)u@gXL#7_V!Y8;dZJ2)SsAyRu8dLsiLV)+1k5#kX>JURx&jLMhu zNT7-A;oyugmln(y!Vd~IhCoi8M>%p3AcP?+3p<67M`#Z{8*z#}q$N{15Cn1nj_Q=d zVO@^lkU`m!V>sX<&c%zNc#8Sk5l!EGCZpr{u-SPmWx zFLgFB*ck=^fqWAB&k0JoL~bV$plm7fkU*hr-Xu~wQBY{Ga zTm-F{wy0p25U?1{LI63T=pjHkG3wY1hB`4S7#aAgGxdV7fQeL6F_?5B$Wl4P%vs}s z3w$2vfU+Tg-cuQbMPP@-8i_4PK_G0x$54^PFVGJi;OYYg5=s)Q=OKXb?T#2z<(r`{ zs|{oYtU(QED$s!tm5+A6C`icBi>6a--h^Jw%q+je!M!A3?O-ES$ z97%ENKj46Pn)1=qnISu+0gW;q1Dq4nw3yzEBnkNu1~N;*R0xMj?ILYej`3pC2eefV zVM^%9+QG~Nin3+kg+gMZLSl5N6#+0h9yq5E`S3vHpb`X#MPfjNAPvY~^cAF!0DF)^ zzyd;$HL8JdlY-e}YaL6*C;{V#ZAfgWL^OP)3qY<*h+9Y{D41#|kw?Hm0E##Ek2CIu zfYc6BK}$|k5`2afgbfA^1P@|9loP@Y4}vM>B9sLi3+aJga?vb`NDmDqyaX5L7%Bo(3YyGn5EFX$V;yk;768zQzKJIwAOn6uaHFA&rD7NW88Yfol}z)brVz0(+ZAiR47whQXVeM8 zA_@i1MkZDy5d@8&J8zGMW)Kve9@+hz(OVGELwC5kR9L!QkM5 z=2BN^`hW+Bo_)jM@JXf;J3s(}785y6e4z^@LGb`rVZ{=ApvNdWF=n$sv`VHfPe-jM`4T_O>Dp)$#P7p03PI=gqH-C8mfb|I+}m6 zNH7Ee7$|W;JZLclFA+E+D4!q%Sx;SK$b@QXpQw<8ltP#aF?5_U8fi&OK|8SXh@~U@ z6e+qi^hA54^NDHR!h{T$Pl__703w@*6Mmvzf{qY*WT=bEz<1b?X_T0*gjx{5ECB?= zX$_?JAPXf&Q>h8mEHs8XLBtKAfe9iIfbbcFfD|<6pvftA`jUYf!%bVYsW}K>uyBF| z0{{Y;2&qB=tO2rzsS}*#2u%PbFwutISN6QJ*MHVyYA$DW14IZiB;KSnU?d!g?;rpU zN%+Dic|@jsDJd2*;&b#J0>h5P63G?p&}Jfvy@{}pk2X6qyA%=&Fn{9HNgjA$f=kQ> zqzwfHB1T4Y1sM}ZEE+2wEH$eG;*U!$5L8A}B2v*AORv4Q%R_!(e2C$Fowp4@#74T3pFF->=rBIXbK=as)5uH{|KrEWh zQBfp-stK`7Gj-B4Av$*P)@)w2?Vc50Gj8(KrEcZG6x2*aGF`u@d-Fo z4$CjZacF)|^n(Cd(9kh-7gSE4k(;La#2*lls(fadh?%p`KwCb|^BMkO2@Dfybe@j! zzylfzmk1r9iN7L|T#<-ylji?iBH$(_=D!h#j={iZU>S)?2ms7n3CT$O&>|9HrJS&m zv?Yi(HhRC%4#$g7Ea52o%;6P-frMZ{Sjn_IRtvC_cGUj{5ixx1lxGuQ1Rw-ioiz2r zCU~$*AQILJ*qYYwIteSuXu${tmJ5zF$#j8efR~63R(u#YKsPwp1iuI?iDAHoVF%8D zXu?VobzB`VB@;sYu7j|Wj2T=Vz)D6CWX{04nu5+@*ifc2GEL#Lg353Tg34zw8NM8X zlu;SBY%5cO9MT7$6%>vmJUIH16KayNozV|Aq;lBD>;yQ(gu^}@#8Vkfy`-)XIYBK} zK}rYm^%AYAWFq8Yt$CN@Kwnq#k5zhG_MnwTk z=GX)XLIR*h1eFE6Bx!*FEp>?yO{^BDZ?F+S0AdQbL53s(H6kc6;U&fJXwe4K7X+Z7 z^GMvXXjl%R93vVSiU*iG7fs7}zlRfFs0>mHz)lc=VM|U82To&I6ylAwOoaZhXlR;< zhB)P-X>v*}0=D8&*&<*oRBoUeF%Z(yNWxZsBd$t3O%F(20`DY+3gt`1a9bdg70mnO z_KO!p6|r>~Pw<24BsGx@2zU&!Vlv+&7LA8W3x@<2;M5rsWYDd!f=fe59E~RF2!Lr} zT!pAn1dhm&Ac<1IANmg#e^DbE2IfS`p$|gmq-ZLI*=Q&lP7icMju0bCGbNg zjUlIHV=9Ga{ip*0DuoIMI^aQUol1dnN6HPRKFk(b$qod}NQAio|2ezPekTMplnJUM}G?$PQN4?+!xFR03JVDLERF`2E9|VeDw6wy$V_A+6j@I4D zZ(0#eN_`axiZ9d$kSMhW0SUt}5e5!gByxj51z_VGhJg(;ri2)38?c0!5(0!u)MOe~ z@R!PHWkw+Y<-xEH(ZT8hx+^yYEBN%8V>1Y-<_3WZXjPxf&E^5WRRMgV+z=Xy&tUlI zQKgv&mU}RKkG0oWp%w|YUg1Aur3~_;2hzr&sCN8K@hzmR*E?A)oB?d86 zhC+!!fKy@+z&HvNN(=%tj#LOSJe(q@C`7`sY{XEDAQ8E;v5r6r1E?NoNb^17%?NNT z8v$Szjz6l5CRLNlCJZIV14SXkHYu7gl-7>9Xb2ImY-l)$1~#&?$&UwV=Bk(B{fZZ&deuR*UhJ_fE zKug<9fkLQS2_!&pKviV|Vph~NY>=UNPQyY#S;G?0yZ{eQ!$JV4T1CS`1mz}FB|d-y zrs%xfLw?00K#J)jDSE%-Xems zLuQZ?h=6Jjpm&2NDtiFEyQ&I_FO(aI%H8>`SC!V7Cevr+CfOkb za>7`I#7q){Ju=%M&CQ@C;5(F=Dr}ZMQ+Du5u4hnYewPk*Nwz{fkeihbJpBC`&MoA@ zfk$QKP-cjm{!%n(<}JW6bc&|SISyClGv!9JxSm1m5lL5SXJ8Y^Eg}mEXbb^mr4$j! zO-4q=XO)(VXegK`3ALPDNq)B+9TTxhACQi940AP=&xCYj>Eu2u_~Y-U(NHi~6M{bZ znkcuN(2dODOjUwiL-jLd0=9822eK*WCS)T!CHEP~ro`z)glu$NBI9%-Ae(Y-LN+={ zkgFTWrt+C`1KAXxiI;%}MbKXGAcYGAg7rv6G@&~gJr&W=Sy*aPWJKt?BAS~vBZeRi zuBeD6UPfh;Iv@fDa?!v*MKsk!CTdnCwpXZV311Omno~5%5&To=MJiVrrh9|nedRj)VR;U!>Y4#e4*Tghot+H^;qdMt#d(#L2mjC z6}$=y18*j4G9C&J2TQWbXF@|V05A?mcI4muk#Z9f(sGdEvjPXn^$gJp9FzbDE4d2< zIC7B>2wX2PXTZqf)347=`6fFvV!>r-OyHWP@)cjm8pWfxu6fiP(yM6 zCSCR!2SCE;2lOQaG#-_?VOCHgImR|<#JSuscBy=(++@>dg~QZUZMsRz#2}q&@qalz z{i|u~|Euwe=``39n^uE5CD2c4$(+6aL%bA7j{{;cpZx#ln=OnG0HEZ;*iTkPvWom0 z^ZzC^;3H1VmTa(K$z+Aa0}O_gNF1%n_HvLS%T{m5gpb3Xv3`dDv%!E>k%I}mNAaK) zE3z$N!I2Duq!kJAph98ap+y~fkTDFnfe~yhLIA3g=A!_`fe2_6_f-~<9_4dgv}>EQ=SOQ4w)6H5f3X^8=StU}`#H4Q=<0n+3F8G<-u zbJf03+bi42+^VQ##4$8MUw?f^qiBhpWVeJ3Ho=q{hmPZcW)lv<5JwNL9t4>F0sMiK zgixn$06p0{Cv0x;cLf$fA%>{OTZY15M1>iFMx3lAz(jJ5Aa@GpA^|wiHUWGdGof z6Nc*pmWznMa4@_*0FQQ)^@-f;5kR}?4m-{_7$t+B!tokiBEHM87>Tey5$h_*AP0|R zF1=(3M=JUawG}_e&jBnP%mi~|2yPhEXep0c#kqA6#L*VS)7}c^0t&w!glG~EE>8+D zFbnL3CRXSa%SvW<81AWXFjFi9Km?H8k^4xQXd)>gdB7ZK;Ean9W1?jABNG=~obVOX zF+528kmDYxgtC&K3WAK6amnby4z~G%`E{`_QoFelF>z)-&{PV|@z7S1Z`>X`wn~fj zCF&p2K`b!GAAlSD70AY|@)BW^M;O3J1VM%%80bi0#Av{u45I<^z-0+&1>_SRKolXy zjiePG1Ykx9M6P7%0nCUnVCo^XMYE{2)NAswg|8gJmbDi=0o@>_3Zw-uV0`5vE1?QA zy|L*Bc?aVs*c<2Cj7r(sJ_@1|!Eu1Z1xEEIBl;6c3g{ z&S{ExARa9s(JvAYFeXr+vEdRHN$L^C5FSqyAd@W`Lch>H@K3Vrfbsw;st?qT2U>)V zQi#|)HIm^GAsC5MbP)qV|vv~eE>@-U=gbrX0A_vnfj0D_uASx737^do~A!(Nm~0b)ql zPKvtO7Bym9Fr{#m2vZ6`LDP0X0K$y6umMzLMWJms2!L&%P;?O(1*Qx-MCUlY2^>fc zaf9BYS>!w<2f&#tJ|qmGDjJ8+WPoJ8Na$pJvPBJgc5X-QO#4d9SpjAFb=uFD9R)M22#sb0zfQTVgwwzHvt$hKb zIh_D7KvM|Opp_74i4Tx97A`4pS7%)#rMiC+? zZsb~qGHBe0m0-`Rx3?O7&ee20t=%GuwSqb1ctN z0S<0LB1BsCDiG=RWB8&CjRBtxgD z5E^4JElvW^wHjO;=~ciF8Ujv$p(zTqLSkHQg9pPhl3TR#5p{#b6PEI1LVLQR0QZ;C zK?^i!zm8n6@OQ?|dfsk5hC1VHHuu2Lo;XC!4R;wfm*t7Nz*g+baV^Q z60yU`2GSX7x-|CmiJL`IarW%1siT*>XJ`)_OWhIf-X2=U9)a%Dw79d;dU6SHw*%k^ z#z=M2>1HEwSEJtF9H~ZWtZ|fCpwkq+k#s?wC(CBbwG}pZy`h1QxZly(+s%{Cd9x05 z@ft%t{C$90t%S&8ktmM$_Wj z>;LrNj4Jm^{Pme_zyiKhkGppQd=>LMN!7zm-q?D1TIaM4zwTEydvmjXe(kMI{NJ|h zH(Ta6`EpkMb4d&P`)btUH+-SrEwd?PSnZLQn#Ye>d~~S!=8+~IJ4Zi^Hn)yAnyX{K zc53a_L#M3Xk=Sy4gw38_<_kub3wO^nTjdqFxHvE1?e;p^`)?kNFig4prQGQHkCayv zH#e$NW5mH)?Oq$n@;}-+e9*M?Z{_y=>wV$*v&Dvw>uL3?addR|lJ0Alq%`|pBd}Ih zvynzY6&EkNjVZ2W^RvUGhr#~$GY4La_6Tn<>C~)>E$!7t^xt!8?&&2nJ-iDtozr|W0* z&)(6Y`=B8@rcc_3a`MGwZPG>_+Dp z&n~Zq+W4&wxBGrXu;6C>DM3NQE6$dWjvj7#;E!6*-b9|!S`i#S{+qfE@A68ArXPMv zUK^L~9rNyn=CBa!uTAdNe>|^kzS^g=hf4y!w{tb9*X3ZnpnKa6q}e`CZTkI>Eb*jI zqHj?#dbvH%>}%X>Xnwv`YRQ;_JvS2#=9=o~`y|wl_KS^t^}fU5I?sKZPP~0uZQ9Is zd6Bgz8 z-n8gbtCPmR8M8PkG0pjr>y4tLqub3iJHywoXmq%{u5IX8?d&U|YmALwb~YZbVX6Lj zYL`atcShWs+H-6E!XbSw9ZopuJ~Z=u^Tt8b=eKG3qG*)P1f3&88x|A~9ye^c&+bq2 zhS`SN?5NjvXG_C*>kM1Ba*olM>|f@Y*nId9{={tOB?ry!-Yb~DHGAInhCP!u=P%xF zIKpPm@yqoVt2Y+U95?RyG8c^(SGKD!*58!1s@L2F?S|hS?0lx(@Ubt}IhyyFexTLF zlb(^^0*8FAWtZN5wX=D>&1xIQZh61SvtW7fp?-BxScS%-|LD^SN#*;jC^Buo*buh+vmotd(At)d==>5$7Ai_bwf-i4jtw) zaaQPMO|9?xRs!>YYsZ?HKX*(VcmIZG^3L@uPxM-oIKeGoTBys!*PkYTzH@bH>%zL@ zo)5j=>H3EmI(Cz?rzCmbis@szqPcMO1gA^hogTQ|Tz64h&%`PwtdE}E{VDfr)U8!~ z?%AsC$u^IiJqD$HG`}>w^wQS$Yn%7pzRhKpfyVG*wp#Iz`jo0I8(#DEeD%wnA8OxI zx7eqpyJ@-I&1H2T#dWW9<>{(R>TC2aZTDOhyl{QKz0^;>GkI&_{3OH4XB;zyIj5S; z8Ps8eda;JuJXyt|?9Mjp4%zp*+D~7-;h5hBs@)AG4H~9 z|23B*X1&-o>1MLa1(QRWJ?>q!nfR*Fmeu>^@%97zXofX-vL^n4+Sy@8FF)UYT4VM6 z>6=@~i0Y}2X`@6&guMqJ)`FT{V0)hYY? z-EP^PJe(3?ZM(&}-MJ=hihVsl+2nuOU8b`!WRT(UEgEX|Bu1m3tQgl#tHFGJTi>gT zzWSEtd>Iq_SeBAE*5E>&BhB@k`}XerasJjG8YPDUy_a8hbZS&r(yfWyCM0URTZh(P z{Xg?YrtKWk@66Ydwz`7D8~QAA4w^b9d2-s3tiq!<+nq(1f>RBn8a}()SEtYWX9g=X zTHWlKa_qyVk+~r))*s}hubRJjUf~{>E?1Xj=twg1FHA6+u%_tbglMnMlEW*qRt1hr zI^HervfH;1CvoK0UHr9bhnKHv?lax`(C%|>tgSSDcFJz0wo5mD$>kYlQN!XxF4igO zH(j&;%ukjdcPx8-uEB+zu$)sfYH93DXtFbI!l$))J5S^kl^;DAuF>Gh&Sp<$v{T;i{c-3iAb2XD{^FmMY@~QR!_AGo0n9wtX2KbNeeFI`>wZhHTd4{ z!jk**&eghbqOg9wnJG!~;ZN?iuQx4cYP1j+tsVJT zL#=MvwWHbR%`7I}b1A%M7#rVjXVjyu*Ru^*yo+t~TCHB=qzBdozK2ga7R08V&b|Mn zVq@Q{A1M<|fQZAHVny3r&p#vki}OE#AELJ|;$c`?Z(bclUQ$S?JCka)*-*v_*!F6U+kNe9HB#lo}cfFSKaBu5GI8ZSABjqx;?3cj9*D*xuI~H+EXFV0;IA zm;1V5jqh*pJicR6jUU~m$urttI8^U$egliGucanpZ$$2YDs@+xA_ z6h2FByTA0_jznR2R?_j74*kNrO?xJj`Mv2nEq2*vS)CH!JogymkUHJl@*4Og8?PKS ztY@GTPp#IVFMT$wdr&^geMGPQV~5-slxH{~hM zH)hTAto7k)aBKmp zeaQWKc2d7y^%I^sG*2DaKlJ%=199+0SIcV+oiyCKESkNn`I)xsyICDQR8x1}wUlC62Gep_+y`HTJ(+j+4RP(1y(QkwvS#|9(lT{ z=y023Q$Ok4(aK%>WZ{|4xwTK~zZ!l!Zu6e~J(txh(YbW#MWFc|iojdcj@`QuqI=Nz3bfSn{R0Nm&Bfae*PtH!r(!Y ziA5K4^sXMb)5(8yY*f~>6RAsbTqhsi>o=|2f<<-L>%Hq?Yq)20kj~-JB2kVT-$cL8 zqJi&PdMp~8EohL|ZCmz&V2eq5Y4!X!FWr1M*1Y$c5xbM}Cir+A^6I62aLgEW^F?pY z86VLu?46UCx60r`>or3()=ikbVa^M?(|dcz%+0b$>2f_b%l+J=P3UbypV&v*BnzsGJc6kLv@NTE>PM9&= zVb-Fx=W_(})Fw|!OyE5|xS>`WW9Oo%;}MP-hA89-g-+y*EdJHB*Zlw-RRKh z7FjoY*_IsMXX9R|k-CiM-#ZtaI=*W0vFDLCLLXtHfHPlq-w<}@ zYdp~Sqw`LqQ9dO)o5l$~l)5fyU%%Wvt<&yUtB1SWv^thC^N$U2#g{x|#*gu{^85eV z`|7YLyRB~(5kX2(DQN-e?vj%3ZiZnPh8moqQ$Q(^5)q^n1S#oGkw&_uQ;-@$y1pCR z=RD`U&-cCGpXa_V#`|7-?X~w_JKV9>Z|`T0cSOwCkB+#=$!+ykL{H0t1}%`Dg}J@9 z?M|13$#6udMi-p>vlp=$x^5n97RY-(^0CoKtj%D}F=F>ev@!Q5F-v$|FH zdhq_iwH;HP>s0#ceI61XPs@jW%Lc5Jhi|2=T&=F-NhXk;N{xeIiephxs4+UEsO^z{4HRD?2dF$Ehu5zM*6XqnD; zr|^xH^V}PNwz@S)R`>R* zu#$J3gB2DD?3OZX1+t!>S%>RHuXEkIJ51>4(9gdz`zhQUViq%hA+=4RonD!p!ad>H zeZDO8f_=Ui(k}gvCVCGjEFANcJP1C#*B4;N>POSMiW|rm@k^)ONSUrp`rASz+b*wkfgD{<__N7( zCh2#$p%k?Abs1sV_9zpEU0 zK!MUm^QxgZq`tItrRp?q)A3U{RJUcUEsmdbW^id#eE*XEgUhQ|zMN}xAXf_^+0G-7 zznL`+)n)K1)#*lNa@7WpeaX}Cpxq2R*y?K;g$>@>8pN!1kMXm5e0W6{{(jdr@Z;Nf zi+vK3ecNocCksBE(ekYo^hFicQziX3`m3+*piM>ZUD-?@@L;viabQy&=Ms06@eZUd zOC#w*n^(xg`TPQUVY?diZaR-75SJ*pl?*Irq}#=_b+ESu*()M5z%Q|8u-0~(2-9M98r-sU5WB=|1ZUU^RlN2>I-fAs2ClGeEAhEf1ZlaR#(jc z>lZR;obX4)eby#xunO$Pgf%JB`Peh5oA=(uxRI$ zy-Up~s=1@E-f1_76qzAzV5WdvX~3DY#arr&u6Q{&GtL#0)vSy0X%^orG9xBeG8wCu z;^vHjSf}eFm-qt?1e@#Qk7IWR^92(qhD3%JO8TW*^(ZgeUA$TtfO_-^pD?T-Ue7K# z%LUHnvP=J^>q?nuz=@00>}XP5;YFrPzI$Y9ExA-_Ui~G00*_+nukd+N=v|i#t-N=zNA^dh`)i;OW=U9ei`Yc|EOf9FXY=07WOx8J6dirWh(3+7J z+7Yl`%q1DnS3z8+GKx<+qb|#KQtuXv0d>?me^j+wQ$!J6fb%LF6Z7_MbDxWM6kcM2 zuD~p*?&#imA`z4M_EBb0)CC4y%IK^3mJlp(+)W%!q2a5k8hnN^uLkuq%xp2x4K7k& zfT+EGkW`DD^rQ$|k5t_Vn~XnPt2`9hWo9TH<_TC4T+o~6HO!AtT96B!9o=U(db)Lc zw<*R0_0VYWN|#RZg1DU+@>HG%%7{I@WH#8^ zGMh)3xKl^~Mrpr@X=_;6Onl;+6e-%GIN@3z$GEzkw50>unwS9ty<|b|vn-Y{5>J6g z$D($KH)?};6OFY=BVJP;Jlvt1PO?rqu+0~k!*=Tj1#db+mKV(0E)z7vx%Ul4x3rey z!ets3`n4r8h7v7ZKM(8Zy!&3&XjU8y`}=!S$$7_YZwMS8^(k;y9=Bn8tg zRv_N4P#mxp?VBSxX(BcDeBTaJ(h?!d740`S`c5X~<25#E*5ip6KDj9a zCI{t(4h#%^-wk62y!FmUdw63?@#Az8PZ00s3N*%2IL`~b8~!x^Nf|L^xBH<1+1yPV zck1fdqE@Nub!AlApxBcR@AhQi4Y^8P`jIcMpEObI+3p$#T{Y2;<$HZU^Z7#1k7GXKxLys>{f_0nKcV6wj|41a}6<<^1UCzLe^eK^_2~M<-7kG-Ju4wZ@(oVH~ z1W_g?W~}?(%Q!0PZl+y^SB#KbH1Ak~yN|b96A5_n*dCRWNGxc&HeKj(D&AI<+f#0{ zj4G7OH=b%9NK^?=zDu`&)hP|G{;*=Qt&V!%X0c`bMF};wST$jw0UNShgJ8_2hbA-S z2gNUNY$;d9#@iI6i!64;GSlW{Bi{7x;C?v~8fzvS-cqPasL6g4C=3_fIJEer+?)hE z=H1E6KYa7n&f0w-bt0pDi0wpb zQ;DR&^7`m)9d`IrA-svSH*SZV^RNag!PA6Ad;jYKG7)oB{e=AG4XJuj+a5(q@jJT( zNhIa(s{689jp->SvbT)N*X%mK!*%W2JPyR>T-JTi zzaOiy&{rNm)<8VG(D_;nd?{w5sg<0Rt;@H1-5pU=qdMc|Ukpn`#v-eg)D=hTvfb&S zQzOH>2Jz5m4hW%Sp=JIs&WV)H$!mu_nCla!<7{={yle6v?ISenZdKIJ zts^}Cv)G3M`b`hqUS->QHu2T>Ae*YwiOKDg`fBl&i_oUy#>4A8HXn$+XDq`@3z%cx<1ZqVyX9NH zPB{jxHOcF*=PF^fe6tz&$@0@FZHDZL7;C*>K_BI_68QN!$(#3ksGZMmV7ta_c^;jp z&ZKUue~yYM6p<~TXs`gso1LU?i3AaGkd{9=5R;3B4c#3p$MlR<4&{7$DE#i6Q|2=#M4|`c?R7W5{3JpDlP=|Kp4W%V?2$aNt`45yGHUMJJLt_Ypz6`RnT#G z-jHe1Rrmhl7ggGau(*wQg&BC`z=_gD5TWGam|jCF|Z; z$D6*ap?Ca@H6KO=*NS)hoZ}Lvkf!mJf7P5`8N9%SgZIJKj(AdX>U`T&$LxuX&`h9& zpNVrw1z2e*#|k>=)Z47r68rqX-U4Q)qfmB>!&{TAhPH2Z)cPqu*)nUae|kl(hK|g* z%hKBPVd7%N`bd=y|7>}?mP8!S3fkC>_+8bdG)WN%ZE`15BzJC$37T81MPNEjb2VZI zJ-%`idmFiz^FXl8@sn^)5vek1HSic^@7; zOf9%jgM%ZUFsiaScbQ`olYu+_c1>-dQfzQi93$BP1t<&=k2A+hGqUWavCTdVmhA$1H(hZ0UI;M9?7)?;5MUI)J7-E|S)jkz1 z0w)-8li6Kmp$O#8e8mWxoS}Ww`1nGw2lt!M1BV&Q6eeeC0J7NUIId@F1?&Ic^ zcJ9hN8J=i*Z7e-Jt9!E`rUEZrNO9l3XtKbQu+op#gDIEg;EDh=)AyBKdd6d=g82CZr3O z3dT7K7bg}%A)SM-1d%&$*TRn%H@afK6i0a)3qC;JPhY#c2-V*8Ih-s^6zy$#G*k_H zfwy;0G*XOK&78u0p{Y9TkF^s;qbwF5 zN=-{!q(4#1(8$mMeHM-o!@v|adJjUu6?i^qQRiTppyBxL)&uA+^65!rO)o= zstg1s*1aLK%jGq=!>E!=AeQK-LP#ZM=yfV%bLt(p5b9;yboiOnv-_Z9N4d7KCg{uP z9ZVD4(G%$?iTqn#hYQ+fE<81!#dp@9cc0dKkm?hK-LKk~*mISb8>5r5M0IJy zipa2aJSU-`kHP(+ka&!-hbk8$kLnIB3JLFX~q#}Lelr3WxoER8Rt zG##cAmsG!8+z@J$hHH!JZtE^ah3PaqLp~XnrkGTM@qYRT`&`; z$5TeD8JS$6TEW`s0e2LA(DO)|>hq3Vbc=`r-)Or6n^ zWeT@g($sdZM8~R91q5-;NvO5*K}v+>73Vv2Xq)eSYICMW4%kODSMc5oUR>BR(>BlE zOQx4fymv#@iF={v+UK>kez$!Yn*AE*HnDowfaKBb)Hh;-hvD0CoKzLKlsfNZ(|tcj z7e`e;F~m*s!mh`lB0;-a!+wy$wTR9Wi4yuG{<8+pCx3N1FzHS zniI#?#f#c-NOk(7h~1^UELYD*C@-?BD?gkJ+-wow#3&r5Cp?CEmQ4;bCXa$p&Uz4+ zAuk?chHj)N&ur=(&O>`>Y7ljzA{pv}tUq=Z;sP4Rh?Zlo)YfAvtV+mT!`+N?Xe*~6;y zWa(I≩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%0ADBXAI=Krr< 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 Date: Fri, 1 Nov 2024 13:46:02 -0400 Subject: [PATCH 049/131] Added riff regression test --- tests/inputs/riff.bin | Bin 0 -> 30322 bytes tests/riff.rs | 8 ++++++++ 2 files changed, 8 insertions(+) create mode 100644 tests/inputs/riff.bin create mode 100644 tests/riff.rs diff --git a/tests/inputs/riff.bin b/tests/inputs/riff.bin new file mode 100644 index 0000000000000000000000000000000000000000..8a39e72d197b56a508c0af0bebc0bd122abd1e29 GIT binary patch literal 30322 zcmV(tKTmC{=ev&ww;z9|_ry=T z^PTx_`2Lsq!+NdrPv?>9GyT5%ruBFDOIy!7>zDLCzZ=2*7lI$!`*?qu-#_f1)A|8> zgU`wfy|Mi-K)-`?+roe8JwUwG@2>SfU@y^rvcK|qE&cEQhp<8wpptVpQWhb!X}Zd%R$eqq0vegID&;yS z!@|+2PxyC^DtG1o4Ga1{5Nl0s&+YO@go{R+4Od+M?-^gad_8=WjKDnv2|TrLo?nT| zA_K+5HRwKnp30vvG`)`5Pf%xm-J)~2vMAx8{F5Fl!`m=i-;Se=xGamtY|PJYlWdGK zsFNM6Qxn#Z9pMVuGjY6k!^S0E9j^SZ*I9RmJS-6OqQ?yt%Ft$Q6{6881V7H(okMR1pZP9!V`IDsRtc${F!5oJ7yS_gDklLmBy z!6bMV80~AwGCEDim)kQ=T$l~mqJbb=i&BL2Efa+ zfJmyJQ?QUILxy0_m1^8i^&vbtLi%7uEqUECLm8rH3eM@qzQR1ag@!9;fwxF9Xw>66UhLocR*N^W+gr_9va|DM%=x7FjYzH5_0 za|b1>odX;i_55r2gpAb~SFY^RG>{i4%C^4D6yD$4(q1-j&yIa-x8DT;)v8@&ZU>L59=7XBU=V8=Cx%4d3={>BB5?;~zwy1;hnJZnR%P;8rjEF{-u+vKc#iW0DH5rDd9<8f0R+XoY|{1lKxHNKMKGM;!VH z=WZX1niQA;9_VL@)@d@4JOVg{sW+$(!*KGf_XX_Nt2{CEMHkWg7LXb=-MuyF<$}Bu zsi*5WD(z%)pSG6s*C;2|N$lgwPF2;%nKgmA({J*t*1x!vmrTD8mB2oXluEw0rJB@)P^zGP9 zpMJ&UdR*)!>kW#Jc?ud4InYzImQewdsq>34mB-M9$88(U}%z%^Y- z(^D9|fr_A3@$x2$TSg4qqMOTjW@IrmGG@^f^W5~1*sLq$E}X?vLa^-(?!Jhv-4^H6 zVZ>BSfFK|u*N^LnB?%SFN{r+)9LVOD(#;Lb>;T3JwDCF*M_EpaL8%t%Pt0G7BanQ$wR{5Z>Q6j;vYlkhw zd7z6W!!eh439>CaRG=UiF85}f-dAg(si4k*gzev-(a2yN35sHxmlAa>0>`;qimz(y zasKBA{@bKq%QmEbV@QOh%K5rBtv?NbXxuqc!L;{gnd3Z)8Rdpv1XfdL=PcR!$Ooiz zm?;}n|U@Om;WXj^{woV2bocR>P7_B@tIUhff!wkiAq^$a=LWVhz3mtv4=5mv{EjHYKT= zII@1j_=&Mp-KXRdArrbPiB#Ge4$Gtm;tK#<-C1HU=dm`PKCj%S%oNeURmoKi4O8*U zl{&)^*f}6JL^|eckO8;f+qUZ&G4ZPb3_kdc4TTKb7S0!XTDJdkG|y1m;cn(=LvEMN zp&PQB2rHgB!ED4sk9;B3#6B{ef`m7+Szk z3>1~9j>vWWX^7z2z&+r{#?dlnE`4!QKrQWEPzQoq7E#{F>8h?rM&~25jChdXf4R-Z( zij+k~V?YV-K3a@5L1pJ`ngV=?F2SHV_HHJu77VY*2fEbr>b|mpj7%!w01=fHJp1f6 z?x7CgUwhaKF~wQ4S0m)NaD@F;{Z6Iw?lQk)n*%ufGQgY=37onk;D-lVi08Nz>$N63 zhfch@jc((5p(f(dWja=>1)n*E$J#pF|5|kcaLYP3Jni(;)D>nDRKlHv%8&2S`n7>o zB8v?`uGi(rd#)K#&|hDbfE&lwrlr~P4Jrv0IY9=m`1`>(`LYMbHP)wjxh)>{xE)_V z=&OG0XZ$bxl4z9PxH`K(PC;1D7P(CyIAXh@v-`v;LbG0Vo*Q=q(IbJrXO*IIgp&PV z{u*`or!jGn;5b`dq~#)t1}x(u>8rZZJ~5p3IM}~(T+*HtG`ukaRoPfbEbz+YSqfd*?fT8m0RfQ9!iWh7(!YX!gp< z%%47vEJwy|2r>qbdi=B_CC`et&34IFNd`~<)t|v^T1kc@i?ztj`US!)35oq>4vsyi z6{TuL=m#7xht|GtTBWin?>9UU+M-qnDX{NC6&;$DU3-|22!EULn!{ul-9k&45rh*v zzZ=pYQ$lj`x{+WN?%P=v2P@2>imL=Y&OQ}eVQ~#T&fDiLZqNCBE%Q=Sg9xE?kj@!G zuSXye-?rA9Q_3Ts+-T#fH@0|uS-2A!d!6LSefTZF8OOyQPQVn(?92o7yypE4vE}Cq zd^S9;RaOHUPk1N)zyRPrG0YiG)lu&B-ASlqd(NY{ecv>tVo?6{4u8(^O=oodHkKpo z%cV>@q;|V}A_FGS`8dko4)>Sxrm*XYiF0k9|Ezn?g&jH|*dZ;)irT?W|Dsm7EZq1x zl5h1bFS$Op@aw8=R_F2m;bZzSH^y_47C+_gXWr#-%m3ALY9h1lFjD*27=ll(xI@Z+ zH=*c+gItf?%k`cES@*(Bd$w9^ILLWhQ%%)iV zoNMp-703waEa25w2YfGog@h-FA0l=R_jyRrXYtY_-ECfzD?SE8=P~kGuNI063x)3l zsDyZ_!w1rL9=-yrx#~Isxd6ydeoUl94up1N!c-eGVE`Q)T6%x)+|V|GQWIAhUlU8) zIfI5FK^muZ+fwd0l4--Phm0n1q=kMO5@rXbBkZy`(iCAW1dEd>9Wj2#Bm03H-~YXc7Ij4*6Bv7`aX1?&(yf$_SR079 zXxxqR9mL6Z2P^HoP#a>U?99Jb4ZTbR%PbVBWi0a-5?fxksIj!HHUof7(0HVaEi_j= z?-MZ@^Aep0n7Y#}1!yv6YRx_MUdzP6(#bm?a6QdQ*s=WA8lIZAY8LpnDwZGpv8yrR z;O2KsI_U?bXhZea%$52*j&ju_(ERh1i7k?GQ6r*UV5TYmKZPVkj+LVr?Z;%#xxU3S zDpm(m>OU>E_=dKw`z9n`;+L&oLlRv{6ewN`tk8D>3-02F7V(NxV)*I#E!UuDTEKU! z92O&<4ZQ_Zj`qqow3Rq%kL(#l1OBjJAD?L~C8t<6UR>Gd*bf%rGw894N-{?Tkv{uY z8rvvbs~AW`YetHqwKxCPW}ZANeS}e)89~A@R(kiaaA)^qe`f4YYcbSgM9%s7$3-gU zV*=eU1U5rvaf=waixw2d$sP=Mj-b&^BH52sy)zfAoi!y+cm3$p&1x&GQt-i%o(+Yv zoTr-jt9icMECqe2eD_$H8DzoH(?qByp!GKWyCSlR931f^HZ2*xDr=cQf-xYpQ%15@ zt=9Cpf$6bc_HsZ52AM}d-Rz_ejHm$p*dh&I?fmg4&EV7c%DV~VFr|S33L)#ihaRm; za3kI-cfH^YgPMre;$uP@sj{1GGuM-+`CQ438;osgZ$ARuZI%Lqm;1nUPQ}D>s_0o0 zg3iJZV@`va?cn<|YY`(6EagS!l>ko!V0R*i0}m8qT1v$cNF^^MKI%3Wxo!YAJ|Mnl z^1j$;3Xd2+)lT7?AhZ1ALcDvaDord5YqYElY4JwH+ZCjCUODNI3DBCye;Nx*Y#QUsyU2R0;q}XE4tfaU6f-E93=|_Hq|7@3Pjd1GA z0tG;P50tWH21^Tvem!H*-J58X0mt6tmVCp*k6tWwYjGf>G+3{M7!=R7FO!RT;EGB; z9)@IO<&o5*1e9n|4gJGJEXM6I!y4Ln02#0bb*slwA|kSu1G^*1W3XxVyB>LE1tac) z=Ypz}e8?)f&;j?s;rf>S!?5r%*IKs0L>SboMm~)e086*Wo~VA-1{$={k9X#8ahSu| z%z_)$b+BcC*p5Av+Z^Sv_P>lN*fhT?sgLrcy6|nyw(^}63lRGW-h%Mjm74W>Ih#S1 zy{x=}3N08FbF)38=>{d`071E0-oI*R^HK$R}o4jN&1sk)K4+jid-ZMtR zH#2+!(5dLh<0N|*;)D@|%cIF`g{BD0cD-gp7uqmJ$ddS!}$hlTtX>5y%nm~a8^$UrfA*yqK@uuwN}#8wi3D$=Hl2(`E-@o6hH38U6y ziLJ+-wz%+ua9d!Bea2}Z^Xn+cx_%Pio>{D`$3ck0J0gg_?hW=(|6@v(Vw(T$$IL3B zJWs3L_Kqev3})KtaRahfQ^hq;izpE0ebIwr@MIMhKB!vOG+(T)p$MY>L+0#G!vCh@#eC^;<{rH*|@e^wP{1Zkcl zoVTH69n9ADX%^7fYAU8Y21~%d@;Q4{)6h5oE%w6}&TNR23%u`4Rk-86)?Rxx{x9kY zCAWCTkH!gD?EhnjeSXzwA>;D;`+XF}z@5S8dJ3=&ABCYDhS$~_P>GjAf{EZE$Gsnx z763|jlRjB5GUWxp?1PR?JY#gQ+D;!CqD!<6Te z8g04Hq6Oghx->Qcq?WN=uR}}*j!C9^w)qM|mh|)&%*9=%vkjO5+0`gfPosFc?*urL z|2(Am66NRI<@)Hnz}JcfyJ6d@FwQjZ<`(PeTQlZyx}Z|>T$uRa9KyTXf+`YDIgs#g z@neS*j?q2FxD*r;$|z>)1)3$6VvO)EtiI{_yh>o*=roXYtTJL_zA?zsWFTY9bjXy~ zvrI6Za$vxU)CWTF7)tT-J8DIAx#ntz*bRXUPfD`vC=9xyGU|Gt>U3A$$ZR*t+ra_| z=G>X%3)c(ULlJwbH*x%U^--DLC&NzH)OrRoB zM_-lF3!|5*V)4tv=EI$uA{1q=b~u@v{z^WP6SF3rxb!dbi+XpUZV=W%41t~-7x{wkmynW2MQ~aBlC*2um1~C9go{8Ovnscfev5ZNmmojBV9$?QYMr4{f2O06kLJa z+%0l0gD2YeB%j@rp=nR3vP;M~K;FC#np7j}aiAjuUsBi+pYWB42Yv(uaf_2DSuXGr8=P~B zrXX43Vs#p^0_hcaD@dDDfBLDg=Wk4GJKKqRUhg!e{>dD!@{os$xEGY2h^m*wQ z40yHrz`qNf<)qV^oSrio%T>;R$WOh`H|(exWZ#KZ9WUU+%()MB=Q6HD2=s(~Pd*vR zVLyW9hEnM3&pcE;3(8Vc{6nw9Uha$0Wt>okv&7pi$NtI#$4JG+JE<-o@*rbiIS*_$ zjNJU!rc8n zix@!+*ZJ_3EN(hN)$Q3#J@8mK3x@t8rc8pxNplN>aJ4_ircDzySGb(xIsYtDJNW9W zT~SfGl3#+@7O%63tI1f-^LAejL*u9n+l zC0ToI&x5@|6w34xr{tF$Cq~a^AVOTz_w?$bwsxI_5^mILg{U5LstmO)?XUwkZK#(| zp9>HAd0wkOb6!Wx^LyDd1K;k&`>q{qFUJVIM%PuTTfh6qw(#-$o$((PqFF3V`#&bw zmf)(V3^32?O1e0tk^sMpL5i>1A2J^PaU}r$WW=z&|H*BUAZZ=PtDx<;;}+4l-d4B5 ziJ;7eC!n^OieFtVY4lI43|oz4kgA6zOJF@YQ^61xzhL&B57W&rzQ{uD--!oSDqYegAJW`V^ zaJuLNuqMAJ$0=rENEovut#QX24_D~u05(}1(3l- zAw4Y<8dAE8hDiZL9ul zZMYcyNno+8n#=MLvtCh4UJNAOX!ZToE$g5o?Hivq3TVDygtwl%A^Ca_{AaK*IH>5i zrbOGUx>b+NTR5%*&TeqGXL%&j-8oQBynzdNcid}0(!nBrU#xo_RhcYfW6b;e`gGIb zz4qm+7I##Zu8g76Ca*mu5nH!Z;s--no{zNuT?x96nDn8U!}(Zz*FSztq^`PiL^K0A zyv-xc9J_VYSg-U=x8+GF!|sB47T7i_)LhUV;QoydW?*$EU*|$`GL3e2ks3_&ADfKH zI~JM)-CgtbE0%nNO-4d)ouAsX%|&?cf+kQ^DZ6vfPd=z9X*;X{Lx4OGn#)S67vy%^ zLMUtbrl$a#gnnr59WDfy_~Wq8`f#+9X^eXkfL-|q$J~yQP`tXrw9e;p%uI=bEGO?? zEFTYqWOmwl-y&3*NBVB8U^6hY>80sdV-*>(5DGESl5GM;QWGY_HhIYS@>BH+Bi|Sv z<{Od|l=)ra`DZG(@J%(k=qW-~6ODj@vU5(XLxT8g$G-Vorh&heHS?l{&k+mSJE#1y z(6u%XL@ZdQW;u{ACFl(SPeKrWzk1MAPDewLps#m5h-0VP89l8ZX`EVqEy!!kV2voq z^(n}&myqfIvQVXv%+S?20hu}81Pvvdhtb!Tmwosqk=uRMRak$g-yyiuaBXZ_&amZ( zEoeF(pl!Al|8yFFw^fvpsy!5^0buD#uc8yBNH7ES7!W+Ujg!L=)1if@=Do9gU-?#2 zCd26u>nqb>TIce0(%#V}fn3K&C=(VHU}l-X3ovE$V%+aq{S@p@O$t*n8~I&>Enu>P z4S|%Kj{3VR!3ejO2T7|yZP4dpS9WhF(^2iJi|sOLXJ647ig9e=9z$Ei53#!VyIuYsl3!R%M~5nkP~)Ijl$pGhrcAel-mHp{a>Jw z!p#67{?oiLVno6ivQ97=oTjor$IIRMNSQHmhSLq~c)$iTp4%^l6NB}wG{DFSVHSWO zFx8_tIwi%ZtOOm4`zs&L^p)u{BgOJkV0x2MgrbkMygbnM9|3hpE)7t910<@p+!q(z z@vOqjXXb_z=Xr@du;u5wMn_*^tLNEHaratU1++ng`l$v*ZC5MBszlywAI31hHD!jT z-2FzJuAyFO80SI|fz75MaXR@?GSNsDn^L+`C3>6zr8RDmR*C7cz1Oi;7y5VQI;0OM0Y zBQZP;5(Q5q6VITR-1h7Y+@ud!YG+Hkg7mi{z!8^cy2G+vb_IJ0-tmMyy#VKdB~j6` zqrcZBa)f1@L&Z)}L_JtA2w(=*EF$5{YXh9qIwPL0UgjwUXt|&@sTR8^^Dy#Twe`b* zcJelmQG`=ThmsE2V1oA;yvr`Jw#YmyjienmKV=3ZAfG)GbeKmYmvWlq$O;S|^fr{T z?Ne50<}`@&oG)y~HY_?p4-dib1EB9tnN{{yL-0xdi72xvgpIGDe)X$}+H{t?2G~iY1XR|CB?%=cW(GE$s7SHaI>%ghC zBXCrIVng=KCS;Z(;rTWwwvh?-(${HS(JSlGm<_o=V0}&kRv_X@>$YcT8->OQ{ngn^ z;I71Uz*~+#g}DOM^1Q>RWI=BS5<+CiE$j&#NTUl@VC@_|^W9%Bi~JMlX7S>N_Ce29 zVX|ZMFmthmNaj)8`N5iO$mao|aOY`bpWKVB3JYuH4W}orfE%5*f@5__8|}lttim{- za4I`O>T=65v#Zo z2hktLfS8oiiEAz4H&q^+Xt?>P5~Ky!e{Z*>kONop(&s!jjXqVgcqt4vZqdC9a;;$z z;Haz-*r{O+-8~O7Q7RzItzl5-+3_$nWHYUfe?xozwL1_1BFTXQ2!M)Ci#W7 ziY-j(duF9W$}lf46Ph;8Dt5PkSCE3w@ye<*ZN#0vHz|@(Z!n(z=rzN8o8NOYyEBcJ zPviB_ADNwU<2)(3pj9S2f7T~8*c-M*J^P+rQ1L~Y;h*{b?84(rgfX?873ikDrMg|#(S zOO06VNVlb-agfMkk5hqVvg_i3SN`4GEVV77{wibWrnq}Gq$w^rd(@z5|!P+-nn}7H-%2c@B=W~&F5rovV{#V z|4qI;_8DhJa_%w52FHX&#aX3{$azpjwP(c_C3qc`dwWG0x zvlBoCaDeh23OC_Ed`-A=I}co-M2+aD-M)n={*!#aQV4&*hy|;m&zeJC@(V7g8i5&O zgFaZSc*x*WNE?+|>w7iSs z@r8r<9lMiyZ2~7aZ558xvgQx;i^N1L4g(5N$-RzCk?9AQ(tCX}&$|>6A+6t!;&m%3Snkq{qk6%I*75K z94dlFRk&1ui36O&fyT1)mnUv2DaP0fjH)a$Tf0V75rL;-zP@K9iupZk#by&n%E@}d zc-Dz(ELA|6N-i7)bY%NB637M<;(qDQ_{6kDNP*r`EWyY`5WjsA(`(D58Eu_nk)dIy zV4*j9$v)dMo^7Y%)k@-zAO_)5rRJg!tZTkrRo$p z;3*BA_n!Z#uQf1*nIHNh5vv&@fu1bT3jRbyk0i%?fMKbjZ)HvH!nt$B!*Z6DkIi$< z)#57GcTRg>JOOC7d>9DtGy35(%kQb#6ho;lZ{$rJG39YK%^$C&toH(hXf~1IZB@Lh z4;xCJB(0m;m6Td2_hLjHe2e2`ihY$i9k(~F2;>fSc?-cb!%ME5<*f$wi`4YSqV5AL zH}3!{O9{S#Yi|*D{aEe|WeL4^BcefMJU6IdQ1*Aqt z)V439EIA&ZCdj1P#7%r;E-8uKqFpSiPHXR7^^kXniVKh%=PNz2lPytd>TMEWX&n~H zzP1ugN%PzfFLgPE9Q(k94PUW@wN1;ZuX|Y11``@m9Cq`^V^SJpKWACPa}N54reKHw zB_bKXV3^%{#fRgK8UKf!+DVQ#p<-q-ckrO8v`C-CLegKo3%-@5@eUW56{i_S&hg6e zpR{u6kFkd7UAY7@(H;5a`G{~ci$qE=x19Eso7e^Fn>X#p$XcMaIm^CA88Qk}>7?m0 ze9)Nv(H*#sMHqN^nwlokq_TeBBfUH1{mOB8uK~dsW1(*)pSkt@^a)8@Mt~x@S z?aqhWtLdJyK98|Ef7vHm0Ufi`f$=-hDEx&C#HLWzM7+&lCl zWCA-kdhhut`HUH-Tx*q|HDi10bYTrI!r9blTJ0nP-GxPSj~t@_9j&}^gOa3)gzSAj zKm%->4CCS#&dm!08u+Sc&hU+pwl|~Z>L}I(%2J!HY{k1mI@lmR0Y;9*r0BpRDyT#U zv`S2K_RrVsj6H!>2%JRa0E<=&Ktt-F*pB_etRy7u;@lDE{Z4fSDC6-^y+U;u*lM}N&lzW&8PNRzi#@%`jU+oGpxvAjq{lJE*<|Foz zSBx${OXL~1;Z!l0>ojF>@vqqaSW42c-?n?7t8ztgo$_R@# zx8#`Qjbw^a3p-Hk#3e-_E)|5k;QSuqv@si!Wy_1#iFtyHdsUuxrTPj?4Nr!DmD2g- zu&KhYWDNaYS002aEHpFNwG8#rmej9IH9&FGkcXbvs(CY%eNycLSqYFGqEpwO{qknT zN2R++ysj0qMYmj)2K%w&Xw=|fk_cBcD^@vZO{=Jr@TC$I+PW%AuOgox76lLx z-i0vdc$7;Zws64%nvU041ebs+G)K(+a{r<&oqxv7Sa}#r7)LWECwLrv)OEFVaD9Wl zQVYdD|Mn@uF=N&bmDeL3BUtB|&|LUF!9B*w&rgL~fvcfIY%KvNSB)lApyBZhI)J|( z=%niZ!M|5IG@f*kAp>-LVbMM=zE7jgM?VDKKuk|*P8{Hj13TD<8_jjL<#dmlOK^qU=kZV(H)@s1@r?gnrIl$t3PfS9+sbZ7t_ z6T9mN$B;#o;uA&pzhP}XSf3PW@Rlg4C^4zPn%6?m-zj7kc@CCe(XU%1fMO$1v=i;< zG|bTg3V@*wG9ICabJ1$C9sQuL@$w9uhUucjAz?>+mQbWdvoZ*i!n&|*UXHx&$)f!z zSUoIUhyG;ZGb|Hf`g~)%ZP^IC%Zarvi5se2ZJ8yr+HlWAACBhZ1gFVy;#|(XA%gBd zoqgLX)7awaC1sYV-!i3{WcIQ7f~=0>w`$MiU3akUQ%;Cf5MjiY@SNW%(Al{<^cx0V z+1Z7Lq+&Y7i}+2X7!?q-`~<6`ywsV$*r9z$pGM-I(y#=YaS^}sF({kvd9O1%TNNWs z^qXc@R{u9;EraSlSc@ii5|!6yU~i{__M-J6$s(TD3@Fxk3w(m)ffLW$DuCL4MGS;a zXJ%3zr7tsQ;lWo)JY4G%GVUCBF z>qaR=2Uh2e15A0UJAdYD}EQ_b;C2A8^az-Issgft<5WgV*2PcrzPjFSO2fO zS|8_Bgmj)hlzt`K* z5xpQe^zuLMRu#E^6o51;pw{5elAG-b~K8tB?RotJ0coyk7r zHP$)CTX6WI*jor-YnNJGQJyPg4$U$yNk|!7hu8suIQBCmKToA$(ayvYbk#K20D!(y z0*xpU3B}V1)Xadi*{k8p9;lBa7K`MsPvw-$U8*kK%vuX;iH%-&pCh57%$&t3Q&s4L zUW{blCY>q@4Hb!vJYjt~c#}IsJF4FP(1ebKuU(2Ifyg$H!|-bRRiiqz9GVDN8F624 zSFZs3sgcjYZF+cNvTDZlC_VdCxLdDTk|-A$)$Xzl#-2VD zVcx$+V_E6V*4PpLwN1>x{L9}rx4&Me81E{v)ZKn8!Ij&nKd?CVADf}cpLd6zUDu!` z{mo|{W;cR2`QS+uE*NqFPYv#DtWN?cH++goAOB!L1-iwzUtk%DfjPg$ob?52>BXt{ z(e;+&xgZyAG(K|M?;V{#2$RE4RBF}}k)k>IL-AZryIYU2t#Cz5E54#02vL^bxY9jP z@py50Toj3}F0#NP#)HSHyz%)RET6c0JJfp`v@}lu#Ul_1PzemQ*m9jq{&YW4e*6dy zi#Uix)+^xL2qkla#aJDzF4KfIBWdhrg8@ugPQ`}Nf?cJnS+{_agfDbUB9T`H$_j(3 z>Ps{H_0xVk#ccL%hx-oN=+yR8Eoa}p8{C+yPsuU$F#q8H`=X=OF`vvjU5)szmmS5C zFX9^jap1^s1ZVMh3O@BwwI^-{XB3wUw^ASl6$-o*Q|v6m2GOUzt#%e1_yi!8D}xc>>1YF46H_4%*2+6L5ynbd=hI?0V)-pFU8 z1DFiab*|zYuUg*aOhje#Lei1Hz=XBwpU?(nM2Xoqg3x&EYuSPNx9do9;{nNFTT~dE z{PG*K*->NK>sBzcDXZ-YHsCcM*E(Jqj<1N|*>z5qUQ&P=vN7oc&Q|YKDKfIcA{4I_ z2(%7DkjL$v#iT%)BF8U5B>3F2)#h-E8eNEwO95G)bb!Tq{T#snsbf9*ZZXO$Yp>$- zLo+%FGc?3k@bsOPDSl62iQp?t{nN?w?oqOvH z6p3&i)py?sn^fNz!iN^DK%G~XoVE*%Hs}L$dpyIQu~~>L5`W}v1wMe^Ow1hiFuE8J zUsZ#8gkZNCIx5gnRmDpw*_8on`{2s@N`SP&_;zysKJjlUAda0=q+dXHTMFRW7zpv=Aan`@lNi632F8nn@Mcv4A zDsV{#88^75+os59SkO8u7r2qM5AGn8(j9&f?cEK&gBV&o(q5!vj)_is#C)6aH4NbY z)D^cprH4oI*?wMTA_hJLx8&i{tz%7-4_;MkEAGV`3}_q)ka9q{viZ(p><>LWJO;5t ztHw|zIvGnBTA3E7AaXq^`X0gZk>um2FH_6t|Ea4k-HC^m5tA>4^5bQyBZO+(zj*~z zE&MjdR`Ew#^iH*s}cPL4m0T-R~tZtrX@BJ27Cm+(6IX983+4aEMbOuW^d+uD<#)`ce`n{sEtFSW*ik?qQVTi;$R#LE1tbDjvIL!7p zU;S)r!##`RB7NWmAI{2m>I(VSbO3t}dAw;{o#!E#65>vUa&jfn1zZZ2H}NLxP6f37 zGC~n9UR!IEKYlmoB0EHKpN4r~aMnW9Glizk;)0LXn(PBM_rarN%!tz|HkZyXrR%sw zjMtR-^#y<5$#JdV%jhM|C^QHTTxU1Y;YI*|vzdKNv+p*L#O`9V1yn2VpR1(n09V<* zqN|a{opD!0?j>~iZW0+oLDI(2B`|UDGtO5&O;+zI(dx%tlO%j7?ch^7rJt3J4F{xQ z)_TXmIt~%eu8In!u2$-2X4DY+tKG3jpbw7FJcJz&Ym@u!#x~4svV#aMDF6r8n&kE? zs*J=cc<@p)6ZK6yH=Ax z+Thu>8-XwY=FD#j6kwdN4GHV@u&!_eGgf~bl8n;}AH$XjF zTt_jD%{U}wfx1l5@$XYp5^*r|;&C~#HMEnKg>dTX^;oolT~J|L^z1pU@;haha{+iD za7NJapbCo^UHEMbJ%+LAY_zw$$=Vo*|6Vv8A*2|ng=27tIou5O(tpdhju5se1&pIQ z7oA;zwP=La8f3aZG&3e7?~YULTp{YSCw_(_K4ETH7xQWj>%9w$7cKMiPEK*?+XcHo zi`o-E$Z#0nz8DXyL1QqtTp8LphJ(yrQO8ErDIn*CbyKE_TN6aVokIPlt7HZ^HsF(m z#&g_a^)TVJYAH~iJ?4v2*y!IGIA`IG=B764oZ##B)B)J)@D4b+%QZJ12yz`=m=sNC z4Z$A`BhqnysW?DP7k=i@u9#8he5q2+-f9KRNb>9Gvld@5vGx9O-GEy^wOhVGBHxuH z+Bj&R+a>>-NMC6(P=h87fmzYJ7Ym8zE9FTz3mdldRxA$APEh|7-#K<79i*H$nswQG z?%A$}c@!ye0nT=&q>-o=cO{r@M7%eMBZFY?pg6{}W(Y|gRy$Qzlt>?PH!?(lH@N5&xI!P=QKzcs!`TQq z105@T)(dVQGoGQZ1+&@}ZF{^G_>7Vo(a%ngY5^hp*dP#(ZF#YA7w44GJ-J1TJ=kEaRM`|EorBIaHkRjdQ?je z_77!|G_MF}w-8E2zu?LPFM)%{1S{KT1kHASpE$o{DRH=9g2JaBOhX#5C;OJ|w;V&& zfxZcDLMOm>DLZUm=m8ugc=cJr8;Ci8`BbJN2Cvs0?x%l?R&LUTDg?ApDO zlvGaS&n>fso$ELcs zXLOaLFY&99;5NG8?c}{SmUgfbDGS(wh%V zr$b;K^sp3#May_^=H!wCBW7~MV^ejH%vOr0-OI`f;bpwOIjfY+n<$ z|MSb)!?{&n+9(RpiiBZq4Ks-3d2xui*pfkl45>N6|9n$FC!F~(U|-cR#x_j4`A)CH zSX=sFLKxQ=A4%4xIkWMjxAfZ%^k+s@s?mYbSzidFD`}l}kJ90* zr@ne>RV`_7=n6>tG|-3`^@wf=FpkpJ;Uh)?@vP;Ax1u&D`dU##DztEBmC@nkDes8d z#d!6db<7tHDZ9DEmtk7m_b61SHgd0i_9$a1eCXT+#gf(TePChFsHm%5!M~5g33@(f zN3xz;$v+>K`tw3>fIP+m$5nscLU%tKd{(wMh`M~>bRh6i-s)QZzh}%z=(4LqBWbbo zFSdnNH3Gb@<{0f3$qRgE60@5z-GNmurCygss|njGU&wA%QtEok0BRH$bwlcIW2{_C z#I`ddzD+dT_wY>^1us0zLYD?4COjD%{wq27iVi=T5A5q^wd2tMICoAJzO`EmH@Ex* zN64bLa|3|>&uPeGx1S;s0se7938Ntx#XrsLIpPOqhpUk+nzI+aHkgJg)sy>QCEHZ@w!?e)_QC z#w58OWlDVHnF1`(b9@&;f8%_2^j+29ao3dU2a_1cCz zVS>DNLJ%zuo#0go4_MgUcScZNU;gjZUqD;{{#{fYZ6TlfU~n;Euo|i$bjXPiOu0vo zc!CB|BFCcUtPW~_I=BtaODx1)U3&ztq7`3~M14_aM7SE2Gph+2Z(}8(_#4(@CkXJm z%MuL9LFQOH*7Z| z;;Aq~I458nf^ybUKQAhn@6b&9q0749Q3S1Hyv{a6vHJocP<==h?o$<}Xfp6+yB=(L z?Tv#+qm664g0 z(H(`|4kvJ5zVC^P_t`n?%fK>Mpt9*xS{kG#uEp!5`oljKEE{(bh1d%Hv`B}+IHr*= zxb`dQA}GTsjBX5oV9?5GVINeq18GsN>QClQ!Ri5DHlWEL`!%CmQs_QwZC%e*G`{i zO3g?2&{JZHr?M0i{~2Xiq7;U$2}BGk>;d<8UhhQwg(+66FN-`OM2Rtwsnc!MxXF#z zU{0rr&5DlP(`W0nRp06tC7;`XpB3-8eZ^aC9D9p%`XvZ)QiKX)6>b^gR1qm4GScI9 zXNqS?@rDnRRoc8ZcyF2E1h0(`-w1q#%N(WTu&|g?l1wO~;t8*^k?5_`hfcRZSGNv6 zt_FS#5Uo~!Tx17!khIUux;!Wq=To+$pVj}FuqjKKB}?WQ&Ncvh%L#y z)Aynxogw@vS8vhAzW+62XCgm8Z?iH?y0IQQQHh6y&fkKH_x|1mF=%o*F_%NGcZ=$! zKLlaYgENErPcrY}05S_D9D#Mm$IJR~8rIIeC{vlocBRsWK^U5o_|t_rS@oPX7n?iGV( zeCww8ztLjIVkoq}wQYpB>xH(q=^E@_p_FMa#u*HN>5Q%EO(*8;k)*P8W+1V!2h`%2 z3ZVn)FKZ-w9=H0G#C5J0vBGu=Z6?eHXX3q{$oJc z00omZ@Zj`9MuyX-XLr+3lDXiwK87j3^(Sj}Mp6YIwF2{OgA99ix@4Cu%-=1u$BPoeO4ySzPUWqHpv z7^m(<+(WYmrR~KQb2xTivriIzSie-~>+53f`!_%uV?bKMh=(|X&jtQjsW40pVA zrof?oQSM{oYusGY^Xx^hK^>pId0xoJ5&xC;&M9WaS-s#pg}u;1Kkw0%-tP{1+VZiK zhu~$891)*%FRpFV2Wr8^-0xDD#6CLM#-aqfKVG)uAA$G$tmY)mG5jTF=d|;KV~T|#5Ztlmz>F0%jY>Q0YH0N>)gOods0X9 zCGlSgT(M_yY}B9O`l>yQaV~9l_B?-}C!HtVu5W?g?DZwlu;|KGcct2j6zTf6t%&^C zkawaTk@~dZ2U3!D>&A1A9QoFEkaNcxnUau@Krlb`SJ8If`9g%^LSU8hXLiO6SF*Bad?uJRtzpwY3sKqCy7T zCh@6wln^fuL`=WLsaCcUp>?Ub_3I}dWS*Z71HtNiWk4h+E{b#0$(lM$fE%svvE2Nh zoFCPLUEzd=h!HMth7MwmLL$j%Ff(S%Q0emRMl(%CP=UE+6o)-7{oDu}>l z1Y~h8db>Zx<2R=N_fXSONz^*zoe3wu>YfT$LP!uY#FO6H*>qp-U}W^X4L>S+WJ6ge zRyU+gK=Pkj8KxF*&!-t6;cW&*ZuOTpI9}J~v52+DI7JDMgB?NPj_}2@*B8!7NR03mbGSMlh8t8}BGMO4+WL4(xS1a9M%+%;s3RQ);i zq@~JhIYn&2H6j`G;jK*N$h@RmH040#>e_9ew)-xxKre3z+%XXSJ_k_vh?T&M+o=Ts zai&CYZx_PHr^fvbu^f&y2(1~()w8*}B0N*0_gIchQvBN<*~Ls@+W1R-*%LBio+a3l zabzSx^HBmvFF|xhwdPM*InRBQ3-kj2$b~Ctwg-o2>J9zcv7zF1AaZkcYKA{2 z#HPgDG)f2mB;W}cZD4f-EjzFT3>WDi$MY_~RFNpsux$1OIkGL4m%hOoDW(yx&x53H zz1wBw%{gWBq2o4a$j@G$e*kZ4MV%B;PlT>(Z&ipJnH;n)C1k20{p@k<@tIyZt-e!z6O|cY^@7tTH3D%(CDLr#fo*LVW6A+!AK!wAR6{2k2P+vmGWX0r0nb4Rg!sY^onba8h>@=@)UjDC0D`K;DvQ~9TdiL_R z#q><}kL!|5=&!XeRYjnJ%5>8`7=*}=&vsnCZW#B_DDS;c#tvLr7BAaO(LZWWtOZdB zyn`HNhJ)B-`dGuCM`Hh=FWB)aE*~{FU#yqlt11hG^A*8=J&t?@Ddi@yUWJ$T6SU?9o#FJf?C3u()QS_&3(ofArWc+4F z#JT=K2Vif+X@I{SNWo2A3>!+v?g_4>L=@EM^YRZtA5>0}rS(&0tA)##>6+_{X9aNW z;(u~nu!gZ|ON2(}8~o*cNc+iV!2U)hw&o}4zt-OWJ)Vly_gAkKo*P0uRgj4>Ig!>Di;56`}$Y1y`{iZ>IVH2>GHJU4qQ*#JCI*$4j{) zeC{EthErzxqy+nH^oL4JtcS$NGgSQZCp`X84>*9T@u@H*C=>-B&wcw0GOv#>#CN}rh@6Ys;({982orYS`{KytVOnyIudVq9qd79gG`jzad zkmtoouvnFcm7ogubNSRswtH857U}EP;7t}RV08KSNh|fj#oVO)>Vr7n5X3%*`WzB+ z9cC)z5n2@q!kEWAc%P$T-|Q4HGZ&#t{2yOXz3&{-McVHB+Q7L&d9-?74N+ar!itM~^=awD;hmm5hT{Hu0oy=H^Uo7N| zmnVO>o-#f}u}p}!4Lk0vGToeM&V-(6tewwy7y!DSy+Q_B4z55&+uJKyod&tx3Wc_a zv#6NJp~F_NYrlx-X&{xYc@S6g?EZ~@R8y5`gN^xg*ZBiK&Q6E}_MA>qsY790rYvvU z!NFig*2krnh;*v*M){Nu4FO)S4#wd%%++PD~|+R^2;yqB}tZBx9$(r z^NzPh7&^Ce{i|8Kkx-p_%-hCUB`**&2^_^GamA6$-Xa#L+t@7O3*{Gg3%&{ecEz?h zlgeaIv=$^)&Dkt~awwCnoRd5%>j}?Y0HD-9f~4Oj`O0g*!Fv}T(B#!ETV61xMM#PV zsmt7^A=>3TVFRAWw!L(=g+a{}-9DyZrz$(@jYfC-B~7A)2+T>V?$MMbT|;t5Oz{ zE&>9;u#zH;LT_at7T0*rfgs3?O#ViKYTb7KJ0c%NzK$$kguzIz8P`S^zs|8QckzfX6)&O_NH!2pF}ahh263`9 z7BY2y&GFkE!xML(w1Fy;$Jv7P4hcYC{+bwCe_iFljWU2*3eXlb{O~1mjHi&hr1-7K zb?z-P;ZttNgIy)m=l;x+WecNm6dCe5HU#FGnIEwRY~SfJ8;g|@%-wC{%V9u6Zn%Q% zq~c|yXI?;Bd#+0DwI*W42#>}|WW(f01JDz9lrIVF%IxD| zi0F=ZPfoDA&?~4+8QYS}!+effJ}4b&M1^;Mgly3JHh*op+Y7_n$40(GV$9p>^l}xe zXhS>e2`;T&u$S%C$u5NeTV{NpU3GI(pmvLO+MJ!o2?OT5eN5p2q3~m<8ixyrLC4g+ zyUqfI1(pC)QlE*RLJezqAAJMzvn~Nf#YKy`2U*b?_SK_dY#unCNxx$=06J32PsVAh z4#Q5QWh|*^(iI5KyA3ZTF>R9E)k{VljqeX|@kZE|J?D~u2kmfKL;#K|Uhqn)%5kvU zjf#^S)8WQ|8UCB`U;z(gLX8<)UAvDF%QfW=+-ai?|zs6pg5h3YRo;%a8Wg_xO za=#2*ORaaI^2wOk9$FkSqSLU6E0n(;;&zEG3)G|!q0CfaF8&r}IMr4sz&Q@I3-J`# zQ)w!NJWl1z+K)%B;rg*?nEt?_mhYzrl_w4ucwaC7bs!~GYV$;(hshuR55Nzhx3@Fakt zn`6fjk6ROk02d9wVg9sL8>bd{Th<1?^ugJ(a*-Jdw7-<=rI#9Ex8;d;x5{Y81Cg3H zXADKPPnF?px{L#nit%LBGd@kq=7Q`@wH=`#^UmgA~51K z%t*v71t2(PEBppRekXzf176OLDI8vCNeFCQO|!;=A0&+O#6No+Vt-@gIs@Sk7YS6RJV3U-UyyM8r< zC%r%YfV!79=U+y_$>3%MSg|rLHl(D^rEbgqm-U8Jp0Ua%8>m<;yq)bQ zh5uJbdm#;e6+DOYF5NZ;9;sYFCyDSr_i(ll-GU>t;sAe)(UXRO@gk0_`|!p>JM#Ge z2iClKbE2A<)1S$JL-UfTqI-`re1Cg^0?bL}@!mDjPH_$Q*`SYVfj$%sS>Rwb6Qfsj z8_#ML=!Gm!q#r2SBA^RK_~61f27W>}u5O*xfX%#BbO0|X z;t^u@=Y4RBw&d8jXU^Z!Q6ic1QhPphrqkKZGw;^;(@S6DFwJ(sd6v2f2ecGBF+n#l z-z)(02#-%hgZKUsIh~tu;YB5 z-2g(P1DJKVN+Kk)NV30HAmnD3MSaqJ&Vu3!Y*09zCEuX#H`r=o2Z|a<5+pkn<^uw- z3LMh2N6GRN-Y55dT-)jBiSJT2VQiqskr(jh2E9|tJ#^c#)sKl^u*~1WANs%PRM22D zRSSdE7ybfpT;Uw0Wy27?53=wSm{XX%mWQ709fpMORcCC(JfBGyf#GIW8;xDl$ zwBrXnAY~&*EIui3kxtGkw=0(3W0(A#m`ujhZ2bs|%i-Hn_}bsAGzh)PmdEvsKJ65N zESq;~fqINSkwrHT;vtf$bx`mCWQdG^mpUaBy^QKMpbm5kO>N*#&3t*nJB9X`Fuv$n!3@Y)2h3Q@NVHve4kaJ=b^&%;8 zjh5A@NP)OgXH7!Iay(-IX|#M*le7hB7=Ly#?aYp4QBOcpF_~SjE?THlFBqvvKUuaX zd72~*oz)dH#P;`iQlSDdqUlROlS!eYn7yO%3^>2e(DNskf6!_i+56NMs%h@;woSRx zn*q&aXDc#v+UluP?%_~$1D7|>uAZ4%@-fh+{wNR0T$2P`g9~e!<*_P;Gyx?GnN|~i zowYdH#);sr>H@q^$AF>wE3KZx^=CQ~f4S}Mb4;*J02Q8c9LC;Y64NrS`H)y6QKOZO zf#g2G$$(w@Dp|jI17wF&X(@|Z{b&EtKoOTz5@q8CYaI{VN!o5)R65fq86d7oiN4n7 zjXdR0x>iJFPYH`A(LPx3#l=rdE%w53CIV9hD9f7e#RRg%DN89vX(CG?t>E{T!EX_C zWO%fonlflnrC%T)$eN7BK%EuF6O#&Wh@ihfu1qMwoiG{GvWRc`ip_UxT^F_^*JBcP zm5tP_5of3;dP#P5ERFKsjxI2ZSOuK6W(zkvS{pZAG;iQ-!RL%5AzCrUvy3?dZw=T7 zAy2uMB@aCLKMQPbq8I7&Fl)brx1;T}vYVxwsN*lzt>BS+Z|o4i$?EhT(9WJ9(1X1> zc3Ta9i03nLK74tXQIUfabTz4B|1c8yC)xuy7;!BG{-@I@+2drS2-JB1#a*ItU8WVv zO2<8hJI(dE4|tgR&_W@GCSD@#8w5~%fH@9QUHl{+JUR0h2DHkAw|RGF8NZnX2g|)k zb43=S9D&<*Vx~9vMn|O|Sd`^*p;9DQ`HYaP%q21zhR6k?^?YZJ!@?C|1N0wATK1*? ze$=oeXaBrhdF^t*7dozPf@h_~9P5jjLG>gb$H=OnhqVT#;Hjp@Kt zJAq&87}@81jp4cJcs&ax zZ*KG`=tX6$;F1^YhWtxY1%4oE_&Ib`93vaHrZ@nyNXI;!cg$7 zgRE8xX(GX{6o>KiYu9x3#r_1Xy{t!a7q@NTY^}!a2BZkhsYh*Dx10{NOgp^LuNMW^ zmT`{a{$(Eu&GAdxL0k5JBz)mKO=$haSlE1t_t3NcoK$kS=$b?eq5cZQN|t$1K!Vy( zO*9!3-m-1%-38{?UO1Ny1GArelvt}F3VvjxU`0aR%x32^jJU*wax3M>c^y%Yg329N zxIiAS@o)p)i5b>q@*K}6l-OK%h(K?)DaJMg^h_TBTP5q6h(d+Nyh%30RrNvSyoc}^ zyjQ<3r;I_)JN0iZx$f6(wf0PcROM^Yj>&}3u*fNv=1uq|XwbRU$71fRc?rtG?L%@L z_^!wxuZ09;4wBEonC?i7t@tYaM*WR^oqA8rgOcryVrft_~IQ6x^M$ z=vmaxXmrBCl-is|+hRaHx6jz{*&jbDP3o?ddzuj>0t(R6{iPmXx?820e5b{SBi=jP z=4LNy)UL9wopVnkX!_G|e>(b!5Rn_kLMqi-LQBNNyX5F}%XL52kxc-&V07ZK`nD+_ zw9wdj14;|YcTC~9t9jD3GM;9w%^(>md)%v1I}5=x$Ri%xnB9%QH0iz~SL$ zD@h*CGP2RPs61eS^p+ko#!BEOS?(pkEpb5g;_2XMcEH1HMe$AkF=4g?m_j&=_Cs`elEzkWXo zt@$F!1{9{Q8#xZb2ReaP3v|g&wrMsOQlKw2)?(z49 z><0|${StF(CbX0*Zzc(8-Ia!4CB<-{wOHpsbKycEOI+NyWmT{opIVhHHr^$KUz}*q zs;5sA>&RFoY~vSQlj!Pq>{BWCR-{fO@u(1lJ*%z=C@mb_Ufa(6ITZ0$)=ZK9CWET@ zoiD= zDAYxEH_(q=?vAr?RH^d0McBw|FB9qAhW6WdWyQ$jjjAXVNalcB%T6OtQU&>R3`a=8 z8xMF!^CyeYcx@WXI9S|T8_WPb;otSDdV3^M9BGw?696-Asb9BRBsTpN#$<)XQ892G`&Em4x(BswDbNgM z8B-X8{c0o)una#^&WlYq(U12slhZ*~P7-+MY9W5jk2l+m)9uc7bXySJ&Q4+F5||SA z^H7k;y09Yz*y1$b#(cpZyt3sKdA}}!LNID}x$7VLFKb3Ij}}=?h^{|sKo0O=WK{Zo z5dIS(nvAbW+Dppda| z^lIfhL(A?ZJ5zyq(l=uuLwvF?>$C({!@-3>I-{3DBnkwIgRF3++R4(7DsJ&GrtuEQ zqA^?cncdofW1^2i$u|3#VNmbg3Ry2Igzz#GZ{flRcif1LrJpC8bldH6hP*+JIEtv! zmH@HpmRrMhX9GA9Tc6vj^m$Q0^ae&gdpeq)n~490dzj3 z-SL=&_!VI1!hj?q*T>JB+;6X@5-0WxeiUQeQ3S)+tmAruhFu==2nNau^DL((%LtEwOnW6LXWIzjdfh* zj#EI3^9nG}1dJS3!#WSm)|A9nyf4ZzrIXN>x(m$&DWpn5n}M!9R<^Sv9iNUn80>@c zrq9&e$Z=_8r2w84HKZCt+d(1Ub_8xdsr0}q+aUIVI8~kHh{Hy*A5(Hg=dY<{o_*It zKx7Zlzkim;oUZqqcOkOR(SM{4t3?aR4=a>4#UVs%?FH`O!X!kRfOo~cJEpXbZ!C4m zJ9TSBDft* zZiJ;ryei(vO$-Y%d-i>cGxxz>7S&caO6}7tZy=`%#pSA}l6P8jy#`Z9;8RZ8C6Lh! zqd6KIiK^DoC+BsYA%BQ91}@+`|Ke&|VfguFlCpCV#T#X}L9vmXcRt%zgZY!elLlyK zSrQ2~aqD>PcL8e%%3OU6A4>f-h5S_zqsuN)L}L7(=6n|{i*fhMi6ON@O*>b;eKnTN=@%Dy-JS@rs3VUbx6j2CwTn4jjfZV@3Y3#@ zZpk&VdlOR)IS^H%!K%;D3>7ObuA&JLEPqDQ-X9cDYisS~+)TYiMQmio;lR>31-E`h zj~}l-^Lbb81=>tO=yO&a7%Ae9m|^hRbo#~9NmQE9k!gl8ufm+Go{@acBQ47bFI1Nl zKqU^2Y1AvMeCKtZkKhdqoMbySCxTakv6IkkLXSa8omD zuGy6M=@xsA&G`axww-hulPip^*)1`el6@T;#c9V)t(!$S{WGu(?Hd=3%x{|TUym&7 znO4-qXaucj<~U)V*s_y?k}%Ogu)8KKaooo+Cpw|P@9K3TdeF_n3i72|7t1Gc z4x|F&J2=MFeGr?ysCY}fpEfY*B$%o)3}$WU%>~^B4<*R>dMG$3^L0L*el5(}7q_PD z2TDQb7tdn6nU5^G=}%br>hcK^R~c90`l|A`=3xOTjRw+X!&4!JjHF8c&L6KHSNR$jt=qYXs?ciCZ(E9V&7VIq6*FVsR&ZQhWL-uop|x53@&0^67aPNn zMwmS(LpTSFe+<@6V*Y-+9a3Zhdt3^6*~IXNim9?G`p%ow(=Tv}^sDy&cp9y0W9-{f zq5~eOS^;=2cxXIy++?dmRH~`tY4ntjW1SPdJci)uO(+%t%X&4Ku3`@-hctQPf!Z7u z$S+=MtG?@rozX6{Cs4mwz?nYGh>2|dVL4zO@CN9Hc&ZK3K;UfMe7?j#id}|NnW@Xr zK7MzYMCllvG!DT5eF)ACiz@C+vVJ+0`zMtbXfJlLs|sLs)FF){Mo?>v2&YY?2U;Zj zvj-D>vincFWS+*!*hyYVn2$mlGWd$1Wu&{ytJoc39Awo<}E9Es1M)ciku;J)@ zZl0n*!oxYm)03fb2Zu%Qnt7Xin56!X*-}Kd*3}QX_o_T}aJw2=r)PjYTkZf%!=MBr zl34Snd6)Z{J9d9Nxv$lKyjpJkE?q==T*@DO@5e0%ebx8-0F|HBKm1?*tS8qIGiI|U za7)f5v81`NjH<3iCZ|)nY}U3_!{?fQc|(6Gi3o~|Y6TS)5$bFJ4nc05^bK6-&%>kC z%)jGGsNd12mV$PRHb=2ZHIfTps#8rI=OcJ06Z3Dr^!O!rAZj6S1Iuz-usz}V|M5_N z_5KWdjFt9X+1s5>iEL4xiTr`NASEWj703da-M#u!*n}AXQsKg{JsF*mo*5ORwIN33 z{hMVU_N`g402gTwQ{x)J49c{0S3qb&iBfQJAn@r06bPJB2LH*qOso_TQjO0VK+cJe1s$o4xIV zfd^+-*iP?)_=Da41N(FcM}YE?r3hEK8kq(PkeS;WmHHZ$?>=J7<@G7#3+0~Ga1N`d zdYJZyg@Pzfi*onONbhj7NBs{-5m2g2KI;?e_I+WO$8AyJHS+(hg^x2D8|rY0vDAU$ zb3qum1XX!c%;-s!^AuGMy>$qoLLF(RoZLFPKr&79g_y+zIGV z1-kim**;L~726t#oEYwQrB41(#lsM?dUh)j%UA^eY$5d)i_qdiYCrFgi0eN}iO6m1 zRYR#@1~X$V=~FH=2w`M(H6jQ|)9i!}a5$WUz?}zLQK>TqY*eMVm*Dh;I%w#zCD%a( zM=h4Tb>y`(DX;$AG`z}U`aVI4q28dZL)u%3$ojG_KL2w4r=vxZRg>(Yh}T7`}NvE!1-xY_iLVtsb^!ppaT`^Ll|8V@p8rc4A4(-@jnmR^nn4gRR?QgN%73( z(22hooQLiq__ETn8HjxEi!eW43tQDAPK&kBmBIQsA_m7q#^M?lE`9rtq|2QV;8gqs zm+Hnn$u6K|jNC^P;AU=cl07F3ue-8g4PKQ;iurt=U)p1#{7V-q`IA_E*{XHWPw)p8 zMK&wqfAh$NSM#SLHPo2EU}-r4Am*16Kj-T zN$C!ItE)*0P5O|fEaOY4kXl0$;YwulZ59s41Dh1q0Vy*aVZ_x!b9*ncav0qOg)ozY zsu?O@9AtzpViN+(b7 zmrARxNIrhh_i$yJ5kESHCL|}EJs;7J4k!R+IqvL~LWcYWsLEj@GFcLhw5TrbDyTGG zmNPvrS`99z>=TW(Tu$0`Ww~`{4GNX_dM8qGK}i7>D%<^~wEE3lPDQrA9z#wHlUGX+hAu4j@yh{4Y@1d_U~y0kH(B?nuE^5 z{!B=Ul+#)7E*4RFjs%h|W|58Lku7zt^W#gRr2a7C=~YjaVxjlu^Od`lAFa?0CK$@H zwv{^*aD;b>8!)6g+y(c;5=b@dm`=hH+M3NJvJQN=i?`c~9g2!-88|MxLqD92Py^}h zp1pD#-}CCJ*v_YvnNe)m&C@hKp=dXo)R{?}tn0nmYu+fEXU}1}xo)J4+F$l)U3ry(m6S5@W3@lhI*TAw}|lcdJut7C?T$@`J35b0z0O)_Vz zH;X1Zgz7}keG*5Atr{B{nD1}5V@VIvt*1&bdfcDep9l1`U*3|4j2Vk}-3i}@zpnMO zR2{|5BAr)9GN*yq5ymz5W^$l82Zhcb+I`F5X>miEd=Jx(hdP3)OAd468bs=)m5y?= z#>Tn)0J+yWM5zbIjNJVdN!#cTEfH^0ftHJ5*#mu~_AWx0tmjHEt`D@iw*I_~n!;9U z>xuOv=RW6>O)-{cA;1;PlsIS6_nD5P6BEK>>a6WLCwehG#CzGe<^_70kZ?u@dzI`G z)-HYU#G;SIj91&)_E-y_&wgoVeEkw?2f59C@k)fmDGFAFfI;k-EjdyvH8~?1gf|7I z?0RScuA2yEq49=p6L1#9xS0MBT7v1zDke-#RGAJVf7x=GEgw~`BPOof+^!7-G&`C_ z=;4$syvsWGp^HD^6_LrgLUUht+WBJbyYxa9Spn=#f0k?UE4FG~JC@aA)>_cuf=f`R zhsB=tJ2y)*L?|P{SC==uQ^dQpP1A!Pc3?_(xH<+O?Yd<~88R2D0IBgwjI0PO7fhuG?v{ z2pdy)zAH;U^V;hk$w%D-{&|h`T_IYHG{kL`3u{y;? z*w@-@8jdv4khSP$skp}SJ(6EJwI&UHPR(n^gVgo?msng98i;)L(@S}Oz(sH*)Eclo zy!uAn-&|R$5V%grsRP6sIYOLgB-l&eXsG`Y_b4Tg!Do4kx7rj?DMW-)y^PzmdV~l( zRjd@Fp^op;GCyYZg=Y=~SA#ovAwYsr_cbiyx5%gbs`EKM%ld0lUi^m%RHbm&6xEo2 zL=gL8{33T?AAszSR?@|I<|6)8F^wbY=dW~dMzeE641qR_FH6)$kL&ZVTc1G)-xiIm z`e4+X-`DTinwedt-*AWk`8yK?@0qQ19=p`oV>mE-ERYc$PSBSUPmnMhV>|qb@Sz*` zM=-*vfcBiu_;L|yBX=!Z2hxckGGP`f1w2os#G0eH_m28k4Ap=q%&^DZ@*jlS27ZM; z3vJlX9s&Q#mtiOF3TChfU**1m4>@26>mZ#X4e$XmYtdSQs`C?QfrepP9&)ryTn)BL zWS5v#syUn(t#MW@suWi?gN%t(2pZ3ckeAY69{^U8)-y8u4((@;XqgMEG$^y#isT^n zkUBRqMT&haUHr_E427ta;`*8|RlwttJ{Dda|cE+n|)x1e| zh}4I?gRxaTFzy`E+A=r=~`x~nzngSwcIz!28#J2OL$=7p3AvIhV zMrb+{QN1A~_Hm-elGCM&H;JgH`V*1WB3G4SqWcpw0bVqmER9IS^-;7?BK&WiTvfra zcZZjyi7@lyF<3EhkL^1%X##D!=?8R>wZpJtx7r#e9NQjkT2@g+m0q|C0J%1y4GAMr)C1rGmLINdP+phiuNcq(~z$+gMihPjOn^(L-|SPr-C^o>Oom9<_uZ6T8V~g-bQK%fE#k9yZV$BFOL zIMfJUO}G~Dv5Y8kb6(@tD6?SE(#%~TF_j_h5c+sfRJX_OS#PmpH~$i#+&}OuWE^|3 ztU@7(R)%k5FaQ{&w-MfS#U{^R)Po)0Bo|kQDM=EVD8rp8ZKKER+ndQSHbu)$rdV1| zJdIiIg3#wP!c}h>Fa#KwhBkELj;3*rzkj`dy)_HZyOJ VU=pkm8Veub3_|1vJMaJiK?)>cCtm;n literal 0 HcmV?d00001 diff --git a/tests/riff.rs b/tests/riff.rs new file mode 100644 index 000000000..450481145 --- /dev/null +++ b/tests/riff.rs @@ -0,0 +1,8 @@ +mod common; + +#[test] +fn pdf_integration() { + const SIGNATURE_TYPE: &str = "riff"; + const INPUT_FILE_NAME: &str = "riff.bin"; + let _ = common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); +} From ec3a7b76196ab9a1bc93260160eab6721801e7ed Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 2 Nov 2024 11:33:18 -0400 Subject: [PATCH 050/131] Updated doc tests; added 7z integration test --- src/binwalk.rs | 52 ++++++--- src/extractors/common.rs | 232 +++++++++++++++++++++++++++------------ tests/arcadyan.rs | 4 +- tests/common/mod.rs | 31 ++++-- tests/gzip.rs | 4 +- tests/inputs/7z.bin | Bin 0 -> 218 bytes tests/pdf.rs | 4 +- tests/riff.rs | 4 +- tests/sevenzip.rs | 8 ++ 9 files changed, 232 insertions(+), 107 deletions(-) create mode 100644 tests/inputs/7z.bin create mode 100644 tests/sevenzip.rs diff --git a/src/binwalk.rs b/src/binwalk.rs index ea55b13af..ca201a779 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -534,16 +534,24 @@ impl Binwalk { /// /// ## Example /// - /// ```no_run + /// ``` /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_binwalk_rs_529_0() -> Result { /// use binwalk::Binwalk; /// - /// # std::fs::remove_dir_all("/tmp/foobar"); - /// let target_path = "/usr/share/man/man2/accept.2.gz".to_string(); - /// let extraction_directory = "/tmp/foobar/extractions".to_string(); + /// let target_path = std::path::Path::new("tests") + /// .join("inputs") + /// .join("gzip.bin") + /// .display() + /// .to_string(); + /// + /// let extraction_directory = std::path::Path::new("tests") + /// .join("extractions") + /// .display() + /// .to_string(); /// + /// # std::fs::remove_dir_all(&extraction_directory); /// let binwalker = Binwalk::configure(Some(target_path), - /// Some(extraction_directory), + /// Some(extraction_directory.clone()), /// None, /// None, /// None, @@ -556,8 +564,12 @@ impl Binwalk { /// /// assert_eq!(scan_results.len(), 1); /// assert_eq!(extraction_results.len(), 1); - /// assert_eq!(std::path::Path::new("/tmp/foobar/extractions/accept.2.gz.extracted/0/decompressed.bin").exists(), true); - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// assert_eq!(std::path::Path::new(&extraction_directory) + /// .join("gzip.bin.extracted") + /// .join("0") + /// .join("decompressed.bin") + /// .exists(), true); + /// # std::fs::remove_dir_all(&extraction_directory); /// # Ok(binwalker) /// # } _doctest_main_src_binwalk_rs_529_0(); } /// ``` @@ -636,16 +648,24 @@ impl Binwalk { /// /// ## Example /// - /// ```no_run + /// ``` /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_binwalk_rs_624_0() -> Result { /// use binwalk::Binwalk; /// - /// # std::fs::remove_dir_all("/tmp/foobar"); - /// let target_path = "/usr/share/man/man2/accept.2.gz".to_string(); - /// let extraction_directory = "/tmp/foobar/extractions".to_string(); + /// let target_path = std::path::Path::new("tests") + /// .join("inputs") + /// .join("gzip.bin") + /// .display() + /// .to_string(); + /// + /// let extraction_directory = std::path::Path::new("tests") + /// .join("extractions") + /// .display() + /// .to_string(); /// + /// # std::fs::remove_dir_all(&extraction_directory); /// let binwalker = Binwalk::configure(Some(target_path), - /// Some(extraction_directory), + /// Some(extraction_directory.clone()), /// None, /// None, /// None, @@ -655,8 +675,12 @@ impl Binwalk { /// /// assert_eq!(analysis_results.file_map.len(), 1); /// assert_eq!(analysis_results.extractions.len(), 1); - /// assert_eq!(std::path::Path::new("/tmp/foobar/extractions/accept.2.gz.extracted/0/decompressed.bin").exists(), true); - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// assert_eq!(std::path::Path::new(&extraction_directory) + /// .join("gzip.bin.extracted") + /// .join("0") + /// .join("decompressed.bin") + /// .exists(), true); + /// # std::fs::remove_dir_all(&extraction_directory); /// # Ok(binwalker) /// # } _doctest_main_src_binwalk_rs_624_0(); } /// ``` diff --git a/src/extractors/common.rs b/src/extractors/common.rs index e9fd85ac7..59e9d6859 100644 --- a/src/extractors/common.rs +++ b/src/extractors/common.rs @@ -92,13 +92,17 @@ impl Chroot { /// ``` /// use binwalk::extractors::common::Chroot; /// - /// # std::fs::remove_dir_all("/tmp/foobar"); - /// let chroot_directory = "/tmp/foobar".to_string(); - /// let chroot = Chroot::new(Some(&chroot_directory)); + /// let chroot_dir = std::path::Path::new(&std::env::temp_dir()) + /// .join("binwalk_unit_tests") + /// .display() + /// .to_string(); /// - /// assert_eq!(chroot.chroot_directory, "/tmp/foobar"); - /// assert_eq!(std::path::Path::new("/tmp/foobar").exists(), true); - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # std::fs::remove_dir_all(&chroot_dir); + /// let chroot = Chroot::new(Some(&chroot_dir)); + /// + /// assert_eq!(&chroot.chroot_directory, &chroot_dir); + /// assert_eq!(std::path::Path::new(&chroot_dir).exists(), true); + /// # std::fs::remove_dir_all(&chroot_dir); /// ``` pub fn new(chroot_directory: Option<&String>) -> Chroot { let mut chroot_instance = Chroot { @@ -150,22 +154,41 @@ impl Chroot { /// /// ``` /// use binwalk::extractors::common::Chroot; + /// use std::path::MAIN_SEPARATOR; + /// + /// let chroot_dir = std::path::Path::new(&std::env::temp_dir()) + /// .join("binwalk_unit_tests") + /// .display() + /// .to_string(); + /// + /// # std::fs::remove_dir_all(&chroot_dir); + /// let chroot = Chroot::new(Some(&chroot_dir)); + /// + /// let dir_name = "etc"; + /// let file_name = "passwd"; + /// let abs_path = format!("{}{}{}{}", MAIN_SEPARATOR, dir_name, MAIN_SEPARATOR, file_name); + /// let abs_path_dir = format!("{}{}", MAIN_SEPARATOR, dir_name); + /// let rel_path_dir = format!("..{}..{}..{}{}", MAIN_SEPARATOR, MAIN_SEPARATOR, MAIN_SEPARATOR, dir_name); + /// let abs_path_file = format!("{}{}", MAIN_SEPARATOR, file_name); + /// let rel_path_file = format!("..{}..{}..{}{}", MAIN_SEPARATOR, MAIN_SEPARATOR, MAIN_SEPARATOR, file_name); /// - /// let chroot_directory = "/tmp/foobar".to_string(); + /// let path1 = chroot.safe_path_join(&abs_path_dir, file_name); + /// let expected_path1 = std::path::Path::new(&chroot_dir).join(dir_name).join(file_name); /// - /// # std::fs::remove_dir_all("/tmp/foobar"); - /// let chroot = Chroot::new(Some(&chroot_directory)); + /// let path2 = chroot.safe_path_join(&abs_path_dir, &rel_path_file); + /// let expected_path2 = std::path::Path::new(&chroot_dir).join(file_name); /// - /// let path1 = chroot.safe_path_join("/etc", "passwd"); - /// let path2 = chroot.safe_path_join("/etc", "../../passwd"); - /// let path3 = chroot.safe_path_join("../../../etc", "/passwd"); - /// let path4 = chroot.safe_path_join("/tmp/foobar/", "/etc/passwd"); + /// let path3 = chroot.safe_path_join(&rel_path_dir, &abs_path_file); + /// let expected_path3 = std::path::Path::new(&chroot_dir).join(dir_name).join(file_name); /// - /// assert_eq!(path1, "/tmp/foobar/etc/passwd"); - /// assert_eq!(path2, "/tmp/foobar/passwd"); - /// assert_eq!(path3, "/tmp/foobar/etc/passwd"); - /// assert_eq!(path4, "/tmp/foobar/etc/passwd"); - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// let path4 = chroot.safe_path_join(&chroot_dir, &abs_path); + /// let expected_path4 = std::path::Path::new(&chroot_dir).join(dir_name).join(file_name); + /// + /// assert_eq!(path1, expected_path1.display().to_string()); + /// assert_eq!(path2, expected_path2.display().to_string()); + /// assert_eq!(path3, expected_path3.display().to_string()); + /// assert_eq!(path4, expected_path4.display().to_string()); + /// # std::fs::remove_dir_all(&chroot_dir); /// ``` pub fn safe_path_join(&self, path1: impl Into, path2: impl Into) -> String { // Join and sanitize both paths; retain the leading '/' (if there is one) @@ -198,12 +221,17 @@ impl Chroot { /// ``` /// use binwalk::extractors::common::Chroot; /// - /// let chroot_dir = "/tmp/foobar/".to_string(); + /// let chroot_dir = std::path::Path::new(&std::env::temp_dir()) + /// .join("binwalk_unit_tests") + /// .display() + /// .to_string(); + /// + /// let file_name = "test.txt"; /// /// let chroot = Chroot::new(Some(&chroot_dir)); - /// let path = chroot.chrooted_path("test.txt"); + /// let path = chroot.chrooted_path(file_name); /// - /// assert_eq!(path, "/tmp/foobar/test.txt"); + /// assert_eq!(path, std::path::Path::new(&chroot_dir).join(file_name).display().to_string()); /// ``` pub fn chrooted_path(&self, file_path: impl Into) -> String { self.safe_path_join(file_path, "".to_string()) @@ -217,15 +245,21 @@ impl Chroot { /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_213_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// - /// let chroot_dir = "/tmp/foobar".to_string(); /// let file_data: &[u8] = b"foobar"; /// - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// let file_name = "created_file.txt"; + /// + /// let chroot_dir = std::path::Path::new("tests") + /// .join("binwalk_unit_tests") + /// .display() + /// .to_string(); + /// + /// # std::fs::remove_dir_all(&chroot_dir); /// let chroot = Chroot::new(Some(&chroot_dir)); /// - /// assert_eq!(chroot.create_file("created_file.txt", file_data), true); - /// assert_eq!(std::fs::read_to_string("/tmp/foobar/created_file.txt")?, "foobar"); - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// assert_eq!(chroot.create_file(file_name, file_data), true); + /// assert_eq!(std::fs::read_to_string(std::path::Path::new(&chroot_dir).join(file_name))?, std::str::from_utf8(file_data)?); + /// # std::fs::remove_dir_all(&chroot_dir); /// # Ok(()) /// # } _doctest_main_src_extractors_common_rs_213_0(); } /// ``` @@ -259,15 +293,23 @@ impl Chroot { /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_255_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// - /// let chroot_dir = "/tmp/foobar".to_string(); - /// let file_data_with_trailing_junk: &[u8] = b"foobarJUNK"; + /// const CARVE_SIZE: usize = 6; + /// + /// let data: &[u8] = b"foobarJUNK"; + /// + /// let file_name = "carved_file.txt"; /// - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// let chroot_dir = std::path::Path::new("tests") + /// .join("binwalk_unit_tests") + /// .display() + /// .to_string(); + /// + /// # std::fs::remove_dir_all(&chroot_dir); /// let chroot = Chroot::new(Some(&chroot_dir)); /// - /// assert_eq!(chroot.carve_file("carved_file.txt", file_data_with_trailing_junk, 0, 6), true); - /// assert_eq!(std::fs::read_to_string("/tmp/foobar/carved_file.txt")?, "foobar"); - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// assert_eq!(chroot.carve_file(file_name, data, 0, CARVE_SIZE), true); + /// assert_eq!(std::fs::read_to_string(std::path::Path::new(&chroot_dir).join(file_name))?, std::str::from_utf8(&data[0..CARVE_SIZE])?); + /// # std::fs::remove_dir_all(&chroot_dir); /// # Ok(()) /// } _doctest_main_src_extractors_common_rs_255_0(); } /// ``` @@ -316,16 +358,21 @@ impl Chroot { /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_312_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// - /// let chroot_dir = "/tmp/foobar".to_string(); + /// let chroot_dir = std::path::Path::new("tests") + /// .join("binwalk_unit_tests") + /// .display() + /// .to_string(); + /// /// let dev_major: usize = 1; /// let dev_minor: usize = 2; + /// let file_name = "char_device"; /// - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # std::fs::remove_dir_all(&chroot_dir); /// let chroot = Chroot::new(Some(&chroot_dir)); /// - /// assert_eq!(chroot.create_character_device("char_device", dev_major, dev_minor), true); - /// assert_eq!(std::fs::read_to_string("/tmp/foobar/char_device")?, "c 1 2"); - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// assert_eq!(chroot.create_character_device(file_name, dev_major, dev_minor), true); + /// assert_eq!(std::fs::read_to_string(std::path::Path::new(&chroot_dir).join(file_name))?, "c 1 2"); + /// # std::fs::remove_dir_all(&chroot_dir); /// # Ok(()) /// # } _doctest_main_src_extractors_common_rs_312_0(); } /// ``` @@ -348,16 +395,21 @@ impl Chroot { /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_345_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// - /// let chroot_dir = "/tmp/foobar".to_string(); + /// let chroot_dir = std::path::Path::new("tests") + /// .join("binwalk_unit_tests") + /// .display() + /// .to_string(); + /// /// let dev_major: usize = 1; /// let dev_minor: usize = 2; + /// let file_name = "block_device"; /// - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # std::fs::remove_dir_all(&chroot_dir); /// let chroot = Chroot::new(Some(&chroot_dir)); /// - /// assert_eq!(chroot.create_block_device("block_device", dev_major, dev_minor), true); - /// assert_eq!(std::fs::read_to_string("/tmp/foobar/block_device")?, "b 1 2"); - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// assert_eq!(chroot.create_block_device(file_name, dev_major, dev_minor), true); + /// assert_eq!(std::fs::read_to_string(std::path::Path::new(&chroot_dir).join(file_name))?, "b 1 2"); + /// # std::fs::remove_dir_all(&chroot_dir); /// # Ok(()) /// # } _doctest_main_src_extractors_common_rs_345_0(); } /// ``` @@ -380,14 +432,19 @@ impl Chroot { /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_377_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// - /// let chroot_dir = "/tmp/foobar".to_string(); + /// let chroot_dir = std::path::Path::new("tests") + /// .join("binwalk_unit_tests") + /// .display() + /// .to_string(); /// - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// let file_name = "fifo_file"; + /// + /// # std::fs::remove_dir_all(&chroot_dir); /// let chroot = Chroot::new(Some(&chroot_dir)); /// - /// assert_eq!(chroot.create_fifo("fifo_file"), true); - /// assert_eq!(std::fs::read_to_string("/tmp/foobar/fifo_file")?, "fifo"); - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// assert_eq!(chroot.create_fifo(file_name), true); + /// assert_eq!(std::fs::read_to_string(std::path::Path::new(&chroot_dir).join(file_name))?, "fifo"); + /// # std::fs::remove_dir_all(&chroot_dir); /// # Ok(()) /// # } _doctest_main_src_extractors_common_rs_377_0(); } /// ``` @@ -405,14 +462,19 @@ impl Chroot { /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_401_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// - /// let chroot_dir = "/tmp/foobar".to_string(); + /// let chroot_dir = std::path::Path::new("tests") + /// .join("binwalk_unit_tests") + /// .display() + /// .to_string(); + /// + /// let file_name = "socket_file"; /// - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # std::fs::remove_dir_all(&chroot_dir); /// let chroot = Chroot::new(Some(&chroot_dir)); /// - /// assert_eq!(chroot.create_socket("socket_file"), true); - /// assert_eq!(std::fs::read_to_string("/tmp/foobar/socket_file")?, "socket"); - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// assert_eq!(chroot.create_socket(file_name), true); + /// assert_eq!(std::fs::read_to_string(std::path::Path::new(&chroot_dir).join(file_name))?, "socket"); + /// # std::fs::remove_dir_all(&chroot_dir); /// # Ok(()) /// # } _doctest_main_src_extractors_common_rs_401_0(); } /// ``` @@ -430,15 +492,20 @@ impl Chroot { /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_426_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// - /// let chroot_dir = "/tmp/foobar".to_string(); - /// let my_file_data: &[u8] = b"foobar"; + /// let chroot_dir = std::path::Path::new("tests") + /// .join("binwalk_unit_tests") + /// .display() + /// .to_string(); /// - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// let file_data: &[u8] = b"foobar"; + /// let file_name = "append.txt"; + /// + /// # std::fs::remove_dir_all(&chroot_dir); /// let chroot = Chroot::new(Some(&chroot_dir)); /// - /// assert_eq!(chroot.append_to_file("append.txt", my_file_data), true); - /// assert_eq!(std::fs::read_to_string("/tmp/foobar/append.txt")?, "foobar"); - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// assert_eq!(chroot.append_to_file(file_name, file_data), true); + /// assert_eq!(std::fs::read_to_string(std::path::Path::new(&chroot_dir).join(file_name))?, std::str::from_utf8(file_data)?); + /// # std::fs::remove_dir_all(&chroot_dir); /// # Ok(()) /// # } _doctest_main_src_extractors_common_rs_426_0(); } /// ``` @@ -482,14 +549,19 @@ impl Chroot { /// ``` /// use binwalk::extractors::common::Chroot; /// - /// let chroot_dir = "/tmp/foobar".to_string(); + /// let chroot_dir = std::path::Path::new("tests") + /// .join("binwalk_unit_tests") + /// .display() + /// .to_string(); + /// + /// let dir_name = "my_directory"; /// - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # std::fs::remove_dir_all(&chroot_dir); /// let chroot = Chroot::new(Some(&chroot_dir)); /// - /// assert_eq!(chroot.create_directory("/usr/bin/"), true); - /// assert_eq!(std::path::Path::new("/tmp/foobar/usr/bin").exists(), true); - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// assert_eq!(chroot.create_directory(dir_name), true); + /// assert_eq!(std::path::Path::new(&chroot_dir).join(dir_name).exists(), true); + /// # std::fs::remove_dir_all(&chroot_dir); /// ``` pub fn create_directory(&self, dir_path: impl Into) -> bool { let safe_dir_path: String = self.chrooted_path(dir_path); @@ -513,14 +585,19 @@ impl Chroot { /// ``` /// use binwalk::extractors::common::Chroot; /// - /// let chroot_dir = "/tmp/foobar".to_string(); + /// let chroot_dir = std::path::Path::new("tests") + /// .join("binwalk_unit_tests") + /// .display() + /// .to_string(); + /// + /// let file_name = "runme.exe"; /// - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # std::fs::remove_dir_all(&chroot_dir); /// let chroot = Chroot::new(Some(&chroot_dir)); - /// chroot.create_file("runme.exe", b"AAAA"); + /// chroot.create_file(file_name, b"AAAA"); /// - /// assert_eq!(chroot.make_executable("runme.exe"), true); - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// assert_eq!(chroot.make_executable(file_name), true); + /// # std::fs::remove_dir_all(&chroot_dir); /// ``` pub fn make_executable(&self, file_path: impl Into) -> bool { // Make the file globally executable @@ -575,14 +652,23 @@ impl Chroot { /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_extractors_common_rs_571_0() -> Result<(), Box> { /// use binwalk::extractors::common::Chroot; /// - /// let chroot_dir = "/tmp/foobar".to_string(); + /// let chroot_dir = std::path::Path::new("tests") + /// .join("binwalk_unit_tests") + /// .display() + /// .to_string(); + /// + /// let symlink_name = "symlink"; + /// let target_path = "target"; + /// + /// let expected_symlink_path = std::path::Path::new(&chroot_dir).join(symlink_name); + /// let expected_target_path = std::path::Path::new(&chroot_dir).join(target_path); /// - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// # std::fs::remove_dir_all(&chroot_dir); /// let chroot = Chroot::new(Some(&chroot_dir)); /// - /// assert_eq!(chroot.create_symlink("symlink", "/"), true); - /// assert_eq!(std::fs::canonicalize("/tmp/foobar/symlink")?.to_str(), Some("/tmp/foobar")); - /// # std::fs::remove_dir_all("/tmp/foobar"); + /// assert_eq!(chroot.create_symlink(symlink_name, target_path), true); + /// assert_eq!(std::fs::canonicalize(expected_symlink_path)?.to_str(), expected_target_path.to_str()); + /// # std::fs::remove_dir_all(&chroot_dir); /// # Ok(()) /// # } _doctest_main_src_extractors_common_rs_571_0(); } /// ``` diff --git a/tests/arcadyan.rs b/tests/arcadyan.rs index 9b733713a..1dd3a6298 100644 --- a/tests/arcadyan.rs +++ b/tests/arcadyan.rs @@ -1,8 +1,8 @@ mod common; #[test] -fn pdf_integration() { +fn integration_test() { const SIGNATURE_TYPE: &str = "arcadyan"; const INPUT_FILE_NAME: &str = "arcadyan.bin"; - let _ = common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); + common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); } diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 5e57409e0..98d056f24 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,6 +1,23 @@ use binwalk::{AnalysisResults, Binwalk}; -pub fn integration_test(signature_filter: &str, file_name: &str) -> AnalysisResults { +/// Run an integration test against the specified file, with the provided signature filter +pub fn integration_test(signature_filter: &str, file_name: &str) { + // Run binwalk, get analysis/extraction results + let results = run_binwalk(signature_filter, file_name); + + // Each test is expected to have a single result at offset 0 in the file + assert!(results.file_map.len() == 1); + assert!(results.file_map[0].offset == 0); + + // Tests which support extraction are expected to have a single successful extraction + if !results.extractions.is_empty() { + assert!(results.extractions.len() == 1); + assert!(results.extractions[&results.file_map[0].id].success); + } +} + +/// Run Binwalk, with extraction, against the specified file, with the provided signature filter +pub fn run_binwalk(signature_filter: &str, file_name: &str) -> AnalysisResults { // Build the path to the input file let file_path = std::path::Path::new("tests") .join("inputs") @@ -9,7 +26,7 @@ pub fn integration_test(signature_filter: &str, file_name: &str) -> AnalysisResu .to_string(); // Build the path to the output directory - let output_directory = std::path::Path::new(&std::env::temp_dir().display().to_string()) + let output_directory = std::path::Path::new("tests") .join("binwalk_integration_test_extractions") .display() .to_string(); @@ -31,16 +48,6 @@ pub fn integration_test(signature_filter: &str, file_name: &str) -> AnalysisResu // Run analysis let results = binwalker.analyze(&binwalker.base_target_file, true); - // Each test is expected to have a single result at offset 0 in the file - assert!(results.file_map.len() == 1); - assert!(results.file_map[0].offset == 0); - - // Tests which support extraction are expected to have a single successful extraction - if !results.extractions.is_empty() { - assert!(results.extractions.len() == 1); - assert!(results.extractions[&results.file_map[0].id].success); - } - // Clean up the output directory let _ = std::fs::remove_dir_all(output_directory); diff --git a/tests/gzip.rs b/tests/gzip.rs index b8abbc9ab..43dcbc4a0 100644 --- a/tests/gzip.rs +++ b/tests/gzip.rs @@ -1,8 +1,8 @@ mod common; #[test] -fn gzip_integration() { +fn integration_test() { const SIGNATURE_TYPE: &str = "gzip"; const INPUT_FILE_NAME: &str = "gzip.bin"; - let _ = common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); + common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); } diff --git a/tests/inputs/7z.bin b/tests/inputs/7z.bin new file mode 100644 index 0000000000000000000000000000000000000000..9795a6e528da014a73a0a494e93e67b53cd3eec3 GIT binary patch literal 218 zcmXr7+Ou9=hJodpV9(?T1_(%k(sM&o|36?zX9$R8P!e)m^Zd`Xr-u%kzcEX-^S+k9 z)Q)>m9kU19gRuFYS@Z5%tbX-TFG9y=@!lyCn^-2V5y*16-7Z(Q)U-J8*|P2H%)g`? zIx^n7ezfIMyD}@#d`1>F21d>Z26k>n21Z3iMh2b?1`aO9S7v?-7#LU?C3&E308@gJ z3^@$N3`q>S3`Gp7Kz1raB9Na7l$2y*U=ZPAWMF8%aZyM2HlrvTBZET2l12sw03pCU Ak^lez literal 0 HcmV?d00001 diff --git a/tests/pdf.rs b/tests/pdf.rs index d7d016d9c..1b7659509 100644 --- a/tests/pdf.rs +++ b/tests/pdf.rs @@ -1,8 +1,8 @@ mod common; #[test] -fn pdf_integration() { +fn integration_test() { const SIGNATURE_TYPE: &str = "pdf"; const INPUT_FILE_NAME: &str = "pdf.bin"; - let _ = common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); + common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); } diff --git a/tests/riff.rs b/tests/riff.rs index 450481145..ad46fa513 100644 --- a/tests/riff.rs +++ b/tests/riff.rs @@ -1,8 +1,8 @@ mod common; #[test] -fn pdf_integration() { +fn integration_test() { const SIGNATURE_TYPE: &str = "riff"; const INPUT_FILE_NAME: &str = "riff.bin"; - let _ = common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); + common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); } diff --git a/tests/sevenzip.rs b/tests/sevenzip.rs new file mode 100644 index 000000000..23032e02a --- /dev/null +++ b/tests/sevenzip.rs @@ -0,0 +1,8 @@ +mod common; + +#[test] +fn integration_test() { + const SIGNATURE_TYPE: &str = "7zip"; + const INPUT_FILE_NAME: &str = "7z.bin"; + common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); +} From 026dea5a8991fbbe2795cc99c703d2a5ac45a729 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 2 Nov 2024 11:38:36 -0400 Subject: [PATCH 051/131] Added bzip2 integration test --- tests/bzip2.rs | 8 ++++++++ tests/inputs/bzip2.bin | Bin 0 -> 43843 bytes 2 files changed, 8 insertions(+) create mode 100644 tests/bzip2.rs create mode 100644 tests/inputs/bzip2.bin diff --git a/tests/bzip2.rs b/tests/bzip2.rs new file mode 100644 index 000000000..46e547d27 --- /dev/null +++ b/tests/bzip2.rs @@ -0,0 +1,8 @@ +mod common; + +#[test] +fn integration_test() { + const SIGNATURE_TYPE: &str = "bzip2"; + const INPUT_FILE_NAME: &str = "bzip2.bin"; + common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); +} diff --git a/tests/inputs/bzip2.bin b/tests/inputs/bzip2.bin new file mode 100644 index 0000000000000000000000000000000000000000..75ca4669cd80c1c7949af2efbba00c669356b6aa GIT binary patch literal 43843 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 Date: Sat, 2 Nov 2024 11:45:11 -0400 Subject: [PATCH 052/131] Added link time optimization to release builds (fixes issue #730) --- Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 3d0e6b7ca..0f96f7e07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,3 +39,5 @@ features = [ "macro-diagnostics", # Enable better diagnostics for compile-time UUIDs ] +[profile.release] +lto = true From bceaa9cdb2e774c5310c2f982a7e4a30951f64ee Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 2 Nov 2024 13:45:55 -0400 Subject: [PATCH 053/131] Added support for Dahua ZIP archives --- src/extractors.rs | 1 + src/extractors/dahua_zip.rs | 80 +++++++++++++++++++++++++++++++++++++ src/extractors/gif.rs | 2 +- src/magic.rs | 11 +++++ src/signatures.rs | 1 + src/signatures/dahua_zip.rs | 27 +++++++++++++ src/signatures/zip.rs | 8 ++-- 7 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 src/extractors/dahua_zip.rs create mode 100644 src/signatures/dahua_zip.rs diff --git a/src/extractors.rs b/src/extractors.rs index 87b19ff52..7942f7e7b 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -146,6 +146,7 @@ pub mod autel; pub mod bzip2; pub mod cab; pub mod common; +pub mod dahua_zip; pub mod dmg; pub mod dtb; pub mod dumpifs; diff --git a/src/extractors/dahua_zip.rs b/src/extractors/dahua_zip.rs new file mode 100644 index 000000000..7a13ca1d6 --- /dev/null +++ b/src/extractors/dahua_zip.rs @@ -0,0 +1,80 @@ +use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; +use crate::signatures::zip::find_zip_eof; + +/// Defines the internal extractor function for carving Dahua ZIP files +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::dahua_zip::dahua_zip_extractor; +/// +/// match dahua_zip_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` +pub fn dahua_zip_extractor() -> Extractor { + Extractor { + utility: ExtractorType::Internal(extract_dahua_zip), + ..Default::default() + } +} + +/// Carves out a Dahua ZIP file and converts it to a normal ZIP file +pub fn extract_dahua_zip( + file_data: &[u8], + offset: usize, + output_directory: Option<&String>, +) -> ExtractionResult { + const OUTFILE_NAME: &str = "dahua.zip"; + const ZIP_HEADER: &[u8] = b"PK"; + + let mut result = ExtractionResult { + ..Default::default() + }; + + // Locate the end of the zip archive + if let Ok(zip_info) = find_zip_eof(file_data, offset) { + // Calculate total size of the zip archive, report success + result.size = Some(zip_info.eof - offset); + result.success = true; + + // If extraction was requested, carve the zip archive to disk, replacing the Dahua ZIP magic bytes + // with the standard ZIP magic bytes. + if output_directory.is_some() { + // Start and end offsets of the data to carve + let start_data = offset + ZIP_HEADER.len(); + let end_data = offset + result.size.unwrap(); + + let chroot = Chroot::new(output_directory); + + // Get the data to carve + match file_data.get(start_data..end_data) { + None => { + result.success = false; + } + Some(zip_data) => { + // First write the normal ZIP header magic bytes to disk + if !chroot.create_file(OUTFILE_NAME, ZIP_HEADER) { + result.success = false; + } else { + // Append the rest of the ZIP archive to disk + result.success = chroot.append_to_file(OUTFILE_NAME, zip_data); + } + } + } + } + } + + result +} diff --git a/src/extractors/gif.rs b/src/extractors/gif.rs index 0ec4beaa8..d92a069a6 100644 --- a/src/extractors/gif.rs +++ b/src/extractors/gif.rs @@ -3,7 +3,7 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use crate::structures::common::StructureError; use crate::structures::gif::{parse_gif_extension, parse_gif_header, parse_gif_image_descriptor}; -/// Defines the internal extractor function for carving out JPEG images +/// Defines the internal extractor function for carving out GIF images /// /// ``` /// use std::io::ErrorKind; diff --git a/src/magic.rs b/src/magic.rs index a3336104c..5fbe1b81a 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -943,6 +943,17 @@ pub fn patterns() -> Vec { description: signatures::wince::DESCRIPTION.to_string(), extractor: Some(extractors::wince::wince_extractor()), }, + // Dahua ZIP + signatures::common::Signature { + name: "dahua_zip".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::dahua_zip::dahua_zip_magic(), + parser: signatures::dahua_zip::dahua_zip_parser, + description: signatures::dahua_zip::DESCRIPTION.to_string(), + extractor: Some(extractors::dahua_zip::dahua_zip_extractor()), + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index 0fbc596e8..51d322251 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -121,6 +121,7 @@ pub mod compressd; pub mod copyright; pub mod cpio; pub mod cramfs; +pub mod dahua_zip; pub mod deb; pub mod dlob; pub mod dmg; diff --git a/src/signatures/dahua_zip.rs b/src/signatures/dahua_zip.rs new file mode 100644 index 000000000..cba58fe00 --- /dev/null +++ b/src/signatures/dahua_zip.rs @@ -0,0 +1,27 @@ +use crate::signatures::common::{SignatureError, SignatureResult}; +use crate::signatures::zip; + +/// Human readable description +pub const DESCRIPTION: &str = "Dahua ZIP archive"; + +/// Dahua ZIP file entry magic bytes +pub fn dahua_zip_magic() -> Vec> { + // The first ZIP file entry in the Dahua ZIP file is has "DH" instead of "PK". + // Otherwise, it is a normal ZIP file. + vec![b"DH\x03\x04".to_vec()] +} + +/// Validates a Dahua ZIP file entry signature +pub fn dahua_zip_parser( + file_data: &[u8], + offset: usize, +) -> Result { + // Parse & validate the Dahua ZIP file like a normal ZIP file + if let Ok(mut result) = zip::zip_parser(file_data, offset) { + // Replace the normal ZIP description string with our description string + result.description = result.description.replace(zip::DESCRIPTION, DESCRIPTION); + return Ok(result); + } + + Err(SignatureError) +} diff --git a/src/signatures/zip.rs b/src/signatures/zip.rs index abefea286..812827704 100644 --- a/src/signatures/zip.rs +++ b/src/signatures/zip.rs @@ -36,13 +36,13 @@ pub fn zip_parser(file_data: &[u8], offset: usize) -> Result Result { +pub fn find_zip_eof(file_data: &[u8], offset: usize) -> Result { // This magic string assumes that the disk_number and central_directory_disk_number are 0 const ZIP_EOCD_MAGIC: &[u8; 8] = b"PK\x05\x06\x00\x00\x00\x00"; From 9d704610059c62a99a9a946c8f7539b95f66694d Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 2 Nov 2024 17:31:50 -0400 Subject: [PATCH 054/131] Added YAFFS and Squashfs tests --- tests/inputs/squashfs.bin | Bin 0 -> 4096 bytes tests/inputs/yaffs2.bin | Bin 0 -> 135168 bytes tests/squashfs.rs | 8 ++++++++ tests/yaffs2.rs | 8 ++++++++ 4 files changed, 16 insertions(+) create mode 100644 tests/inputs/squashfs.bin create mode 100644 tests/inputs/yaffs2.bin create mode 100644 tests/squashfs.rs create mode 100644 tests/yaffs2.rs diff --git a/tests/inputs/squashfs.bin b/tests/inputs/squashfs.bin new file mode 100644 index 0000000000000000000000000000000000000000..68245ec2233be9091b942e4f3739bef933701ae6 GIT binary patch literal 4096 zcmc~OE-YqZU|`rkQ!Sl=fr)_;$Yx{^WHAO-$Eb?)ETn7=Z$ zvALUtii@=$9@1NP@SNj3M#Xvm>b7|aG>aUN`syQE{WG!id)G^5rIslINE<6qoKb*5Q55PKmWCJ13=FzZ s9#rutH5vk=Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0)syU00~)OWdHyG literal 0 HcmV?d00001 diff --git a/tests/inputs/yaffs2.bin b/tests/inputs/yaffs2.bin new file mode 100644 index 0000000000000000000000000000000000000000..72938c798ebc19dc5e4206393ba22ac7854a14ad GIT binary patch literal 135168 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 z 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 Date: Sat, 2 Nov 2024 17:33:58 -0400 Subject: [PATCH 055/131] Added Cramfs test --- tests/cramfs.rs | 8 ++++++++ tests/inputs/cramfs.bin | Bin 0 -> 4096 bytes 2 files changed, 8 insertions(+) create mode 100644 tests/cramfs.rs create mode 100644 tests/inputs/cramfs.bin diff --git a/tests/cramfs.rs b/tests/cramfs.rs new file mode 100644 index 000000000..44bd198e9 --- /dev/null +++ b/tests/cramfs.rs @@ -0,0 +1,8 @@ +mod common; + +#[test] +fn integration_test() { + const SIGNATURE_TYPE: &str = "cramfs"; + const INPUT_FILE_NAME: &str = "cramfs.bin"; + common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); +} diff --git a/tests/inputs/cramfs.bin b/tests/inputs/cramfs.bin new file mode 100644 index 0000000000000000000000000000000000000000..0091ed564fd53b0c2e2d5ff9682078afe23ee440 GIT binary patch literal 4096 zcmZ>@J*&YWz`(%F00GYVxdlb3#l@*93PJw9Zoyr5UakenFaj|X5F_M4q6`dw9bYg@ zFfhD0z{0?=r11rF29WK{#=wwMoTOWnnv-%B>~`f8ok z)_hvj*u}E**A6ST-M6G9UrNq6;5zqjY|LMo+SuI9LdC_}4-e_BJ9y4<9;4#Ce|6iu z1e!$-NPYDYt#N9ax`V+tRrV^_1*61h2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk Nz-S1Jh5(@u006%JLVExJ literal 0 HcmV?d00001 From 5dc3eeb18107d616ad9ed3072f480777442535d9 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 2 Nov 2024 17:46:42 -0400 Subject: [PATCH 056/131] Added RomFS test --- src/structures/romfs.rs | 4 +++- tests/inputs/romfs.bin | Bin 0 -> 1024 bytes tests/romfs.rs | 8 ++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 tests/inputs/romfs.bin create mode 100644 tests/romfs.rs diff --git a/src/structures/romfs.rs b/src/structures/romfs.rs index d2680d298..c6dcb0e3d 100644 --- a/src/structures/romfs.rs +++ b/src/structures/romfs.rs @@ -172,7 +172,9 @@ fn romfs_crc_valid(crc_data: &[u8]) -> bool { // Sum each word while i < crc_data.len() { - sum += u32::from_be_bytes(crc_data[i..i + word_size].try_into().unwrap()); + sum = sum.wrapping_add(u32::from_be_bytes( + crc_data[i..i + word_size].try_into().unwrap(), + )); i += word_size; } diff --git a/tests/inputs/romfs.bin b/tests/inputs/romfs.bin new file mode 100644 index 0000000000000000000000000000000000000000..7c82a839198684f7d20da530dee27de17b9fc48b GIT binary patch literal 1024 zcmdNb%Fi`SE7oOTVEFLCC3FFht6*ksWM-LcWDFDo0Z$-S05LB9|36(1#6SfJK&}Ev z=;Foy4SJXgm_Twskg;_Bz<>uQ^on44P(7j|(Cb`J6k2=VmyvsHo^qyW~aXR6>6 T60F1pwrrFb4S~@RKnVc=LCQ7R literal 0 HcmV?d00001 diff --git a/tests/romfs.rs b/tests/romfs.rs new file mode 100644 index 000000000..bbb81fb09 --- /dev/null +++ b/tests/romfs.rs @@ -0,0 +1,8 @@ +mod common; + +#[test] +fn integration_test() { + const SIGNATURE_TYPE: &str = "romfs"; + const INPUT_FILE_NAME: &str = "romfs.bin"; + common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); +} From 5eb775a90a32b802462f34743f09a4854f1f0c7d Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 2 Nov 2024 17:49:14 -0400 Subject: [PATCH 057/131] Added MBR test --- tests/inputs/mbr.bin | Bin 0 -> 5120 bytes tests/mbr.rs | 8 ++++++++ 2 files changed, 8 insertions(+) create mode 100644 tests/inputs/mbr.bin create mode 100644 tests/mbr.rs diff --git a/tests/inputs/mbr.bin b/tests/inputs/mbr.bin new file mode 100644 index 0000000000000000000000000000000000000000..292e7b19634eaf43fa93c781156d59e23153a112 GIT binary patch literal 5120 zcmeIuu?@f=5CcFbUD%HqGDwOHk%~4`0xQrVohvt%{x6Xo1-^E_^X@ZGN{-R4g*WQI bFft)PfB*pk1PBlyK!5-N0t5&U*hruQdd>sG literal 0 HcmV?d00001 diff --git a/tests/mbr.rs b/tests/mbr.rs new file mode 100644 index 000000000..afbd78460 --- /dev/null +++ b/tests/mbr.rs @@ -0,0 +1,8 @@ +mod common; + +#[test] +fn integration_test() { + const SIGNATURE_TYPE: &str = "mbr"; + const INPUT_FILE_NAME: &str = "mbr.bin"; + common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); +} From b83242ffbd54997d11c7f7e304c17bf9582e38fe Mon Sep 17 00:00:00 2001 From: David Roman Date: Sun, 3 Nov 2024 16:37:37 +0100 Subject: [PATCH 058/131] switch from p7zip to 7zip --- src/extractors/sevenzip.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extractors/sevenzip.rs b/src/extractors/sevenzip.rs index a67509eeb..284430f02 100644 --- a/src/extractors/sevenzip.rs +++ b/src/extractors/sevenzip.rs @@ -24,7 +24,7 @@ use crate::extractors; /// ``` pub fn sevenzip_extractor() -> extractors::common::Extractor { extractors::common::Extractor { - utility: extractors::common::ExtractorType::External("7z".to_string()), + utility: extractors::common::ExtractorType::External("7zz".to_string()), extension: "bin".to_string(), arguments: vec![ "x".to_string(), // Perform extraction From fc4308a9a37ab25c425dfb0a2ade6b2304fbd5b9 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sun, 3 Nov 2024 15:03:23 -0500 Subject: [PATCH 059/131] Updated dependency from p7zip to 7zip --- dependencies/ubuntu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/ubuntu.sh b/dependencies/ubuntu.sh index e67c6a6c4..60b9c9690 100755 --- a/dependencies/ubuntu.sh +++ b/dependencies/ubuntu.sh @@ -5,7 +5,7 @@ SCRIPT_DIRECTORY=$(dirname -- "$( readlink -f -- "$0"; )") # Install dependencies from apt repository DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install \ - p7zip-full \ + 7zip \ zstd \ tar \ unzip \ From a9e018953c757a565fa25fc36b63ecb4c637b78d Mon Sep 17 00:00:00 2001 From: devttys0 Date: Tue, 5 Nov 2024 13:16:25 -0500 Subject: [PATCH 060/131] Fixed openssl signature bug --- src/magic.rs | 2 +- src/structures/openssl.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/magic.rs b/src/magic.rs index 5fbe1b81a..5f3c20cef 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -673,7 +673,7 @@ pub fn patterns() -> Vec { name: "openssl".to_string(), short: false, magic_offset: 0, - always_display: false, + always_display: true, magic: signatures::openssl::openssl_crypt_magic(), parser: signatures::openssl::openssl_crypt_parser, description: signatures::openssl::DESCRIPTION.to_string(), diff --git a/src/structures/openssl.rs b/src/structures/openssl.rs index 1b5c28de3..524972f22 100644 --- a/src/structures/openssl.rs +++ b/src/structures/openssl.rs @@ -7,7 +7,7 @@ pub struct OpenSSLCryptHeader { /// Parse an OpenSSl crypto header pub fn parse_openssl_crypt_header(ssl_data: &[u8]) -> Result { - let ssl_structure = vec![("magic", "u32"), ("salt", "u64")]; + let ssl_structure = vec![("magic", "u64"), ("salt", "u64")]; if let Ok(ssl_header) = common::parse(ssl_data, &ssl_structure, "big") { return Ok(OpenSSLCryptHeader { From 7ea0e6c11fdf73cd389e44d1b05c84263716427a Mon Sep 17 00:00:00 2001 From: devttys0 Date: Tue, 5 Nov 2024 19:57:37 -0500 Subject: [PATCH 061/131] Adds D-Link firmware signature; adds sanity check to openssl signature --- src/magic.rs | 11 +++++++++ src/signatures.rs | 1 + src/signatures/mh01.rs | 35 +++++++++++++++++++++++++++ src/structures.rs | 1 + src/structures/mh01.rs | 51 +++++++++++++++++++++++++++++++++++++++ src/structures/openssl.rs | 8 +++--- 6 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 src/signatures/mh01.rs create mode 100644 src/structures/mh01.rs diff --git a/src/magic.rs b/src/magic.rs index 5f3c20cef..eb2c2f6b8 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -954,6 +954,17 @@ pub fn patterns() -> Vec { description: signatures::dahua_zip::DESCRIPTION.to_string(), extractor: Some(extractors::dahua_zip::dahua_zip_extractor()), }, + // DLink MH01 + signatures::common::Signature { + name: "mh01".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::mh01::mh01_magic(), + parser: signatures::mh01::mh01_parser, + description: signatures::mh01::DESCRIPTION.to_string(), + extractor: None, + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index 51d322251..d137863e3 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -146,6 +146,7 @@ pub mod lzfse; pub mod lzma; pub mod lzop; pub mod mbr; +pub mod mh01; pub mod ntfs; pub mod openssl; pub mod packimg; diff --git a/src/signatures/mh01.rs b/src/signatures/mh01.rs new file mode 100644 index 000000000..d1e461878 --- /dev/null +++ b/src/signatures/mh01.rs @@ -0,0 +1,35 @@ +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use crate::structures::mh01::parse_mh01_header; + +/// Human readable description +pub const DESCRIPTION: &str = "D-Link MH01 firmware image"; + +/// MH01 firmware images always start with these bytes +pub fn mh01_magic() -> Vec> { + vec![b"MH01".to_vec()] +} + +/// Validates the MH01 header +pub fn mh01_parser(file_data: &[u8], offset: usize) -> Result { + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + if let Ok(mh01_header) = parse_mh01_header(&file_data[offset..]) { + result.size = mh01_header.header_size; + result.description = format!( + "{}, header size: {} bytes, data size: {} bytes, data hash: {}", + result.description, + mh01_header.header_size, + mh01_header.data_size, + mh01_header.data_hash, + ); + return Ok(result); + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index 7abec370b..8996fda23 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -126,6 +126,7 @@ pub mod lzfse; pub mod lzma; pub mod lzop; pub mod mbr; +pub mod mh01; pub mod ntfs; pub mod openssl; pub mod packimg; diff --git a/src/structures/mh01.rs b/src/structures/mh01.rs new file mode 100644 index 000000000..9aa9a03e0 --- /dev/null +++ b/src/structures/mh01.rs @@ -0,0 +1,51 @@ +use crate::common::get_cstring; +use crate::structures::common::{self, StructureError}; + +/// Struct to store MH01 header info +#[derive(Debug, Default, Clone)] +pub struct MH01Header { + pub data_size: usize, + pub header_size: usize, + pub data_hash: String, +} + +/// Parses an MH01 header +pub fn parse_mh01_header(mh01_data: &[u8]) -> Result { + let mh01_structure = vec![ + ("magic1", "u32"), + ("image_size", "u32"), + ("footer_size", "u32"), + ("unknown1", "u32"), + ("magic2", "u32"), + ("hash_size", "u32"), + ("encrypted_data_size", "u32"), + ("unknown2", "u32"), + // hash string of length hash_size immediately follows + ]; + + // Parse the header + if let Ok(header) = common::parse(mh01_data, &mh01_structure, "little") { + // Make sure the expected magic bytes match + if header["magic1"] == header["magic2"] { + // Calculate the start and end bytes of the payload hash (ASCII hex) + let hash_bytes_start = common::size(&mh01_structure); + let hash_bytes_end = hash_bytes_start + header["hash_size"]; + + // Get the payload hash string + if let Some(hash_bytes) = mh01_data.get(hash_bytes_start..hash_bytes_end) { + let hash_string = get_cstring(hash_bytes); + + // Make sure we got a string of the expected length + if hash_string.len() == header["hash_size"] { + return Ok(MH01Header { + data_size: header["encrypted_data_size"], + header_size: hash_bytes_end, + data_hash: hash_string.trim().to_string(), + }); + } + } + } + } + + Err(StructureError) +} diff --git a/src/structures/openssl.rs b/src/structures/openssl.rs index 524972f22..422a4f915 100644 --- a/src/structures/openssl.rs +++ b/src/structures/openssl.rs @@ -10,9 +10,11 @@ pub fn parse_openssl_crypt_header(ssl_data: &[u8]) -> Result Date: Tue, 5 Nov 2024 22:22:45 -0500 Subject: [PATCH 062/131] Fixed bug in linux kernel version signature --- src/signatures/linux.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/signatures/linux.rs b/src/signatures/linux.rs index 24cd33a0b..c1899a74f 100644 --- a/src/signatures/linux.rs +++ b/src/signatures/linux.rs @@ -102,6 +102,7 @@ pub fn linux_kernel_version_parser( const AMPERSAND: &str = "@"; const PERIOD_OFFSET_1: usize = 15; const PERIOD_OFFSET_2: usize = 17; + const PERIOD_OFFSET_3: usize = 18; const MIN_FILE_SIZE: usize = 100 * 1024; const MIN_VERSION_STRING_LENGTH: usize = 75; const GCC_VERSION_STRING: &str = "gcc "; @@ -127,9 +128,12 @@ pub fn linux_kernel_version_parser( if kernel_version_string.contains(AMPERSAND) { // The kernel version string should end with a new line if kernel_version_string.ends_with(NEW_LINE) { + let kv_bytes = kernel_version_string.as_bytes(); + // Make sure the linux kernel version has periods at the expected locations - if kernel_version_string.as_bytes()[PERIOD_OFFSET_1] == PERIOD - && kernel_version_string.as_bytes()[PERIOD_OFFSET_2] == PERIOD + if kv_bytes[PERIOD_OFFSET_1] == PERIOD + && (kv_bytes[PERIOD_OFFSET_2] == PERIOD + || kv_bytes[PERIOD_OFFSET_3] == PERIOD) { // Try to locate a Linux kernel symbol table let symtab_present = has_linux_symbol_table(file_data); From b404ac46c8985e36d7f1909b654a2d0430db29d1 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 8 Nov 2024 09:52:40 -0500 Subject: [PATCH 063/131] Added support for uImage headers with invalid CRC's (D-link) --- src/extractors/uimage.rs | 35 +++++++++++++++++++++-------------- src/signatures/uimage.rs | 20 +++++++++++++++++--- src/structures/uimage.rs | 36 ++++++++++++++++++------------------ 3 files changed, 56 insertions(+), 35 deletions(-) diff --git a/src/extractors/uimage.rs b/src/extractors/uimage.rs index 56e54680b..b8700e768 100644 --- a/src/extractors/uimage.rs +++ b/src/extractors/uimage.rs @@ -50,26 +50,33 @@ pub fn extract_uimage( let image_data_start = offset + uimage_header.header_size; let image_data_end = image_data_start + uimage_header.data_size; - // Get the raw image data after the uImage header and validate the data CRC + // Get the raw image data after the uImage header to validate the data CRC if let Some(image_data) = file_data.get(image_data_start..image_data_end) { - if crc32(image_data) == (uimage_header.data_checksum as u32) { - result.success = true; - result.size = Some(uimage_header.header_size + uimage_header.data_size); + result.success = true; + result.size = Some(uimage_header.header_size); - // If extraction was requested, carve the uImage data out to a file - if output_directory.is_some() { - let chroot = Chroot::new(output_directory); - let mut file_base_name: String = DEFAULT_OUTPUT_FILE_NAME.to_string(); + // Check the data CRC + let data_crc_valid: bool = + crc32(image_data) == (uimage_header.data_checksum as u32); - // Use the name specified in the uImage header as the file name, if one was provided - if !uimage_header.name.is_empty() { - file_base_name = uimage_header.name.replace(" ", "_"); - } + // If the data CRC is valid, include the size of the data in the reported size + if data_crc_valid { + result.size = Some(result.size.unwrap() + uimage_header.data_size); + } - let output_file = format!("{}.{}", file_base_name, OUTPUT_FILE_EXT); + // If extraction was requested and the data CRC is valid, carve the uImage data out to a file + if data_crc_valid && output_directory.is_some() { + let chroot = Chroot::new(output_directory); + let mut file_base_name: String = DEFAULT_OUTPUT_FILE_NAME.to_string(); - result.success = chroot.create_file(&output_file, image_data); + // Use the name specified in the uImage header as the file name, if one was provided + if !uimage_header.name.is_empty() { + file_base_name = uimage_header.name.replace(" ", "_"); } + + let output_file = format!("{}.{}", file_base_name, OUTPUT_FILE_EXT); + + result.success = chroot.create_file(&output_file, image_data); } } } diff --git a/src/signatures/uimage.rs b/src/signatures/uimage.rs index fd551c835..5d8a6aa69 100644 --- a/src/signatures/uimage.rs +++ b/src/signatures/uimage.rs @@ -1,6 +1,8 @@ use crate::common::epoch_to_string; use crate::extractors::uimage::extract_uimage; -use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; +use crate::signatures::common::{ + SignatureError, SignatureResult, CONFIDENCE_HIGH, CONFIDENCE_LOW, CONFIDENCE_MEDIUM, +}; use crate::structures::uimage::parse_uimage_header; /// Human readable description @@ -29,9 +31,10 @@ pub fn uimage_parser(file_data: &[u8], offset: usize) -> Result Result Result Date: Fri, 8 Nov 2024 09:53:44 -0500 Subject: [PATCH 064/131] Updated version to 3.1.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c2bbb455..74b19d93c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,7 +101,7 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "binwalk" -version = "3.1.0" +version = "3.1.1" dependencies = [ "aho-corasick", "base64", diff --git a/Cargo.toml b/Cargo.toml index 0f96f7e07..a53076486 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "binwalk" -version = "3.1.0" +version = "3.1.1" edition = "2021" authors = ["Craig Heffner "] license = "MIT" From 434892d122ede9e96f5247c8c115d8f6241d5142 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 13 Nov 2024 20:15:26 -0500 Subject: [PATCH 065/131] Added explicit little/big endian extraction for squashfs images --- src/extractors/squashfs.rs | 28 ++++++++++++++++++++++++++++ src/signatures/squashfs.rs | 12 +++++++----- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/extractors/squashfs.rs b/src/extractors/squashfs.rs index 4747d541f..25c7b6570 100644 --- a/src/extractors/squashfs.rs +++ b/src/extractors/squashfs.rs @@ -33,6 +33,34 @@ pub fn squashfs_extractor() -> extractors::common::Extractor { } } +pub fn squashfs_le_extractor() -> extractors::common::Extractor { + extractors::common::Extractor { + utility: extractors::common::ExtractorType::External("sasquatch".to_string()), + extension: "sqsh".to_string(), + arguments: vec![ + "-le".to_string(), + extractors::common::SOURCE_FILE_PLACEHOLDER.to_string() + ], + // Exit code may be 0 or 2; 2 indicates running as not root, but otherwise extraction is ok + exit_codes: vec![0, 2], + ..Default::default() + } +} + +pub fn squashfs_be_extractor() -> extractors::common::Extractor { + extractors::common::Extractor { + utility: extractors::common::ExtractorType::External("sasquatch".to_string()), + extension: "sqsh".to_string(), + arguments: vec![ + "-be".to_string(), + extractors::common::SOURCE_FILE_PLACEHOLDER.to_string() + ], + // Exit code may be 0 or 2; 2 indicates running as not root, but otherwise extraction is ok + exit_codes: vec![0, 2], + ..Default::default() + } +} + /// Describes how to run the sasquatch-v4be utility to extract big endian SquashFSv4 images /// /// ``` diff --git a/src/signatures/squashfs.rs b/src/signatures/squashfs.rs index 6aa485d6c..f261c96ac 100644 --- a/src/signatures/squashfs.rs +++ b/src/signatures/squashfs.rs @@ -1,5 +1,5 @@ use crate::common::epoch_to_string; -use crate::extractors::squashfs::squashfs_v4_be_extractor; +use crate::extractors::squashfs::{squashfs_be_extractor, squashfs_le_extractor, squashfs_v4_be_extractor}; use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; use crate::structures::squashfs::{parse_squashfs_header, parse_squashfs_uid_entry}; use std::collections::HashMap; @@ -90,11 +90,13 @@ pub fn squashfs_parser(file_data: &[u8], offset: usize) -> Result Date: Wed, 13 Nov 2024 20:21:14 -0500 Subject: [PATCH 066/131] Code formatting, doc tests --- src/extractors/squashfs.rs | 48 ++++++++++++++++++++++++++++++++++++-- src/signatures/squashfs.rs | 4 +++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/extractors/squashfs.rs b/src/extractors/squashfs.rs index 25c7b6570..f9376eb39 100644 --- a/src/extractors/squashfs.rs +++ b/src/extractors/squashfs.rs @@ -33,13 +33,35 @@ pub fn squashfs_extractor() -> extractors::common::Extractor { } } +/// Describes how to run the sasquatch utility to extract little endian SquashFS images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::squashfs::squashfs_le_extractor; +/// +/// match squashfs_le_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn squashfs_le_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("sasquatch".to_string()), extension: "sqsh".to_string(), arguments: vec![ "-le".to_string(), - extractors::common::SOURCE_FILE_PLACEHOLDER.to_string() + extractors::common::SOURCE_FILE_PLACEHOLDER.to_string(), ], // Exit code may be 0 or 2; 2 indicates running as not root, but otherwise extraction is ok exit_codes: vec![0, 2], @@ -47,13 +69,35 @@ pub fn squashfs_le_extractor() -> extractors::common::Extractor { } } +/// Describes how to run the sasquatch utility to extract big endian SquashFS images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::squashfs::squashfs_be_extractor; +/// +/// match squashfs_be_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` pub fn squashfs_be_extractor() -> extractors::common::Extractor { extractors::common::Extractor { utility: extractors::common::ExtractorType::External("sasquatch".to_string()), extension: "sqsh".to_string(), arguments: vec![ "-be".to_string(), - extractors::common::SOURCE_FILE_PLACEHOLDER.to_string() + extractors::common::SOURCE_FILE_PLACEHOLDER.to_string(), ], // Exit code may be 0 or 2; 2 indicates running as not root, but otherwise extraction is ok exit_codes: vec![0, 2], diff --git a/src/signatures/squashfs.rs b/src/signatures/squashfs.rs index f261c96ac..f31dac7d0 100644 --- a/src/signatures/squashfs.rs +++ b/src/signatures/squashfs.rs @@ -1,5 +1,7 @@ use crate::common::epoch_to_string; -use crate::extractors::squashfs::{squashfs_be_extractor, squashfs_le_extractor, squashfs_v4_be_extractor}; +use crate::extractors::squashfs::{ + squashfs_be_extractor, squashfs_le_extractor, squashfs_v4_be_extractor, +}; use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; use crate::structures::squashfs::{parse_squashfs_header, parse_squashfs_uid_entry}; use std::collections::HashMap; From be2b5e8590adfe9fb93fa42df2d8c6ceedb75b41 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 15 Nov 2024 16:50:24 -0500 Subject: [PATCH 067/131] Added support for extracting CSMan DAT files --- src/extractors.rs | 1 + src/extractors/csman.rs | 105 ++++++++++++++++++++++++++++++++++++++++ src/magic.rs | 11 +++++ src/signatures.rs | 1 + src/signatures/csman.rs | 34 +++++++++++++ src/structures.rs | 1 + src/structures/csman.rs | 78 +++++++++++++++++++++++++++++ 7 files changed, 231 insertions(+) create mode 100644 src/extractors/csman.rs create mode 100644 src/signatures/csman.rs create mode 100644 src/structures/csman.rs diff --git a/src/extractors.rs b/src/extractors.rs index 7942f7e7b..be57a7d9a 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -146,6 +146,7 @@ pub mod autel; pub mod bzip2; pub mod cab; pub mod common; +pub mod csman; pub mod dahua_zip; pub mod dmg; pub mod dtb; diff --git a/src/extractors/csman.rs b/src/extractors/csman.rs new file mode 100644 index 000000000..7838677b2 --- /dev/null +++ b/src/extractors/csman.rs @@ -0,0 +1,105 @@ +use crate::common::is_offset_safe; +use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; +use crate::structures::csman::{parse_csman_entry, parse_csman_header, CSManEntry}; + +/// Defines the internal extractor function for CSMan DAT files +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::csman::csman_extractor; +/// +/// match csman_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` +pub fn csman_extractor() -> Extractor { + Extractor { + utility: ExtractorType::Internal(extract_csman_dat), + ..Default::default() + } +} + +/// Validate and extract CSMan DAT file entries +pub fn extract_csman_dat( + file_data: &[u8], + offset: usize, + output_directory: Option<&String>, +) -> ExtractionResult { + // Return value + let mut result = ExtractionResult { + ..Default::default() + }; + + let mut csman_entries: Vec = Vec::new(); + + // Parse the CSMAN header + if let Ok(csman_header) = parse_csman_header(&file_data[offset..]) { + // Calulate the start and end offsets of the CSMAN entries + let entries_start: usize = offset + csman_header.header_size; + let entries_end: usize = entries_start + csman_header.data_size; + + // Get the CSMAN entry data + if let Some(entry_data) = file_data.get(entries_start..entries_end) { + // Offsets for processing CSMAN entries in entry_data + let mut next_offset: usize = 0; + let mut previous_offset = None; + let available_data: usize = entry_data.len(); + + // Loop while there is still data that can be safely parsed + while is_offset_safe(available_data, next_offset, previous_offset) { + // Parse the next entry + match parse_csman_entry(&entry_data[next_offset..]) { + Err(_) => { + break; + } + Ok(entry) => { + if entry.eof { + // Last entry should be an EOF marker; an EOF marker should always exist. + // There should be at least one valid entry. + result.success = !csman_entries.is_empty(); + break; + } else { + // Append this entry to the list of entries and update the offsets to process the next entry + csman_entries.push(entry.clone()); + previous_offset = Some(next_offset); + next_offset += entry.size; + } + } + } + } + + // If all entries were processed successfully + if result.success { + // Update the reported size of data processed + result.size = Some(csman_header.header_size + csman_header.data_size); + + // If extraction was requested, extract each entry using the entry key as the file name + if output_directory.is_some() { + let chroot = Chroot::new(output_directory); + + for entry in csman_entries { + let file_name = format!("{:X}.dat", entry.key); + if !chroot.create_file(&file_name, &entry.value) { + result.success = false; + break; + } + } + } + } + } + } + + result +} diff --git a/src/magic.rs b/src/magic.rs index eb2c2f6b8..f3b5f08b1 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -965,6 +965,17 @@ pub fn patterns() -> Vec { description: signatures::mh01::DESCRIPTION.to_string(), extractor: None, }, + // CSman DAT + signatures::common::Signature { + name: "csman".to_string(), + short: true, + magic_offset: 0, + always_display: false, + magic: signatures::csman::csman_magic(), + parser: signatures::csman::csman_parser, + description: signatures::csman::DESCRIPTION.to_string(), + extractor: Some(extractors::csman::csman_extractor()), + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index d137863e3..79955ad10 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -121,6 +121,7 @@ pub mod compressd; pub mod copyright; pub mod cpio; pub mod cramfs; +pub mod csman; pub mod dahua_zip; pub mod deb; pub mod dlob; diff --git a/src/signatures/csman.rs b/src/signatures/csman.rs new file mode 100644 index 000000000..be0219ed8 --- /dev/null +++ b/src/signatures/csman.rs @@ -0,0 +1,34 @@ +use crate::extractors::csman::extract_csman_dat; +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; + +/// Human readable description +pub const DESCRIPTION: &str = "CSman DAT file"; + +/// CSMAN DAT files always start with these bytes +pub fn csman_magic() -> Vec> { + vec![b"SC".to_vec()] +} + +/// Validates the CSMAN DAT file +pub fn csman_parser(file_data: &[u8], offset: usize) -> Result { + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_HIGH, + ..Default::default() + }; + + let dry_run = extract_csman_dat(file_data, offset, None); + + if dry_run.success { + if let Some(total_size) = dry_run.size { + result.size = total_size; + result.description = + format!("{}, total size: {} bytes", result.description, result.size); + return Ok(result); + } + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index 8996fda23..fbf494184 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -106,6 +106,7 @@ pub mod chk; pub mod common; pub mod cpio; pub mod cramfs; +pub mod csman; pub mod deb; pub mod dlob; pub mod dmg; diff --git a/src/structures/csman.rs b/src/structures/csman.rs new file mode 100644 index 000000000..6058f2971 --- /dev/null +++ b/src/structures/csman.rs @@ -0,0 +1,78 @@ +use crate::structures::common::{self, StructureError}; + +/// Struct to store CSMAN header info +#[derive(Debug, Default, Clone)] +pub struct CSManHeader { + pub data_size: usize, + pub header_size: usize, +} + +/// Parses a CSMAN header +pub fn parse_csman_header(csman_data: &[u8]) -> Result { + let csman_header_structure = vec![ + ("magic", "u16"), + ("unknown1", "u16"), + ("data_size_1", "u32"), + ("unknown2", "u32"), + ("data_size_2", "u32"), + ]; + + // Parse the header + if let Ok(csman_header) = common::parse(csman_data, &csman_header_structure, "big") { + // Data size is repeated in both these fields + if csman_header["data_size_1"] == csman_header["data_size_2"] { + return Ok(CSManHeader { + data_size: csman_header["data_size_1"], + header_size: common::size(&csman_header_structure), + }); + } + } + + Err(StructureError) +} + +/// Stores info about a single CSMan DAT file entry +#[derive(Debug, Default, Clone)] +pub struct CSManEntry { + pub size: usize, + pub eof: bool, + pub key: usize, + pub value: Vec, +} + +/// Parses a single CSMan DAT file entry +pub fn parse_csman_entry(entry_data: &[u8]) -> Result { + const EOF_TAG: usize = 0; + + let csman_last_entry_structure = vec![("eof", "u32")]; + + let csman_entry_structure = vec![ + ("key", "u32"), + ("size", "u16"), + // value of size bytes immediately follows + ]; + + let mut entry = CSManEntry { + ..Default::default() + }; + + if let Ok(entry_header) = common::parse(entry_data, &csman_entry_structure, "big") { + let value_start: usize = common::size(&csman_entry_structure); + let value_end: usize = value_start + entry_header["size"]; + + if let Some(entry_value) = entry_data.get(value_start..value_end) { + entry.key = entry_header["key"]; + entry.value = entry_value.to_vec(); + entry.size = common::size(&csman_entry_structure) + entry_value.len(); + return Ok(entry); + } + } else if let Ok(entry_header) = common::parse(entry_data, &csman_last_entry_structure, "big") { + if entry_header["eof"] == EOF_TAG { + entry.eof = true; + entry.size = common::size(&csman_last_entry_structure); + return Ok(entry); + } + } + + Err(StructureError) +} From ba6d90c3b4ba587192d25f1d4f493c64fb9655cf Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 16 Nov 2024 10:40:27 -0500 Subject: [PATCH 068/131] Added support for duplicate key entries --- src/extractors/csman.rs | 54 +++++++++++++++++++++++++++++------------ src/structures/csman.rs | 2 ++ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/extractors/csman.rs b/src/extractors/csman.rs index 7838677b2..5983219b0 100644 --- a/src/extractors/csman.rs +++ b/src/extractors/csman.rs @@ -1,6 +1,7 @@ use crate::common::is_offset_safe; use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; use crate::structures::csman::{parse_csman_entry, parse_csman_header, CSManEntry}; +use std::collections::HashMap; /// Defines the internal extractor function for CSMan DAT files /// @@ -59,22 +60,30 @@ pub fn extract_csman_dat( // Loop while there is still data that can be safely parsed while is_offset_safe(available_data, next_offset, previous_offset) { - // Parse the next entry - match parse_csman_entry(&entry_data[next_offset..]) { - Err(_) => { + // Get the next entry's data + match entry_data.get(next_offset..) { + None => { break; } - Ok(entry) => { - if entry.eof { - // Last entry should be an EOF marker; an EOF marker should always exist. - // There should be at least one valid entry. - result.success = !csman_entries.is_empty(); - break; - } else { - // Append this entry to the list of entries and update the offsets to process the next entry - csman_entries.push(entry.clone()); - previous_offset = Some(next_offset); - next_offset += entry.size; + Some(next_entry_data) => { + // Parse the next entry + match parse_csman_entry(next_entry_data) { + Err(_) => { + break; + } + Ok(entry) => { + if entry.eof { + // Last entry should be an EOF marker; an EOF marker should always exist. + // There should be at least one valid entry. + result.success = !csman_entries.is_empty(); + break; + } else { + // Append this entry to the list of entries and update the offsets to process the next entry + csman_entries.push(entry.clone()); + previous_offset = Some(next_offset); + next_offset += entry.size; + } + } } } } @@ -87,10 +96,25 @@ pub fn extract_csman_dat( // If extraction was requested, extract each entry using the entry key as the file name if output_directory.is_some() { + // All files will be written inside the provided output directory let chroot = Chroot::new(output_directory); + // There may be more than one entry with the same key; track the key and how many times it was encountered + let mut processed_entries: HashMap = HashMap::new(); + + // Loop through all entries for entry in csman_entries { - let file_name = format!("{:X}.dat", entry.key); + // File name is [key value, in ASCII hex].dat + let mut file_name = format!("{:08X}.dat", entry.key); + + // If this key value has already been extracted, file name is [key value, in ASCII hex].dat_[count] + if processed_entries.contains_key(&entry.key) { + file_name = format!("{}_{}", file_name, processed_entries[&entry.key]); + processed_entries.insert(entry.key, processed_entries[&entry.key] + 1); + } else { + processed_entries.insert(entry.key, 1); + } + if !chroot.create_file(&file_name, &entry.value) { result.success = false; break; diff --git a/src/structures/csman.rs b/src/structures/csman.rs index 6058f2971..29d4b5c0a 100644 --- a/src/structures/csman.rs +++ b/src/structures/csman.rs @@ -44,8 +44,10 @@ pub struct CSManEntry { pub fn parse_csman_entry(entry_data: &[u8]) -> Result { const EOF_TAG: usize = 0; + // The last entry is just a single 4-byte NULL value let csman_last_entry_structure = vec![("eof", "u32")]; + // Entries consist of a 4-byte identifier, a 2-byte size, and a value let csman_entry_structure = vec![ ("key", "u32"), ("size", "u16"), From 1fbc0cd457a5bf9a28504fb159c6492d278ea6eb Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 16 Nov 2024 12:23:32 -0500 Subject: [PATCH 069/131] Updated MH01 parsing and reported firmware information --- src/signatures/mh01.rs | 29 ++++++++++++-------- src/structures/mh01.rs | 61 +++++++++++++++++++++++++++++------------- 2 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/signatures/mh01.rs b/src/signatures/mh01.rs index d1e461878..641f2c713 100644 --- a/src/signatures/mh01.rs +++ b/src/signatures/mh01.rs @@ -1,4 +1,5 @@ -use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; +use crate::signatures::openssl::openssl_crypt_parser; use crate::structures::mh01::parse_mh01_header; /// Human readable description @@ -15,20 +16,26 @@ pub fn mh01_parser(file_data: &[u8], offset: usize) -> Result Result { + const HEADER_SIZE: usize = 16; + + // This structure is actually two MH01 headers, each header is HEADER_SIZE bytes long. + // The first header describes the offset and size of the firmware signature. + // The second header describes the offset and size of the encrypted firmware image. + // The OpenSSL IV is stored as an ASCII hex string between the second header and the encrypted firmware image. let mh01_structure = vec![ ("magic1", "u32"), - ("image_size", "u32"), - ("footer_size", "u32"), + ("signature_offset", "u32"), + ("signature_size", "u32"), ("unknown1", "u32"), ("magic2", "u32"), - ("hash_size", "u32"), + ("iv_size", "u32"), ("encrypted_data_size", "u32"), ("unknown2", "u32"), - // hash string of length hash_size immediately follows + // IV string of length iv_size immediately follows ]; + let mut result = MH01Header { + ..Default::default() + }; + // Parse the header if let Ok(header) = common::parse(mh01_data, &mh01_structure, "little") { // Make sure the expected magic bytes match if header["magic1"] == header["magic2"] { - // Calculate the start and end bytes of the payload hash (ASCII hex) - let hash_bytes_start = common::size(&mh01_structure); - let hash_bytes_end = hash_bytes_start + header["hash_size"]; + // IV size is specified in the header and immediately follows the header + result.iv_size = header["iv_size"]; + result.iv_offset = common::size(&mh01_structure); + + // The encrypted firmware image immediately follows the IV + result.encrypted_data_size = header["encrypted_data_size"]; + result.encrypted_data_offset = result.iv_offset + result.iv_size; + + // The signature should immediately follow the encrypted firmware image + result.signature_size = header["signature_size"]; + result.signature_offset = HEADER_SIZE + header["signature_offset"]; + + // Calculate the start and end bytes of the IV (ASCII hex) + let iv_bytes_start = result.iv_offset; + let iv_bytes_end = result.encrypted_data_offset; // Get the payload hash string - if let Some(hash_bytes) = mh01_data.get(hash_bytes_start..hash_bytes_end) { - let hash_string = get_cstring(hash_bytes); + if let Some(iv_bytes) = mh01_data.get(iv_bytes_start..iv_bytes_end) { + let iv_string = get_cstring(iv_bytes); // Make sure we got a string of the expected length - if hash_string.len() == header["hash_size"] { - return Ok(MH01Header { - data_size: header["encrypted_data_size"], - header_size: hash_bytes_end, - data_hash: hash_string.trim().to_string(), - }); + if iv_string.len() == result.iv_size { + result.iv = iv_string.trim().to_string(); + result.total_size = result.signature_offset + result.signature_size; + return Ok(result); } } } From abc78bd8a27c8cbc13b9f6170e41627dff176a88 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 16 Nov 2024 12:45:50 -0500 Subject: [PATCH 070/131] Added carving of MH01 firmware images --- src/extractors.rs | 1 + src/extractors/mh01.rs | 83 ++++++++++++++++++++++++++++++++++++++++++ src/magic.rs | 2 +- src/signatures/mh01.rs | 2 +- 4 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 src/extractors/mh01.rs diff --git a/src/extractors.rs b/src/extractors.rs index be57a7d9a..467bf4f51 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -163,6 +163,7 @@ pub mod lzfse; pub mod lzma; pub mod lzop; pub mod mbr; +pub mod mh01; pub mod pcap; pub mod pem; pub mod png; diff --git a/src/extractors/mh01.rs b/src/extractors/mh01.rs new file mode 100644 index 000000000..42004dc7c --- /dev/null +++ b/src/extractors/mh01.rs @@ -0,0 +1,83 @@ +use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; +use crate::structures::mh01::parse_mh01_header; + +/// Defines the internal extractor function for carving out MH01 firmware images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::mh01::mh01_extractor; +/// +/// match mh01_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` +pub fn mh01_extractor() -> Extractor { + Extractor { + utility: ExtractorType::Internal(extract_mh01_image), + ..Default::default() + } +} + +/// Internal extractor for carve pieces of MH01 images to disk +pub fn extract_mh01_image( + file_data: &[u8], + offset: usize, + output_directory: Option<&String>, +) -> ExtractionResult { + // File names for the three portions of the MH01 firmware image + const IV_FILE_NAME: &str = "iv.bin"; + const SIGNATURE_FILE_NAME: &str = "signature.bin"; + const ENCRYPTED_DATA_FILE_NAME: &str = "encrypted.bin"; + + let mut result = ExtractionResult { + ..Default::default() + }; + + // Get the MH01 image data + if let Some(mh01_data) = file_data.get(offset..) { + // Parse the MH01 header + if let Ok(mh01_header) = parse_mh01_header(mh01_data) { + result.size = Some(mh01_header.total_size); + + // If extraction was requested, do it + if output_directory.is_some() { + let chroot = Chroot::new(output_directory); + + // Extract each part of the firmware image, ensuring that each one extracts without error + result.success = chroot.carve_file( + IV_FILE_NAME, + mh01_data, + mh01_header.iv_offset, + mh01_header.iv_size, + ) && chroot.carve_file( + SIGNATURE_FILE_NAME, + mh01_data, + mh01_header.signature_offset, + mh01_header.signature_size, + ) && chroot.carve_file( + ENCRYPTED_DATA_FILE_NAME, + mh01_data, + mh01_header.encrypted_data_offset, + mh01_header.encrypted_data_size, + ); + // No extraction requested, just return success + } else { + result.success = true; + } + } + } + + result +} diff --git a/src/magic.rs b/src/magic.rs index f3b5f08b1..c1f5bda8d 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -963,7 +963,7 @@ pub fn patterns() -> Vec { magic: signatures::mh01::mh01_magic(), parser: signatures::mh01::mh01_parser, description: signatures::mh01::DESCRIPTION.to_string(), - extractor: None, + extractor: Some(extractors::mh01::mh01_extractor()), }, // CSman DAT signatures::common::Signature { diff --git a/src/signatures/mh01.rs b/src/signatures/mh01.rs index 641f2c713..e3378e952 100644 --- a/src/signatures/mh01.rs +++ b/src/signatures/mh01.rs @@ -27,7 +27,7 @@ pub fn mh01_parser(file_data: &[u8], offset: usize) -> Result Date: Sat, 16 Nov 2024 18:46:07 -0500 Subject: [PATCH 071/131] Added little endian support for CSMAN DAT files --- src/extractors/csman.rs | 2 +- src/signatures/csman.rs | 3 ++- src/structures/csman.rs | 44 ++++++++++++++++++++++++++++++++--------- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/extractors/csman.rs b/src/extractors/csman.rs index 5983219b0..f7b62cf26 100644 --- a/src/extractors/csman.rs +++ b/src/extractors/csman.rs @@ -67,7 +67,7 @@ pub fn extract_csman_dat( } Some(next_entry_data) => { // Parse the next entry - match parse_csman_entry(next_entry_data) { + match parse_csman_entry(next_entry_data, &csman_header.endianness) { Err(_) => { break; } diff --git a/src/signatures/csman.rs b/src/signatures/csman.rs index be0219ed8..9328406a7 100644 --- a/src/signatures/csman.rs +++ b/src/signatures/csman.rs @@ -6,7 +6,8 @@ pub const DESCRIPTION: &str = "CSman DAT file"; /// CSMAN DAT files always start with these bytes pub fn csman_magic() -> Vec> { - vec![b"SC".to_vec()] + // Big and little endian magic + vec![b"SC".to_vec(), b"CS".to_vec()] } /// Validates the CSMAN DAT file diff --git a/src/structures/csman.rs b/src/structures/csman.rs index 29d4b5c0a..5a2ae384a 100644 --- a/src/structures/csman.rs +++ b/src/structures/csman.rs @@ -4,11 +4,14 @@ use crate::structures::common::{self, StructureError}; #[derive(Debug, Default, Clone)] pub struct CSManHeader { pub data_size: usize, + pub endianness: String, pub header_size: usize, } /// Parses a CSMAN header pub fn parse_csman_header(csman_data: &[u8]) -> Result { + const LITTLE_ENDIAN_MAGIC: usize = 0x4353; + let csman_header_structure = vec![ ("magic", "u16"), ("unknown1", "u16"), @@ -17,14 +20,32 @@ pub fn parse_csman_header(csman_data: &[u8]) -> Result Result { +pub fn parse_csman_entry( + entry_data: &[u8], + endianness: &str, +) -> Result { const EOF_TAG: usize = 0; // The last entry is just a single 4-byte NULL value @@ -58,7 +82,7 @@ pub fn parse_csman_entry(entry_data: &[u8]) -> Result Result Date: Sun, 17 Nov 2024 20:59:25 -0500 Subject: [PATCH 072/131] Added support for compressed CSMAN files --- Cargo.lock | 1 + Cargo.toml | 1 + src/extractors/csman.rs | 22 +++++++++++++++++++++- src/structures/csman.rs | 28 +++++++++++++++++++++------- 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 74b19d93c..af41cda0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -115,6 +115,7 @@ dependencies = [ "env_logger", "flate2", "log", + "miniz_oxide 0.8.0", "plotters", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index a53076486..df8b3a990 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ threadpool = "1.8.1" serde_json = "1.0" env_logger = "0.11.5" flate2 = "1.0.34" +miniz_oxide = "0.8.0" aho-corasick = "1.1.3" serde = { version = "1.0", features = ["derive"]} clap = { version = "4.5.16", features = ["derive"] } diff --git a/src/extractors/csman.rs b/src/extractors/csman.rs index f7b62cf26..c07e3b021 100644 --- a/src/extractors/csman.rs +++ b/src/extractors/csman.rs @@ -1,6 +1,7 @@ use crate::common::is_offset_safe; use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; use crate::structures::csman::{parse_csman_entry, parse_csman_header, CSManEntry}; +use miniz_oxide::inflate; use std::collections::HashMap; /// Defines the internal extractor function for CSMan DAT files @@ -38,6 +39,8 @@ pub fn extract_csman_dat( offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { + const COMPRESSED_HEADER_SIZE: usize = 2; + // Return value let mut result = ExtractionResult { ..Default::default() @@ -47,12 +50,29 @@ pub fn extract_csman_dat( // Parse the CSMAN header if let Ok(csman_header) = parse_csman_header(&file_data[offset..]) { + println!("{:?}", csman_header); // Calulate the start and end offsets of the CSMAN entries let entries_start: usize = offset + csman_header.header_size; let entries_end: usize = entries_start + csman_header.data_size; // Get the CSMAN entry data - if let Some(entry_data) = file_data.get(entries_start..entries_end) { + if let Some(raw_entry_data) = file_data.get(entries_start..entries_end) { + let mut entry_data = raw_entry_data.to_vec(); + + // If the entries are compressed, decompress it (zlib compression) + if csman_header.compressed { + if let Some(compressed_data) = raw_entry_data.get(COMPRESSED_HEADER_SIZE..) { + match inflate::decompress_to_vec(compressed_data) { + Err(_) => { + return result; + } + Ok(decompressed_data) => { + entry_data = decompressed_data.clone(); + } + } + } + } + // Offsets for processing CSMAN entries in entry_data let mut next_offset: usize = 0; let mut previous_offset = None; diff --git a/src/structures/csman.rs b/src/structures/csman.rs index 5a2ae384a..72e23ef9d 100644 --- a/src/structures/csman.rs +++ b/src/structures/csman.rs @@ -3,6 +3,7 @@ use crate::structures::common::{self, StructureError}; /// Struct to store CSMAN header info #[derive(Debug, Default, Clone)] pub struct CSManHeader { + pub compressed: bool, pub data_size: usize, pub endianness: String, pub header_size: usize, @@ -10,14 +11,15 @@ pub struct CSManHeader { /// Parses a CSMAN header pub fn parse_csman_header(csman_data: &[u8]) -> Result { + const COMPRESSED_MAGIC: &[u8] = b"\x78"; const LITTLE_ENDIAN_MAGIC: usize = 0x4353; let csman_header_structure = vec![ ("magic", "u16"), ("unknown1", "u16"), - ("data_size_1", "u32"), + ("compressed_size", "u32"), ("unknown2", "u32"), - ("data_size_2", "u32"), + ("decompressed_size", "u32"), ]; let mut result = CSManHeader { @@ -39,12 +41,24 @@ pub fn parse_csman_header(csman_data: &[u8]) -> Result Date: Sun, 17 Nov 2024 21:42:13 -0500 Subject: [PATCH 073/131] Removed debug print --- src/extractors/csman.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/extractors/csman.rs b/src/extractors/csman.rs index c07e3b021..1d7a22d60 100644 --- a/src/extractors/csman.rs +++ b/src/extractors/csman.rs @@ -50,7 +50,6 @@ pub fn extract_csman_dat( // Parse the CSMAN header if let Ok(csman_header) = parse_csman_header(&file_data[offset..]) { - println!("{:?}", csman_header); // Calulate the start and end offsets of the CSMAN entries let entries_start: usize = offset + csman_header.header_size; let entries_end: usize = entries_start + csman_header.data_size; From 5781db7815adcd31075226e8a0cb3b71e400bebe Mon Sep 17 00:00:00 2001 From: cohaereo Date: Wed, 20 Nov 2024 11:25:10 +0100 Subject: [PATCH 074/131] Added support for DirectX shader bytecode files --- src/extractors.rs | 1 + src/extractors/dxbc.rs | 59 ++++++++++++++++++++++++++++++++++++++++++ src/magic.rs | 11 ++++++++ src/signatures.rs | 1 + src/signatures/dxbc.rs | 45 ++++++++++++++++++++++++++++++++ src/structures.rs | 1 + src/structures/dxbc.rs | 56 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 174 insertions(+) create mode 100644 src/extractors/dxbc.rs create mode 100644 src/signatures/dxbc.rs create mode 100644 src/structures/dxbc.rs diff --git a/src/extractors.rs b/src/extractors.rs index 467bf4f51..d86d04ae0 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -151,6 +151,7 @@ pub mod dahua_zip; pub mod dmg; pub mod dtb; pub mod dumpifs; +pub mod dxbc; pub mod gif; pub mod gzip; pub mod inflate; diff --git a/src/extractors/dxbc.rs b/src/extractors/dxbc.rs new file mode 100644 index 000000000..5bcf82e43 --- /dev/null +++ b/src/extractors/dxbc.rs @@ -0,0 +1,59 @@ +use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; +use crate::structures::dxbc::parse_dxbc_header; + +/// Defines the internal extractor function for carving out DXBC images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::dxbc::dxbc_extractor; +/// +/// match dxbc_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` +pub fn dxbc_extractor() -> Extractor { + Extractor { + do_not_recurse: true, + utility: ExtractorType::Internal(extract_dxbc_file), + ..Default::default() + } +} + +pub fn extract_dxbc_file( + file_data: &[u8], + offset: usize, + output_directory: Option<&String>, +) -> ExtractionResult { + const OUTFILE_NAME: &str = "shader.dxbc"; + + let mut result = ExtractionResult { + ..Default::default() + }; + + if let Ok(header) = parse_dxbc_header(&file_data[offset..]) { + // Report success + result.size = Some(header.size); + result.success = true; + + // Do extraction, if requested + if output_directory.is_some() { + let chroot = Chroot::new(output_directory); + result.success = + chroot.carve_file(OUTFILE_NAME, file_data, offset, result.size.unwrap()); + } + } + + result +} diff --git a/src/magic.rs b/src/magic.rs index c1f5bda8d..9c2716d77 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -976,6 +976,17 @@ pub fn patterns() -> Vec { description: signatures::csman::DESCRIPTION.to_string(), extractor: Some(extractors::csman::csman_extractor()), }, + // DirectX ByteCode + signatures::common::Signature { + name: "dxbc".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::dxbc::dxbc_magic(), + parser: signatures::dxbc::dxbc_parser, + description: signatures::dxbc::DESCRIPTION.to_string(), + extractor: Some(extractors::dxbc::dxbc_extractor()), + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index 79955ad10..a07cdcc4a 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -127,6 +127,7 @@ pub mod deb; pub mod dlob; pub mod dmg; pub mod dtb; +pub mod dxbc; pub mod ecos; pub mod efigpt; pub mod elf; diff --git a/src/signatures/dxbc.rs b/src/signatures/dxbc.rs new file mode 100644 index 000000000..dc3769bb7 --- /dev/null +++ b/src/signatures/dxbc.rs @@ -0,0 +1,45 @@ +use crate::signatures::common::{ + SignatureError, SignatureResult, CONFIDENCE_HIGH, CONFIDENCE_MEDIUM, +}; +use crate::structures::dxbc::parse_dxbc_header; + +/// Human readable description +pub const DESCRIPTION: &str = "DirectX shader bytecode"; + +/// DXBC file magic bytes +pub fn dxbc_magic() -> Vec> { + vec![b"DXBC".to_vec()] +} + +/// Validates the DXBC header +pub fn dxbc_parser(file_data: &[u8], offset: usize) -> Result { + const CHUNK_SM4: [u8; 4] = *b"SHDR"; + const CHUNK_SM5: [u8; 4] = *b"SHEX"; + + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + if let Ok(header) = parse_dxbc_header(&file_data[offset..]) { + result.confidence = CONFIDENCE_HIGH; + result.size = header.size; + + let shader_model = if header.chunk_ids.contains(&CHUNK_SM4) { + "Shader Model 4" + } else if header.chunk_ids.contains(&CHUNK_SM5) { + "Shader Model 5" + } else { + "Unknown Shader Model" + }; + + result.description = format!("{}, {}", result.description, shader_model); + + return Ok(result); + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index fbf494184..820615382 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -111,6 +111,7 @@ pub mod deb; pub mod dlob; pub mod dmg; pub mod dtb; +pub mod dxbc; pub mod efigpt; pub mod elf; pub mod ext; diff --git a/src/structures/dxbc.rs b/src/structures/dxbc.rs new file mode 100644 index 000000000..fa7886b25 --- /dev/null +++ b/src/structures/dxbc.rs @@ -0,0 +1,56 @@ +use crate::structures::common::{self, StructureError}; + +#[derive(Debug, Default, Clone)] +pub struct DXBCHeader { + pub size: usize, + pub chunk_ids: Vec<[u8; 4]>, +} + +// http://timjones.io/blog/archive/2015/09/02/parsing-direct3d-shader-bytecode +pub fn parse_dxbc_header(data: &[u8]) -> Result { + let dxbc_header_structure = vec![ + ("magic", "u32"), + ("signature_p1", "u64"), + ("signature_p2", "u64"), + ("one", "u32"), + ("total_size", "u32"), + ("chunk_count", "u32"), + ]; + + // Parse the header + if let Ok(header) = common::parse(data, &dxbc_header_structure, "little") { + if header["one"] != 1 { + return Err(StructureError); + } + + // Sanity check: There are at least 14 known chunks, but most likely no more than 32. + // Prevents the for loop from spiraling into an OOM on the offchance that both the magic and "one" check pass on garbage data + if header["chunk_count"] > 32 { + return Err(StructureError); + } + + let header_end = common::size(&dxbc_header_structure); + + let mut chunk_ids = vec![]; + for i in 0..header["chunk_count"] { + let offset_data = data + .get((header_end + i * 4)..(header_end + i * 4) + 4) + .ok_or(StructureError)?; + let offset = u32::from_le_bytes(offset_data.try_into().unwrap()) as usize; + + chunk_ids.push( + data.get(offset..offset + 4) + .ok_or(StructureError)? + .try_into() + .unwrap(), + ); + } + + return Ok(DXBCHeader { + size: header["total_size"], + chunk_ids, + }); + } + + Err(StructureError) +} From eddfe537a602a94a05186ab9ead6f6d23d255bad Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 20 Nov 2024 11:01:17 -0500 Subject: [PATCH 075/131] Improved JPEG end-of-file detection --- src/extractors/jpeg.rs | 98 ++++++++++++++++++++++++++++++++++++------ src/signatures/jpeg.rs | 13 +++--- 2 files changed, 93 insertions(+), 18 deletions(-) diff --git a/src/extractors/jpeg.rs b/src/extractors/jpeg.rs index 99c5d6e0c..2c4e2604d 100644 --- a/src/extractors/jpeg.rs +++ b/src/extractors/jpeg.rs @@ -1,5 +1,4 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; -use aho_corasick::AhoCorasick; /// Defines the internal extractor function for carving out JPEG images /// @@ -58,22 +57,97 @@ pub fn extract_jpeg_image( result } +/// Parses JPEG markers until the EOF marker is found fn get_jpeg_data_size(jpeg_data: &[u8]) -> Option { - const EOF_SIZE: usize = 2; - const JPEG_DELIM: u8 = 0xFF; + const SIZE_FIELD_LENGTH: usize = 2; + const SOS_SCAN_AHEAD_LENGTH: usize = 2; + const MARKER_MAGIC: u8 = 0xFF; + const SOS_MARKER: u8 = 0xDA; + const EOF_MARKER: u8 = 0xD9; - // This is a short EOF marker to search for, but in a valid JPEG it *should* only occur at EOF - let grep = AhoCorasick::new(vec![b"\xFF\xD9"]).unwrap(); + let mut next_marker_offset: usize = 0; - for eof_match in grep.find_overlapping_iter(jpeg_data) { - let eof_candidate: usize = eof_match.start() + EOF_SIZE; + // Most JPEG markers include a size field; these do not + let no_length_markers: Vec = vec![ + 0x00, 0x01, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, EOF_MARKER, + ]; - // Make sure the expected EOF marker is not immediately followed by 0xFF (which would indicate the JPEG continues...) - if eof_candidate < jpeg_data.len() && jpeg_data[eof_candidate] == JPEG_DELIM { - continue; - } + // In a Start Of Scan block, ignore 0xFF marker magics that are followed by one of these bytes + let sos_skip_markers: Vec = vec![0x00, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7]; + + loop { + // Read the marker magic byte + match jpeg_data.get(next_marker_offset) { + None => { + break; + } + Some(marker_magic) => { + // Make sure this is the correct marker magic + if *marker_magic != MARKER_MAGIC { + break; + } + + // Include marker magic byte in side of the marker + next_marker_offset += 1; + + // Read the marker ID byte + match jpeg_data.get(next_marker_offset) { + None => { + break; + } + Some(marker_id) => { + // Include marker ID byte in the size of the marker + next_marker_offset += 1; - return Some(eof_match.start() + EOF_SIZE); + // Most markers have a 2-byte length field after the marker, stored in big-endian + if !no_length_markers.contains(marker_id) { + match jpeg_data + .get(next_marker_offset..next_marker_offset + SIZE_FIELD_LENGTH) + { + None => { + break; + } + Some(size_bytes) => { + next_marker_offset += + u16::from_be_bytes(size_bytes.try_into().unwrap()) as usize; + } + } + } + + // Start Of Scan markers have a size field, but are immediately followed by data not included int + // the size field. Need to scan all the bytes until the next valid JPEG marker is found. + if *marker_id == SOS_MARKER { + loop { + // Get the next two bytes + match jpeg_data.get( + next_marker_offset..next_marker_offset + SOS_SCAN_AHEAD_LENGTH, + ) { + None => { + break; + } + Some(next_bytes) => { + // Check if the next byte is a marker magic byte, *and* that it is not followed by a marker escape byte + if next_bytes[0] == MARKER_MAGIC + && !sos_skip_markers.contains(&next_bytes[1]) + { + break; + } else { + // Go to the next byte + next_marker_offset += 1; + } + } + } + } + } + + // EOF marker indicates the end of the JPEG image + if *marker_id == EOF_MARKER { + return Some(next_marker_offset); + } + } + } + } + } } None diff --git a/src/signatures/jpeg.rs b/src/signatures/jpeg.rs index ebf4aa30f..377997c3b 100644 --- a/src/signatures/jpeg.rs +++ b/src/signatures/jpeg.rs @@ -32,15 +32,16 @@ pub fn jpeg_parser(file_data: &[u8], offset: usize) -> Result Date: Wed, 20 Nov 2024 19:43:49 -0500 Subject: [PATCH 076/131] Added JPEG test --- tests/common/mod.rs | 29 +++++++++++++++++++++-------- tests/jpeg.rs | 13 +++++++++++++ tests/pdf.rs | 7 ++++++- 3 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 tests/jpeg.rs diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 98d056f24..e650893b1 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,18 +1,31 @@ use binwalk::{AnalysisResults, Binwalk}; -/// Run an integration test against the specified file, with the provided signature filter +/// Convenience function for running an integration test against the specified file, with the provided signature filter. +/// Assumes that there will be one signature result and one extraction result at file offset 0. +#[allow(dead_code)] pub fn integration_test(signature_filter: &str, file_name: &str) { + let expected_signature_offsets: Vec = vec![0]; + let expected_extraction_offsets: Vec = vec![0]; + // Run binwalk, get analysis/extraction results let results = run_binwalk(signature_filter, file_name); - // Each test is expected to have a single result at offset 0 in the file - assert!(results.file_map.len() == 1); - assert!(results.file_map[0].offset == 0); + // Assert that there was a valid signature and successful result at, and only at, file offset 0 + assert_results_ok(results, expected_signature_offsets, expected_extraction_offsets); +} + +/// Assert that there was a valid signature match and corresponding extraction at, and only at, the specified file offsets +pub fn assert_results_ok(results: AnalysisResults, signature_offsets: Vec, extraction_offsets: Vec) { + // Assert that the number of signature results and extractions match the expected results + assert!(results.file_map.len() == signature_offsets.len()); + assert!(results.extractions.len() == extraction_offsets.len()); - // Tests which support extraction are expected to have a single successful extraction - if !results.extractions.is_empty() { - assert!(results.extractions.len() == 1); - assert!(results.extractions[&results.file_map[0].id].success); + // Assert that each signature match was at an expected offset and that extraction, if expected, was successful + for signature_result in results.file_map { + assert!(signature_offsets.contains(&signature_result.offset)); + if extraction_offsets.contains(&signature_result.offset) { + assert!(results.extractions[&signature_result.id].success); + } } } diff --git a/tests/jpeg.rs b/tests/jpeg.rs new file mode 100644 index 000000000..d62349d0a --- /dev/null +++ b/tests/jpeg.rs @@ -0,0 +1,13 @@ +mod common; + +#[test] +fn integration_test() { + const SIGNATURE_TYPE: &str = "jpeg"; + const INPUT_FILE_NAME: &str = "jpeg.bin"; + + let expected_signature_offsets: Vec = vec![0, 0x15BBE]; + let expected_extraction_offsets: Vec = vec![0, 0x15BBE]; + + let results = common::run_binwalk(SIGNATURE_TYPE, INPUT_FILE_NAME); + common::assert_results_ok(results, expected_signature_offsets, expected_extraction_offsets); +} diff --git a/tests/pdf.rs b/tests/pdf.rs index 1b7659509..4c6c3566a 100644 --- a/tests/pdf.rs +++ b/tests/pdf.rs @@ -4,5 +4,10 @@ mod common; fn integration_test() { const SIGNATURE_TYPE: &str = "pdf"; const INPUT_FILE_NAME: &str = "pdf.bin"; - common::integration_test(SIGNATURE_TYPE, INPUT_FILE_NAME); + + let expected_signature_offsets: Vec = vec![0]; + let expected_extraction_offsets: Vec = vec![]; + + let results = common::run_binwalk(SIGNATURE_TYPE, INPUT_FILE_NAME); + common::assert_results_ok(results, expected_signature_offsets, expected_extraction_offsets); } From 1cb781f801b856243e94cf0e53065d1c17b1af0c Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 20 Nov 2024 19:58:38 -0500 Subject: [PATCH 077/131] Added JPEG test input file --- tests/inputs/jpeg.bin | Bin 0 -> 103595 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/inputs/jpeg.bin diff --git a/tests/inputs/jpeg.bin b/tests/inputs/jpeg.bin new file mode 100644 index 0000000000000000000000000000000000000000..df65e11269eba2564ac520eee3850127e78fa09e GIT binary patch literal 103595 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 XZ4ByvrwVTN+W86}Wr9=@-k1Lu`QCbN literal 0 HcmV?d00001 From 1674a3a520e6d6a6da6f915d931cbedada40c825 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 20 Nov 2024 20:50:12 -0500 Subject: [PATCH 078/131] Added --carve command line option --- src/binwalk.rs | 31 +++++++++++++++++++++++++++++++ src/cliparser.rs | 4 ++++ src/main.rs | 8 ++++++++ 3 files changed, 43 insertions(+) diff --git a/src/binwalk.rs b/src/binwalk.rs index ca201a779..c500fdea0 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -714,6 +714,37 @@ impl Binwalk { results } + + /// Carve signatures identified during analysis to separate files on disk + pub fn carve(&self, results: &AnalysisResults) -> bool { + if !results.file_map.is_empty() { + if let Ok(file_data) = read_file(&results.file_path) { + let chroot = extractors::common::Chroot::new(None); + + for signature_result in &results.file_map { + let carved_file_path = format!( + "{}_{:X}-{:X}.carved", + results.file_path, + signature_result.offset, + signature_result.offset + signature_result.size + ); + debug!("Carving {}", carved_file_path); + if !chroot.carve_file( + &carved_file_path, + &file_data, + signature_result.offset, + signature_result.size, + ) { + return false; + } + } + + return true; + } + } + + false + } } /// Initializes the extraction output directory diff --git a/src/cliparser.rs b/src/cliparser.rs index e2aad1130..a8839f70c 100644 --- a/src/cliparser.rs +++ b/src/cliparser.rs @@ -19,6 +19,10 @@ pub struct CliArgs { #[arg(short, long)] pub extract: bool, + /// Carve raw file data to disk during extraction + #[arg(short, long)] + pub carve: bool, + /// Recursively scan extracted files #[arg(short = 'M', long)] pub matryoshka: bool, diff --git a/src/main.rs b/src/main.rs index 69d78d45a..6817af6d9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -162,6 +162,7 @@ fn main() { binwalker.clone(), target_file, cliargs.extract, + cliargs.carve, worker_tx.clone(), ); } @@ -267,11 +268,18 @@ fn spawn_worker( bw: binwalk::Binwalk, target_file: String, do_extraction: bool, + do_carve: bool, worker_tx: mpsc::Sender, ) { pool.execute(move || { // Analyze target file, with extraction, if specified let results = bw.analyze(&target_file, do_extraction); + + // If data carving was requested as part of extraction, carve analysis results to disk + if do_extraction && do_carve && !bw.carve(&results) { + error!("Failed to carve raw data to disk"); + } + // Report file results back to main thread if let Err(e) = worker_tx.send(results) { panic!( From 11df2c68b607fef2eb24b3c25a6a6808ea5ae4ed Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 20 Nov 2024 22:12:12 -0500 Subject: [PATCH 079/131] Changed carved file naming convention; added carving of unknown data blocks --- src/binwalk.rs | 86 ++++++++++++++++++++++++++++++++++++++++---------- src/main.rs | 4 +-- 2 files changed, 72 insertions(+), 18 deletions(-) diff --git a/src/binwalk.rs b/src/binwalk.rs index c500fdea0..81c695cf5 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -715,38 +715,92 @@ impl Binwalk { results } - /// Carve signatures identified during analysis to separate files on disk - pub fn carve(&self, results: &AnalysisResults) -> bool { + /// Carve signatures identified during analysis to separate files on disk. + /// Returns the number of carved files created. + /// Note that unknown blocks of file data are also carved to disk, so the number of files + /// created may be larger than the number of results defined in results.file_map. + pub fn carve(&self, results: &AnalysisResults) -> usize { + let mut carve_count: usize = 0; + let mut last_known_offset: usize = 0; + let mut unknown_bytes: Vec<(usize, usize)> = Vec::new(); + + // No results, don't do anything if !results.file_map.is_empty() { + // Read in the source file if let Ok(file_data) = read_file(&results.file_path) { - let chroot = extractors::common::Chroot::new(None); - + // Loop through all identified signatures in the file for signature_result in &results.file_map { - let carved_file_path = format!( - "{}_{:X}-{:X}.carved", - results.file_path, - signature_result.offset, - signature_result.offset + signature_result.size - ); - debug!("Carving {}", carved_file_path); - if !chroot.carve_file( - &carved_file_path, + // If there is data between the last signature and this signature, it is some chunk of unknown data + if signature_result.offset > last_known_offset { + unknown_bytes.push(( + last_known_offset, + signature_result.offset - last_known_offset, + )); + } + + // Carve this signature's data to disk + if carve_file_data_to_disk( + &results.file_path, &file_data, + &signature_result.name, signature_result.offset, signature_result.size, ) { - return false; + carve_count += 1; } + + // Update the last known offset to the end of this signature's data + last_known_offset = signature_result.offset + signature_result.size; } - return true; + // All known signature data has been carved to disk, now carve any unknown blocks of data to disk + for (offset, size) in unknown_bytes { + if carve_file_data_to_disk( + &results.file_path, + &file_data, + "unknown", + offset, + size, + ) { + carve_count += 1; + } + } } } - false + carve_count } } +/// Carves a block of file data to a new file on disk +fn carve_file_data_to_disk( + source_file_path: &str, + file_data: &[u8], + name: &str, + offset: usize, + size: usize, +) -> bool { + let chroot = extractors::common::Chroot::new(None); + + // Carved file path will be: __.raw + let carved_file_path = format!("{}_{}_{}.raw", source_file_path, offset, name,); + + debug!("Carving {}", carved_file_path); + + // Carve the data to disk + if !chroot.carve_file(&carved_file_path, file_data, offset, size) { + error!( + "Failed to carve {} [{:#X}..{:#X}] to disk", + carved_file_path, + offset, + offset + size, + ); + return false; + } + + true +} + /// Initializes the extraction output directory fn init_extraction_directory( target_file: &String, diff --git a/src/main.rs b/src/main.rs index 6817af6d9..715d1a992 100644 --- a/src/main.rs +++ b/src/main.rs @@ -276,8 +276,8 @@ fn spawn_worker( let results = bw.analyze(&target_file, do_extraction); // If data carving was requested as part of extraction, carve analysis results to disk - if do_extraction && do_carve && !bw.carve(&results) { - error!("Failed to carve raw data to disk"); + if do_extraction && do_carve { + let _ = bw.carve(&results); } // Report file results back to main thread From 485101ef849522dc25261d6c1d65915f05773635 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 20 Nov 2024 22:17:11 -0500 Subject: [PATCH 080/131] Fixed code formatting in tests --- tests/common/mod.rs | 12 ++++++++++-- tests/jpeg.rs | 6 +++++- tests/pdf.rs | 6 +++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/tests/common/mod.rs b/tests/common/mod.rs index e650893b1..0ff9a99a9 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -11,11 +11,19 @@ pub fn integration_test(signature_filter: &str, file_name: &str) { let results = run_binwalk(signature_filter, file_name); // Assert that there was a valid signature and successful result at, and only at, file offset 0 - assert_results_ok(results, expected_signature_offsets, expected_extraction_offsets); + assert_results_ok( + results, + expected_signature_offsets, + expected_extraction_offsets, + ); } /// Assert that there was a valid signature match and corresponding extraction at, and only at, the specified file offsets -pub fn assert_results_ok(results: AnalysisResults, signature_offsets: Vec, extraction_offsets: Vec) { +pub fn assert_results_ok( + results: AnalysisResults, + signature_offsets: Vec, + extraction_offsets: Vec, +) { // Assert that the number of signature results and extractions match the expected results assert!(results.file_map.len() == signature_offsets.len()); assert!(results.extractions.len() == extraction_offsets.len()); diff --git a/tests/jpeg.rs b/tests/jpeg.rs index d62349d0a..a594607d5 100644 --- a/tests/jpeg.rs +++ b/tests/jpeg.rs @@ -9,5 +9,9 @@ fn integration_test() { let expected_extraction_offsets: Vec = vec![0, 0x15BBE]; let results = common::run_binwalk(SIGNATURE_TYPE, INPUT_FILE_NAME); - common::assert_results_ok(results, expected_signature_offsets, expected_extraction_offsets); + common::assert_results_ok( + results, + expected_signature_offsets, + expected_extraction_offsets, + ); } diff --git a/tests/pdf.rs b/tests/pdf.rs index 4c6c3566a..e7d914988 100644 --- a/tests/pdf.rs +++ b/tests/pdf.rs @@ -9,5 +9,9 @@ fn integration_test() { let expected_extraction_offsets: Vec = vec![]; let results = common::run_binwalk(SIGNATURE_TYPE, INPUT_FILE_NAME); - common::assert_results_ok(results, expected_signature_offsets, expected_extraction_offsets); + common::assert_results_ok( + results, + expected_signature_offsets, + expected_extraction_offsets, + ); } From f96488a258991c19d96511d55669e538d46b7fba Mon Sep 17 00:00:00 2001 From: devttys0 Date: Thu, 21 Nov 2024 13:04:46 -0500 Subject: [PATCH 081/131] Move --carve code out of binwalk.rs and into main.rs; support carving even if extraction was not requested --- src/binwalk.rs | 85 ------------------------------------------- src/cliparser.rs | 2 +- src/main.rs | 94 +++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 90 insertions(+), 91 deletions(-) diff --git a/src/binwalk.rs b/src/binwalk.rs index 81c695cf5..ca201a779 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -714,91 +714,6 @@ impl Binwalk { results } - - /// Carve signatures identified during analysis to separate files on disk. - /// Returns the number of carved files created. - /// Note that unknown blocks of file data are also carved to disk, so the number of files - /// created may be larger than the number of results defined in results.file_map. - pub fn carve(&self, results: &AnalysisResults) -> usize { - let mut carve_count: usize = 0; - let mut last_known_offset: usize = 0; - let mut unknown_bytes: Vec<(usize, usize)> = Vec::new(); - - // No results, don't do anything - if !results.file_map.is_empty() { - // Read in the source file - if let Ok(file_data) = read_file(&results.file_path) { - // Loop through all identified signatures in the file - for signature_result in &results.file_map { - // If there is data between the last signature and this signature, it is some chunk of unknown data - if signature_result.offset > last_known_offset { - unknown_bytes.push(( - last_known_offset, - signature_result.offset - last_known_offset, - )); - } - - // Carve this signature's data to disk - if carve_file_data_to_disk( - &results.file_path, - &file_data, - &signature_result.name, - signature_result.offset, - signature_result.size, - ) { - carve_count += 1; - } - - // Update the last known offset to the end of this signature's data - last_known_offset = signature_result.offset + signature_result.size; - } - - // All known signature data has been carved to disk, now carve any unknown blocks of data to disk - for (offset, size) in unknown_bytes { - if carve_file_data_to_disk( - &results.file_path, - &file_data, - "unknown", - offset, - size, - ) { - carve_count += 1; - } - } - } - } - - carve_count - } -} - -/// Carves a block of file data to a new file on disk -fn carve_file_data_to_disk( - source_file_path: &str, - file_data: &[u8], - name: &str, - offset: usize, - size: usize, -) -> bool { - let chroot = extractors::common::Chroot::new(None); - - // Carved file path will be: __.raw - let carved_file_path = format!("{}_{}_{}.raw", source_file_path, offset, name,); - - debug!("Carving {}", carved_file_path); - - // Carve the data to disk - if !chroot.carve_file(&carved_file_path, file_data, offset, size) { - error!( - "Failed to carve {} [{:#X}..{:#X}] to disk", - carved_file_path, - offset, - offset + size, - ); - return false; - } - - true } /// Initializes the extraction output directory diff --git a/src/cliparser.rs b/src/cliparser.rs index a8839f70c..9382ba734 100644 --- a/src/cliparser.rs +++ b/src/cliparser.rs @@ -19,7 +19,7 @@ pub struct CliArgs { #[arg(short, long)] pub extract: bool, - /// Carve raw file data to disk during extraction + /// Carve both known and unknown file contents to disk #[arg(short, long)] pub carve: bool, diff --git a/src/main.rs b/src/main.rs index 715d1a992..96d3fff7c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -83,8 +83,8 @@ fn main() { return; } - // If extraction was requested, we need to initialize the output directory - if cliargs.extract { + // If extraction or data carving was requested, we need to initialize the output directory + if cliargs.extract || cliargs.carve { output_directory = Some(cliargs.directory); } @@ -220,7 +220,7 @@ fn main() { } // If BINWALK_RM_SYMLINK env var was set, delete the base_target_file symlink - if cliargs.extract && std::env::var(BINWALK_RM_SYMLINK).is_ok() { + if (cliargs.carve || cliargs.extract) && std::env::var(BINWALK_RM_SYMLINK).is_ok() { if let Err(e) = std::fs::remove_file(&binwalker.base_target_file) { error!( "Request to remove extraction symlink file {} failed: {}", @@ -276,8 +276,12 @@ fn spawn_worker( let results = bw.analyze(&target_file, do_extraction); // If data carving was requested as part of extraction, carve analysis results to disk - if do_extraction && do_carve { - let _ = bw.carve(&results); + if do_carve { + let carve_count = carve_file_map(&results); + info!( + "Carved {} data blocks to disk from {}", + carve_count, target_file + ); } // Report file results back to main thread @@ -288,3 +292,83 @@ fn spawn_worker( } }); } + +/// Carve signatures identified during analysis to separate files on disk. +/// Returns the number of carved files created. +/// Note that unknown blocks of file data are also carved to disk, so the number of files +/// created may be larger than the number of results defined in results.file_map. +fn carve_file_map(results: &binwalk::AnalysisResults) -> usize { + let mut carve_count: usize = 0; + let mut last_known_offset: usize = 0; + let mut unknown_bytes: Vec<(usize, usize)> = Vec::new(); + + // No results, don't do anything + if !results.file_map.is_empty() { + // Read in the source file + if let Ok(file_data) = common::read_file(&results.file_path) { + // Loop through all identified signatures in the file + for signature_result in &results.file_map { + // If there is data between the last signature and this signature, it is some chunk of unknown data + if signature_result.offset > last_known_offset { + unknown_bytes.push(( + last_known_offset, + signature_result.offset - last_known_offset, + )); + } + + // Carve this signature's data to disk + if carve_file_data_to_disk( + &results.file_path, + &file_data, + &signature_result.name, + signature_result.offset, + signature_result.size, + ) { + carve_count += 1; + } + + // Update the last known offset to the end of this signature's data + last_known_offset = signature_result.offset + signature_result.size; + } + + // All known signature data has been carved to disk, now carve any unknown blocks of data to disk + for (offset, size) in unknown_bytes { + if carve_file_data_to_disk(&results.file_path, &file_data, "unknown", offset, size) + { + carve_count += 1; + } + } + } + } + + carve_count +} + +/// Carves a block of file data to a new file on disk +fn carve_file_data_to_disk( + source_file_path: &str, + file_data: &[u8], + name: &str, + offset: usize, + size: usize, +) -> bool { + let chroot = extractors::common::Chroot::new(None); + + // Carved file path will be: __.raw + let carved_file_path = format!("{}_{}_{}.raw", source_file_path, offset, name,); + + debug!("Carving {}", carved_file_path); + + // Carve the data to disk + if !chroot.carve_file(&carved_file_path, file_data, offset, size) { + error!( + "Failed to carve {} [{:#X}..{:#X}] to disk", + carved_file_path, + offset, + offset + size, + ); + return false; + } + + true +} From 66b2d83e974d231454a2eb62147e939ab57f02f6 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Thu, 21 Nov 2024 15:44:43 -0500 Subject: [PATCH 082/131] Added support for identifying and validationg D-Link TLV formatted firmware headers --- Cargo.lock | 7 ++++ Cargo.toml | 1 + src/magic.rs | 11 +++++++ src/signatures.rs | 1 + src/signatures/dlink_tlv.rs | 55 +++++++++++++++++++++++++++++++ src/structures.rs | 1 + src/structures/dlink_tlv.rs | 66 +++++++++++++++++++++++++++++++++++++ 7 files changed, 142 insertions(+) create mode 100644 src/signatures/dlink_tlv.rs create mode 100644 src/structures/dlink_tlv.rs diff --git a/Cargo.lock b/Cargo.lock index af41cda0a..b7969da81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -115,6 +115,7 @@ dependencies = [ "env_logger", "flate2", "log", + "md5", "miniz_oxide 0.8.0", "plotters", "serde", @@ -656,6 +657,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + [[package]] name = "memchr" version = "2.7.4" diff --git a/Cargo.toml b/Cargo.toml index df8b3a990..06d2cd3bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ threadpool = "1.8.1" serde_json = "1.0" env_logger = "0.11.5" flate2 = "1.0.34" +md5 = "0.7.0" miniz_oxide = "0.8.0" aho-corasick = "1.1.3" serde = { version = "1.0", features = ["derive"]} diff --git a/src/magic.rs b/src/magic.rs index 9c2716d77..1277c5370 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -987,6 +987,17 @@ pub fn patterns() -> Vec { description: signatures::dxbc::DESCRIPTION.to_string(), extractor: Some(extractors::dxbc::dxbc_extractor()), }, + // D-Link TLV firmware + signatures::common::Signature { + name: "dlink_tlv".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::dlink_tlv::dlink_tlv_magic(), + parser: signatures::dlink_tlv::dlink_tlv_parser, + description: signatures::dlink_tlv::DESCRIPTION.to_string(), + extractor: None, + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index a07cdcc4a..298897604 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -124,6 +124,7 @@ pub mod cramfs; pub mod csman; pub mod dahua_zip; pub mod deb; +pub mod dlink_tlv; pub mod dlob; pub mod dmg; pub mod dtb; diff --git a/src/signatures/dlink_tlv.rs b/src/signatures/dlink_tlv.rs new file mode 100644 index 000000000..d4234bb83 --- /dev/null +++ b/src/signatures/dlink_tlv.rs @@ -0,0 +1,55 @@ +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; +use crate::structures::dlink_tlv::parse_dlink_tlv_header; + +/// Human readable description +pub const DESCRIPTION: &str = "D-Link TLV firmware"; + +/// TLV firmware images always start with these bytes +pub fn dlink_tlv_magic() -> Vec> { + vec![b"\x64\x80\x19\x40".to_vec()] +} + +/// Validates the TLV header +pub fn dlink_tlv_parser( + file_data: &[u8], + offset: usize, +) -> Result { + // Checksum calculation includes the 8-byte header that preceeds the actual payload data + const CHECKSUM_OFFSET: usize = 8; + + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_HIGH, + ..Default::default() + }; + + // Parse the header + if let Ok(tlv_header) = parse_dlink_tlv_header(&file_data[offset..]) { + // Calculate the start and end offsets for the payload data over which the checksum is calculated + let data_start = offset + tlv_header.header_size - CHECKSUM_OFFSET; + let data_end = data_start + tlv_header.data_size + CHECKSUM_OFFSET; + + // Get the payload data and calculate the MD5 hash + if let Some(payload_data) = file_data.get(data_start..data_end) { + let payload_md5 = format!("{:x}", md5::compute(payload_data)); + + // Make sure the MD5 hashes match + if payload_md5 == tlv_header.data_checksum { + result.size = tlv_header.header_size; + result.description = format!( + "{}, model name: {}, board ID: {}, header size: {} bytes, data size: {} bytes", + result.description, + tlv_header.model_name, + tlv_header.board_id, + tlv_header.header_size, + tlv_header.data_size, + ); + return Ok(result); + } + } + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index 820615382..6cd72f067 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -108,6 +108,7 @@ pub mod cpio; pub mod cramfs; pub mod csman; pub mod deb; +pub mod dlink_tlv; pub mod dlob; pub mod dmg; pub mod dtb; diff --git a/src/structures/dlink_tlv.rs b/src/structures/dlink_tlv.rs new file mode 100644 index 000000000..6e7b5bf9c --- /dev/null +++ b/src/structures/dlink_tlv.rs @@ -0,0 +1,66 @@ +use crate::common::get_cstring; +use crate::structures::common::{self, StructureError}; + +/// Struct to store DLink TLV firmware header info +#[derive(Debug, Default, Clone)] +pub struct DlinkTLVHeader { + pub model_name: String, + pub board_id: String, + pub header_size: usize, + pub data_size: usize, + pub data_checksum: String, +} + +/// Parses a DLink TLV firmware header +pub fn parse_dlink_tlv_header(tlv_data: &[u8]) -> Result { + const MAX_STRING_LENGTH: usize = 0x20; + + const MODEL_NAME_OFFSET: usize = 4; + const BOARD_ID_OFFSET: usize = 0x24; + const MD5_HASH_OFFSET: usize = 0x4C; + const DATA_TLV_OFFSET: usize = 0x6C; + + const HEADER_SIZE: usize = 0x74; + const EXPECTED_DATA_TYPE: usize = 1; + + let tlv_structure = vec![ + ("type", "u32"), + ("length", "u32"), + // value immediately follows + ]; + + let mut header = DlinkTLVHeader { + ..Default::default() + }; + + // Get the header data + if let Some(header_data) = tlv_data.get(0..HEADER_SIZE) { + // Get the strings from the header + header.board_id = + get_cstring(&header_data[BOARD_ID_OFFSET..BOARD_ID_OFFSET + MAX_STRING_LENGTH]); + header.model_name = + get_cstring(&header_data[MODEL_NAME_OFFSET..MODEL_NAME_OFFSET + MAX_STRING_LENGTH]); + header.data_checksum = + get_cstring(&header_data[MD5_HASH_OFFSET..MD5_HASH_OFFSET + MAX_STRING_LENGTH]); + + // Make sure we got the expected strings OK + if !header.model_name.is_empty() + && !header.board_id.is_empty() + && !header.data_checksum.is_empty() + { + // Parse the type and length values that describe the data the follows the header + if let Ok(data_tlv) = + common::parse(&header_data[DATA_TLV_OFFSET..], &tlv_structure, "little") + { + // Sanity check the reported type (should be 1) + if data_tlv["type"] == EXPECTED_DATA_TYPE { + header.data_size = data_tlv["length"]; + header.header_size = HEADER_SIZE; + return Ok(header); + } + } + } + } + + Err(StructureError) +} From 8d61b239bcab45a6b62e41fc24015b2b8dd37a9d Mon Sep 17 00:00:00 2001 From: devttys0 Date: Thu, 21 Nov 2024 21:05:23 -0500 Subject: [PATCH 083/131] Added dlink_tlv file carver; updated signature to report encrypted firmware --- src/extractors.rs | 1 + src/extractors/dlink_tlv.rs | 66 +++++++++++++++++++++++++++++++++++++ src/magic.rs | 2 +- src/signatures/dlink_tlv.rs | 12 ++++++- 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 src/extractors/dlink_tlv.rs diff --git a/src/extractors.rs b/src/extractors.rs index d86d04ae0..efff7df89 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -148,6 +148,7 @@ pub mod cab; pub mod common; pub mod csman; pub mod dahua_zip; +pub mod dlink_tlv; pub mod dmg; pub mod dtb; pub mod dumpifs; diff --git a/src/extractors/dlink_tlv.rs b/src/extractors/dlink_tlv.rs new file mode 100644 index 000000000..3520d42db --- /dev/null +++ b/src/extractors/dlink_tlv.rs @@ -0,0 +1,66 @@ +use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; +use crate::structures::dlink_tlv::parse_dlink_tlv_header; + +/// Defines the internal extractor function for carving out D-Link TLV firmware images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::dlink_tlv::dlink_tlv_extractor; +/// +/// match dlink_tlv_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` +pub fn dlink_tlv_extractor() -> Extractor { + Extractor { + utility: ExtractorType::Internal(extract_dlink_tlv_image), + ..Default::default() + } +} + +/// Internal extractor for carve pieces of D-Link TLV images to disk +pub fn extract_dlink_tlv_image( + file_data: &[u8], + offset: usize, + output_directory: Option<&String>, +) -> ExtractionResult { + const OUTPUT_FILE_NAME: &str = "image.bin"; + + let mut result = ExtractionResult { + ..Default::default() + }; + + // Get the D-Link TLV image data + if let Some(tlv_data) = file_data.get(offset..) { + // Parse the TLV header + if let Ok(tlv_header) = parse_dlink_tlv_header(tlv_data) { + result.success = true; + result.size = Some(tlv_header.header_size + tlv_header.data_size); + + // If extraction was requested, do it + if output_directory.is_some() { + let chroot = Chroot::new(output_directory); + result.success = chroot.carve_file( + OUTPUT_FILE_NAME, + tlv_data, + tlv_header.header_size, + tlv_header.data_size, + ); + } + } + } + + result +} diff --git a/src/magic.rs b/src/magic.rs index 1277c5370..772e69071 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -996,7 +996,7 @@ pub fn patterns() -> Vec { magic: signatures::dlink_tlv::dlink_tlv_magic(), parser: signatures::dlink_tlv::dlink_tlv_parser, description: signatures::dlink_tlv::DESCRIPTION.to_string(), - extractor: None, + extractor: Some(extractors::dlink_tlv::dlink_tlv_extractor()), }, ]; diff --git a/src/signatures/dlink_tlv.rs b/src/signatures/dlink_tlv.rs index d4234bb83..5ef318a44 100644 --- a/src/signatures/dlink_tlv.rs +++ b/src/signatures/dlink_tlv.rs @@ -1,4 +1,5 @@ use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; +use crate::signatures::openssl::openssl_crypt_parser; use crate::structures::dlink_tlv::parse_dlink_tlv_header; /// Human readable description @@ -37,7 +38,7 @@ pub fn dlink_tlv_parser( // Make sure the MD5 hashes match if payload_md5 == tlv_header.data_checksum { - result.size = tlv_header.header_size; + result.size = tlv_header.header_size + tlv_header.data_size; result.description = format!( "{}, model name: {}, board ID: {}, header size: {} bytes, data size: {} bytes", result.description, @@ -46,6 +47,15 @@ pub fn dlink_tlv_parser( tlv_header.header_size, tlv_header.data_size, ); + + // Check if the firmware data is OpenSSL encrypted + if let Some(crypt_data) = file_data.get(offset + tlv_header.header_size..) { + if let Ok(openssl_signature) = openssl_crypt_parser(crypt_data, 0) { + result.description = + format!("{}, {}", result.description, openssl_signature.description); + } + } + return Ok(result); } } From daccc336f1d270160321718189f258685a5a3683 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 22 Nov 2024 07:11:40 -0500 Subject: [PATCH 084/131] Added DLKE firmware signature and file carver --- src/extractors.rs | 1 + src/extractors/dlke.rs | 86 +++++++++++++++++++++++++++++++++++++++++ src/magic.rs | 11 ++++++ src/signatures.rs | 1 + src/signatures/dlke.rs | 47 ++++++++++++++++++++++ src/structures/jboot.rs | 10 ++--- 6 files changed, 151 insertions(+), 5 deletions(-) create mode 100644 src/extractors/dlke.rs create mode 100644 src/signatures/dlke.rs diff --git a/src/extractors.rs b/src/extractors.rs index efff7df89..54345bfe9 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -149,6 +149,7 @@ pub mod common; pub mod csman; pub mod dahua_zip; pub mod dlink_tlv; +pub mod dlke; pub mod dmg; pub mod dtb; pub mod dumpifs; diff --git a/src/extractors/dlke.rs b/src/extractors/dlke.rs new file mode 100644 index 000000000..31c8dfe21 --- /dev/null +++ b/src/extractors/dlke.rs @@ -0,0 +1,86 @@ +use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; +use crate::structures::jboot::parse_jboot_arm_header; + +/// Defines the internal extractor function for carving out D-Link TLV firmware images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::dlke::dlke_extractor; +/// +/// match dlke_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` +pub fn dlke_extractor() -> Extractor { + Extractor { + utility: ExtractorType::Internal(extract_dlke_image), + ..Default::default() + } +} + +/// Internal extractor for carve pieces of encrypted DLKE firmware images to disk +pub fn extract_dlke_image( + file_data: &[u8], + offset: usize, + output_directory: Option<&String>, +) -> ExtractionResult { + const ENCRYPTED_FILE_NAME: &str = "encrypted.bin"; + const SIGNATURE_FILE_NAME: &str = "signature.bin"; + + let mut result = ExtractionResult { + ..Default::default() + }; + + // Parse the first header, which describes the size of the firmware signature + if let Some(dlke_sig_header_data) = file_data.get(offset..) { + if let Ok(dlke_signature_header) = parse_jboot_arm_header(dlke_sig_header_data) { + // Second header should immediately follow the first + if let Some(dlke_crypt_header_data) = file_data + .get(offset + dlke_signature_header.header_size + dlke_signature_header.data_size..) + { + // Parse the second header, which describes the size of the encrypted data + if let Ok(dlke_crypt_header) = parse_jboot_arm_header(dlke_crypt_header_data) { + result.success = true; + result.size = Some( + dlke_signature_header.header_size + + dlke_signature_header.data_size + + dlke_crypt_header.header_size + + dlke_crypt_header.data_size, + ); + + if output_directory.is_some() { + let chroot = Chroot::new(output_directory); + + if !chroot.carve_file( + SIGNATURE_FILE_NAME, + dlke_sig_header_data, + dlke_signature_header.header_size, + dlke_signature_header.data_size, + ) || !chroot.carve_file( + ENCRYPTED_FILE_NAME, + dlke_crypt_header_data, + dlke_crypt_header.header_size, + dlke_crypt_header.data_size, + ) { + result.success = false; + } + } + } + } + } + } + + result +} diff --git a/src/magic.rs b/src/magic.rs index 772e69071..0e2aa49a2 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -998,6 +998,17 @@ pub fn patterns() -> Vec { description: signatures::dlink_tlv::DESCRIPTION.to_string(), extractor: Some(extractors::dlink_tlv::dlink_tlv_extractor()), }, + // DLKE encrypted firmware + signatures::common::Signature { + name: "dlke".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::dlke::dlke_magic(), + parser: signatures::dlke::dlke_parser, + description: signatures::dlke::DESCRIPTION.to_string(), + extractor: Some(extractors::dlke::dlke_extractor()), + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index 298897604..f44724a8b 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -125,6 +125,7 @@ pub mod csman; pub mod dahua_zip; pub mod deb; pub mod dlink_tlv; +pub mod dlke; pub mod dlob; pub mod dmg; pub mod dtb; diff --git a/src/signatures/dlke.rs b/src/signatures/dlke.rs new file mode 100644 index 000000000..ded452e85 --- /dev/null +++ b/src/signatures/dlke.rs @@ -0,0 +1,47 @@ +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; +use crate::structures::jboot::parse_jboot_arm_header; + +/// Human readable description +pub const DESCRIPTION: &str = "DLK encrypted firmware"; + +/// DLKE encrypted firmware images always start with these bytes +pub fn dlke_magic() -> Vec> { + // These magic bytes are technically the ROM-ID field of a JBOOT header + vec![b"DLK6E8202001".to_vec(), b"DLK6E6110002".to_vec()] +} + +/// Validates the DLKE header +pub fn dlke_parser(file_data: &[u8], offset: usize) -> Result { + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_HIGH, + ..Default::default() + }; + + // Parse the first header, which describes the size of the firmware signature + if let Ok(dlke_signature_header) = parse_jboot_arm_header(&file_data[offset..]) { + // Second header should immediately follow the first + if let Some(dlke_crypt_header_data) = file_data + .get(offset + dlke_signature_header.header_size + dlke_signature_header.data_size..) + { + // Parse the second header, which describes the size of the encrypted data + if let Ok(dlke_crypt_header) = parse_jboot_arm_header(dlke_crypt_header_data) { + result.size = dlke_signature_header.header_size + + dlke_signature_header.data_size + + dlke_crypt_header.header_size + + dlke_crypt_header.data_size; + result.description = format!( + "{}, signature size: {} bytes, encrypted data size: {} bytes", + result.description, + dlke_signature_header.data_size, + dlke_crypt_header.data_size + ); + return Ok(result); + } + } + } + + Err(SignatureError) +} diff --git a/src/structures/jboot.rs b/src/structures/jboot.rs index ea192b6ab..1299620f7 100644 --- a/src/structures/jboot.rs +++ b/src/structures/jboot.rs @@ -22,12 +22,12 @@ pub fn parse_jboot_arm_header(jboot_data: &[u8]) -> Result Result Result Date: Fri, 22 Nov 2024 07:14:28 -0500 Subject: [PATCH 085/131] Removed debug print --- src/structures/jboot.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/structures/jboot.rs b/src/structures/jboot.rs index 1299620f7..086e42d59 100644 --- a/src/structures/jboot.rs +++ b/src/structures/jboot.rs @@ -57,7 +57,6 @@ pub fn parse_jboot_arm_header(jboot_data: &[u8]) -> Result Date: Fri, 22 Nov 2024 07:25:18 -0500 Subject: [PATCH 086/131] Fixed jboot signature magic --- src/signatures/jboot.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/signatures/jboot.rs b/src/signatures/jboot.rs index fdc8c6bc3..db4d64b5e 100644 --- a/src/signatures/jboot.rs +++ b/src/signatures/jboot.rs @@ -14,7 +14,7 @@ pub const JBOOT_SCH2_DESCRIPTION: &str = "JBOOT SCH2 header"; /// JBOOT firmware header magic bytes pub fn jboot_arm_magic() -> Vec> { vec![ - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42\x48\x02\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42\x48" .to_vec(), ] } From 7aa2ad6c98fb6aec621a8149a7991d39d7dc0591 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 22 Nov 2024 08:07:12 -0500 Subject: [PATCH 087/131] Fixed code formatting --- src/signatures/jboot.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/signatures/jboot.rs b/src/signatures/jboot.rs index db4d64b5e..796361c31 100644 --- a/src/signatures/jboot.rs +++ b/src/signatures/jboot.rs @@ -13,10 +13,7 @@ pub const JBOOT_SCH2_DESCRIPTION: &str = "JBOOT SCH2 header"; /// JBOOT firmware header magic bytes pub fn jboot_arm_magic() -> Vec> { - vec![ - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42\x48" - .to_vec(), - ] + vec![b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42\x48".to_vec()] } /// JBOOT STAG header magic bytes From 20da6290d960296857dfd1d3a16686a277910838 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 22 Nov 2024 08:17:05 -0500 Subject: [PATCH 088/131] Added alternate OKLI uImage signature --- src/signatures/uimage.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/signatures/uimage.rs b/src/signatures/uimage.rs index 5d8a6aa69..a4b506fc9 100644 --- a/src/signatures/uimage.rs +++ b/src/signatures/uimage.rs @@ -10,7 +10,12 @@ pub const DESCRIPTION: &str = "uImage firmware image"; /// uImage magic bytes pub fn uimage_magic() -> Vec> { - vec![b"\x27\x05\x19\x56".to_vec()] + vec![ + // Standard uImage magic + b"\x27\x05\x19\x56".to_vec(), + // Alternate uImage magic (https://git.openwrt.org/?p=openwrt/openwrt.git;a=commitdiff;h=01a1e21863aa30c7a2c252ff06b9aef0cf957970) + b"OKLI".to_vec(), + ] } /// Validates uImage signatures From 3df80aa309b6e09b2bd2c2268673baba192a0708 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 22 Nov 2024 08:26:56 -0500 Subject: [PATCH 089/131] Added carve.png for wiki entry --- images/carve.png | Bin 0 -> 72228 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/carve.png diff --git a/images/carve.png b/images/carve.png new file mode 100644 index 0000000000000000000000000000000000000000..ae8698d86b5d0890581124f8b7da546555e14ad7 GIT binary patch literal 72228 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 O00f?{elF{r5}E*JU`)^e literal 0 HcmV?d00001 From 9059ab6a265656c05923930b082f83d15d2d6212 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 22 Nov 2024 10:26:18 -0500 Subject: [PATCH 090/131] Added checksum validation check to zlib --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/extractors/gzip.rs | 16 +++++++++----- src/extractors/inflate.rs | 44 +++++++++++++++++++++------------------ src/extractors/zlib.rs | 28 +++++++++++++++++++------ 5 files changed, 65 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b7969da81..a4d2af845 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,12 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "aho-corasick" version = "1.1.3" @@ -103,6 +109,7 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" name = "binwalk" version = "3.1.1" dependencies = [ + "adler32", "aho-corasick", "base64", "bzip2", diff --git a/Cargo.toml b/Cargo.toml index 06d2cd3bc..ae2819fee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ threadpool = "1.8.1" serde_json = "1.0" env_logger = "0.11.5" flate2 = "1.0.34" +adler32 = "1.2.0" md5 = "0.7.0" miniz_oxide = "0.8.0" aho-corasick = "1.1.3" diff --git a/src/extractors/gzip.rs b/src/extractors/gzip.rs index b7a3004c0..994c273e8 100644 --- a/src/extractors/gzip.rs +++ b/src/extractors/gzip.rs @@ -37,18 +37,24 @@ pub fn gzip_decompress( offset: usize, output_directory: Option<&String>, ) -> ExtractionResult { + let mut exresult = ExtractionResult { + ..Default::default() + }; + // Parse the gzip header if let Ok(gzip_header) = parse_gzip_header(&file_data[offset..]) { // Deflate compressed data starts at the end of the gzip header let deflate_data_start: usize = offset + gzip_header.size; if file_data.len() > deflate_data_start { - return inflate::inflate_decompressor(file_data, deflate_data_start, output_directory); + let inflate_result = + inflate::inflate_decompressor(file_data, deflate_data_start, output_directory); + if inflate_result.success { + exresult.success = true; + exresult.size = Some(inflate_result.size); + } } } - // Return failure - ExtractionResult { - ..Default::default() - } + exresult } diff --git a/src/extractors/inflate.rs b/src/extractors/inflate.rs index 1a773af82..648406eac 100644 --- a/src/extractors/inflate.rs +++ b/src/extractors/inflate.rs @@ -1,33 +1,32 @@ -use crate::extractors::common::{Chroot, ExtractionResult}; +use crate::extractors::common::Chroot; +use adler32::RollingAdler32; use flate2::bufread::DeflateDecoder; use std::io::Read; -/* - * The inflate_decompressor extractor is currently not directly used by any signature definitions. - * -use crate::extractors::common::{ Extractor, ExtractorType }; - -// Defines the internal extractor function for decompressing raw deflate data -pub fn inflate_extractor() -> Extractor { - return Extractor { utility: ExtractorType::Internal(inflate_decompressor), ..Default::default() }; +#[derive(Debug, Default, Clone)] +pub struct DeflateResult { + pub size: usize, + pub adler32: u32, + pub success: bool, } -*/ -/// Internal extractor for inflating deflated data. +/// Decompressor for inflating deflated data. +/// For internal use, does not conform to the standard extractor format. pub fn inflate_decompressor( file_data: &[u8], offset: usize, output_directory: Option<&String>, -) -> ExtractionResult { +) -> DeflateResult { // Size of decompression buffer const BLOCK_SIZE: usize = 8192; // Output file for decompressed data const OUTPUT_FILE_NAME: &str = "decompressed.bin"; - let mut result = ExtractionResult { + let mut result = DeflateResult { ..Default::default() }; + let mut adler32_checksum = RollingAdler32::new(); let mut decompressed_buffer = [0; BLOCK_SIZE]; let mut decompressor = DeflateDecoder::new(&file_data[offset..]); @@ -49,12 +48,16 @@ pub fn inflate_decompressor( break; } Ok(n) => { - // Decompressed a block of data, if extraction was requested write the decompressed block to the output file - if n > 0 && output_directory.is_some() { - let chroot = Chroot::new(output_directory); - if !chroot.append_to_file(OUTPUT_FILE_NAME, &decompressed_buffer[0..n]) { - // If writing data to file fails, break - break; + // Decompressed a block of data, update checksum and if extraction was requested write the decompressed block to the output file + if n > 0 { + adler32_checksum.update_buffer(&decompressed_buffer[0..n]); + + if output_directory.is_some() { + let chroot = Chroot::new(output_directory); + if !chroot.append_to_file(OUTPUT_FILE_NAME, &decompressed_buffer[0..n]) { + // If writing data to file fails, break + break; + } } } @@ -63,7 +66,8 @@ pub fn inflate_decompressor( // If some data was actually decompressed, report success and the number of input bytes consumed if decompressor.total_out() > 0 { result.success = true; - result.size = Some(decompressor.total_in() as usize); + result.adler32 = adler32_checksum.hash(); + result.size = decompressor.total_in() as usize; } // Nothing else to do, break diff --git a/src/extractors/zlib.rs b/src/extractors/zlib.rs index e6d99bd95..88c9e6bcd 100644 --- a/src/extractors/zlib.rs +++ b/src/extractors/zlib.rs @@ -42,15 +42,31 @@ pub fn zlib_decompress( // Size of the zlib header const HEADER_SIZE: usize = 2; + let mut exresult = ExtractionResult { + ..Default::default() + }; + // Do the decompression, ignoring the ZLIB header - let mut result = + let inflate_result = inflate::inflate_decompressor(file_data, offset + HEADER_SIZE, output_directory); - // If the decompression reported the size of the deflate data, update the reported size - // to include the ZLIB header and checksum fields - if let Some(deflate_size) = result.size { - result.size = Some(HEADER_SIZE + deflate_size + CHECKSUM_SIZE); + // Check that the data decompressed OK + if inflate_result.success { + // Calculate the ZLIB checksum offsets + let checksum_start = offset + HEADER_SIZE + inflate_result.size; + let checksum_end = checksum_start + CHECKSUM_SIZE; + + // Get the ZLIB checksum + if let Some(adler32_checksum_bytes) = file_data.get(checksum_start..checksum_end) { + let reported_checksum = u32::from_be_bytes(adler32_checksum_bytes.try_into().unwrap()); + + // Make sure the checksum matches + if reported_checksum == inflate_result.adler32 { + exresult.success = true; + exresult.size = Some(HEADER_SIZE + inflate_result.size + CHECKSUM_SIZE); + } + } } - result + exresult } From 7936630f56d4ca96401488a6e51021e68a0cc303 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 22 Nov 2024 10:43:23 -0500 Subject: [PATCH 091/131] Fixed bug in how many magic patterns were reported to screen; fixed but where short magic signatures were searched for more than once --- src/binwalk.rs | 6 ++++++ src/main.rs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/binwalk.rs b/src/binwalk.rs index ca201a779..933970ded 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -57,6 +57,8 @@ pub struct AnalysisResults { pub struct Binwalk { /// Count of all signatures (short and regular) pub signature_count: usize, + /// Count of all magic patterns (short and regular) + pub pattern_count: usize, /// The base file requested for analysis pub base_target_file: String, /// The base output directory for extracted files @@ -188,6 +190,9 @@ impl Binwalk { // Keep a count of total unique signatures that are supported new_instance.signature_count += 1; + // Keep a count of the total number of magic patterns + new_instance.pattern_count += signature.magic.len(); + // Create a lookup table which associates each signature to its respective extractor new_instance .extractor_lookup_table @@ -198,6 +203,7 @@ impl Binwalk { if signature.short && !full_search { // These are short patterns, and should only be searched for at the very beginning of a file new_instance.short_signatures.push(signature.clone()); + break; } else { /* * Need to keep a mapping of the pattern index and its associated signature diff --git a/src/main.rs b/src/main.rs index 96d3fff7c..586d1f968 100644 --- a/src/main.rs +++ b/src/main.rs @@ -235,7 +235,7 @@ fn main() { run_time, file_count, binwalker.signature_count, - binwalker.patterns.len(), + binwalker.pattern_count, ); } From e43c70c99db5747c9330b33a9baa7e8505fae16f Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sun, 24 Nov 2024 16:32:45 -0500 Subject: [PATCH 092/131] Added support for concatenated XZ streams in a single XZ compressed file --- src/signatures/xz.rs | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/signatures/xz.rs b/src/signatures/xz.rs index 4b0f7d779..76950d126 100644 --- a/src/signatures/xz.rs +++ b/src/signatures/xz.rs @@ -1,3 +1,4 @@ +use crate::common::is_offset_safe; use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; use crate::structures::xz::{parse_xz_footer, parse_xz_header}; use aho_corasick::AhoCorasick; @@ -20,19 +21,40 @@ pub fn xz_parser(file_data: &[u8], offset: usize) -> Result break, + Ok(header_size) => { + match file_data.get(next_offset + header_size..) { + None => break, + Some(xz_stream_data) => { + // Determine the size of the XZ stream data + match xz_stream_size(xz_stream_data) { + Err(_) => break, + Ok(stream_size) => { + previous_offset = Some(next_offset); + next_offset += header_size + stream_size; + } + } + } + } } } - }; + } + + // If at least one valid header and one valid stream were identified, + // next_offset will be greater than the starting offset. + if next_offset > offset { + result.size = next_offset - offset; + result.description = format!("{}, total size: {} bytes", result.description, result.size); + return Ok(result); + } Err(SignatureError) } From f784dcb2bc9501170eebaaccbe4ca81ec63bb233 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Mon, 25 Nov 2024 08:49:16 -0500 Subject: [PATCH 093/131] s/http/https/ for srec downloads --- dependencies/src.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/src.sh b/dependencies/src.sh index a02cfb53e..c0a9033a9 100755 --- a/dependencies/src.sh +++ b/dependencies/src.sh @@ -33,7 +33,7 @@ rm -rf /tmp/dmg2img # Install srec2bin mkdir /tmp/srec cd /tmp/srec -wget http://www.goffart.co.uk/s-record/download/srec_151_src.zip +wget https://www.goffart.co.uk/s-record/download/srec_151_src.zip unzip srec_151_src.zip make cp srec2bin /usr/local/bin/ From b7944efef7c57e0cd87ae384efdb9c4d02002c03 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Mon, 25 Nov 2024 09:23:20 -0500 Subject: [PATCH 094/131] Replaced srec2bin dependency with srec_cat --- dependencies/src.sh | 10 ---------- dependencies/ubuntu.sh | 1 + src/extractors/srec.rs | 8 +++++--- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/dependencies/src.sh b/dependencies/src.sh index c0a9033a9..348a0c539 100755 --- a/dependencies/src.sh +++ b/dependencies/src.sh @@ -30,16 +30,6 @@ make install cd /tmp rm -rf /tmp/dmg2img -# Install srec2bin -mkdir /tmp/srec -cd /tmp/srec -wget https://www.goffart.co.uk/s-record/download/srec_151_src.zip -unzip srec_151_src.zip -make -cp srec2bin /usr/local/bin/ -cd /tmp -rm -rf /tmp/srec - # Install latest version of 7z (static) for APFS support mkdir /tmp/7z cd /tmp/7z diff --git a/dependencies/ubuntu.sh b/dependencies/ubuntu.sh index 60b9c9690..985f7fee8 100755 --- a/dependencies/ubuntu.sh +++ b/dependencies/ubuntu.sh @@ -7,6 +7,7 @@ SCRIPT_DIRECTORY=$(dirname -- "$( readlink -f -- "$0"; )") DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install \ 7zip \ zstd \ + srecord \ tar \ unzip \ sleuthkit \ diff --git a/src/extractors/srec.rs b/src/extractors/srec.rs index 392833c0d..27f7d5dba 100644 --- a/src/extractors/srec.rs +++ b/src/extractors/srec.rs @@ -1,6 +1,6 @@ use crate::extractors; -/// Describes how to run the srec2bin utility to convert Motorola S-records to binary +/// Describes how to run the srec_cat utility to convert Motorola S-records to binary /// /// ``` /// use std::io::ErrorKind; @@ -24,11 +24,13 @@ use crate::extractors; /// ``` pub fn srec_extractor() -> extractors::common::Extractor { extractors::common::Extractor { - utility: extractors::common::ExtractorType::External("srec2bin".to_string()), + utility: extractors::common::ExtractorType::External("srec_cat".to_string()), extension: "hex".to_string(), arguments: vec![ - extractors::common::SOURCE_FILE_PLACEHOLDER.to_string(), + "-output".to_string(), "s-record.bin".to_string(), + "-binary".to_string(), + extractors::common::SOURCE_FILE_PLACEHOLDER.to_string(), ], exit_codes: vec![0], ..Default::default() From 085df570e7c865667bf3c137ab02a72c059c560a Mon Sep 17 00:00:00 2001 From: devttys0 Date: Mon, 25 Nov 2024 09:41:10 -0500 Subject: [PATCH 095/131] Added common false positive check to openssl signature --- src/signatures/openssl.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/signatures/openssl.rs b/src/signatures/openssl.rs index b74763065..384d3ae34 100644 --- a/src/signatures/openssl.rs +++ b/src/signatures/openssl.rs @@ -24,15 +24,22 @@ pub fn openssl_crypt_parser( ..Default::default() }; + // This "salt" value are the bytes commonly found in the openssl binary itself + let known_false_positive_salts: Vec = vec![0x2D252D32]; + // Parse the header if let Ok(openssl_header) = parse_openssl_crypt_header(&file_data[offset..]) { - // If the magic starts at the beginning of a file, our confidence is a bit higher - if offset == 0 { - result.confidence = CONFIDENCE_MEDIUM; - } + // Check common false positive salt values + if !known_false_positive_salts.contains(&openssl_header.salt) { + // If the magic starts at the beginning of a file, our confidence is a bit higher + if offset == 0 { + result.confidence = CONFIDENCE_MEDIUM; + } - result.description = format!("{}, salt: {:#X}", result.description, openssl_header.salt); - return Ok(result); + result.description = + format!("{}, salt: {:#X}", result.description, openssl_header.salt); + return Ok(result); + } } Err(SignatureError) From 88639a595669b30954ba5fbc149446ef21017c44 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Tue, 26 Nov 2024 10:45:10 -0500 Subject: [PATCH 096/131] Added SHRS firmware signature --- Cargo.lock | 7 +++++ Cargo.toml | 1 + src/extractors.rs | 1 + src/extractors/shrs.rs | 71 ++++++++++++++++++++++++++++++++++++++++++ src/magic.rs | 11 +++++++ src/signatures.rs | 1 + src/signatures/shrs.rs | 42 +++++++++++++++++++++++++ src/structures.rs | 1 + src/structures/shrs.rs | 36 +++++++++++++++++++++ 9 files changed, 171 insertions(+) create mode 100644 src/extractors/shrs.rs create mode 100644 src/signatures/shrs.rs create mode 100644 src/structures/shrs.rs diff --git a/Cargo.lock b/Cargo.lock index a4d2af845..a75a0044f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -121,6 +121,7 @@ dependencies = [ "entropy", "env_logger", "flate2", + "hex", "log", "md5", "miniz_oxide 0.8.0", @@ -545,6 +546,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "humantime" version = "2.1.0" diff --git a/Cargo.toml b/Cargo.toml index ae2819fee..e1e6772fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ aho-corasick = "1.1.3" serde = { version = "1.0", features = ["derive"]} clap = { version = "4.5.16", features = ["derive"] } xxhash-rust = { version = "0.8.12", features = ["xxh32"] } +hex = "0.4.3" [dependencies.uuid] version = "1.10.0" diff --git a/src/extractors.rs b/src/extractors.rs index 54345bfe9..3b0a297ab 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -174,6 +174,7 @@ pub mod rar; pub mod riff; pub mod romfs; pub mod sevenzip; +pub mod shrs; pub mod squashfs; pub mod srec; pub mod svg; diff --git a/src/extractors/shrs.rs b/src/extractors/shrs.rs new file mode 100644 index 000000000..243da97a8 --- /dev/null +++ b/src/extractors/shrs.rs @@ -0,0 +1,71 @@ +use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; +use crate::structures::shrs::parse_shrs_header; + +/// Defines the internal extractor function for carving out D-Link SHRS firmware images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::shrs::shrs_extractor; +/// +/// match shrs_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` +pub fn shrs_extractor() -> Extractor { + Extractor { + utility: ExtractorType::Internal(extract_shrs_image), + ..Default::default() + } +} + +/// Internal extractor for carve pieces of encrypted SHRS firmware images to disk +pub fn extract_shrs_image( + file_data: &[u8], + offset: usize, + output_directory: Option<&String>, +) -> ExtractionResult { + const IV_FILE_NAME: &str = "iv.bin"; + const ENCRYPTED_FILE_NAME: &str = "encrypted.bin"; + + let mut result = ExtractionResult { + ..Default::default() + }; + + // Parse the header + if let Some(shrs_header_data) = file_data.get(offset..) { + if let Ok(shrs_header) = parse_shrs_header(shrs_header_data) { + result.success = true; + result.size = Some(shrs_header.header_size + shrs_header.data_size); + + // Carve out the IV and encrypted data blob + if output_directory.is_some() { + let chroot = Chroot::new(output_directory); + + if !chroot.create_file(IV_FILE_NAME, &shrs_header.iv) + || !chroot.carve_file( + ENCRYPTED_FILE_NAME, + file_data, + shrs_header.header_size, + shrs_header.data_size, + ) + { + result.success = false; + } + } + } + } + + result +} diff --git a/src/magic.rs b/src/magic.rs index 0e2aa49a2..31eeea112 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -1009,6 +1009,17 @@ pub fn patterns() -> Vec { description: signatures::dlke::DESCRIPTION.to_string(), extractor: Some(extractors::dlke::dlke_extractor()), }, + // SHRS encrypted firmware + signatures::common::Signature { + name: "shrs".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::shrs::shrs_magic(), + parser: signatures::shrs::shrs_parser, + description: signatures::shrs::DESCRIPTION.to_string(), + extractor: Some(extractors::shrs::shrs_extractor()), + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index f44724a8b..bef14615c 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -169,6 +169,7 @@ pub mod rsa; pub mod rtk; pub mod seama; pub mod sevenzip; +pub mod shrs; pub mod squashfs; pub mod srec; pub mod svg; diff --git a/src/signatures/shrs.rs b/src/signatures/shrs.rs new file mode 100644 index 000000000..5f9206e69 --- /dev/null +++ b/src/signatures/shrs.rs @@ -0,0 +1,42 @@ +use crate::signatures::common::{ + SignatureError, SignatureResult, CONFIDENCE_LOW, CONFIDENCE_MEDIUM, +}; +use crate::structures::shrs::parse_shrs_header; + +/// Human readable description +pub const DESCRIPTION: &str = "SHRS encrypted firmware"; + +/// SHRS firmware images always start with these bytes +pub fn shrs_magic() -> Vec> { + vec![b"SHRS".to_vec()] +} + +/// Validates the SHRS header +pub fn shrs_parser(file_data: &[u8], offset: usize) -> Result { + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_LOW, + ..Default::default() + }; + + if let Ok(shrs_header) = parse_shrs_header(&file_data[offset..]) { + result.size = shrs_header.header_size + shrs_header.data_size; + result.description = format!( + "{}, header size: {} bytes, encrypted data size: {} bytes, IV: {}", + result.description, + shrs_header.header_size, + shrs_header.data_size, + hex::encode(shrs_header.iv), + ); + + if offset == 0 { + result.confidence = CONFIDENCE_MEDIUM; + } + + return Ok(result); + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index 6cd72f067..d75074c05 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -144,6 +144,7 @@ pub mod romfs; pub mod rtk; pub mod seama; pub mod sevenzip; +pub mod shrs; pub mod squashfs; pub mod svg; pub mod tplink; diff --git a/src/structures/shrs.rs b/src/structures/shrs.rs new file mode 100644 index 000000000..7cda760af --- /dev/null +++ b/src/structures/shrs.rs @@ -0,0 +1,36 @@ +use crate::structures::common::{self, StructureError}; + +/// Struct to store SHRS firmware header info +#[derive(Debug, Default, Clone)] +pub struct SHRSHeader { + pub iv: Vec, + pub data_size: usize, + pub header_size: usize, +} + +/// Parses an SHRS header +pub fn parse_shrs_header(shrs_data: &[u8]) -> Result { + const IV_START: usize = 12; + const IV_END: usize = IV_START + 16; + const HEADER_SIZE: usize = 0x6DC; + + let shrs_structure = vec![ + ("magic", "u32"), + ("unknown1", "u32"), + ("encrypted_data_size", "u32"), + // 16-byte IV immediately follows + ]; + + // Parse the header + if let Ok(shrs_header) = common::parse(shrs_data, &shrs_structure, "big") { + if let Some(iv_bytes) = shrs_data.get(IV_START..IV_END) { + return Ok(SHRSHeader { + iv: iv_bytes.to_vec(), + data_size: shrs_header["encrypted_data_size"], + header_size: HEADER_SIZE, + }); + } + } + + Err(StructureError) +} From 7b63f884625665f989bd583fb3086a38ee3f3a4d Mon Sep 17 00:00:00 2001 From: devttys0 Date: Tue, 26 Nov 2024 15:08:18 -0500 Subject: [PATCH 097/131] Added ability to stream JSON to stdout --- src/json.rs | 98 +++++++++++++++++++++++++++++------------------------ src/main.rs | 10 ++++-- 2 files changed, 60 insertions(+), 48 deletions(-) diff --git a/src/json.rs b/src/json.rs index b60497fda..ee73126ba 100644 --- a/src/json.rs +++ b/src/json.rs @@ -8,66 +8,80 @@ use std::io::Write; use crate::binwalk::AnalysisResults; use crate::entropy::FileEntropy; +const STDOUT: &str = "-"; +const JSON_LIST_START: &str = "[\n"; +const JSON_LIST_END: &str = "{\"EOF\": true}\n]\n"; +const JSON_LIST_SEP: &str = ",\n"; + #[derive(Debug, Serialize, Deserialize)] pub enum JSONType { Entropy(FileEntropy), Analysis(AnalysisResults), } -/// If file does not exist, write "[\n\n]". -/// Else, seek to EOF -1 and write ",\n\n]". -pub fn log(json_file: &Option, results: JSONType) { - const JSON_LIST_START: &str = "[\n"; - const JSON_LIST_END: &str = "\n]"; - const JSON_COMMA_SEPERATOR: &str = ",\n"; +#[derive(Debug, Default, Clone)] +pub struct JsonLogger { + pub json_file: Option, + pub json_file_initialized: bool, +} + +impl JsonLogger { + pub fn new(log_file: Option) -> JsonLogger { + let mut new_instance = JsonLogger { ..Default::default() }; + + if log_file.is_some() { + new_instance.json_file = Some(log_file.unwrap().clone()); + } + + new_instance + } + + pub fn close(&self) { + self.write_json(JSON_LIST_END.to_string()); + } + + pub fn log(&mut self, results: JSONType) { + // Convert analysis results to JSON + match serde_json::to_string_pretty(&results) { + Err(e) => error!("Failed to convert analysis results to JSON: {}", e), + Ok(json) => { + if !self.json_file_initialized { + self.write_json(JSON_LIST_START.to_string()); + self.json_file_initialized = true; + } + self.write_json(json); + self.write_json(JSON_LIST_SEP.to_string()); + } + } + } - match json_file { - None => (), - Some(file_name) => { - // Convert analysis results to JSON - match serde_json::to_string_pretty(&results) { - Err(e) => panic!("Failed to convert analysis results to JSON: {}", e), - Ok(json) => { + fn write_json(&self, data: String) { + match &self.json_file { + None => return, + Some(log_file) => { + if log_file == STDOUT { + print!("{data}"); + } else { // Open file for reading and writing, create if does not already exist match fs::OpenOptions::new() .create(true) .append(true) .read(true) - .open(file_name) + .open(log_file) { Err(e) => { - error!("Failed to open JSON log file '{}': {}", file_name, e); + error!("Failed to open JSON log file '{}': {}", log_file, e); } Ok(mut fp) => { // Seek to the end of the file and get the cursor position match fp.seek(io::SeekFrom::End(0)) { Err(e) => { - error!("Failed to see to end of JSON file: {}", e); + error!("Failed to seek to end of JSON file: {}", e); } - Ok(pos) => { - if pos == 0 { - // If EOF is at offset 0, this file is empty and needs an opening JSON list character - write_to_json_file(&fp, JSON_LIST_START.to_string()); - } else { - // If there is already data in the file we want to overwrite the last byte, which should be a closing JSON list character, with a comma - if let Err(e) = fp.seek(io::SeekFrom::Start( - pos - (JSON_LIST_END.len() as u64), - )) { - error!("Failed to seek to EOF-1 in JSON file: {}", e); - return; - } else { - write_to_json_file( - &fp, - JSON_COMMA_SEPERATOR.to_string(), - ); - } + Ok(_) => { + if let Err(e) = fp.write_all(data.as_bytes()) { + error!("Failed to write to JSON log file: {}", e); } - - // Write the JSON data to file - write_to_json_file(&fp, json); - - // Write a closing JSON list character to file - write_to_json_file(&fp, JSON_LIST_END.to_string()); } } } @@ -77,9 +91,3 @@ pub fn log(json_file: &Option, results: JSONType) { } } } - -fn write_to_json_file(mut fp: &fs::File, data: String) { - if let Err(e) = fp.write_all(data.as_bytes()) { - error!("Failed to write to JSON log file: {}", e); - } -} diff --git a/src/main.rs b/src/main.rs index 586d1f968..e3dcf0876 100644 --- a/src/main.rs +++ b/src/main.rs @@ -63,16 +63,18 @@ fn main() { panic!("No target file name specified! Try --help."); } + let mut json_logger = json::JsonLogger::new(cliargs.log); + // If entropy analysis was requested, generate the entropy graph and return if cliargs.entropy { display::print_plain(cliargs.quiet, "Calculating file entropy..."); if let Ok(entropy_results) = entropy::plot(cliargs.file_name.unwrap()) { // Log entropy results to JSON file, if requested - json::log( - &cliargs.log, + json_logger.log( json::JSONType::Entropy(entropy_results.clone()), ); + json_logger.close(); display::print_plain(cliargs.quiet, "entropy graph saved to: "); display::println_plain(cliargs.quiet, &entropy_results.file); @@ -190,7 +192,7 @@ fn main() { file_count += 1; // Log analysis results to JSON file - json::log(&cliargs.log, json::JSONType::Analysis(results.clone())); + json_logger.log(json::JSONType::Analysis(results.clone())); // Nothing found? Nothing else to do for this file. if results.file_map.is_empty() { @@ -219,6 +221,8 @@ fn main() { } } + json_logger.close(); + // If BINWALK_RM_SYMLINK env var was set, delete the base_target_file symlink if (cliargs.carve || cliargs.extract) && std::env::var(BINWALK_RM_SYMLINK).is_ok() { if let Err(e) = std::fs::remove_file(&binwalker.base_target_file) { From d31f3364ff8427df09bb41ba7d75b94f7b025e91 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Tue, 26 Nov 2024 15:59:45 -0500 Subject: [PATCH 098/131] Code cleanup --- src/cliparser.rs | 2 +- src/json.rs | 60 ++++++++++++++++++++++++------------------------ src/main.rs | 4 +--- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/cliparser.rs b/src/cliparser.rs index 9382ba734..2842b38a0 100644 --- a/src/cliparser.rs +++ b/src/cliparser.rs @@ -35,7 +35,7 @@ pub struct CliArgs { #[arg(short = 'E', long, conflicts_with = "extract")] pub entropy: bool, - /// Log JSON results to a file + /// Log JSON results to a file ('-' for stdout) #[arg(short, long)] pub log: Option, diff --git a/src/json.rs b/src/json.rs index ee73126ba..a14552668 100644 --- a/src/json.rs +++ b/src/json.rs @@ -10,7 +10,7 @@ use crate::entropy::FileEntropy; const STDOUT: &str = "-"; const JSON_LIST_START: &str = "[\n"; -const JSON_LIST_END: &str = "{\"EOF\": true}\n]\n"; +const JSON_LIST_END: &str = "\n]\n"; const JSON_LIST_SEP: &str = ",\n"; #[derive(Debug, Serialize, Deserialize)] @@ -27,7 +27,9 @@ pub struct JsonLogger { impl JsonLogger { pub fn new(log_file: Option) -> JsonLogger { - let mut new_instance = JsonLogger { ..Default::default() }; + let mut new_instance = JsonLogger { + ..Default::default() + }; if log_file.is_some() { new_instance.json_file = Some(log_file.unwrap().clone()); @@ -35,7 +37,7 @@ impl JsonLogger { new_instance } - + pub fn close(&self) { self.write_json(JSON_LIST_END.to_string()); } @@ -48,40 +50,38 @@ impl JsonLogger { if !self.json_file_initialized { self.write_json(JSON_LIST_START.to_string()); self.json_file_initialized = true; + } else { + self.write_json(JSON_LIST_SEP.to_string()); } self.write_json(json); - self.write_json(JSON_LIST_SEP.to_string()); } } } fn write_json(&self, data: String) { - match &self.json_file { - None => return, - Some(log_file) => { - if log_file == STDOUT { - print!("{data}"); - } else { - // Open file for reading and writing, create if does not already exist - match fs::OpenOptions::new() - .create(true) - .append(true) - .read(true) - .open(log_file) - { - Err(e) => { - error!("Failed to open JSON log file '{}': {}", log_file, e); - } - Ok(mut fp) => { - // Seek to the end of the file and get the cursor position - match fp.seek(io::SeekFrom::End(0)) { - Err(e) => { - error!("Failed to seek to end of JSON file: {}", e); - } - Ok(_) => { - if let Err(e) = fp.write_all(data.as_bytes()) { - error!("Failed to write to JSON log file: {}", e); - } + if let Some(log_file) = &self.json_file { + if log_file == STDOUT { + print!("{data}"); + } else { + // Open file for reading and writing, create if does not already exist + match fs::OpenOptions::new() + .create(true) + .append(true) + .read(true) + .open(log_file) + { + Err(e) => { + error!("Failed to open JSON log file '{}': {}", log_file, e); + } + Ok(mut fp) => { + // Seek to the end of the file and get the cursor position + match fp.seek(io::SeekFrom::End(0)) { + Err(e) => { + error!("Failed to seek to end of JSON file: {}", e); + } + Ok(_) => { + if let Err(e) = fp.write_all(data.as_bytes()) { + error!("Failed to write to JSON log file: {}", e); } } } diff --git a/src/main.rs b/src/main.rs index e3dcf0876..67e0e2f0a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -71,9 +71,7 @@ fn main() { if let Ok(entropy_results) = entropy::plot(cliargs.file_name.unwrap()) { // Log entropy results to JSON file, if requested - json_logger.log( - json::JSONType::Entropy(entropy_results.clone()), - ); + json_logger.log(json::JSONType::Entropy(entropy_results.clone())); json_logger.close(); display::print_plain(cliargs.quiet, "entropy graph saved to: "); From f10e5a49260de520700d37c00604d5361460593f Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 27 Nov 2024 09:16:53 -0500 Subject: [PATCH 099/131] Updated JSON code to use crate::display for writing to stdout --- src/json.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/json.rs b/src/json.rs index a14552668..989f58ccb 100644 --- a/src/json.rs +++ b/src/json.rs @@ -6,6 +6,7 @@ use std::io::Seek; use std::io::Write; use crate::binwalk::AnalysisResults; +use crate::display; use crate::entropy::FileEntropy; const STDOUT: &str = "-"; @@ -39,7 +40,7 @@ impl JsonLogger { } pub fn close(&self) { - self.write_json(JSON_LIST_END.to_string()); + self.write_json(JSON_LIST_END); } pub fn log(&mut self, results: JSONType) { @@ -48,20 +49,20 @@ impl JsonLogger { Err(e) => error!("Failed to convert analysis results to JSON: {}", e), Ok(json) => { if !self.json_file_initialized { - self.write_json(JSON_LIST_START.to_string()); + self.write_json(JSON_LIST_START); self.json_file_initialized = true; } else { - self.write_json(JSON_LIST_SEP.to_string()); + self.write_json(JSON_LIST_SEP); } - self.write_json(json); + self.write_json(&json); } } } - fn write_json(&self, data: String) { + fn write_json(&self, data: &str) { if let Some(log_file) = &self.json_file { if log_file == STDOUT { - print!("{data}"); + display::print_plain(false, data); } else { // Open file for reading and writing, create if does not already exist match fs::OpenOptions::new() From 97c0a2fb9a1ffc27b4e8fe8a5246d30a25406660 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 27 Nov 2024 09:50:53 -0500 Subject: [PATCH 100/131] Removed panic calls from all but main.rs and doctests --- src/display.rs | 3 +- src/extractors/common.rs | 26 +++++--- src/extractors/vxworks.rs | 3 +- src/structures/common.rs | 125 ++++++++++++++++++++++---------------- 4 files changed, 94 insertions(+), 63 deletions(-) diff --git a/src/display.rs b/src/display.rs index 14c6dab94..a545d667e 100644 --- a/src/display.rs +++ b/src/display.rs @@ -3,6 +3,7 @@ use crate::extractors; use crate::signatures; use colored::ColoredString; use colored::Colorize; +use log::error; use std::collections::HashMap; use std::io; use std::io::Write; @@ -291,7 +292,7 @@ pub fn print_signature_list(quiet: bool, signatures: &Vec { signature_info.extractor = "Built-in".to_string(); } - extractors::common::ExtractorType::None => panic!( + extractors::common::ExtractorType::None => error!( "An invalid extractor type exists for the '{}' signature", signature.description ), diff --git a/src/extractors/common.rs b/src/extractors/common.rs index 59e9d6859..11a66bdd3 100644 --- a/src/extractors/common.rs +++ b/src/extractors/common.rs @@ -916,7 +916,10 @@ pub fn execute( // Decide how to execute the extractor depending on the extractor type match &extractor_definition.utility { ExtractorType::None => { - panic!("An extractor of type None is invalid!"); + error!( + "Signature {}: an extractor of type None is invalid!", + signature.name + ); } ExtractorType::Internal(func) => { @@ -994,17 +997,26 @@ fn spawn( signature: &SignatureResult, mut extractor: Extractor, ) -> Result { - let command: String; let chroot = Chroot::new(None); // This function *only* handles execution of external extraction utilities; internal extractors must be invoked directly - match &extractor.utility { - ExtractorType::External(cmd) => command = cmd.clone(), + let command = match &extractor.utility { + ExtractorType::External(cmd) => cmd.clone(), ExtractorType::Internal(_ext) => { - panic!("Tried to run an internal extractor as an external command!") + error!("Tried to run an internal extractor as an external command!"); + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + "attempt to execute an internal extractor as an external command", + )); } - ExtractorType::None => panic!("An extractor command was defined, but is set to None!"), - } + ExtractorType::None => { + error!("An extractor command was defined, but is set to None!"); + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + "invalid external command of type None", + )); + } + }; // Carved file path will be /_. let carved_file = format!( diff --git a/src/extractors/vxworks.rs b/src/extractors/vxworks.rs index 6b8dbe9b6..b126c3504 100644 --- a/src/extractors/vxworks.rs +++ b/src/extractors/vxworks.rs @@ -3,6 +3,7 @@ use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorTy use crate::structures::vxworks::{ get_symtab_endianness, parse_symtab_entry, VxWorksSymbolTableEntry, }; +use log::error; use serde_json; /// Describes the VxWorks symbol table extractor @@ -87,7 +88,7 @@ pub fn extract_symbol_table( match serde_json::to_string_pretty(&symtab_entries) { // This should never happen... Err(e) => { - panic!("Failed to convert VxWorks symbol table to JSON: {}", e); + error!("Failed to convert VxWorks symbol table to JSON: {}", e); } // Write JSON to file diff --git a/src/structures/common.rs b/src/structures/common.rs index 3bfcaf261..aa7b8bd8f 100644 --- a/src/structures/common.rs +++ b/src/structures/common.rs @@ -1,3 +1,4 @@ +use log::error; use std::collections::HashMap; /* @@ -59,7 +60,6 @@ pub fn parse( const U24_SIZE: usize = 3; let mut value: usize; - let mut csize: usize; let mut offset: usize = 0; let mut parsed_structure = HashMap::new(); @@ -70,57 +70,68 @@ pub fn parse( for (name, ctype) in structure { let data_type: String = ctype.to_string(); - csize = type_to_size(ctype); - - if csize == std::mem::size_of::() { - // u8, endianness doesn't matter - value = u8::from_be_bytes(raw_data[offset..offset + csize].try_into().unwrap()) - as usize; - } else if csize == std::mem::size_of::() { - if endianness == "big" { - value = u16::from_be_bytes(raw_data[offset..offset + csize].try_into().unwrap()) - as usize; - } else { - value = u16::from_le_bytes(raw_data[offset..offset + csize].try_into().unwrap()) - as usize; + match type_to_size(ctype) { + None => return Err(StructureError), + Some(csize) => { + if csize == std::mem::size_of::() { + // u8, endianness doesn't matter + value = + u8::from_be_bytes(raw_data[offset..offset + csize].try_into().unwrap()) + as usize; + } else if csize == std::mem::size_of::() { + if endianness == "big" { + value = u16::from_be_bytes( + raw_data[offset..offset + csize].try_into().unwrap(), + ) as usize; + } else { + value = u16::from_le_bytes( + raw_data[offset..offset + csize].try_into().unwrap(), + ) as usize; + } + + // Yes Virginia, u24's are real + } else if csize == U24_SIZE { + if endianness == "big" { + value = ((raw_data[offset] as usize) << 16) + + ((raw_data[offset + 1] as usize) << 8) + + (raw_data[offset + 2] as usize); + } else { + value = ((raw_data[offset + 2] as usize) << 16) + + ((raw_data[offset + 1] as usize) << 8) + + (raw_data[offset] as usize); + } + } else if csize == std::mem::size_of::() { + if endianness == "big" { + value = u32::from_be_bytes( + raw_data[offset..offset + csize].try_into().unwrap(), + ) as usize; + } else { + value = u32::from_le_bytes( + raw_data[offset..offset + csize].try_into().unwrap(), + ) as usize; + } + } else if csize == std::mem::size_of::() { + if endianness == "big" { + value = u64::from_be_bytes( + raw_data[offset..offset + csize].try_into().unwrap(), + ) as usize; + } else { + value = u64::from_le_bytes( + raw_data[offset..offset + csize].try_into().unwrap(), + ) as usize; + } + } else { + error!( + "Cannot parse structure element with unknown data type '{}'", + data_type + ); + return Err(StructureError); + } + + offset += csize; + parsed_structure.insert(name.to_string(), value); } - - // Yes Virginia, u24's are real - } else if csize == U24_SIZE { - if endianness == "big" { - value = ((raw_data[offset] as usize) << 16) - + ((raw_data[offset + 1] as usize) << 8) - + (raw_data[offset + 2] as usize); - } else { - value = ((raw_data[offset + 2] as usize) << 16) - + ((raw_data[offset + 1] as usize) << 8) - + (raw_data[offset] as usize); - } - } else if csize == std::mem::size_of::() { - if endianness == "big" { - value = u32::from_be_bytes(raw_data[offset..offset + csize].try_into().unwrap()) - as usize; - } else { - value = u32::from_le_bytes(raw_data[offset..offset + csize].try_into().unwrap()) - as usize; - } - } else if csize == std::mem::size_of::() { - if endianness == "big" { - value = u64::from_be_bytes(raw_data[offset..offset + csize].try_into().unwrap()) - as usize; - } else { - value = u64::from_le_bytes(raw_data[offset..offset + csize].try_into().unwrap()) - as usize; - } - } else { - panic!( - "Cannot parse structure element with unknown data type '{}'", - data_type - ); } - - offset += csize; - parsed_structure.insert(name.to_string(), value); } return Ok(parsed_structure); @@ -151,21 +162,27 @@ pub fn size(structure: &Vec<(&str, &str)>) -> usize { let mut struct_size: usize = 0; for (_name, ctype) in structure { - struct_size += type_to_size(ctype); + match type_to_size(ctype) { + None => continue, + Some(member_size) => { + struct_size += member_size; + } + } } struct_size } /// Returns the size of a give type string -fn type_to_size(ctype: &str) -> usize { +fn type_to_size(ctype: &str) -> Option { // This table must be updated when new data types are added let size_lookup_table: HashMap<&str, usize> = HashMap::from([("u8", 1), ("u16", 2), ("u24", 3), ("u32", 4), ("u64", 8)]); if !size_lookup_table.contains_key(ctype) { - panic!("Unknown size for structure type '{}'!", ctype); + error!("Unknown size for structure type '{}'!", ctype); + return None; } - size_lookup_table[ctype] + Some(size_lookup_table[ctype]) } From f558c867414b92bb3c57fa7573b285aeb974ae04 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 27 Nov 2024 10:13:23 -0500 Subject: [PATCH 101/131] Added version number details to ZIP file output --- src/signatures/zip.rs | 10 +++++++--- src/structures/zip.rs | 42 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/signatures/zip.rs b/src/signatures/zip.rs index 812827704..23db5b7f2 100644 --- a/src/signatures/zip.rs +++ b/src/signatures/zip.rs @@ -21,13 +21,17 @@ pub fn zip_parser(file_data: &[u8], offset: usize) -> Result Result { +pub fn parse_zip_header(zip_data: &[u8]) -> Result { // Unused flag bits const UNUSED_FLAGS_MASK: usize = 0b11010111_10000000; + // Encrypted compression type + const COMPRESSION_ENCRYPTED: usize = 99; + let zip_local_file_structure = vec![ ("magic", "u32"), ("version", "u16"), @@ -19,8 +28,30 @@ pub fn parse_zip_header(zip_data: &[u8]) -> Result { ("extra_field_len", "u16"), ]; - let allowed_compression_methods: Vec = - vec![0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 14, 18, 19, 98]; + let allowed_compression_methods: Vec = vec![ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 9, + 10, + 12, + 14, + 18, + 19, + 20, + 93, + 94, + 95, + 96, + 97, + 98, + COMPRESSION_ENCRYPTED, + ]; // Parse the ZIP local file structure if let Ok(zip_local_file_header) = common::parse(zip_data, &zip_local_file_structure, "little") @@ -29,7 +60,10 @@ pub fn parse_zip_header(zip_data: &[u8]) -> Result { if (zip_local_file_header["flags"] & UNUSED_FLAGS_MASK) == 0 { // Specified compression method should be one of the defined ZIP compression methods if allowed_compression_methods.contains(&zip_local_file_header["compression"]) { - return Ok(true); + return Ok(ZipFileHeader { + version_major: zip_local_file_header["version"] / 10, + version_minor: zip_local_file_header["version"] % 10, + }); } } } From dc41a2ec44efa3bf2245f644bcd5a56e2d4424b3 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 27 Nov 2024 10:18:48 -0500 Subject: [PATCH 102/131] Added more JPEG magics --- src/signatures/jpeg.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/signatures/jpeg.rs b/src/signatures/jpeg.rs index 377997c3b..732792436 100644 --- a/src/signatures/jpeg.rs +++ b/src/signatures/jpeg.rs @@ -7,11 +7,9 @@ pub const DESCRIPTION: &str = "JPEG image"; /// JPEG magic bytes pub fn jpeg_magic() -> Vec> { vec![ - /* - * Works for normal jpegs but not exif. - * See: https://github.com/corkami/formats/blob/master/image/jpeg.md - */ b"\xFF\xD8\xFF\xE0\x00\x10JFIF\x00".to_vec(), + b"\xFF\xD8\xFF\xE1".to_vec(), + b"\xFF\xD8\xFF\xDB".to_vec(), ] } From 4ee783104c23a72755cd88388b03e78d4a024e23 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 27 Nov 2024 10:27:57 -0500 Subject: [PATCH 103/131] Disable interactive prompt for password protected archives --- src/extractors/sevenzip.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/extractors/sevenzip.rs b/src/extractors/sevenzip.rs index 284430f02..d8dfd1328 100644 --- a/src/extractors/sevenzip.rs +++ b/src/extractors/sevenzip.rs @@ -27,9 +27,10 @@ pub fn sevenzip_extractor() -> extractors::common::Extractor { utility: extractors::common::ExtractorType::External("7zz".to_string()), extension: "bin".to_string(), arguments: vec![ - "x".to_string(), // Perform extraction - "-y".to_string(), // Assume Yes to all questions - "-o.".to_string(), // Output to current working directory + "x".to_string(), // Perform extraction + "-y".to_string(), // Assume Yes to all questions + "-o.".to_string(), // Output to current working directory + "-p''".to_string(), // Blank password to prevent hangs if archives are password protected extractors::common::SOURCE_FILE_PLACEHOLDER.to_string(), ], // If there is trailing data after the compressed data, extraction will happen but exit code will be 2 From e49c68ad79004379c44906604cd81b99b3b0fdd8 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 27 Nov 2024 11:41:45 -0500 Subject: [PATCH 104/131] Added PKCS DER hash signatures --- src/magic.rs | 11 +++++++ src/signatures.rs | 1 + src/signatures/pkcs_der.rs | 64 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 src/signatures/pkcs_der.rs diff --git a/src/magic.rs b/src/magic.rs index 31eeea112..11a225f32 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -1020,6 +1020,17 @@ pub fn patterns() -> Vec { description: signatures::shrs::DESCRIPTION.to_string(), extractor: Some(extractors::shrs::shrs_extractor()), }, + // PKCS DER hashes + signatures::common::Signature { + name: "pkcs_der_hash".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::pkcs_der::der_hash_magic(), + parser: signatures::pkcs_der::der_hash_parser, + description: signatures::pkcs_der::DESCRIPTION.to_string(), + extractor: None, + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index bef14615c..663c781ef 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -160,6 +160,7 @@ pub mod pdf; pub mod pe; pub mod pem; pub mod pjl; +pub mod pkcs_der; pub mod png; pub mod qnx; pub mod rar; diff --git a/src/signatures/pkcs_der.rs b/src/signatures/pkcs_der.rs new file mode 100644 index 000000000..eee1ba5bd --- /dev/null +++ b/src/signatures/pkcs_der.rs @@ -0,0 +1,64 @@ +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use std::collections::HashMap; + +/// Human readable description +pub const DESCRIPTION: &str = "PKCS DER hash"; + +/// Returns a HashMap of the hash types and their associated signature bytes +fn der_hash_lookups() -> HashMap> { + HashMap::from([ + ( + "MD5".to_string(), + b"\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10".to_vec(), + ), + ( + "SHA1".to_string(), + b"\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14".to_vec(), + ), + ( + "SHA256".to_string(), + b"\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20" + .to_vec(), + ), + ( + "SHA384".to_string(), + b"\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30" + .to_vec(), + ), + ( + "SHA512".to_string(), + b"\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04".to_vec(), + ), + ]) +} + +/// DER hash signatures +pub fn der_hash_magic() -> Vec> { + der_hash_lookups().values().cloned().collect() +} + +/// Validates the DER hash matches +pub fn der_hash_parser(file_data: &[u8], offset: usize) -> Result { + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + for (name, magic) in der_hash_lookups() { + let hash_start = offset; + let hash_end = hash_start + magic.len(); + + if let Some(hash_bytes) = file_data.get(hash_start..hash_end) { + if hash_bytes == magic { + result.size = magic.len(); + result.description = format!("{}, {}", result.description, name); + return Ok(result); + } + } + } + + Err(SignatureError) +} From 1716f2ffc82fa448f5102f77f0bed455a3fa3e0f Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 27 Nov 2024 17:59:19 -0500 Subject: [PATCH 105/131] Added logfs signature --- src/magic.rs | 11 +++++++++ src/signatures.rs | 1 + src/signatures/logfs.rs | 35 +++++++++++++++++++++++++++++ src/structures.rs | 1 + src/structures/logfs.rs | 50 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+) create mode 100644 src/signatures/logfs.rs create mode 100644 src/structures/logfs.rs diff --git a/src/magic.rs b/src/magic.rs index 11a225f32..88819b7ac 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -1031,6 +1031,17 @@ pub fn patterns() -> Vec { description: signatures::pkcs_der::DESCRIPTION.to_string(), extractor: None, }, + // LogFS + signatures::common::Signature { + name: "logfs".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::logfs::logfs_magic(), + parser: signatures::logfs::logfs_parser, + description: signatures::logfs::DESCRIPTION.to_string(), + extractor: None, + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index 663c781ef..131518616 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -144,6 +144,7 @@ pub mod jboot; pub mod jffs2; pub mod jpeg; pub mod linux; +pub mod logfs; pub mod luks; pub mod lz4; pub mod lzfse; diff --git a/src/signatures/logfs.rs b/src/signatures/logfs.rs new file mode 100644 index 000000000..8e45f6e25 --- /dev/null +++ b/src/signatures/logfs.rs @@ -0,0 +1,35 @@ +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use crate::structures::logfs::{parse_logfs_super_block, LOGFS_MAGIC_OFFSET}; + +/// Human readable description +pub const DESCRIPTION: &str = "LogFS file system"; + +/// LogFS magic bytes +pub fn logfs_magic() -> Vec> { + vec![b"\x7A\x3A\x8E\x5C\xB9\xD5\xBF\x67".to_vec()] +} + +/// Validates the LogFS super block +pub fn logfs_parser(file_data: &[u8], offset: usize) -> Result { + // Successful return value + let mut result = SignatureResult { + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + if offset >= LOGFS_MAGIC_OFFSET { + result.offset = offset - LOGFS_MAGIC_OFFSET; + + if let Some(logfs_sb_data) = file_data.get(result.offset..) { + if let Ok(logfs_super_block) = parse_logfs_super_block(logfs_sb_data) { + result.size = logfs_super_block.total_size; + result.description = + format!("{}, total size: {} bytes", result.description, result.size); + return Ok(result); + } + } + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index d75074c05..bfc00aaa7 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -123,6 +123,7 @@ pub mod iso9660; pub mod jboot; pub mod jffs2; pub mod linux; +pub mod logfs; pub mod luks; pub mod lz4; pub mod lzfse; diff --git a/src/structures/logfs.rs b/src/structures/logfs.rs new file mode 100644 index 000000000..84545c933 --- /dev/null +++ b/src/structures/logfs.rs @@ -0,0 +1,50 @@ +use crate::structures::common::{self, StructureError}; + +/// Offset of the LogFS magic bytes from the start of the file system +pub const LOGFS_MAGIC_OFFSET: usize = 0x18; + +/// Struct to store LogFS info +#[derive(Debug, Default, Clone)] +pub struct LogFSSuperBlock { + pub total_size: usize, +} + +/// Parses a LogFS superblock +pub fn parse_logfs_super_block(logfs_data: &[u8]) -> Result { + //const LOGFS_CRC_START: usize = LOGFS_MAGIC_OFFSET + 12; + //const LOGFS_CRC_END: usize = 256; + + let logfs_sb_structure = vec![ + ("magic", "u64"), + ("crc32", "u32"), + ("ifile_levels", "u8"), + ("iblock_levels", "u8"), + ("data_levels", "u8"), + ("segment_shift", "u8"), + ("block_shift", "u8"), + ("write_shift", "u8"), + ("pad0", "u32"), + ("pad1", "u16"), + ("filesystem_size", "u64"), + ("segment_size", "u32"), + ("bad_seg_reserved", "u32"), + ("feature_incompat", "u64"), + ("feature_ro_compat", "u64"), + ("feature_compat", "u64"), + ("feature_flags", "u64"), + ("root_reserve", "u64"), + ("speed_reserve", "u64"), + ]; + + if let Some(sb_struct_data) = logfs_data.get(LOGFS_MAGIC_OFFSET..) { + if let Ok(super_block) = common::parse(sb_struct_data, &logfs_sb_structure, "big") { + if super_block["pad0"] == 0 && super_block["pad1"] == 0 { + return Ok(LogFSSuperBlock { + total_size: super_block["filesystem_size"], + }); + } + } + } + + Err(StructureError) +} From 1503e5386439bba182d9ed998b5b142c9fd3ea38 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Wed, 27 Nov 2024 23:24:09 -0500 Subject: [PATCH 106/131] Some dlink_tlv firmware do not include the checksum in the firmware header --- src/signatures/dlink_tlv.rs | 4 ++-- src/structures/dlink_tlv.rs | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/signatures/dlink_tlv.rs b/src/signatures/dlink_tlv.rs index 5ef318a44..b112b3d71 100644 --- a/src/signatures/dlink_tlv.rs +++ b/src/signatures/dlink_tlv.rs @@ -36,8 +36,8 @@ pub fn dlink_tlv_parser( if let Some(payload_data) = file_data.get(data_start..data_end) { let payload_md5 = format!("{:x}", md5::compute(payload_data)); - // Make sure the MD5 hashes match - if payload_md5 == tlv_header.data_checksum { + // If the MD5 checksum exists, make sure it matches + if tlv_header.data_checksum.is_empty() || payload_md5 == tlv_header.data_checksum { result.size = tlv_header.header_size + tlv_header.data_size; result.description = format!( "{}, model name: {}, board ID: {}, header size: {} bytes, data size: {} bytes", diff --git a/src/structures/dlink_tlv.rs b/src/structures/dlink_tlv.rs index 6e7b5bf9c..013a813cc 100644 --- a/src/structures/dlink_tlv.rs +++ b/src/structures/dlink_tlv.rs @@ -43,11 +43,8 @@ pub fn parse_dlink_tlv_header(tlv_data: &[u8]) -> Result Date: Wed, 27 Nov 2024 23:43:17 -0500 Subject: [PATCH 107/131] Added encrpted_img signature --- src/magic.rs | 11 +++++++++++ src/signatures.rs | 1 + src/signatures/encrpted_img.rs | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 src/signatures/encrpted_img.rs diff --git a/src/magic.rs b/src/magic.rs index 88819b7ac..74cdaa4f2 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -1042,6 +1042,17 @@ pub fn patterns() -> Vec { description: signatures::logfs::DESCRIPTION.to_string(), extractor: None, }, + // encrpted_img + signatures::common::Signature { + name: "encrpted_img".to_string(), + short: true, + magic_offset: 0, + always_display: false, + magic: signatures::encrpted_img::encrpted_img_magic(), + parser: signatures::encrpted_img::encrpted_img_parser, + description: signatures::encrpted_img::DESCRIPTION.to_string(), + extractor: None, + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index 131518616..a30bc7643 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -133,6 +133,7 @@ pub mod dxbc; pub mod ecos; pub mod efigpt; pub mod elf; +pub mod encrpted_img; pub mod ext; pub mod fat; pub mod gif; diff --git a/src/signatures/encrpted_img.rs b/src/signatures/encrpted_img.rs new file mode 100644 index 000000000..421bc468f --- /dev/null +++ b/src/signatures/encrpted_img.rs @@ -0,0 +1,32 @@ +use crate::signatures::common::{ + SignatureError, SignatureResult, CONFIDENCE_LOW, CONFIDENCE_MEDIUM, +}; + +/// Human readable description +pub const DESCRIPTION: &str = "D-Link Encrpted Image"; + +/// encrpted_img firmware images always start with these bytes +pub fn encrpted_img_magic() -> Vec> { + vec![b"encrpted_img".to_vec()] +} + +/// Validates the encrpted_img header +pub fn encrpted_img_parser( + _file_data: &[u8], + offset: usize, +) -> Result { + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + // Nothing to really validate here + if offset != 0 { + result.confidence = CONFIDENCE_LOW; + } + + Ok(result) +} From 0cdaf1ae8568d48548a9074942e616fde3028b66 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Thu, 28 Nov 2024 22:11:53 -0500 Subject: [PATCH 108/131] Added android boot image signature --- src/magic.rs | 11 ++++++++ src/signatures.rs | 1 + src/signatures/android_bootimg.rs | 44 +++++++++++++++++++++++++++++++ src/structures.rs | 1 + src/structures/android_bootimg.rs | 35 ++++++++++++++++++++++++ 5 files changed, 92 insertions(+) create mode 100644 src/signatures/android_bootimg.rs create mode 100644 src/structures/android_bootimg.rs diff --git a/src/magic.rs b/src/magic.rs index 74cdaa4f2..7ef240a8a 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -1053,6 +1053,17 @@ pub fn patterns() -> Vec { description: signatures::encrpted_img::DESCRIPTION.to_string(), extractor: None, }, + // Android boot image + signatures::common::Signature { + name: "android_bootimg".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::android_bootimg::android_bootimg_magic(), + parser: signatures::android_bootimg::android_bootimg_parser, + description: signatures::android_bootimg::DESCRIPTION.to_string(), + extractor: None, + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index a30bc7643..97932b8b2 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -106,6 +106,7 @@ //! } //! ``` pub mod aes; +pub mod android_bootimg; pub mod androidsparse; pub mod apfs; pub mod arcadyan; diff --git a/src/signatures/android_bootimg.rs b/src/signatures/android_bootimg.rs new file mode 100644 index 000000000..2a3d54f1c --- /dev/null +++ b/src/signatures/android_bootimg.rs @@ -0,0 +1,44 @@ +use crate::signatures::common::{ + SignatureError, SignatureResult, CONFIDENCE_LOW, CONFIDENCE_MEDIUM, +}; +use crate::structures::android_bootimg::parse_android_bootimg_header; + +/// Human readable description +pub const DESCRIPTION: &str = "Android boot image"; + +/// Android boot images always start with these bytes +pub fn android_bootimg_magic() -> Vec> { + vec![b"ANDROID!".to_vec()] +} + +/// Validates the android boot image header +pub fn android_bootimg_parser( + file_data: &[u8], + offset: usize, +) -> Result { + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_LOW, + ..Default::default() + }; + + if let Ok(bootimg_header) = parse_android_bootimg_header(&file_data[offset..]) { + if offset == 0 { + result.confidence = CONFIDENCE_MEDIUM; + } + + result.description = format!( + "{}, kernel size: {} bytes, kernel load address: {:#X}, ramdisk size: {} bytes, ramdisk load address: {:#X}", + result.description, + bootimg_header.kernel_size, + bootimg_header.kernel_load_address, + bootimg_header.ramdisk_size, + bootimg_header.ramdisk_load_address, + ); + return Ok(result); + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index bfc00aaa7..808b7fbe3 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -96,6 +96,7 @@ //! } //! ``` +pub mod android_bootimg; pub mod androidsparse; pub mod apfs; pub mod autel; diff --git a/src/structures/android_bootimg.rs b/src/structures/android_bootimg.rs new file mode 100644 index 000000000..ee01b4803 --- /dev/null +++ b/src/structures/android_bootimg.rs @@ -0,0 +1,35 @@ +use crate::structures::common::{self, StructureError}; + +/// Struct to store Android boot image header info +#[derive(Debug, Default, Clone)] +pub struct AndroidBootImageHeader { + pub kernel_size: usize, + pub ramdisk_size: usize, + pub kernel_load_address: usize, + pub ramdisk_load_address: usize, +} + +/// Parses an Android boot image header +pub fn parse_android_bootimg_header( + bootimg_data: &[u8], +) -> Result { + let bootimg_structure = vec![ + ("magic", "u64"), + ("kernel_size", "u32"), + ("kernel_load_addr", "u32"), + ("ramdisk_size", "u32"), + ("ramdisk_load_addr", "u32"), + ]; + + // Parse the header + if let Ok(bootimg_header) = common::parse(bootimg_data, &bootimg_structure, "little") { + return Ok(AndroidBootImageHeader { + kernel_size: bootimg_header["kernel_size"], + kernel_load_address: bootimg_header["kernel_load_addr"], + ramdisk_size: bootimg_header["ramdisk_size"], + ramdisk_load_address: bootimg_header["ramdisk_load_addr"], + }); + } + + Err(StructureError) +} From 298d8028c70b343dea3e1c7d31fd34284565d662 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Thu, 28 Nov 2024 22:42:25 -0500 Subject: [PATCH 109/131] Added Linux ARM zImage signature --- src/magic.rs | 11 +++++++++ src/signatures/linux.rs | 40 ++++++++++++++++++++++++++++++++- src/structures/linux.rs | 50 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/magic.rs b/src/magic.rs index 7ef240a8a..5cce46281 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -192,6 +192,17 @@ pub fn patterns() -> Vec { description: signatures::linux::LINUX_BOOT_IMAGE_DESCRIPTION.to_string(), extractor: None, }, + // linux arm zimage + signatures::common::Signature { + name: "linux_arm_zimage".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::linux::linux_arm_zimage_magic(), + parser: signatures::linux::linux_arm_zimage_parser, + description: signatures::linux::LINUX_ARM_ZIMAGE_DESCRIPTION.to_string(), + extractor: None, + }, // zstd signatures::common::Signature { name: "zstd".to_string(), diff --git a/src/signatures/linux.rs b/src/signatures/linux.rs index c1899a74f..8526c121e 100644 --- a/src/signatures/linux.rs +++ b/src/signatures/linux.rs @@ -2,10 +2,13 @@ use crate::common::get_cstring; use crate::signatures::common::{ SignatureError, SignatureResult, CONFIDENCE_LOW, CONFIDENCE_MEDIUM, }; -use crate::structures::linux::parse_linux_arm64_boot_image_header; +use crate::structures::linux::{ + parse_linux_arm64_boot_image_header, parse_linux_arm_zimage_header, +}; use aho_corasick::AhoCorasick; /// Human readable descriptions +pub const LINUX_ARM_ZIMAGE_DESCRIPTION: &str = "Linux ARM boot executable zImage"; pub const LINUX_BOOT_IMAGE_DESCRIPTION: &str = "Linux kernel boot image"; pub const LINUX_KERNEL_VERSION_DESCRIPTION: &str = "Linux kernel version"; pub const LINUX_ARM64_BOOT_IMAGE_DESCRIPTION: &str = "Linux kernel ARM64 boot image"; @@ -25,6 +28,41 @@ pub fn linux_arm64_boot_image_magic() -> Vec> { vec![b"\x00\x00\x00\x00\x00\x00\x00\x00ARMd".to_vec()] } +/// Magic bytes for Linux ARM zImage +pub fn linux_arm_zimage_magic() -> Vec> { + vec![b"\x18\x28\x6F\x01".to_vec(), b"\x01\x6F\x28\x18".to_vec()] +} + +/// Validate a Linux ARM zImage +pub fn linux_arm_zimage_parser( + file_data: &[u8], + offset: usize, +) -> Result { + const MAGIC_OFFSET: usize = 36; + + let mut result = SignatureResult { + confidence: CONFIDENCE_MEDIUM, + description: LINUX_ARM_ZIMAGE_DESCRIPTION.to_string(), + ..Default::default() + }; + + if offset >= MAGIC_OFFSET { + result.offset = offset - MAGIC_OFFSET; + + if let Some(zimage_data) = file_data.get(result.offset..) { + if let Ok(zimage_header) = parse_linux_arm_zimage_header(zimage_data) { + result.description = format!( + "{}, {} endian", + result.description, zimage_header.endianness + ); + return Ok(result); + } + } + } + + Err(SignatureError) +} + /// Validate a linux ARM64 boot image signature pub fn linux_arm64_boot_image_parser( file_data: &[u8], diff --git a/src/structures/linux.rs b/src/structures/linux.rs index f97a0295a..136d76a08 100644 --- a/src/structures/linux.rs +++ b/src/structures/linux.rs @@ -8,6 +8,56 @@ pub struct LinuxARM64BootHeader { pub endianness: String, } +/// Struct to store Linux ARM zImage info +#[derive(Debug, Default, Clone)] +pub struct LinuxARMzImageHeader { + pub endianness: String, +} + +/// Parses a Linux ARM zImage header +pub fn parse_linux_arm_zimage_header( + zimage_data: &[u8], +) -> Result { + const NOP_LE: usize = 0xE1A00000; + const NOP_BE: usize = 0x0000A0E1; + + let zimage_structure = vec![ + ("nop1", "u32"), + ("nop2", "u32"), + ("nop3", "u32"), + ("nop4", "u32"), + ("nop5", "u32"), + ("nop6", "u32"), + ("nop7", "u32"), + ("nop8", "u32"), + ]; + + if let Ok(zimage_nops) = common::parse(zimage_data, &zimage_structure, "little") { + if zimage_nops["nop1"] == zimage_nops["nop2"] + && zimage_nops["nop1"] == zimage_nops["nop3"] + && zimage_nops["nop1"] == zimage_nops["nop4"] + && zimage_nops["nop1"] == zimage_nops["nop5"] + && zimage_nops["nop1"] == zimage_nops["nop6"] + && zimage_nops["nop1"] == zimage_nops["nop7"] + && zimage_nops["nop1"] == zimage_nops["nop8"] + { + if zimage_nops["nop1"] == NOP_LE { + return Ok(LinuxARMzImageHeader { + endianness: "little".to_string(), + }); + } + + if zimage_nops["nop1"] == NOP_BE { + return Ok(LinuxARMzImageHeader { + endianness: "big".to_string(), + }); + } + } + } + + Err(StructureError) +} + /// Parses a linux ARM64 boot header pub fn parse_linux_arm64_boot_image_header( img_data: &[u8], From 144947293cf10bc5291a76cac4aab05ffbc4e527 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Thu, 28 Nov 2024 22:47:26 -0500 Subject: [PATCH 110/131] Fix clippy errors in display.rs --- src/display.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/display.rs b/src/display.rs index a545d667e..53656c686 100644 --- a/src/display.rs +++ b/src/display.rs @@ -34,7 +34,7 @@ fn line_delimiter() -> String { delim } -fn center_text(text: &String) -> String { +fn center_text(text: &str) -> String { let mut padding_width: i32; let mut centered_string: String = "".to_string(); @@ -95,7 +95,7 @@ fn line_wrap(text: &str, prefix_size: usize) -> String { formatted_string = formatted_string + &this_line; - return formatted_string.trim().to_string(); + formatted_string.trim().to_string() } fn print_column_headers(col1: &str, col2: &str, col3: &str) { @@ -113,7 +113,7 @@ fn print_delimiter() { println!("{}", line_delimiter().bold().bright_blue()); } -fn print_header(title_text: &String) { +fn print_header(title_text: &str) { println!(); println!("{}", center_text(title_text).bold().magenta()); print_delimiter(); From d73658dc53f5fca335138b91fc1d50c3fe8eeeef Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 29 Nov 2024 10:17:38 -0500 Subject: [PATCH 111/131] Added U-Boot version signature, fixed openssl signature validation --- src/common.rs | 34 ++++++++++++++++++++++++++++++++++ src/magic.rs | 11 +++++++++++ src/signatures.rs | 1 + src/signatures/openssl.rs | 25 ++++++++++++++++++++----- src/signatures/uboot.rs | 38 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 src/signatures/uboot.rs diff --git a/src/common.rs b/src/common.rs index cb1276a4c..1f712190b 100644 --- a/src/common.rs +++ b/src/common.rs @@ -119,6 +119,40 @@ pub fn get_cstring(raw_data: &[u8]) -> String { string } +/// Returns true if the provided byte is an ASCII number +/// +/// ## Example +/// +/// ``` +/// use binwalk::common::is_ascii_number; +/// +/// assert!(is_ascii_number(0x31)); +/// assert!(!is_ascii_number(0xFE)); +/// ``` +pub fn is_ascii_number(b: u8) -> bool { + const ZERO: u8 = 48; + const NINE: u8 = 57; + + (ZERO..=NINE).contains(&b) +} + +/// Returns true if the provided byte is a printable ASCII character +/// +/// ## Example +/// +/// ``` +/// use binwalk::common::is_printable_ascii; +/// +/// assert!(is_printable_ascii(0x41)); +/// assert!(!is_printable_ascii(0xFE)); +/// ``` +pub fn is_printable_ascii(b: u8) -> bool { + const ASCII_MIN: u8 = 0x0A; + const ASCII_MAX: u8 = 0x7E; + + (ASCII_MIN..=ASCII_MAX).contains(&b) +} + /// Validates data offsets to prevent out-of-bounds access and infinite loops while parsing file formats. /// /// ## Notes diff --git a/src/magic.rs b/src/magic.rs index 5cce46281..3ce2e94cd 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -1075,6 +1075,17 @@ pub fn patterns() -> Vec { description: signatures::android_bootimg::DESCRIPTION.to_string(), extractor: None, }, + // uboot + signatures::common::Signature { + name: "uboot".to_string(), + short: false, + magic_offset: 0, + always_display: true, + magic: signatures::uboot::uboot_magic(), + parser: signatures::uboot::uboot_parser, + description: signatures::uboot::DESCRIPTION.to_string(), + extractor: None, + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index 97932b8b2..d789a95fc 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -181,6 +181,7 @@ pub mod tarball; pub mod tplink; pub mod trx; pub mod ubi; +pub mod uboot; pub mod uefi; pub mod uimage; pub mod vxworks; diff --git a/src/signatures/openssl.rs b/src/signatures/openssl.rs index 384d3ae34..6fd5f84dd 100644 --- a/src/signatures/openssl.rs +++ b/src/signatures/openssl.rs @@ -1,3 +1,4 @@ +use crate::common::is_printable_ascii; use crate::signatures::common::{ SignatureError, SignatureResult, CONFIDENCE_LOW, CONFIDENCE_MEDIUM, }; @@ -24,13 +25,10 @@ pub fn openssl_crypt_parser( ..Default::default() }; - // This "salt" value are the bytes commonly found in the openssl binary itself - let known_false_positive_salts: Vec = vec![0x2D252D32]; - // Parse the header if let Ok(openssl_header) = parse_openssl_crypt_header(&file_data[offset..]) { - // Check common false positive salt values - if !known_false_positive_salts.contains(&openssl_header.salt) { + // Sanity check the salt value + if !is_salt_invalid(openssl_header.salt) { // If the magic starts at the beginning of a file, our confidence is a bit higher if offset == 0 { result.confidence = CONFIDENCE_MEDIUM; @@ -44,3 +42,20 @@ pub fn openssl_crypt_parser( Err(SignatureError) } + +// Returns true if the salt is entirely comprised of NULL and/or ASCII bytes +fn is_salt_invalid(salt: usize) -> bool { + const SALT_LEN: usize = 8; + + let mut bad_byte_count: usize = 0; + + for i in 0..SALT_LEN { + let salt_byte = ((salt >> (8 * i)) & 0xFF) as u8; + + if salt_byte == 0 || is_printable_ascii(salt_byte) { + bad_byte_count += 1; + } + } + + bad_byte_count == SALT_LEN +} diff --git a/src/signatures/uboot.rs b/src/signatures/uboot.rs new file mode 100644 index 000000000..e4882848b --- /dev/null +++ b/src/signatures/uboot.rs @@ -0,0 +1,38 @@ +use crate::common::{get_cstring, is_ascii_number}; +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; + +/// Human readable description +pub const DESCRIPTION: &str = "U-Boot version string"; + +/// U-Boot version number magic bytes +pub fn uboot_magic() -> Vec> { + vec![b"U-Boot\x20".to_vec()] +} + +/// Validates the U-Boot version number magic +pub fn uboot_parser(file_data: &[u8], offset: usize) -> Result { + const NUMBER_OFFSET: usize = 7; + + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + if let Some(expected_number_byte) = file_data.get(offset + NUMBER_OFFSET) { + if is_ascii_number(*expected_number_byte) { + let uboot_version_string = get_cstring(&file_data[offset + NUMBER_OFFSET..]); + + if !uboot_version_string.is_empty() { + result.size = uboot_version_string.len(); + result.description = + format!("{}: {}", result.description, uboot_version_string); + return Ok(result); + } + } + } + + Err(SignatureError) +} From 7fe81a30fb6783f3db52bde38301722788eb9835 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 29 Nov 2024 10:19:24 -0500 Subject: [PATCH 112/131] Fixed code formatting --- src/signatures/uboot.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/signatures/uboot.rs b/src/signatures/uboot.rs index e4882848b..740804cdf 100644 --- a/src/signatures/uboot.rs +++ b/src/signatures/uboot.rs @@ -27,8 +27,7 @@ pub fn uboot_parser(file_data: &[u8], offset: usize) -> Result Date: Sat, 30 Nov 2024 19:25:59 +1100 Subject: [PATCH 113/131] Minor changes to binwalk error handling - Added a BinwalkError struct with a message field to store error messages. - Stored error messages during binwalk initialization. - Display error message when binwalk initialization fails. --- src/binwalk.rs | 34 +++++++++++++++++++++++++++------- src/main.rs | 5 +++-- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/binwalk.rs b/src/binwalk.rs index 933970ded..ce68ddc58 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -21,7 +21,18 @@ use crate::signatures; /// Returned on initialization error #[derive(Debug, Default, Clone)] -pub struct BinwalkError; +pub struct BinwalkError { + pub message: String, +} + +impl BinwalkError { + pub fn new(message: &str) -> Self { + BinwalkError { + message: message.to_string(), + } + } +} + /// Analysis results returned by Binwalk::analyze #[derive(Debug, Default, Clone, Serialize, Deserialize)] @@ -134,8 +145,11 @@ impl Binwalk { if let Some(target_file) = target_file_name { // Set the target file path, make it an absolute path match path::absolute(&target_file) { - Err(_) => { - return Err(BinwalkError); + Err(e) => { + return Err(BinwalkError::new(&format!( + "Failed to get absolute path for '{}'", + target_file + ))); } Ok(abspath) => { new_instance.base_target_file = abspath.display().to_string(); @@ -146,8 +160,11 @@ impl Binwalk { if let Some(extraction_directory) = output_directory { // Make the extraction directory an absolute path match path::absolute(&extraction_directory) { - Err(_) => { - return Err(BinwalkError); + Err(e) => { + return Err(BinwalkError::new(&format!( + "Failed to get absolute path for '{}'", + extraction_directory + ))); } Ok(abspath) => { new_instance.base_output_directory = abspath.display().to_string(); @@ -161,8 +178,11 @@ impl Binwalk { &new_instance.base_target_file, &new_instance.base_output_directory, ) { - Err(_) => { - return Err(BinwalkError); + Err(e) => { + return Err(BinwalkError::new( &format!( + "Failed to initialize extraction directory: {}", + e + ))); } Ok(new_target_file_path) => { // This is the new base target path (a symlink inside the extraction directory) diff --git a/src/main.rs b/src/main.rs index 67e0e2f0a..d3df28320 100644 --- a/src/main.rs +++ b/src/main.rs @@ -96,8 +96,9 @@ fn main() { cliargs.exclude, None, cliargs.search_all, - ) - .expect("Binwalk initialization failed"); + ).unwrap_or_else(|e| { + panic!("Binwalk initialization failed: {}", e.message); + }); // If the user specified --threads, honor that request; else, auto-detect available parallelism let available_workers = cliargs.threads.unwrap_or_else(|| { From d5598a0b2b434039e721aeb32622a27c108761fa Mon Sep 17 00:00:00 2001 From: P1tt1cus <30161177+P1tt1cus@users.noreply.github.com> Date: Sat, 30 Nov 2024 20:22:17 +1100 Subject: [PATCH 114/131] Reverting changes to src/main.rs --- src/main.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index d3df28320..121ad3d51 100644 --- a/src/main.rs +++ b/src/main.rs @@ -96,9 +96,7 @@ fn main() { cliargs.exclude, None, cliargs.search_all, - ).unwrap_or_else(|e| { - panic!("Binwalk initialization failed: {}", e.message); - }); + ).expect("Binwalk initialization failed"); // If the user specified --threads, honor that request; else, auto-detect available parallelism let available_workers = cliargs.threads.unwrap_or_else(|| { From 58c3dc3b4b839c7a3b32cee3c4e73808ad8129ed Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 30 Nov 2024 10:32:39 -0500 Subject: [PATCH 115/131] Fixed format and clippy warnings --- src/binwalk.rs | 7 +++---- src/main.rs | 9 +++++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/binwalk.rs b/src/binwalk.rs index ce68ddc58..47237fe8a 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -33,7 +33,6 @@ impl BinwalkError { } } - /// Analysis results returned by Binwalk::analyze #[derive(Debug, Default, Clone, Serialize, Deserialize)] pub struct AnalysisResults { @@ -145,7 +144,7 @@ impl Binwalk { if let Some(target_file) = target_file_name { // Set the target file path, make it an absolute path match path::absolute(&target_file) { - Err(e) => { + Err(_) => { return Err(BinwalkError::new(&format!( "Failed to get absolute path for '{}'", target_file @@ -160,7 +159,7 @@ impl Binwalk { if let Some(extraction_directory) = output_directory { // Make the extraction directory an absolute path match path::absolute(&extraction_directory) { - Err(e) => { + Err(_) => { return Err(BinwalkError::new(&format!( "Failed to get absolute path for '{}'", extraction_directory @@ -179,7 +178,7 @@ impl Binwalk { &new_instance.base_output_directory, ) { Err(e) => { - return Err(BinwalkError::new( &format!( + return Err(BinwalkError::new(&format!( "Failed to initialize extraction directory: {}", e ))); diff --git a/src/main.rs b/src/main.rs index 121ad3d51..5576736d0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -89,14 +89,19 @@ fn main() { } // Initialize binwalk - let binwalker = binwalk::Binwalk::configure( + let binwalker = match binwalk::Binwalk::configure( cliargs.file_name, output_directory, cliargs.include, cliargs.exclude, None, cliargs.search_all, - ).expect("Binwalk initialization failed"); + ) { + Err(e) => { + panic!("Binwalk initialization failed: {}", e.message); + } + Ok(bw) => bw, + }; // If the user specified --threads, honor that request; else, auto-detect available parallelism let available_workers = cliargs.threads.unwrap_or_else(|| { From a609599aad676fb4ec43b870802eb52975b4b6c5 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 30 Nov 2024 11:42:10 -0500 Subject: [PATCH 116/131] Added --stdin option --- src/binwalk.rs | 36 +++++++++---------- src/cliparser.rs | 4 +++ src/common.rs | 35 +++++++++++++------ src/entropy.rs | 4 +-- src/main.rs | 91 ++++++++++++++++++++++++++++-------------------- 5 files changed, 102 insertions(+), 68 deletions(-) diff --git a/src/binwalk.rs b/src/binwalk.rs index 47237fe8a..ac6bd5935 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -14,7 +14,7 @@ use std::os::windows; #[cfg(unix)] use std::os::unix; -use crate::common::{is_offset_safe, read_file}; +use crate::common::is_offset_safe; use crate::extractors; use crate::magic; use crate::signatures; @@ -709,30 +709,30 @@ impl Binwalk { /// # Ok(binwalker) /// # } _doctest_main_src_binwalk_rs_624_0(); } /// ``` - pub fn analyze(&self, target_file: &String, do_extraction: bool) -> AnalysisResults { + pub fn analyze( + &self, + file_data: &[u8], + target_file: &String, + do_extraction: bool, + ) -> AnalysisResults { // Return value let mut results: AnalysisResults = AnalysisResults { file_path: target_file.clone(), ..Default::default() }; + // Scan file data for signatures debug!("Analysis start: {}", target_file); - - // Read file into memory - if let Ok(file_data) = read_file(target_file) { - // Scan file data for signatures - info!("Scanning {}", target_file); - results.file_map = self.scan(&file_data); - - // Only extract if told to, and if there were some signatures found in this file - if do_extraction && !results.file_map.is_empty() { - // Extract everything we can - debug!( - "Submitting {} signature results to extractor", - results.file_map.len() - ); - results.extractions = self.extract(&file_data, target_file, &results.file_map); - } + results.file_map = self.scan(file_data); + + // Only extract if told to, and if there were some signatures found in this file + if do_extraction && !results.file_map.is_empty() { + // Extract everything we can + debug!( + "Submitting {} signature results to extractor", + results.file_map.len() + ); + results.extractions = self.extract(file_data, target_file, &results.file_map); } debug!("Analysis end: {}", target_file); diff --git a/src/cliparser.rs b/src/cliparser.rs index 2842b38a0..0e9afe09a 100644 --- a/src/cliparser.rs +++ b/src/cliparser.rs @@ -7,6 +7,10 @@ pub struct CliArgs { #[arg(short = 'L', long)] pub list: bool, + /// Read data from standard input + #[arg(short, long)] + pub stdin: bool, + /// Supress output to stdout #[arg(short, long)] pub quiet: bool, diff --git a/src/common.rs b/src/common.rs index 1f712190b..0dce84b4f 100644 --- a/src/common.rs +++ b/src/common.rs @@ -17,25 +17,38 @@ use std::io::Read; /// # Ok(()) /// # } _doctest_main_src_common_rs_11_0(); } /// ``` -pub fn read_file(file: impl Into) -> Result, std::io::Error> { +pub fn read_file(file: impl Into, stdin: bool) -> Result, std::io::Error> { let mut file_data = Vec::new(); let file_path = file.into(); - match File::open(&file_path) { - Err(e) => { - error!("Failed to open file {}: {}", file_path, e); - Err(e) - } - Ok(mut fp) => match fp.read_to_end(&mut file_data) { + if stdin { + match std::io::stdin().read_to_end(&mut file_data) { Err(e) => { - error!("Failed to read file {} into memory: {}", file_path, e); + error!("Failed to read data from stdin: {}", e); Err(e) } - Ok(file_size) => { - debug!("Loaded {} bytes from {}", file_size, file_path); + Ok(nbytes) => { + debug!("Loaded {} bytes from stdin", nbytes); Ok(file_data) } - }, + } + } else { + match File::open(&file_path) { + Err(e) => { + error!("Failed to open file {}: {}", file_path, e); + Err(e) + } + Ok(mut fp) => match fp.read_to_end(&mut file_data) { + Err(e) => { + error!("Failed to read file {} into memory: {}", file_path, e); + Err(e) + } + Ok(file_size) => { + debug!("Loaded {} bytes from {}", file_size, file_path); + Ok(file_data) + } + }, + } } } diff --git a/src/entropy.rs b/src/entropy.rs index e3455262f..b44ffbb8f 100644 --- a/src/entropy.rs +++ b/src/entropy.rs @@ -58,7 +58,7 @@ fn blocks(data: &[u8]) -> Vec { /// Generate a plot of a file's entropy. /// Will output a file to the current working directory with the name `.png`. -pub fn plot(file_path: impl Into) -> Result { +pub fn plot(file_path: impl Into, stdin: bool) -> Result { const FILE_EXTENSION: &str = "png"; const SHANNON_MAX_VALUE: i32 = 8; const IMAGE_PIXEL_WIDTH: u32 = 2048; @@ -87,7 +87,7 @@ pub fn plot(file_path: impl Into) -> Result { } // Read in the target file data - if let Ok(file_data) = read_file(&target_file) { + if let Ok(file_data) = read_file(&target_file, stdin) { let mut points: Vec<(i32, i32)> = vec![]; // Calculate the entropy for each file block diff --git a/src/main.rs b/src/main.rs index 5576736d0..9ab4bfbc5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,9 @@ mod signatures; mod structures; fn main() { + // File name used when reading from stdin + const STDIN: &str = "stdin"; + // Only use one thread if unable to auto-detect available core info const DEFAULT_WORKER_COUNT: usize = 1; @@ -50,7 +53,7 @@ fn main() { env_logger::init(); // Process command line aguments - let cliargs = cliparser::parse(); + let mut cliargs = cliparser::parse(); // If --list was specified, just display a list of signatures and return if cliargs.list { @@ -58,6 +61,11 @@ fn main() { return; } + // Set a dummy file name when reading from stdin + if cliargs.stdin { + cliargs.file_name = Some(STDIN.to_string()); + } + // If --list was not specified, a target file must be provided if cliargs.file_name.is_none() { panic!("No target file name specified! Try --help."); @@ -69,7 +77,7 @@ fn main() { if cliargs.entropy { display::print_plain(cliargs.quiet, "Calculating file entropy..."); - if let Ok(entropy_results) = entropy::plot(cliargs.file_name.unwrap()) { + if let Ok(entropy_results) = entropy::plot(cliargs.file_name.unwrap(), cliargs.stdin) { // Log entropy results to JSON file, if requested json_logger.log(json::JSONType::Entropy(entropy_results.clone())); json_logger.close(); @@ -165,6 +173,7 @@ fn main() { &workers, binwalker.clone(), target_file, + cliargs.stdin && file_count == 0, cliargs.extract, cliargs.carve, worker_tx.clone(), @@ -225,8 +234,10 @@ fn main() { json_logger.close(); - // If BINWALK_RM_SYMLINK env var was set, delete the base_target_file symlink - if (cliargs.carve || cliargs.extract) && std::env::var(BINWALK_RM_SYMLINK).is_ok() { + // If BINWALK_RM_SYMLINK env var was set, or if data was read from stdin, delete the base_target_file symlink + if (cliargs.carve || cliargs.extract) + && (cliargs.stdin || std::env::var(BINWALK_RM_SYMLINK).is_ok()) + { if let Err(e) = std::fs::remove_file(&binwalker.base_target_file) { error!( "Request to remove extraction symlink file {} failed: {}", @@ -273,17 +284,27 @@ fn spawn_worker( pool: &ThreadPool, bw: binwalk::Binwalk, target_file: String, + stdin: bool, do_extraction: bool, do_carve: bool, worker_tx: mpsc::Sender, ) { pool.execute(move || { + // Read in file data + let file_data = match common::read_file(&target_file, stdin) { + Err(_) => { + error!("Failed to read {} data", target_file); + b"".to_vec() + } + Ok(data) => data, + }; + // Analyze target file, with extraction, if specified - let results = bw.analyze(&target_file, do_extraction); + let results = bw.analyze(&file_data, &target_file, do_extraction); // If data carving was requested as part of extraction, carve analysis results to disk if do_carve { - let carve_count = carve_file_map(&results); + let carve_count = carve_file_map(&file_data, &results); info!( "Carved {} data blocks to disk from {}", carve_count, target_file @@ -303,46 +324,42 @@ fn spawn_worker( /// Returns the number of carved files created. /// Note that unknown blocks of file data are also carved to disk, so the number of files /// created may be larger than the number of results defined in results.file_map. -fn carve_file_map(results: &binwalk::AnalysisResults) -> usize { +fn carve_file_map(file_data: &[u8], results: &binwalk::AnalysisResults) -> usize { let mut carve_count: usize = 0; let mut last_known_offset: usize = 0; let mut unknown_bytes: Vec<(usize, usize)> = Vec::new(); // No results, don't do anything if !results.file_map.is_empty() { - // Read in the source file - if let Ok(file_data) = common::read_file(&results.file_path) { - // Loop through all identified signatures in the file - for signature_result in &results.file_map { - // If there is data between the last signature and this signature, it is some chunk of unknown data - if signature_result.offset > last_known_offset { - unknown_bytes.push(( - last_known_offset, - signature_result.offset - last_known_offset, - )); - } - - // Carve this signature's data to disk - if carve_file_data_to_disk( - &results.file_path, - &file_data, - &signature_result.name, - signature_result.offset, - signature_result.size, - ) { - carve_count += 1; - } + // Loop through all identified signatures in the file + for signature_result in &results.file_map { + // If there is data between the last signature and this signature, it is some chunk of unknown data + if signature_result.offset > last_known_offset { + unknown_bytes.push(( + last_known_offset, + signature_result.offset - last_known_offset, + )); + } - // Update the last known offset to the end of this signature's data - last_known_offset = signature_result.offset + signature_result.size; + // Carve this signature's data to disk + if carve_file_data_to_disk( + &results.file_path, + file_data, + &signature_result.name, + signature_result.offset, + signature_result.size, + ) { + carve_count += 1; } - // All known signature data has been carved to disk, now carve any unknown blocks of data to disk - for (offset, size) in unknown_bytes { - if carve_file_data_to_disk(&results.file_path, &file_data, "unknown", offset, size) - { - carve_count += 1; - } + // Update the last known offset to the end of this signature's data + last_known_offset = signature_result.offset + signature_result.size; + } + + // All known signature data has been carved to disk, now carve any unknown blocks of data to disk + for (offset, size) in unknown_bytes { + if carve_file_data_to_disk(&results.file_path, file_data, "unknown", offset, size) { + carve_count += 1; } } } From 27eb641366819cbdd2c02228b884e8673bc37c2b Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 30 Nov 2024 12:14:06 -0500 Subject: [PATCH 117/131] Updated tests --- src/binwalk.rs | 6 ++++-- src/common.rs | 2 +- tests/common/mod.rs | 7 +++++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/binwalk.rs b/src/binwalk.rs index ac6bd5935..0e991e00f 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -675,7 +675,7 @@ impl Binwalk { /// /// ``` /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_binwalk_rs_624_0() -> Result { - /// use binwalk::Binwalk; + /// use binwalk::{Binwalk, common}; /// /// let target_path = std::path::Path::new("tests") /// .join("inputs") @@ -688,6 +688,8 @@ impl Binwalk { /// .display() /// .to_string(); /// + /// let file_data = common::read_file(&target_path, false).expect("Failed to read file data"); + /// /// # std::fs::remove_dir_all(&extraction_directory); /// let binwalker = Binwalk::configure(Some(target_path), /// Some(extraction_directory.clone()), @@ -696,7 +698,7 @@ impl Binwalk { /// None, /// false)?; /// - /// let analysis_results = binwalker.analyze(&binwalker.base_target_file, true); + /// let analysis_results = binwalker.analyze(&file_data, &binwalker.base_target_file, true); /// /// assert_eq!(analysis_results.file_map.len(), 1); /// assert_eq!(analysis_results.extractions.len(), 1); diff --git a/src/common.rs b/src/common.rs index 0dce84b4f..3e919b18d 100644 --- a/src/common.rs +++ b/src/common.rs @@ -12,7 +12,7 @@ use std::io::Read; /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_common_rs_11_0() -> Result<(), Box> { /// use binwalk::common::read_file; /// -/// let file_data = read_file("/etc/passwd")?; +/// let file_data = read_file("/etc/passwd", false)?; /// assert!(file_data.len() > 0); /// # Ok(()) /// # } _doctest_main_src_common_rs_11_0(); } diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 0ff9a99a9..861771c72 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,4 +1,4 @@ -use binwalk::{AnalysisResults, Binwalk}; +use binwalk::{common, AnalysisResults, Binwalk}; /// Convenience function for running an integration test against the specified file, with the provided signature filter. /// Assumes that there will be one signature result and one extraction result at file offset 0. @@ -55,6 +55,9 @@ pub fn run_binwalk(signature_filter: &str, file_name: &str) -> AnalysisResults { // Delete the output directory, if it exists let _ = std::fs::remove_dir_all(&output_directory); + // Read in file data + let file_data = common::read_file(&file_path, false).expect("Failed to read test file"); + // Configure binwalk let binwalker = Binwalk::configure( Some(file_path), @@ -67,7 +70,7 @@ pub fn run_binwalk(signature_filter: &str, file_name: &str) -> AnalysisResults { .expect("Binwalk initialization failed"); // Run analysis - let results = binwalker.analyze(&binwalker.base_target_file, true); + let results = binwalker.analyze(&file_data, &binwalker.base_target_file, true); // Clean up the output directory let _ = std::fs::remove_dir_all(output_directory); From 052c318e288ce9ccc2e7c3ebb7514577c30606f3 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 30 Nov 2024 12:53:32 -0500 Subject: [PATCH 118/131] Removed API breakage --- src/binwalk.rs | 92 ++++++++++++++++++++++++++++++++++++--------- src/common.rs | 78 +++++++++++++++++++++++++------------- src/entropy.rs | 4 +- src/main.rs | 10 ++--- tests/common/mod.rs | 7 +--- 5 files changed, 134 insertions(+), 57 deletions(-) diff --git a/src/binwalk.rs b/src/binwalk.rs index 0e991e00f..b7ed48fe2 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -14,7 +14,7 @@ use std::os::windows; #[cfg(unix)] use std::os::unix; -use crate::common::is_offset_safe; +use crate::common::{is_offset_safe, read_file}; use crate::extractors; use crate::magic; use crate::signatures; @@ -601,9 +601,10 @@ impl Binwalk { pub fn extract( &self, file_data: &[u8], - file_path: &String, + file_name: impl Into, file_map: &Vec, ) -> HashMap { + let file_path = file_name.into(); let mut extraction_results: HashMap = HashMap::new(); @@ -622,7 +623,7 @@ impl Binwalk { Some(_) => { // Run an extraction for this signature let mut extraction_result = - extractors::common::execute(file_data, file_path, signature, &extractor); + extractors::common::execute(file_data, &file_path, signature, &extractor); if !extraction_result.success { debug!( @@ -653,7 +654,7 @@ impl Binwalk { // Re-run the extraction extraction_result = extractors::common::execute( file_data, - file_path, + &file_path, &new_signature, &extractor, ); @@ -669,12 +670,12 @@ impl Binwalk { extraction_results } - /// Analyze a file and optionally extract the file contents. + /// Analyze a data buffer and optionally extract the file contents. /// /// ## Example /// /// ``` - /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_binwalk_rs_624_0() -> Result { + /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_binwalk_rs_672_0() -> Result { /// use binwalk::{Binwalk, common}; /// /// let target_path = std::path::Path::new("tests") @@ -688,7 +689,7 @@ impl Binwalk { /// .display() /// .to_string(); /// - /// let file_data = common::read_file(&target_path, false).expect("Failed to read file data"); + /// let file_data = common::read_file(&target_path).expect("Failed to read file data"); /// /// # std::fs::remove_dir_all(&extraction_directory); /// let binwalker = Binwalk::configure(Some(target_path), @@ -698,7 +699,7 @@ impl Binwalk { /// None, /// false)?; /// - /// let analysis_results = binwalker.analyze(&file_data, &binwalker.base_target_file, true); + /// let analysis_results = binwalker.analyze_buf(&file_data, &binwalker.base_target_file, true); /// /// assert_eq!(analysis_results.file_map.len(), 1); /// assert_eq!(analysis_results.extractions.len(), 1); @@ -709,22 +710,24 @@ impl Binwalk { /// .exists(), true); /// # std::fs::remove_dir_all(&extraction_directory); /// # Ok(binwalker) - /// # } _doctest_main_src_binwalk_rs_624_0(); } + /// # } _doctest_main_src_binwalk_rs_672_0(); } /// ``` - pub fn analyze( + pub fn analyze_buf( &self, file_data: &[u8], - target_file: &String, + target_file: impl Into, do_extraction: bool, ) -> AnalysisResults { + let file_path = target_file.into(); + // Return value let mut results: AnalysisResults = AnalysisResults { - file_path: target_file.clone(), + file_path: file_path.clone(), ..Default::default() }; // Scan file data for signatures - debug!("Analysis start: {}", target_file); + debug!("Analysis start: {}", file_path); results.file_map = self.scan(file_data); // Only extract if told to, and if there were some signatures found in this file @@ -734,19 +737,74 @@ impl Binwalk { "Submitting {} signature results to extractor", results.file_map.len() ); - results.extractions = self.extract(file_data, target_file, &results.file_map); + results.extractions = self.extract(file_data, &file_path, &results.file_map); } - debug!("Analysis end: {}", target_file); + debug!("Analysis end: {}", file_path); results } + + /// Analyze a file on disk and optionally extract its contents. + /// + /// ## Example + /// + /// ``` + /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_binwalk_rs_745_0() -> Result { + /// use binwalk::Binwalk; + /// + /// let target_path = std::path::Path::new("tests") + /// .join("inputs") + /// .join("gzip.bin") + /// .display() + /// .to_string(); + /// + /// let extraction_directory = std::path::Path::new("tests") + /// .join("extractions") + /// .display() + /// .to_string(); + /// + /// # std::fs::remove_dir_all(&extraction_directory); + /// let binwalker = Binwalk::configure(Some(target_path), + /// Some(extraction_directory.clone()), + /// None, + /// None, + /// None, + /// false)?; + /// + /// let analysis_results = binwalker.analyze(&binwalker.base_target_file, true); + /// + /// assert_eq!(analysis_results.file_map.len(), 1); + /// assert_eq!(analysis_results.extractions.len(), 1); + /// assert_eq!(std::path::Path::new(&extraction_directory) + /// .join("gzip.bin.extracted") + /// .join("0") + /// .join("decompressed.bin") + /// .exists(), true); + /// # std::fs::remove_dir_all(&extraction_directory); + /// # Ok(binwalker) + /// # } _doctest_main_src_binwalk_rs_745_0(); } + /// ``` + #[allow(dead_code)] + pub fn analyze(&self, target_file: impl Into, do_extraction: bool) -> AnalysisResults { + let file_path = target_file.into(); + + let file_data = match read_file(&file_path) { + Err(_) => { + error!("Failed to read data from {}", file_path); + b"".to_vec() + } + Ok(data) => data, + }; + + self.analyze_buf(&file_data, &file_path, do_extraction) + } } /// Initializes the extraction output directory fn init_extraction_directory( - target_file: &String, - extraction_directory: &String, + target_file: &str, + extraction_directory: &str, ) -> Result { // Create the output directory, equivalent of mkdir -p match fs::create_dir_all(extraction_directory) { diff --git a/src/common.rs b/src/common.rs index 3e919b18d..111e7c1de 100644 --- a/src/common.rs +++ b/src/common.rs @@ -4,51 +4,75 @@ use log::{debug, error}; use std::fs::File; use std::io::Read; -/// Read a file into memory and return its contents. +/// Read a data into memory, either from disk or from stdin, and return its contents. /// /// ## Example /// /// ``` /// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_common_rs_11_0() -> Result<(), Box> { -/// use binwalk::common::read_file; +/// use binwalk::common::read_input; /// -/// let file_data = read_file("/etc/passwd", false)?; +/// let file_data = read_input("/etc/passwd", false)?; /// assert!(file_data.len() > 0); /// # Ok(()) /// # } _doctest_main_src_common_rs_11_0(); } /// ``` -pub fn read_file(file: impl Into, stdin: bool) -> Result, std::io::Error> { +pub fn read_input(file: impl Into, stdin: bool) -> Result, std::io::Error> { + if stdin { + read_stdin() + } else { + read_file(file) + } +} + +/// Read data from standard input and return its contents. +pub fn read_stdin() -> Result, std::io::Error> { + let mut stdin_data = Vec::new(); + + match std::io::stdin().read_to_end(&mut stdin_data) { + Err(e) => { + error!("Failed to read data from stdin: {}", e); + Err(e) + } + Ok(nbytes) => { + debug!("Loaded {} bytes from stdin", nbytes); + Ok(stdin_data) + } + } +} + +/// Read a file data into memory and return its contents. +/// +/// ## Example +/// +/// ``` +/// # fn main() { #[allow(non_snake_case)] fn _doctest_main_src_common_rs_48_0() -> Result<(), Box> { +/// use binwalk::common::read_file; +/// +/// let file_data = read_file("/etc/passwd")?; +/// assert!(file_data.len() > 0); +/// # Ok(()) +/// # } _doctest_main_src_common_rs_48_0(); } +/// ``` +pub fn read_file(file: impl Into) -> Result, std::io::Error> { let mut file_data = Vec::new(); let file_path = file.into(); - if stdin { - match std::io::stdin().read_to_end(&mut file_data) { + match File::open(&file_path) { + Err(e) => { + error!("Failed to open file {}: {}", file_path, e); + Err(e) + } + Ok(mut fp) => match fp.read_to_end(&mut file_data) { Err(e) => { - error!("Failed to read data from stdin: {}", e); + error!("Failed to read file {} into memory: {}", file_path, e); Err(e) } - Ok(nbytes) => { - debug!("Loaded {} bytes from stdin", nbytes); + Ok(file_size) => { + debug!("Loaded {} bytes from {}", file_size, file_path); Ok(file_data) } - } - } else { - match File::open(&file_path) { - Err(e) => { - error!("Failed to open file {}: {}", file_path, e); - Err(e) - } - Ok(mut fp) => match fp.read_to_end(&mut file_data) { - Err(e) => { - error!("Failed to read file {} into memory: {}", file_path, e); - Err(e) - } - Ok(file_size) => { - debug!("Loaded {} bytes from {}", file_size, file_path); - Ok(file_data) - } - }, - } + }, } } diff --git a/src/entropy.rs b/src/entropy.rs index b44ffbb8f..5c2c9a8e2 100644 --- a/src/entropy.rs +++ b/src/entropy.rs @@ -1,4 +1,4 @@ -use crate::common::read_file; +use crate::common::read_input; use entropy::shannon_entropy; use log::error; use plotters::prelude::*; @@ -87,7 +87,7 @@ pub fn plot(file_path: impl Into, stdin: bool) -> Result = vec![]; // Calculate the entropy for each file block diff --git a/src/main.rs b/src/main.rs index 9ab4bfbc5..ba903986b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -234,10 +234,8 @@ fn main() { json_logger.close(); - // If BINWALK_RM_SYMLINK env var was set, or if data was read from stdin, delete the base_target_file symlink - if (cliargs.carve || cliargs.extract) - && (cliargs.stdin || std::env::var(BINWALK_RM_SYMLINK).is_ok()) - { + // If BINWALK_RM_SYMLINK env var was set, delete the base_target_file symlink + if (cliargs.carve || cliargs.extract) && std::env::var(BINWALK_RM_SYMLINK).is_ok() { if let Err(e) = std::fs::remove_file(&binwalker.base_target_file) { error!( "Request to remove extraction symlink file {} failed: {}", @@ -291,7 +289,7 @@ fn spawn_worker( ) { pool.execute(move || { // Read in file data - let file_data = match common::read_file(&target_file, stdin) { + let file_data = match common::read_input(&target_file, stdin) { Err(_) => { error!("Failed to read {} data", target_file); b"".to_vec() @@ -300,7 +298,7 @@ fn spawn_worker( }; // Analyze target file, with extraction, if specified - let results = bw.analyze(&file_data, &target_file, do_extraction); + let results = bw.analyze_buf(&file_data, &target_file, do_extraction); // If data carving was requested as part of extraction, carve analysis results to disk if do_carve { diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 861771c72..0ff9a99a9 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,4 +1,4 @@ -use binwalk::{common, AnalysisResults, Binwalk}; +use binwalk::{AnalysisResults, Binwalk}; /// Convenience function for running an integration test against the specified file, with the provided signature filter. /// Assumes that there will be one signature result and one extraction result at file offset 0. @@ -55,9 +55,6 @@ pub fn run_binwalk(signature_filter: &str, file_name: &str) -> AnalysisResults { // Delete the output directory, if it exists let _ = std::fs::remove_dir_all(&output_directory); - // Read in file data - let file_data = common::read_file(&file_path, false).expect("Failed to read test file"); - // Configure binwalk let binwalker = Binwalk::configure( Some(file_path), @@ -70,7 +67,7 @@ pub fn run_binwalk(signature_filter: &str, file_name: &str) -> AnalysisResults { .expect("Binwalk initialization failed"); // Run analysis - let results = binwalker.analyze(&file_data, &binwalker.base_target_file, true); + let results = binwalker.analyze(&binwalker.base_target_file, true); // Clean up the output directory let _ = std::fs::remove_dir_all(output_directory); From 940aa70df1ac0277827f9e974196f83d753fb0ba Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 30 Nov 2024 15:07:58 -0500 Subject: [PATCH 119/131] Added DMS firmware signature; added byte-swap extractor --- src/extractors.rs | 1 + src/extractors/swapped.rs | 105 ++++++++++++++++++++++++++++++++++++++ src/magic.rs | 11 ++++ src/signatures.rs | 1 + src/signatures/dms.rs | 45 ++++++++++++++++ src/structures.rs | 1 + src/structures/dms.rs | 32 ++++++++++++ 7 files changed, 196 insertions(+) create mode 100644 src/extractors/swapped.rs create mode 100644 src/signatures/dms.rs create mode 100644 src/structures/dms.rs diff --git a/src/extractors.rs b/src/extractors.rs index 3b0a297ab..02dc8e9b5 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -178,6 +178,7 @@ pub mod shrs; pub mod squashfs; pub mod srec; pub mod svg; +pub mod swapped; pub mod tarball; pub mod trx; pub mod tsk; diff --git a/src/extractors/swapped.rs b/src/extractors/swapped.rs new file mode 100644 index 000000000..1cb5102b1 --- /dev/null +++ b/src/extractors/swapped.rs @@ -0,0 +1,105 @@ +use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; + +/// Defines the internal extractor function for u16 swapped firmware images +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::swapped::swapped_extractor_u16; +/// +/// match swapped_extractor_u16().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` +pub fn swapped_extractor_u16() -> Extractor { + Extractor { + utility: ExtractorType::Internal(extract_swapped_u16), + ..Default::default() + } +} + +/// Extract firmware where every two bytes have been swapped +pub fn extract_swapped_u16( + file_data: &[u8], + offset: usize, + output_directory: Option<&String>, +) -> ExtractionResult { + const SWAP_BYTE_COUNT: usize = 2; + extract_swapped(file_data, offset, output_directory, SWAP_BYTE_COUNT) +} + +/// Extract a block of data where every n bytes have been swapped +fn extract_swapped( + file_data: &[u8], + offset: usize, + output_directory: Option<&String>, + n: usize, +) -> ExtractionResult { + const OUTPUT_FILE_NAME: &str = "swapped.bin"; + + let mut result = ExtractionResult { + ..Default::default() + }; + + if let Some(data) = file_data.get(offset..) { + let swapped_data = byte_swap(data, n); + + result.success = !swapped_data.is_empty(); + + if result.success { + result.size = Some(swapped_data.len()); + + // Write to file, if requested + if output_directory.is_some() { + let chroot = Chroot::new(output_directory); + result.success = chroot.create_file(OUTPUT_FILE_NAME, &swapped_data); + } + } + } + + result +} + +/// Swap every n bytes of the provided data +/// +/// ## Example: +/// +/// ``` +/// use binwalk::extractors::swapped::byte_swap; +/// +/// assert_eq!(byte_swap(b"ABCD", 2), b"CDAB"); +/// ``` +pub fn byte_swap(data: &[u8], n: usize) -> Vec { + let chunk_size = n * 2; + let mut chunker = data.chunks(chunk_size); + let mut swapped_data: Vec = Vec::new(); + + loop { + match chunker.next() { + None => { + break; + } + Some(chunk) => { + if chunk.len() != chunk_size { + break; + } + + swapped_data.extend(chunk[n..].to_vec()); + swapped_data.extend(chunk[0..n].to_vec()); + } + } + } + + swapped_data +} diff --git a/src/magic.rs b/src/magic.rs index 3ce2e94cd..f29ca4c98 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -1086,6 +1086,17 @@ pub fn patterns() -> Vec { description: signatures::uboot::DESCRIPTION.to_string(), extractor: None, }, + // dms firmware + signatures::common::Signature { + name: "dms".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::dms::dms_magic(), + parser: signatures::dms::dms_parser, + description: signatures::dms::DESCRIPTION.to_string(), + extractor: Some(extractors::swapped::swapped_extractor_u16()), + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index d789a95fc..00da4fdbe 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -129,6 +129,7 @@ pub mod dlink_tlv; pub mod dlke; pub mod dlob; pub mod dmg; +pub mod dms; pub mod dtb; pub mod dxbc; pub mod ecos; diff --git a/src/signatures/dms.rs b/src/signatures/dms.rs new file mode 100644 index 000000000..fa7e232e9 --- /dev/null +++ b/src/signatures/dms.rs @@ -0,0 +1,45 @@ +use crate::extractors::swapped::byte_swap; +use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use crate::structures::dms::parse_dms_header; + +/// Human readable description +pub const DESCRIPTION: &str = "DMS firmware image"; + +/// DMS firmware image magic bytes +pub fn dms_magic() -> Vec> { + vec![b"0><1".to_vec()] +} + +/// Validates the DMS header +pub fn dms_parser(file_data: &[u8], offset: usize) -> Result { + const MIN_SIZE: usize = 0x100; + const BYTE_SWAP_SIZE: usize = 2; + const MAGIC_OFFSET: usize = 4; + + // Successful return value + let mut result = SignatureResult { + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + // The magic bytes start at offset 4 + if offset >= MAGIC_OFFSET { + result.offset = offset - MAGIC_OFFSET; + + if let Some(dms_data) = file_data.get(result.offset..result.offset + MIN_SIZE) { + // DMS firmware images have every 2 bytes swapped + let swapped_data = byte_swap(dms_data, BYTE_SWAP_SIZE); + + // Validate the DMS firmware header + if let Ok(dms_header) = parse_dms_header(&swapped_data) { + result.size = dms_header.image_size; + result.description = + format!("{}, total size: {} bytes", result.description, result.size); + return Ok(result); + } + } + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index 808b7fbe3..b20d9513a 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -112,6 +112,7 @@ pub mod deb; pub mod dlink_tlv; pub mod dlob; pub mod dmg; +pub mod dms; pub mod dtb; pub mod dxbc; pub mod efigpt; diff --git a/src/structures/dms.rs b/src/structures/dms.rs new file mode 100644 index 000000000..b2ce840e5 --- /dev/null +++ b/src/structures/dms.rs @@ -0,0 +1,32 @@ +use crate::structures::common::{self, StructureError}; + +/// Struct to store DMS header info +#[derive(Debug, Default, Clone)] +pub struct DMSHeader { + pub image_size: usize, +} + +/// Parses a DMS header +pub fn parse_dms_header(dms_data: &[u8]) -> Result { + const MAGIC_P1: usize = 0x4D47; + const MAGIC_P2: usize = 0x3C31303E; + + let dms_structure = vec![ + ("unknown1", "u16"), + ("magic_p1", "u16"), + ("magic_p2", "u32"), + ("unknown2", "u32"), + ("image_size", "u32"), + ]; + + // Parse the first half of the header + if let Ok(dms_header) = common::parse(dms_data, &dms_structure, "big") { + if dms_header["magic_p1"] == MAGIC_P1 && dms_header["magic_p2"] == MAGIC_P2 { + return Ok(DMSHeader { + image_size: dms_header["image_size"], + }); + } + } + + Err(StructureError) +} From 6109dd20fe01a1814ac3d736c116e5f2ae801e92 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 30 Nov 2024 19:17:01 -0500 Subject: [PATCH 120/131] Replaced external DTB extractor with an internal one --- dependencies/ubuntu.sh | 1 - src/extractors/dtb.rs | 96 +++++++++++++++++++++++++++++++++++------- src/structures/dtb.rs | 94 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+), 17 deletions(-) diff --git a/dependencies/ubuntu.sh b/dependencies/ubuntu.sh index 985f7fee8..3d3efb368 100755 --- a/dependencies/ubuntu.sh +++ b/dependencies/ubuntu.sh @@ -17,7 +17,6 @@ DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install \ git \ lz4 \ lzop \ - device-tree-compiler \ unrar \ unyaffs \ python3-pip \ diff --git a/src/extractors/dtb.rs b/src/extractors/dtb.rs index 1753ca0ab..e05e63b61 100644 --- a/src/extractors/dtb.rs +++ b/src/extractors/dtb.rs @@ -1,6 +1,9 @@ -use crate::extractors; +use crate::common::is_offset_safe; +use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; +use crate::structures::dtb::{parse_dtb_header, parse_dtb_node}; +use log::error; -/// Describes how to run the dtc utility to extract DTB files +/// Defines the internal extractor function for extracting Device Tree Blobs /// /// ``` /// use std::io::ErrorKind; @@ -22,20 +25,81 @@ use crate::extractors; /// } /// } /// ``` -pub fn dtb_extractor() -> extractors::common::Extractor { - extractors::common::Extractor { - utility: extractors::common::ExtractorType::External("dtc".to_string()), - extension: "dtb".to_string(), - arguments: vec![ - "-I".to_string(), // Input type: dtb - "dtb".to_string(), - "-O".to_string(), // Output type: dts - "dts".to_string(), - "-o".to_string(), // Output file name: system.dtb - "system.dtb".to_string(), - extractors::common::SOURCE_FILE_PLACEHOLDER.to_string(), - ], - exit_codes: vec![0], +pub fn dtb_extractor() -> Extractor { + Extractor { + utility: ExtractorType::Internal(extract_dtb), ..Default::default() } } + +/// Internal extractor for extracting Device Tree Blobs +pub fn extract_dtb( + file_data: &[u8], + offset: usize, + output_directory: Option<&String>, +) -> ExtractionResult { + let mut heirerarchy: Vec = Vec::new(); + + let mut result = ExtractionResult { + ..Default::default() + }; + + // Parse the DTB file header + if let Ok(dtb_header) = parse_dtb_header(&file_data[offset..]) { + // Get all the DTB data + if let Some(dtb_data) = file_data.get(offset..offset + dtb_header.total_size) { + // DTB node entries start at the structure offset specified in the DTB header + let mut entry_offset = dtb_header.struct_offset; + let mut previous_entry_offset = None; + let available_data = dtb_data.len(); + + // Loop over all DTB node entries + while is_offset_safe(available_data, entry_offset, previous_entry_offset) { + // Parse the next DTB node entry + let node = parse_dtb_node(&dtb_header, dtb_data, entry_offset); + + // Beginning of a node, add it to the heirerarchy list + if node.begin { + if !node.name.is_empty() { + heirerarchy.push(node.name.clone()); + } + // End of a node, remove it from the heirerarchy list + } else if node.end { + if !heirerarchy.is_empty() { + heirerarchy.pop(); + } + // End of the DTB structure, return success only if the whole DTB structure was parsed successfully up to the EOF marker + } else if node.eof { + result.success = true; + result.size = Some(available_data); + break; + // DTB property, extract it to disk + } else if node.property { + if output_directory.is_some() { + let chroot = Chroot::new(output_directory); + let dir_path = heirerarchy.join(std::path::MAIN_SEPARATOR_STR); + let file_path = chroot.safe_path_join(&dir_path, &node.name); + + if !chroot.create_directory(dir_path) { + break; + } + + if !chroot.create_file(file_path, &node.data) { + break; + } + } + // The only other supported node type is NOP + } else if !node.nop { + error!("Unknown or invalid DTB node"); + break; + } + + // Update offsets to parse the next DTB structure entry + previous_entry_offset = Some(entry_offset); + entry_offset += node.total_size; + } + } + } + + result +} diff --git a/src/structures/dtb.rs b/src/structures/dtb.rs index 141139cb0..eaf0378bf 100644 --- a/src/structures/dtb.rs +++ b/src/structures/dtb.rs @@ -1,3 +1,4 @@ +use crate::common::get_cstring; use crate::structures::common::{self, StructureError}; /// Struct to store DTB info @@ -67,3 +68,96 @@ pub fn parse_dtb_header(dtb_data: &[u8]) -> Result { Err(StructureError) } + +/// Describes a DTB node entry +#[derive(Debug, Default, Clone)] +pub struct DTBNode { + pub begin: bool, + pub end: bool, + pub eof: bool, + pub nop: bool, + pub property: bool, + pub name: String, + pub data: Vec, + pub total_size: usize, +} + +/// Parse a DTB node from the DTB data structure +pub fn parse_dtb_node(dtb_header: &DTBHeader, dtb_data: &[u8], node_offset: usize) -> DTBNode { + const FDT_BEGIN_NODE: usize = 1; + const FDT_END_NODE: usize = 2; + const FDT_PROP: usize = 3; + const FDT_NOP: usize = 4; + const FDT_END: usize = 9; + + let node_token = vec![("id", "u32")]; + let node_property = vec![("data_len", "u32"), ("name_offset", "u32")]; + + let mut node = DTBNode { + ..Default::default() + }; + + if let Some(node_data) = dtb_data.get(node_offset..) { + if let Ok(token) = common::parse(node_data, &node_token, "big") { + // Set total node size to the size of the token entry + node.total_size = common::size(&node_token); + + if token["id"] == FDT_END_NODE { + node.end = true; + } else if token["id"] == FDT_NOP { + node.nop = true; + } else if token["id"] == FDT_END { + node.eof = true; + // All other node types must include additional data, so the available data must be greater than just the token entry size + } else if node_data.len() > node.total_size { + if token["id"] == FDT_BEGIN_NODE { + // Begin nodes are immediately followed by a NULL-terminated name, padded to a 4-byte boundary if necessary + node.begin = true; + node.name = get_cstring(&node_data[node.total_size..]); + node.total_size += dtb_aligned(node.name.len() + 1); + } else if token["id"] == FDT_PROP { + // Property tokens are followed by a property structure + if let Ok(property) = + common::parse(&node_data[node.total_size..], &node_property, "big") + { + // Update the total node size to include the property structure + node.total_size += common::size(&node_property); + + // The property's data will immediately follow the property structure; property data may be NULL-padded for alignment + if let Some(property_data) = + node_data.get(node.total_size..node.total_size + property["data_len"]) + { + node.data = property_data.to_vec(); + node.total_size += dtb_aligned(node.data.len()); + + // Get the property name from the DTB strings table + if let Some(property_name_data) = + dtb_data.get(dtb_header.strings_offset + property["name_offset"]..) + { + node.name = get_cstring(property_name_data); + if !node.name.is_empty() { + node.property = true; + } + } + } + } + } + } + } + } + + node +} + +/// DTB entries must be aligned to 4-byte boundaries +fn dtb_aligned(len: usize) -> usize { + const ALIGNMENT: usize = 4; + + let rem = len % ALIGNMENT; + + if rem == 0 { + len + } else { + len + (ALIGNMENT - rem) + } +} From 703d03d1dc5b673453ba57c09aab0b87d7649a3f Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sun, 1 Dec 2024 21:56:55 -0500 Subject: [PATCH 121/131] Added DKBS firmware header signature --- src/magic.rs | 11 ++++++++ src/signatures.rs | 1 + src/signatures/dkbs.rs | 56 ++++++++++++++++++++++++++++++++++++++ src/structures.rs | 1 + src/structures/dkbs.rs | 61 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 130 insertions(+) create mode 100644 src/signatures/dkbs.rs create mode 100644 src/structures/dkbs.rs diff --git a/src/magic.rs b/src/magic.rs index f29ca4c98..700f55d9c 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -1097,6 +1097,17 @@ pub fn patterns() -> Vec { description: signatures::dms::DESCRIPTION.to_string(), extractor: Some(extractors::swapped::swapped_extractor_u16()), }, + // dkbs firmware + signatures::common::Signature { + name: "dkbs".to_string(), + short: false, + magic_offset: 0, + always_display: false, + magic: signatures::dkbs::dkbs_magic(), + parser: signatures::dkbs::dkbs_parser, + description: signatures::dkbs::DESCRIPTION.to_string(), + extractor: None, + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index 00da4fdbe..61dcbb7ed 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -125,6 +125,7 @@ pub mod cramfs; pub mod csman; pub mod dahua_zip; pub mod deb; +pub mod dkbs; pub mod dlink_tlv; pub mod dlke; pub mod dlob; diff --git a/src/signatures/dkbs.rs b/src/signatures/dkbs.rs new file mode 100644 index 000000000..33ed5685e --- /dev/null +++ b/src/signatures/dkbs.rs @@ -0,0 +1,56 @@ +use crate::signatures::common::{ + SignatureError, SignatureResult, CONFIDENCE_HIGH, CONFIDENCE_MEDIUM, +}; +use crate::structures::dkbs::parse_dkbs_header; + +/// Human readable description +pub const DESCRIPTION: &str = "DKBS firmware header"; + +/// DKBS firmware magic +pub fn dkbs_magic() -> Vec> { + vec![b"_dkbs_".to_vec()] +} + +/// Validates the DKBS header +pub fn dkbs_parser(file_data: &[u8], offset: usize) -> Result { + const MAGIC_OFFSET: usize = 7; + + // Successful return value + let mut result = SignatureResult { + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + // Sanity check the magic bytes offset + if offset >= MAGIC_OFFSET { + // Magic bytes occur 7 bytes into the actual firmware header + result.offset = offset - MAGIC_OFFSET; + + // Parse the firmware header + if let Ok(dkbs_header) = parse_dkbs_header(&file_data[result.offset..]) { + // Calculate the total bytes available after the firmware header + let available_data: usize = file_data.len() - result.offset; + + // Sanity check on the total reported DKBS firmware size + if available_data >= (dkbs_header.header_size + dkbs_header.data_size) { + // If this header starts at the beginning of the file, confidence is high + if result.offset == 0 { + result.confidence = CONFIDENCE_HIGH; + } + + // Report header size and description + result.size = dkbs_header.header_size; + result.description = format!( + "{}, board ID: {}, firmware version: {}, boot device: {}, header size: {} bytes, data size: {}", + result.description, dkbs_header.board_id, dkbs_header.version, dkbs_header.boot_device, dkbs_header.header_size, dkbs_header.data_size + ); + + // Return OK + return Ok(result); + } + } + } + + Err(SignatureError) +} diff --git a/src/structures.rs b/src/structures.rs index b20d9513a..7bf8194ed 100644 --- a/src/structures.rs +++ b/src/structures.rs @@ -109,6 +109,7 @@ pub mod cpio; pub mod cramfs; pub mod csman; pub mod deb; +pub mod dkbs; pub mod dlink_tlv; pub mod dlob; pub mod dmg; diff --git a/src/structures/dkbs.rs b/src/structures/dkbs.rs new file mode 100644 index 000000000..aa065762e --- /dev/null +++ b/src/structures/dkbs.rs @@ -0,0 +1,61 @@ +use crate::common::get_cstring; +use crate::structures::common::{self, StructureError}; + +/// Struct to store DKBS header info +#[derive(Debug, Default, Clone)] +pub struct DKBSHeader { + pub data_size: usize, + pub header_size: usize, + pub board_id: String, + pub version: String, + pub boot_device: String, +} + +/// Parses a DKBS header +pub fn parse_dkbs_header(dkbs_data: &[u8]) -> Result { + // Header is a fixed size + const HEADER_SIZE: usize = 0xA0; + + // Constant offsets for strings and known header fields + const BOARD_ID_START: usize = 0; + const BOARD_ID_END: usize = 0x20; + const VERSION_START: usize = 0x28; + const VERSION_END: usize = 0x48; + const BOOT_DEVICE_START: usize = 0x70; + const BOOT_DEVICE_END: usize = 0x90; + const DATA_SIZE_START: usize = 0x68; + const DATA_SIZE_END: usize = DATA_SIZE_START + 4; + + let data_size_field = vec![("size", "u32")]; + + let mut header = DKBSHeader { + header_size: HEADER_SIZE, + ..Default::default() + }; + + // Available data should be at least big enough for the header to fit + if dkbs_data.len() >= HEADER_SIZE { + // Parse the version, board ID, and boot device strings + header.version = get_cstring(&dkbs_data[VERSION_START..VERSION_END]); + header.board_id = get_cstring(&dkbs_data[BOARD_ID_START..BOARD_ID_END]); + header.boot_device = get_cstring(&dkbs_data[BOOT_DEVICE_START..BOOT_DEVICE_END]); + + // Sanity check to make sure the strings were retrieved + if !header.version.is_empty() + && !header.board_id.is_empty() + && !header.boot_device.is_empty() + { + // Parse the payload size field + if let Ok(data_size) = common::parse( + &dkbs_data[DATA_SIZE_START..DATA_SIZE_END], + &data_size_field, + "big", + ) { + header.data_size = data_size["size"]; + return Ok(header); + } + } + } + + Err(StructureError) +} From 7b4355f1eb0d2ac25fd94d59ee985bffa4da27eb Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sun, 1 Dec 2024 22:30:29 -0500 Subject: [PATCH 122/131] Added endianness detection for dkbs signatures --- src/signatures/dkbs.rs | 4 ++-- src/structures/dkbs.rs | 24 ++++++++++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/signatures/dkbs.rs b/src/signatures/dkbs.rs index 33ed5685e..c67ae423d 100644 --- a/src/signatures/dkbs.rs +++ b/src/signatures/dkbs.rs @@ -42,8 +42,8 @@ pub fn dkbs_parser(file_data: &[u8], offset: usize) -> Result Result && !header.board_id.is_empty() && !header.boot_device.is_empty() { - // Parse the payload size field - if let Ok(data_size) = common::parse( - &dkbs_data[DATA_SIZE_START..DATA_SIZE_END], - &data_size_field, - "big", - ) { - header.data_size = data_size["size"]; - return Ok(header); + if let Some(data_size_bytes) = dkbs_data.get(DATA_SIZE_START..DATA_SIZE_END) { + // Parse the payload size field + if let Ok(data_size) = common::parse(data_size_bytes, &data_size_field, "big") { + if data_size["size"] & 0xFF000000 == 0 { + header.data_size = data_size["size"]; + header.endianness = "big".to_string(); + } else if let Ok(data_size) = common::parse(data_size_bytes, &data_size_field, "little") { + header.data_size = data_size["size"]; + header.endianness = "little".to_string(); + } + } + + if header.data_size != 0 { + return Ok(header); + } } } } From ef2c3de8d5662ef8b672ca0280861ecfe8196758 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sun, 1 Dec 2024 22:30:57 -0500 Subject: [PATCH 123/131] Code formatting --- src/structures/dkbs.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/structures/dkbs.rs b/src/structures/dkbs.rs index b8b7afc60..3eac0d857 100644 --- a/src/structures/dkbs.rs +++ b/src/structures/dkbs.rs @@ -52,7 +52,9 @@ pub fn parse_dkbs_header(dkbs_data: &[u8]) -> Result if data_size["size"] & 0xFF000000 == 0 { header.data_size = data_size["size"]; header.endianness = "big".to_string(); - } else if let Ok(data_size) = common::parse(data_size_bytes, &data_size_field, "little") { + } else if let Ok(data_size) = + common::parse(data_size_bytes, &data_size_field, "little") + { header.data_size = data_size["size"]; header.endianness = "little".to_string(); } From 0388cba60163c5b36e5f13151d2f1ef2902741f6 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sun, 1 Dec 2024 23:55:55 -0500 Subject: [PATCH 124/131] Fixed trailing data carve bug --- src/main.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main.rs b/src/main.rs index ba903986b..d5a9915a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -354,6 +354,14 @@ fn carve_file_map(file_data: &[u8], results: &binwalk::AnalysisResults) -> usize last_known_offset = signature_result.offset + signature_result.size; } + // Calculate the size of any remaining data from the end of the last signature to EOF + let remaining_data = file_data.len() - last_known_offset; + + // Add any remaining unknown data to the unknown_bytes list + if remaining_data > 0 { + unknown_bytes.push((last_known_offset, remaining_data)); + } + // All known signature data has been carved to disk, now carve any unknown blocks of data to disk for (offset, size) in unknown_bytes { if carve_file_data_to_disk(&results.file_path, file_data, "unknown", offset, size) { From cace1bc7556e153580a8a3655dca2f2ac473201e Mon Sep 17 00:00:00 2001 From: devttys0 Date: Mon, 2 Dec 2024 07:54:56 -0500 Subject: [PATCH 125/131] Truncate u-boot version string if too long --- src/signatures/uboot.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/signatures/uboot.rs b/src/signatures/uboot.rs index 740804cdf..f6baad2ee 100644 --- a/src/signatures/uboot.rs +++ b/src/signatures/uboot.rs @@ -27,7 +27,8 @@ pub fn uboot_parser(file_data: &[u8], offset: usize) -> Result Date: Tue, 3 Dec 2024 11:19:42 -0500 Subject: [PATCH 126/131] Adds signatures for some known encrypted firmware types --- src/magic.rs | 11 +++++++ src/signatures.rs | 1 + src/signatures/encfw.rs | 66 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 src/signatures/encfw.rs diff --git a/src/magic.rs b/src/magic.rs index 700f55d9c..7a9b81a2c 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -1108,6 +1108,17 @@ pub fn patterns() -> Vec { description: signatures::dkbs::DESCRIPTION.to_string(), extractor: None, }, + // known encrypted firmware + signatures::common::Signature { + name: "encfw".to_string(), + short: true, + magic_offset: 0, + always_display: true, + magic: signatures::encfw::encfw_magic(), + parser: signatures::encfw::encfw_parser, + description: signatures::encfw::DESCRIPTION.to_string(), + extractor: None, + }, ]; binary_signatures diff --git a/src/signatures.rs b/src/signatures.rs index 61dcbb7ed..9bd382001 100644 --- a/src/signatures.rs +++ b/src/signatures.rs @@ -136,6 +136,7 @@ pub mod dxbc; pub mod ecos; pub mod efigpt; pub mod elf; +pub mod encfw; pub mod encrpted_img; pub mod ext; pub mod fat; diff --git a/src/signatures/encfw.rs b/src/signatures/encfw.rs new file mode 100644 index 000000000..7a6a2b9f8 --- /dev/null +++ b/src/signatures/encfw.rs @@ -0,0 +1,66 @@ +use crate::signatures::common::{ + SignatureError, SignatureResult, CONFIDENCE_LOW, CONFIDENCE_MEDIUM, +}; +use std::collections::HashMap; + +/// Known encrypted firmware magics and their associated make/model +fn encfw_known_firmware() -> HashMap, String> { + HashMap::from([ + ( + b"\xdf\x8c\x39\x0d".to_vec(), + "D-Link DIR-822 rev C".to_string(), + ), + (b"\x35\x66\x6f\x68".to_vec(), "D-Link DAP-1665".to_string()), + ( + b"\xf5\x2a\xa0\xb4".to_vec(), + "D-Link DIR-842 rev C".to_string(), + ), + ( + b"\xe3\x13\x00\x5b".to_vec(), + "D-Link DIR-850 rev A".to_string(), + ), + ( + b"\x0a\x14\xe4\x24".to_vec(), + "D-Link DIR-850 rev B".to_string(), + ), + ]) +} + +/// Human readable description +pub const DESCRIPTION: &str = "Known encrypted firmware"; + +/// Known encrypted firmware magic bytes +pub fn encfw_magic() -> Vec> { + encfw_known_firmware().keys().cloned().collect() +} + +/// Parse the magic signature match +pub fn encfw_parser(file_data: &[u8], offset: usize) -> Result { + const MAGIC_LEN: usize = 4; + + // Successful return value + let mut result = SignatureResult { + offset, + description: DESCRIPTION.to_string(), + confidence: CONFIDENCE_MEDIUM, + ..Default::default() + }; + + if let Some(magic_bytes) = file_data.get(offset..offset + MAGIC_LEN) { + if encfw_known_firmware().contains_key(magic_bytes) { + if result.offset != 0 { + result.confidence = CONFIDENCE_LOW; + } + + result.description = format!( + "{}, {}", + result.description, + encfw_known_firmware()[magic_bytes] + ); + + return Ok(result); + } + } + + Err(SignatureError) +} From d751375196e2a8f4ab866629cb1555ec50db6dbd Mon Sep 17 00:00:00 2001 From: devttys0 Date: Thu, 5 Dec 2024 21:58:25 -0500 Subject: [PATCH 127/131] Added ability to specify an output file name for entropy plots --- src/cliparser.rs | 4 ++-- src/entropy.rs | 18 +++++++++++++----- src/main.rs | 8 ++++++-- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/cliparser.rs b/src/cliparser.rs index 0e9afe09a..6dd859c5a 100644 --- a/src/cliparser.rs +++ b/src/cliparser.rs @@ -35,9 +35,9 @@ pub struct CliArgs { #[arg(short = 'a', long)] pub search_all: bool, - /// Plot the entropy of the specified file + /// Write entropy plot image to the ENTROPY file #[arg(short = 'E', long, conflicts_with = "extract")] - pub entropy: bool, + pub entropy: Option, /// Log JSON results to a file ('-' for stdout) #[arg(short, long)] diff --git a/src/entropy.rs b/src/entropy.rs index 5c2c9a8e2..7b2e9bfb6 100644 --- a/src/entropy.rs +++ b/src/entropy.rs @@ -58,13 +58,23 @@ fn blocks(data: &[u8]) -> Vec { /// Generate a plot of a file's entropy. /// Will output a file to the current working directory with the name `.png`. -pub fn plot(file_path: impl Into, stdin: bool) -> Result { - const FILE_EXTENSION: &str = "png"; +pub fn plot( + png_file_path: impl Into, + file_path: impl Into, + stdin: bool, +) -> Result { + const FILE_EXTENSION: &str = ".png"; const SHANNON_MAX_VALUE: i32 = 8; const IMAGE_PIXEL_WIDTH: u32 = 2048; const IMAGE_PIXEL_HEIGHT: u32 = ((IMAGE_PIXEL_WIDTH as f64) * 0.6) as u32; let target_file: String = file_path.into(); + let mut png_path: String = png_file_path.into(); + + // Make sure the output file extension is .png + if !png_path.ends_with(FILE_EXTENSION) { + png_path = format!("{}{}", png_path, FILE_EXTENSION); + } // Get the base name of the target file let target_file_name = path::Path::new(&target_file) @@ -74,12 +84,10 @@ pub fn plot(file_path: impl Into, stdin: bool) -> Result Date: Fri, 6 Dec 2024 08:13:43 -0500 Subject: [PATCH 128/131] Added --png argument; some entropy code clean up --- src/cliparser.rs | 10 ++++++--- src/entropy.rs | 54 +++++++++++++++++++++--------------------------- src/main.rs | 10 ++++----- 3 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/cliparser.rs b/src/cliparser.rs index 6dd859c5a..271344136 100644 --- a/src/cliparser.rs +++ b/src/cliparser.rs @@ -11,7 +11,7 @@ pub struct CliArgs { #[arg(short, long)] pub stdin: bool, - /// Supress output to stdout + /// Supress normal stdout output #[arg(short, long)] pub quiet: bool, @@ -35,9 +35,13 @@ pub struct CliArgs { #[arg(short = 'a', long)] pub search_all: bool, - /// Write entropy plot image to the ENTROPY file + /// Generate a PNG entropy graph #[arg(short = 'E', long, conflicts_with = "extract")] - pub entropy: Option, + pub entropy: bool, + + /// Specify an alternate file name for the PNG entropy graph + #[arg(short, long, requires = "entropy")] + pub png: Option, /// Log JSON results to a file ('-' for stdout) #[arg(short, long)] diff --git a/src/entropy.rs b/src/entropy.rs index 7b2e9bfb6..684726afe 100644 --- a/src/entropy.rs +++ b/src/entropy.rs @@ -23,34 +23,28 @@ pub struct FileEntropy { /// Splits the supplied data up into blocks and calculates the entropy of each block. fn blocks(data: &[u8]) -> Vec { - const MIN_BLOCK_SIZE: usize = 1024; - const NUM_DATA_POINTS: usize = 4096 * 10; + const BLOCK_SIZE: usize = 1024 * 4; let mut offset: usize = 0; + let mut chunker = data.chunks(BLOCK_SIZE); let mut entropy_blocks: Vec = vec![]; - let mut block_size: usize = (data.len() as f64 / NUM_DATA_POINTS as f64).ceil() as usize; - if block_size < MIN_BLOCK_SIZE { - block_size = MIN_BLOCK_SIZE; - } - - while offset < data.len() { - let mut block = BlockEntropy { - ..Default::default() - }; - - block.start = offset; - block.end = block.start + block_size; - - if block.end > data.len() { - block.end = data.len(); + loop { + match chunker.next() { + None => break, + Some(block_data) => { + let mut block = BlockEntropy { + ..Default::default() + }; + + block.start = offset; + block.entropy = shannon_entropy(block_data); + block.end = block.start + block_data.len(); + + offset = block.end; + entropy_blocks.push(block); + } } - - block.entropy = shannon_entropy(&data[block.start..block.end]); - - entropy_blocks.push(block); - - offset += block_size; } entropy_blocks @@ -59,22 +53,22 @@ fn blocks(data: &[u8]) -> Vec { /// Generate a plot of a file's entropy. /// Will output a file to the current working directory with the name `.png`. pub fn plot( - png_file_path: impl Into, file_path: impl Into, stdin: bool, + png_file_path: Option, ) -> Result { - const FILE_EXTENSION: &str = ".png"; + const FILE_EXTENSION: &str = "png"; const SHANNON_MAX_VALUE: i32 = 8; const IMAGE_PIXEL_WIDTH: u32 = 2048; const IMAGE_PIXEL_HEIGHT: u32 = ((IMAGE_PIXEL_WIDTH as f64) * 0.6) as u32; let target_file: String = file_path.into(); - let mut png_path: String = png_file_path.into(); - // Make sure the output file extension is .png - if !png_path.ends_with(FILE_EXTENSION) { - png_path = format!("{}{}", png_path, FILE_EXTENSION); - } + // Use the specified output file path, else generate a default output file name + let png_path: String = match png_file_path { + Some(fpath) => fpath, + None => format!("{}.{}", target_file, FILE_EXTENSION), + }; // Get the base name of the target file let target_file_name = path::Path::new(&target_file) diff --git a/src/main.rs b/src/main.rs index 223e40cf2..ed46ef5fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -74,14 +74,12 @@ fn main() { let mut json_logger = json::JsonLogger::new(cliargs.log); // If entropy analysis was requested, generate the entropy graph and return - if let Some(entropy_output_file) = cliargs.entropy { + if cliargs.entropy { display::print_plain(cliargs.quiet, "Calculating file entropy..."); - if let Ok(entropy_results) = entropy::plot( - &entropy_output_file, - cliargs.file_name.unwrap(), - cliargs.stdin, - ) { + if let Ok(entropy_results) = + entropy::plot(cliargs.file_name.unwrap(), cliargs.stdin, cliargs.png) + { // Log entropy results to JSON file, if requested json_logger.log(json::JSONType::Entropy(entropy_results.clone())); json_logger.close(); From c96544a367a3cf65391d2e6f44f85065aeb74ec4 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 6 Dec 2024 13:47:00 -0500 Subject: [PATCH 129/131] Fixed bug in validating/extracting GPG signed files --- src/extractors.rs | 1 + src/extractors/gpg.rs | 57 +++++++++++++++++++++++++++++++++++++++++++ src/magic.rs | 2 +- src/signatures/gpg.rs | 7 +++--- 4 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 src/extractors/gpg.rs diff --git a/src/extractors.rs b/src/extractors.rs index 02dc8e9b5..809b5f810 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -190,3 +190,4 @@ pub mod wince; pub mod yaffs2; pub mod zlib; pub mod zstd; +pub mod gpg; diff --git a/src/extractors/gpg.rs b/src/extractors/gpg.rs new file mode 100644 index 000000000..1c5fa9427 --- /dev/null +++ b/src/extractors/gpg.rs @@ -0,0 +1,57 @@ +use crate::extractors::common::{ExtractionResult, Extractor, ExtractorType}; +use crate::extractors::inflate; + +/// Defines the internal extractor function for decompressing signed GPG data +/// +/// ``` +/// use std::io::ErrorKind; +/// use std::process::Command; +/// use binwalk::extractors::common::ExtractorType; +/// use binwalk::extractors::gpg::gpg_extractor; +/// +/// match gpg_extractor().utility { +/// ExtractorType::None => panic!("Invalid extractor type of None"), +/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), +/// ExtractorType::External(cmd) => { +/// if let Err(e) = Command::new(&cmd).output() { +/// if e.kind() == ErrorKind::NotFound { +/// panic!("External extractor '{}' not found", cmd); +/// } else { +/// panic!("Failed to execute external extractor '{}': {}", cmd, e); +/// } +/// } +/// } +/// } +/// ``` +pub fn gpg_extractor() -> Extractor { + Extractor { + utility: ExtractorType::Internal(gpg_decompress), + ..Default::default() + } +} + +/// Internal extractor for decompressing signed GPG data +pub fn gpg_decompress( + file_data: &[u8], + offset: usize, + output_directory: Option<&String>, +) -> ExtractionResult { + // Size of the GPG header + const HEADER_SIZE: usize = 2; + + let mut exresult = ExtractionResult { + ..Default::default() + }; + + // Do the decompression, ignoring the GPG header + let inflate_result = + inflate::inflate_decompressor(file_data, offset + HEADER_SIZE, output_directory); + + // Check that the data decompressed OK + if inflate_result.success { + exresult.success = true; + exresult.size = Some(HEADER_SIZE + inflate_result.size); + } + + exresult +} diff --git a/src/magic.rs b/src/magic.rs index 7a9b81a2c..1861c6b96 100644 --- a/src/magic.rs +++ b/src/magic.rs @@ -413,7 +413,7 @@ pub fn patterns() -> Vec { magic: signatures::gpg::gpg_signed_magic(), parser: signatures::gpg::gpg_signed_parser, description: signatures::gpg::GPG_SIGNED_DESCRIPTION.to_string(), - extractor: Some(extractors::zlib::zlib_extractor()), + extractor: Some(extractors::gpg::gpg_extractor()), }, // pem certificates signatures::common::Signature { diff --git a/src/signatures/gpg.rs b/src/signatures/gpg.rs index 001044773..f55e310fb 100644 --- a/src/signatures/gpg.rs +++ b/src/signatures/gpg.rs @@ -1,4 +1,4 @@ -use crate::extractors::zlib::{zlib_decompress, CHECKSUM_SIZE}; +use crate::extractors::gpg::gpg_decompress; use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; /// Human readable description @@ -26,13 +26,12 @@ pub fn gpg_signed_parser( * GPG signed files are just zlib compressed files with the zlib magic bytes replaced with the GPG magic bytes. * Decompress the signed file; no output directory specified, dry run only. */ - let decompression_dry_run = zlib_decompress(file_data, offset, None); + let decompression_dry_run = gpg_decompress(file_data, offset, None); // If the decompression dry run was a success, this signature is almost certianly valid if decompression_dry_run.success { if let Some(total_size) = decompression_dry_run.size { - // GPG doesn't include the trailing checksum - result.size = total_size - CHECKSUM_SIZE; + result.size = total_size; result.description = format!("{}, total size: {} bytes", result.description, result.size); return Ok(result); From fc556261b1b0603782ef4f664794642764177213 Mon Sep 17 00:00:00 2001 From: devttys0 Date: Fri, 6 Dec 2024 13:55:24 -0500 Subject: [PATCH 130/131] Code formatting --- src/extractors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extractors.rs b/src/extractors.rs index 809b5f810..2fa399fa7 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -155,6 +155,7 @@ pub mod dtb; pub mod dumpifs; pub mod dxbc; pub mod gif; +pub mod gpg; pub mod gzip; pub mod inflate; pub mod jboot; @@ -190,4 +191,3 @@ pub mod wince; pub mod yaffs2; pub mod zlib; pub mod zstd; -pub mod gpg; From cd6eebd4093871ed7897f2bb63814c3fc1ee4fed Mon Sep 17 00:00:00 2001 From: devttys0 Date: Sat, 7 Dec 2024 11:31:17 -0500 Subject: [PATCH 131/131] Changed -C argument to -d --- src/cliparser.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cliparser.rs b/src/cliparser.rs index 271344136..ff7e89ecb 100644 --- a/src/cliparser.rs +++ b/src/cliparser.rs @@ -60,7 +60,7 @@ pub struct CliArgs { pub include: Option>, /// Extract files/folders to a custom directory - #[arg(short = 'C', long, default_value = "extractions")] + #[arg(short, long, default_value = "extractions")] pub directory: String, /// Path to the file to analyze

@IuJ`4*>nTNO0r6g6#s~`!K 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