From 166d61535469dab9956306131d536acfcfefe003 Mon Sep 17 00:00:00 2001 From: Alexander Tsay <48321920+aktsay6@users.noreply.github.com> Date: Wed, 13 Jan 2021 07:50:51 +0300 Subject: [PATCH 01/11] bugfix/bug-documentation-generation (#701) ### What's done: * Fixed bug --- info/buildSrc/gradle.properties | 2 +- .../cqfn/diktat/generation/docs/LatexUtils.kt | 2 +- wp/sections/appendix.tex | 236 +++++++++--------- 3 files changed, 120 insertions(+), 120 deletions(-) diff --git a/info/buildSrc/gradle.properties b/info/buildSrc/gradle.properties index 66cd2f5a2f..f9343f1708 100644 --- a/info/buildSrc/gradle.properties +++ b/info/buildSrc/gradle.properties @@ -1 +1 @@ -version=0.2.1-SNAPSHOT \ No newline at end of file +version=0.3.1-SNAPSHOT \ No newline at end of file diff --git a/info/buildSrc/src/main/kotlin/org/cqfn/diktat/generation/docs/LatexUtils.kt b/info/buildSrc/src/main/kotlin/org/cqfn/diktat/generation/docs/LatexUtils.kt index f31f2fcb8f..dde58772f0 100644 --- a/info/buildSrc/src/main/kotlin/org/cqfn/diktat/generation/docs/LatexUtils.kt +++ b/info/buildSrc/src/main/kotlin/org/cqfn/diktat/generation/docs/LatexUtils.kt @@ -9,7 +9,7 @@ import java.io.PrintWriter @Suppress("VARIABLE_NAME_INCORRECT_FORMAT") val NUMBER_IN_TAG = Regex("\"([a-z0-9.]*)\"") // finds "r1.0.2" @Suppress("VARIABLE_NAME_INCORRECT_FORMAT") -val RULE_NAME = Regex("([A-Za-z 0-9'.-]*)") // get's rule name from ### ... Rule name +val RULE_NAME = Regex("([A-Za-z 0-9':.-]*)") // get's rule name from ### ... Rule name @Suppress("VARIABLE_NAME_INCORRECT_FORMAT") val BOLD_TEXT = Regex("""\*\*([^*]+)\*\*""") // finds bold text in regular lines @Suppress("VARIABLE_NAME_INCORRECT_FORMAT") diff --git a/wp/sections/appendix.tex b/wp/sections/appendix.tex index 6ad32803fc..ef8f2b9eae 100644 --- a/wp/sections/appendix.tex +++ b/wp/sections/appendix.tex @@ -16,113 +16,113 @@ \section*{Available Rules} \hline \textbf{diKTat rule} & \textbf{code style} & \textbf{autofix} & \textbf{config} \\ \hline -VARIABLE\underline{ }NAME\underline{ }INCORRECT & \hyperref[sec:1.1.1]{ 1.1.1} & no & no \\ -VARIABLE\underline{ }HAS\underline{ }PREFIX & \hyperref[sec:1.1.1]{ 1.1.1} & yes & no \\ -IDENTIFIER\underline{ }LENGTH & \hyperref[sec:1.1.1]{ 1.1.1} & no & no \\ -GENERIC\underline{ }NAME & \hyperref[sec:1.1.1]{ 1.1.1} & yes & no \\ -BACKTICKS\underline{ }PROHIBITED & \hyperref[sec:1.1.1]{ 1.1.1} & no & no \\ -FILE\underline{ }NAME\underline{ }INCORRECT & \hyperref[sec:1.1.1]{ 1.1.1} & yes & no \\ -EXCEPTION\underline{ }SUFFIX & \hyperref[sec:1.1.1]{ 1.1.1} & yes & no \\ -CONFUSING\underline{ }IDENTIFIER\underline{ }NAMING & \hyperref[sec:1.1.1]{ 1.1.1} & no & no \\ -PACKAGE\underline{ }NAME\underline{ }MISSING & \hyperref[sec:1.2.1]{ 1.2.1} & yes & no \\ -PACKAGE\underline{ }NAME\underline{ }INCORRECT\underline{ }CASE & \hyperref[sec:1.2.1]{ 1.2.1} & yes & no \\ -PACKAGE\underline{ }NAME\underline{ }INCORRECT\underline{ }PREFIX & \hyperref[sec:1.2.1]{ 1.2.1} & yes & no \\ -PACKAGE\underline{ }NAME\underline{ }INCORRECT\underline{ }SYMBOLS & \hyperref[sec:1.2.1]{ 1.2.1} & no & no \\ -PACKAGE\underline{ }NAME\underline{ }INCORRECT\underline{ }PATH & \hyperref[sec:1.2.1]{ 1.2.1} & yes & no \\ -INCORRECT\underline{ }PACKAGE\underline{ }SEPARATOR & \hyperref[sec:1.2.1]{ 1.2.1} & yes & no \\ -CLASS\underline{ }NAME\underline{ }INCORRECT & \hyperref[sec:1.3.1]{ 1.3.1} & yes & no \\ -OBJECT\underline{ }NAME\underline{ }INCORRECT & \hyperref[sec:1.3.1]{ 1.3.1} & yes & no \\ -ENUM\underline{ }VALUE & \hyperref[sec:1.3.1]{ 1.3.1} & yes & enumStyle: snakeCase, pascalCase \\ -FUNCTION\underline{ }NAME\underline{ }INCORRECT\underline{ }CASE & \hyperref[sec:1.4.1]{ 1.4.1} & yes & no \\ -CONSTANT\underline{ }UPPERCASE & \hyperref[sec:1.5.1]{ 1.5.1} & yes & no \\ -VARIABLE\underline{ }NAME\underline{ }INCORRECT\underline{ }FORMAT & \hyperref[sec:1.6.1]{ 1.6.1} & yes & no \\ -FUNCTION\underline{ }BOOLEAN\underline{ }PREFIX & \hyperref[sec:1.6.2]{ 1.6.2} & yes & no \\ -MISSING\underline{ }KDOC\underline{ }TOP\underline{ }LEVEL & \hyperref[sec:2.1.1]{ 2.1.1} & no & no \\ -MISSING\underline{ }KDOC\underline{ }CLASS\underline{ }ELEMENTS & \hyperref[sec:2.1.1]{ 2.1.1} & no & no \\ -MISSING\underline{ }KDOC\underline{ }ON\underline{ }FUNCTION & \hyperref[sec:2.1.1]{ 2.1.1} & yes & no \\ -KDOC\underline{ }NO\underline{ }CONSTRUCTOR\underline{ }PROPERTY & \hyperref[sec:2.1.1]{ 2.1.1} & yes & no \\ -KDOC\underline{ }EXTRA\underline{ }PROPERTY & \hyperref[sec:2.1.1]{ 2.1.1} & no & no \\ -KDOC\underline{ }NO\underline{ }CONSTRUCTOR\underline{ }PROPERTY\underline{ }WITH\underline{ }COMMENT & \hyperref[sec:2.1.1]{ 2.1.1} & yes & no \\ -KDOC\underline{ }WITHOUT\underline{ }PARAM\underline{ }TAG & \hyperref[sec:2.1.2]{ 2.1.2} & yes & no \\ -KDOC\underline{ }WITHOUT\underline{ }RETURN\underline{ }TAG & \hyperref[sec:2.1.2]{ 2.1.2} & yes & no \\ -KDOC\underline{ }WITHOUT\underline{ }THROWS\underline{ }TAG & \hyperref[sec:2.1.2]{ 2.1.2} & yes & no \\ -KDOC\underline{ }EMPTY\underline{ }KDOC & \hyperref[sec:2.1.3]{ 2.1.3} & no & no \\ -KDOC\underline{ }WRONG\underline{ }SPACES\underline{ }AFTER\underline{ }TAG & \hyperref[sec:2.1.3]{ 2.1.3} & yes & no \\ -KDOC\underline{ }WRONG\underline{ }TAGS\underline{ }ORDER & \hyperref[sec:2.1.3]{ 2.1.3} & yes & no \\ -KDOC\underline{ }NEWLINES\underline{ }BEFORE\underline{ }BASIC\underline{ }TAGS & \hyperref[sec:2.1.3]{ 2.1.3} & yes & no \\ -KDOC\underline{ }NO\underline{ }NEWLINES\underline{ }BETWEEN\underline{ }BASIC\underline{ }TAGS & \hyperref[sec:2.1.3]{ 2.1.3} & yes & no \\ -KDOC\underline{ }NO\underline{ }NEWLINE\underline{ }AFTER\underline{ }SPECIAL\underline{ }TAGS & \hyperref[sec:2.1.3]{ 2.1.3} & yes & no \\ -KDOC\underline{ }NO\underline{ }DEPRECATED\underline{ }TAG & \hyperref[sec:2.1.3]{ 2.1.3} & yes & no \\ -KDOC\underline{ }NO\underline{ }EMPTY\underline{ }TAGS & \hyperref[sec:2.2.1]{ 2.2.1} & no & no \\ -HEADER\underline{ }WRONG\underline{ }FORMAT & \hyperref[sec:2.2.1]{ 2.2.1} & yes & no \\ -HEADER\underline{ }MISSING\underline{ }OR\underline{ }WRONG\underline{ }COPYRIGHT & \hyperref[sec:2.2.1]{ 2.2.1} & yes & mandatoryCopyright \\ -WRONG\underline{ }COPYRIGHT\underline{ }YEAR & \hyperref[sec:2.2.1]{ 2.2.1} & yes & no \\ -HEADER\underline{ }CONTAINS\underline{ }DATE\underline{ }OR\underline{ }AUTHOR & \hyperref[sec:2.2.1]{ 2.2.1} & no & no \\ -HEADER\underline{ }MISSING\underline{ }IN\underline{ }NON\underline{ }SINGLE\underline{ }CLASS\underline{ }FILE & \hyperref[sec:2.2.1]{ 2.2.1} & no & no \\ -HEADER\underline{ }NOT\underline{ }BEFORE\underline{ }PACKAGE & \hyperref[sec:2.2.1]{ 2.2.1} & yes & no \\ -KDOC\underline{ }TRIVIAL\underline{ }KDOC\underline{ }ON\underline{ }FUNCTION & \hyperref[sec:2.3.1]{ 2.3.1} & no & no \\ -WRONG\underline{ }NEWLINES\underline{ }AROUND\underline{ }KDOC & \hyperref[sec:2.4.1]{ 2.4.1} & yes & no \\ -FIRST\underline{ }COMMENT\underline{ }NO\underline{ }SPACES & \hyperref[sec:2.4.1]{ 2.4.1} & yes & no \\ -COMMENT\underline{ }WHITE\underline{ }SPACE & \hyperref[sec:2.4.1]{ 2.4.1} & yes & maxSpaces \\ -IF\underline{ }ELSE\underline{ }COMMENTS & \hyperref[sec:2.4.1]{ 2.4.1} & yes & no \\ -COMMENTED\underline{ }OUT\underline{ }CODE & \hyperref[sec:2.4.2]{ 2.4.2} & no & no \\ -FILE\underline{ }IS\underline{ }TOO\underline{ }LONG & \hyperref[sec:3.1.1]{ 3.1.1} & no & maxSize ignoreFolders \\ -FILE\underline{ }CONTAINS\underline{ }ONLY\underline{ }COMMENTS & \hyperref[sec:3.1.2]{ 3.1.2} & no & no \\ -FILE\underline{ }INCORRECT\underline{ }BLOCKS\underline{ }ORDER & \hyperref[sec:3.1.2]{ 3.1.2} & yes & no \\ -FILE\underline{ }NO\underline{ }BLANK\underline{ }LINE\underline{ }BETWEEN\underline{ }BLOCKS & \hyperref[sec:3.1.2]{ 3.1.2} & yes & no \\ -FILE\underline{ }UNORDERED\underline{ }IMPORTS & \hyperref[sec:3.1.2]{ 3.1.2} & yes & no \\ -FILE\underline{ }WILDCARD\underline{ }IMPORTS & \hyperref[sec:3.1.2]{ 3.1.2} & no & allowedWildcards \\ -FILE\underline{ }NAME\underline{ }MATCH\underline{ }CLASS & \hyperref[sec:3.1.2]{ 3.1.2} & yes & no \\ -WRONG\underline{ }ORDER\underline{ }IN\underline{ }CLASS\underline{ }LIKE\underline{ }STRUCTURES & \hyperref[sec:3.1.4]{ 3.1.4} & yes & no \\ -BLANK\underline{ }LINE\underline{ }BETWEEN\underline{ }PROPERTIES & \hyperref[sec:3.1.4]{ 3.1.4} & yes & no \\ -WRONG\underline{ }DECLARATIONS\underline{ }ORDER & \hyperref[sec:3.1.4]{ 3.1.4} & yes & no \\ -NO\underline{ }BRACES\underline{ }IN\underline{ }CONDITIONALS\underline{ }AND\underline{ }LOOPS & \hyperref[sec:3.2.1]{ 3.2.1} & yes & no \\ -BRACES\underline{ }BLOCK\underline{ }STRUCTURE\underline{ }ERROR & \hyperref[sec:3.2.2]{ 3.2.2} & yes & openBraceNewline closeBraceNewline \\ -WRONG\underline{ }INDENTATION & \hyperref[sec:3.3.1]{ 3.3.1} & yes & extendedIndentOfParameters alignedParameters extendedIndentAfterOperators extendedIndentBeforeDot indentationSize \\ -EMPTY\underline{ }BLOCK\underline{ }STRUCTURE\underline{ }ERROR & \hyperref[sec:3.4.1]{ 3.4.1} & yes & allowEmptyBlocks styleEmptyBlockWithNewline \\ -LONG\underline{ }LINE & \hyperref[sec:3.5.1]{ 3.5.1} & yes & lineLength \\ -MORE\underline{ }THAN\underline{ }ONE\underline{ }STATEMENT\underline{ }PER\underline{ }LINE & \hyperref[sec:3.6.1]{ 3.6.1} & yes & no \\ -REDUNDANT\underline{ }SEMICOLON & \hyperref[sec:3.6.2]{ 3.6.2} & yes & no \\ -WRONG\underline{ }NEWLINES & \hyperref[sec:3.6.2]{ 3.6.2} & yes & no \\ -TOO\underline{ }MANY\underline{ }BLANK\underline{ }LINES & \hyperref[sec:3.7.1]{ 3.7.1} & yes & no \\ -WRONG\underline{ }WHITESPACE & \hyperref[sec:3.8.1]{ 3.8.1} & yes & no \\ -TOO\underline{ }MANY\underline{ }CONSECUTIVE\underline{ }SPACES & \hyperref[sec:3.8.1]{ 3.8.1} & yes & maxSpaces saveInitialFormattingForEnums \\ -ENUMS\underline{ }SEPARATED & \hyperref[sec:3.9.1]{ 3.9.1} & yes & no \\ -LOCAL\underline{ }VARIABLE\underline{ }EARLY\underline{ }DECLARATION & \hyperref[sec:3.10.2]{ 3.10.2} & no & no \\ -WHEN\underline{ }WITHOUT\underline{ }ELSE & \hyperref[sec:3.11.1]{ 3.11.1} & yes & no \\ -ANNOTATION\underline{ }NEW\underline{ }LINE & \hyperref[sec:3.12.1]{ 3.12.1} & yes & no \\ -WRONG\underline{ }MULTIPLE\underline{ }MODIFIERS\underline{ }ORDER & \hyperref[sec:3.14.1]{ 3.14.1} & yes & no \\ -LONG\underline{ }NUMERICAL\underline{ }VALUES\underline{ }SEPARATED & \hyperref[sec:3.14.2]{ 3.14.2} & yes & maxLength \\ -STRING\underline{ }CONCATENATION & \hyperref[sec:3.15.1]{ 3.15.1} & no & no \\ -STRING\underline{ }TEMPLATE\underline{ }CURLY\underline{ }BRACES & \hyperref[sec:3.15.2]{ 3.15.2} & yes & no \\ -STRING\underline{ }TEMPLATE\underline{ }QUOTES & \hyperref[sec:3.15.2]{ 3.15.2} & yes & no \\ -FLOAT\underline{ }IN\underline{ }ACCURATE\underline{ }CALCULATIONS & \hyperref[sec:4.1.1]{ 4.1.1} & no & no \\ -SAY\underline{ }NO\underline{ }TO\underline{ }VAR & \hyperref[sec:4.1.3]{ 4.1.3} & no & no \\ -SMART\underline{ }CAST\underline{ }NEEDED & \hyperref[sec:4.2.1]{ 4.2.1} & yes & no \\ -TYPE\underline{ }ALIAS & \hyperref[sec:4.2.2]{ 4.2.2} & no & typeReferenceLength \\ -NULLABLE\underline{ }PROPERTY\underline{ }TYPE & \hyperref[sec:4.3.1]{ 4.3.1} & yes & no \\ -GENERIC\underline{ }VARIABLE\underline{ }WRONG\underline{ }DECLARATION & \hyperref[sec:4.3.2]{ 4.3.2} & yes & no \\ -AVOID\underline{ }NULL\underline{ }CHECKS & \hyperref[sec:4.3.3]{ 4.3.3} & no & no \\ -TOO\underline{ }LONG\underline{ }FUNCTION & \hyperref[sec:5.1.1]{ 5.1.1} & no & maxFunctionLength isIncludeHeader\\ -NESTED\underline{ }BLOCK & \hyperref[sec:5.1.2]{ 5.1.2} & no & maxNestedBlockQuantit\\ -AVOID\underline{ }NESTED\underline{ }FUNCTIONS & \hyperref[sec:5.1.3]{ 5.1.3} & yes & no \\ -LAMBDA\underline{ }IS\underline{ }NOT\underline{ }LAST\underline{ }PARAMETER & \hyperref[sec:5.2.1]{ 5.2.1} & no & no \\ -TOO\underline{ }MANY\underline{ }PARAMETERS & \hyperref[sec:5.2.2]{ 5.2.2} & no & maxParameterListSize \\ -WRONG\underline{ }OVERLOADING\underline{ }FUNCTION\underline{ }ARGUMENTS & \hyperref[sec:5.2.3]{ 5.2.3} & no & no \\ -SINGLE\underline{ }CONSTRUCTOR\underline{ }SHOULD\underline{ }BE\underline{ }PRIMARY & \hyperref[sec:6.1.1]{ 6.1.1} & yes & no \\ -USE\underline{ }DATA\underline{ }CLASS & \hyperref[sec:6.1.2]{ 6.1.2} & no & no \\ -EMPTY\underline{ }PRIMARY\underline{ }CONSTRUCTOR & \hyperref[sec:6.1.3]{ 6.1.3} & yes & no \\ -MULTIPLE\underline{ }INIT\underline{ }BLOCKS & \hyperref[sec:6.1.4]{ 6.1.4} & yes & no \\ -USELESS\underline{ }SUPERTYPE & \hyperref[sec:6.1.5]{ 6.1.5} & yes & no \\ -CLASS\underline{ }SHOULD\underline{ }NOT\underline{ }BE\underline{ }ABSTRACT & \hyperref[sec:6.1.6]{ 6.1.6} & yes & no \\ -NO\underline{ }CORRESPONDING\underline{ }PROPERTY & \hyperref[sec:6.1.7]{ 6.1.7} & no & no \\ -CUSTOM\underline{ }GETTERS\underline{ }SETTERS & \hyperref[sec:6.1.8]{ 6.1.8} & no & no \\ -WRONG\underline{ }NAME\underline{ }OF\underline{ }VARIABLE\underline{ }INSIDE\underline{ }ACCESSOR & \hyperref[sec:6.1.9]{ 6.1.9} & no & no \\ -TRIVIAL\underline{ }ACCESSORS\underline{ }ARE\underline{ }NOT\underline{ }RECOMMENDED & \hyperref[sec:6.1.10]{ 6.1.10} & yes & no \\ -COMPACT\underline{ }OBJECT\underline{ }INITIALIZATION & \hyperref[sec:6.1.11]{ 6.1.11} & yes & no \\ -EXTENSION\underline{ }FUNCTION\underline{ }SAME\underline{ }SIGNATURE & \hyperref[sec:6.2.2]{ 6.2.2} & no & no \\ -AVOID\underline{ }USING\underline{ }UTILITY\underline{ }CLASS & \hyperref[sec:6.4.1]{ 6.4.1} & no & no \\ -OBJECT\underline{ }IS\underline{ }PREFERRED & \hyperref[sec:6.4.2]{ 6.4.2} & yes & no \\ +VARIABLE\underline{ }NAME\underline{ }INCORRECT & \hyperref[sec:1.1.1]{1.1.1} & no & no \\ +VARIABLE\underline{ }HAS\underline{ }PREFIX & \hyperref[sec:1.1.1]{1.1.1} & yes & no \\ +IDENTIFIER\underline{ }LENGTH & \hyperref[sec:1.1.1]{1.1.1} & no & no \\ +GENERIC\underline{ }NAME & \hyperref[sec:1.1.1]{1.1.1} & yes & no \\ +BACKTICKS\underline{ }PROHIBITED & \hyperref[sec:1.1.1]{1.1.1} & no & no \\ +FILE\underline{ }NAME\underline{ }INCORRECT & \hyperref[sec:1.1.1]{1.1.1} & yes & no \\ +EXCEPTION\underline{ }SUFFIX & \hyperref[sec:1.1.1]{1.1.1} & yes & no \\ +CONFUSING\underline{ }IDENTIFIER\underline{ }NAMING & \hyperref[sec:1.1.1]{1.1.1} & no & no \\ +PACKAGE\underline{ }NAME\underline{ }MISSING & \hyperref[sec:1.2.1]{1.2.1} & yes & no \\ +PACKAGE\underline{ }NAME\underline{ }INCORRECT\underline{ }CASE & \hyperref[sec:1.2.1]{1.2.1} & yes & no \\ +PACKAGE\underline{ }NAME\underline{ }INCORRECT\underline{ }PREFIX & \hyperref[sec:1.2.1]{1.2.1} & yes & no \\ +PACKAGE\underline{ }NAME\underline{ }INCORRECT\underline{ }SYMBOLS & \hyperref[sec:1.2.1]{1.2.1} & no & no \\ +PACKAGE\underline{ }NAME\underline{ }INCORRECT\underline{ }PATH & \hyperref[sec:1.2.1]{1.2.1} & yes & no \\ +INCORRECT\underline{ }PACKAGE\underline{ }SEPARATOR & \hyperref[sec:1.2.1]{1.2.1} & yes & no \\ +CLASS\underline{ }NAME\underline{ }INCORRECT & \hyperref[sec:1.3.1]{1.3.1} & yes & no \\ +OBJECT\underline{ }NAME\underline{ }INCORRECT & \hyperref[sec:1.3.1]{1.3.1} & yes & no \\ +ENUM\underline{ }VALUE & \hyperref[sec:1.3.1]{1.3.1} & yes & enumStyle: snakeCase, pascalCase \\ +FUNCTION\underline{ }NAME\underline{ }INCORRECT\underline{ }CASE & \hyperref[sec:1.4.1]{1.4.1} & yes & no \\ +CONSTANT\underline{ }UPPERCASE & \hyperref[sec:1.5.1]{1.5.1} & yes & no \\ +VARIABLE\underline{ }NAME\underline{ }INCORRECT\underline{ }FORMAT & \hyperref[sec:1.6.1]{1.6.1} & yes & no \\ +FUNCTION\underline{ }BOOLEAN\underline{ }PREFIX & \hyperref[sec:1.6.2]{1.6.2} & yes & no \\ +MISSING\underline{ }KDOC\underline{ }TOP\underline{ }LEVEL & \hyperref[sec:2.1.1]{2.1.1} & no & no \\ +MISSING\underline{ }KDOC\underline{ }CLASS\underline{ }ELEMENTS & \hyperref[sec:2.1.1]{2.1.1} & no & no \\ +MISSING\underline{ }KDOC\underline{ }ON\underline{ }FUNCTION & \hyperref[sec:2.1.1]{2.1.1} & yes & no \\ +KDOC\underline{ }NO\underline{ }CONSTRUCTOR\underline{ }PROPERTY & \hyperref[sec:2.1.1]{2.1.1} & yes & no \\ +KDOC\underline{ }EXTRA\underline{ }PROPERTY & \hyperref[sec:2.1.1]{2.1.1} & no & no \\ +KDOC\underline{ }NO\underline{ }CONSTRUCTOR\underline{ }PROPERTY\underline{ }WITH\underline{ }COMMENT & \hyperref[sec:2.1.1]{2.1.1} & yes & no \\ +KDOC\underline{ }WITHOUT\underline{ }PARAM\underline{ }TAG & \hyperref[sec:2.1.2]{2.1.2} & yes & no \\ +KDOC\underline{ }WITHOUT\underline{ }RETURN\underline{ }TAG & \hyperref[sec:2.1.2]{2.1.2} & yes & no \\ +KDOC\underline{ }WITHOUT\underline{ }THROWS\underline{ }TAG & \hyperref[sec:2.1.2]{2.1.2} & yes & no \\ +KDOC\underline{ }EMPTY\underline{ }KDOC & \hyperref[sec:2.1.3]{2.1.3} & no & no \\ +KDOC\underline{ }WRONG\underline{ }SPACES\underline{ }AFTER\underline{ }TAG & \hyperref[sec:2.1.3]{2.1.3} & yes & no \\ +KDOC\underline{ }WRONG\underline{ }TAGS\underline{ }ORDER & \hyperref[sec:2.1.3]{2.1.3} & yes & no \\ +KDOC\underline{ }NEWLINES\underline{ }BEFORE\underline{ }BASIC\underline{ }TAGS & \hyperref[sec:2.1.3]{2.1.3} & yes & no \\ +KDOC\underline{ }NO\underline{ }NEWLINES\underline{ }BETWEEN\underline{ }BASIC\underline{ }TAGS & \hyperref[sec:2.1.3]{2.1.3} & yes & no \\ +KDOC\underline{ }NO\underline{ }NEWLINE\underline{ }AFTER\underline{ }SPECIAL\underline{ }TAGS & \hyperref[sec:2.1.3]{2.1.3} & yes & no \\ +KDOC\underline{ }NO\underline{ }DEPRECATED\underline{ }TAG & \hyperref[sec:2.1.3]{2.1.3} & yes & no \\ +KDOC\underline{ }NO\underline{ }EMPTY\underline{ }TAGS & \hyperref[sec:2.2.1]{2.2.1} & no & no \\ +HEADER\underline{ }WRONG\underline{ }FORMAT & \hyperref[sec:2.2.1]{2.2.1} & yes & no \\ +HEADER\underline{ }MISSING\underline{ }OR\underline{ }WRONG\underline{ }COPYRIGHT & \hyperref[sec:2.2.1]{2.2.1} & yes & mandatoryCopyright \\ +WRONG\underline{ }COPYRIGHT\underline{ }YEAR & \hyperref[sec:2.2.1]{2.2.1} & yes & no \\ +HEADER\underline{ }CONTAINS\underline{ }DATE\underline{ }OR\underline{ }AUTHOR & \hyperref[sec:2.2.1]{2.2.1} & no & no \\ +HEADER\underline{ }MISSING\underline{ }IN\underline{ }NON\underline{ }SINGLE\underline{ }CLASS\underline{ }FILE & \hyperref[sec:2.2.1]{2.2.1} & no & no \\ +HEADER\underline{ }NOT\underline{ }BEFORE\underline{ }PACKAGE & \hyperref[sec:2.2.1]{2.2.1} & yes & no \\ +KDOC\underline{ }TRIVIAL\underline{ }KDOC\underline{ }ON\underline{ }FUNCTION & \hyperref[sec:2.3.1]{2.3.1} & no & no \\ +WRONG\underline{ }NEWLINES\underline{ }AROUND\underline{ }KDOC & \hyperref[sec:2.4.1]{2.4.1} & yes & no \\ +FIRST\underline{ }COMMENT\underline{ }NO\underline{ }SPACES & \hyperref[sec:2.4.1]{2.4.1} & yes & no \\ +COMMENT\underline{ }WHITE\underline{ }SPACE & \hyperref[sec:2.4.1]{2.4.1} & yes & maxSpaces \\ +IF\underline{ }ELSE\underline{ }COMMENTS & \hyperref[sec:2.4.1]{2.4.1} & yes & no \\ +COMMENTED\underline{ }OUT\underline{ }CODE & \hyperref[sec:2.4.2]{2.4.2} & no & no \\ +FILE\underline{ }IS\underline{ }TOO\underline{ }LONG & \hyperref[sec:3.1.1]{3.1.1} & no & maxSize ignoreFolders \\ +FILE\underline{ }CONTAINS\underline{ }ONLY\underline{ }COMMENTS & \hyperref[sec:3.1.2]{3.1.2} & no & no \\ +FILE\underline{ }INCORRECT\underline{ }BLOCKS\underline{ }ORDER & \hyperref[sec:3.1.2]{3.1.2} & yes & no \\ +FILE\underline{ }NO\underline{ }BLANK\underline{ }LINE\underline{ }BETWEEN\underline{ }BLOCKS & \hyperref[sec:3.1.2]{3.1.2} & yes & no \\ +FILE\underline{ }UNORDERED\underline{ }IMPORTS & \hyperref[sec:3.1.2]{3.1.2} & yes & no \\ +FILE\underline{ }WILDCARD\underline{ }IMPORTS & \hyperref[sec:3.1.2]{3.1.2} & no & allowedWildcards \\ +FILE\underline{ }NAME\underline{ }MATCH\underline{ }CLASS & \hyperref[sec:3.1.2]{3.1.2} & yes & no \\ +WRONG\underline{ }ORDER\underline{ }IN\underline{ }CLASS\underline{ }LIKE\underline{ }STRUCTURES & \hyperref[sec:3.1.4]{3.1.4} & yes & no \\ +BLANK\underline{ }LINE\underline{ }BETWEEN\underline{ }PROPERTIES & \hyperref[sec:3.1.4]{3.1.4} & yes & no \\ +WRONG\underline{ }DECLARATIONS\underline{ }ORDER & \hyperref[sec:3.1.4]{3.1.4} & yes & no \\ +NO\underline{ }BRACES\underline{ }IN\underline{ }CONDITIONALS\underline{ }AND\underline{ }LOOPS & \hyperref[sec:3.2.1]{3.2.1} & yes & no \\ +BRACES\underline{ }BLOCK\underline{ }STRUCTURE\underline{ }ERROR & \hyperref[sec:3.2.2]{3.2.2} & yes & openBraceNewline closeBraceNewline \\ +WRONG\underline{ }INDENTATION & \hyperref[sec:3.3.1]{3.3.1} & yes & extendedIndentOfParameters alignedParameters extendedIndentAfterOperators extendedIndentBeforeDot indentationSize \\ +EMPTY\underline{ }BLOCK\underline{ }STRUCTURE\underline{ }ERROR & \hyperref[sec:3.4.1]{3.4.1} & yes & allowEmptyBlocks styleEmptyBlockWithNewline \\ +LONG\underline{ }LINE & \hyperref[sec:3.5.1]{3.5.1} & yes & lineLength \\ +MORE\underline{ }THAN\underline{ }ONE\underline{ }STATEMENT\underline{ }PER\underline{ }LINE & \hyperref[sec:3.6.1]{3.6.1} & yes & no \\ +REDUNDANT\underline{ }SEMICOLON & \hyperref[sec:3.6.2]{3.6.2} & yes & no \\ +WRONG\underline{ }NEWLINES & \hyperref[sec:3.6.2]{3.6.2} & yes & no \\ +TOO\underline{ }MANY\underline{ }BLANK\underline{ }LINES & \hyperref[sec:3.7.1]{3.7.1} & yes & no \\ +WRONG\underline{ }WHITESPACE & \hyperref[sec:3.8.1]{3.8.1} & yes & no \\ +TOO\underline{ }MANY\underline{ }CONSECUTIVE\underline{ }SPACES & \hyperref[sec:3.8.1]{3.8.1} & yes & maxSpaces saveInitialFormattingForEnums \\ +ENUMS\underline{ }SEPARATED & \hyperref[sec:3.9.1]{3.9.1} & yes & no \\ +LOCAL\underline{ }VARIABLE\underline{ }EARLY\underline{ }DECLARATION & \hyperref[sec:3.10.2]{3.10.2} & no & no \\ +WHEN\underline{ }WITHOUT\underline{ }ELSE & \hyperref[sec:3.11.1]{3.11.1} & yes & no \\ +ANNOTATION\underline{ }NEW\underline{ }LINE & \hyperref[sec:3.12.1]{3.12.1} & yes & no \\ +WRONG\underline{ }MULTIPLE\underline{ }MODIFIERS\underline{ }ORDER & \hyperref[sec:3.14.1]{3.14.1} & yes & no \\ +LONG\underline{ }NUMERICAL\underline{ }VALUES\underline{ }SEPARATED & \hyperref[sec:3.14.2]{3.14.2} & yes & maxNumberLength maxBlockLength \\ +STRING\underline{ }CONCATENATION & \hyperref[sec:3.15.1]{3.15.1} & no & no \\ +STRING\underline{ }TEMPLATE\underline{ }CURLY\underline{ }BRACES & \hyperref[sec:3.15.2]{3.15.2} & yes & no \\ +STRING\underline{ }TEMPLATE\underline{ }QUOTES & \hyperref[sec:3.15.2]{3.15.2} & yes & no \\ +FLOAT\underline{ }IN\underline{ }ACCURATE\underline{ }CALCULATIONS & \hyperref[sec:4.1.1]{4.1.1} & no & no \\ +SAY\underline{ }NO\underline{ }TO\underline{ }VAR & \hyperref[sec:4.1.3]{4.1.3} & no & no \\ +SMART\underline{ }CAST\underline{ }NEEDED & \hyperref[sec:4.2.1]{4.2.1} & yes & no \\ +TYPE\underline{ }ALIAS & \hyperref[sec:4.2.2]{4.2.2} & no & typeReferenceLength \\ +NULLABLE\underline{ }PROPERTY\underline{ }TYPE & \hyperref[sec:4.3.1]{4.3.1} & yes & no \\ +GENERIC\underline{ }VARIABLE\underline{ }WRONG\underline{ }DECLARATION & \hyperref[sec:4.3.2]{4.3.2} & yes & no \\ +AVOID\underline{ }NULL\underline{ }CHECKS & \hyperref[sec:4.3.3]{4.3.3} & no & no \\ +TOO\underline{ }LONG\underline{ }FUNCTION & \hyperref[sec:5.1.1]{5.1.1} & no & maxFunctionLength isIncludeHeader \\ +NESTED\underline{ }BLOCK & \hyperref[sec:5.1.2]{5.1.2} & no & maxNestedBlockQuantit\\ +AVOID\underline{ }NESTED\underline{ }FUNCTIONS & \hyperref[sec:5.1.3]{5.1.3} & yes & no \\ +LAMBDA\underline{ }IS\underline{ }NOT\underline{ }LAST\underline{ }PARAMETER & \hyperref[sec:5.2.1]{5.2.1} & no & no \\ +TOO\underline{ }MANY\underline{ }PARAMETERS & \hyperref[sec:5.2.2]{5.2.2} & no & maxParameterListSize \\ +WRONG\underline{ }OVERLOADING\underline{ }FUNCTION\underline{ }ARGUMENTS & \hyperref[sec:5.2.3]{5.2.3} & no & no \\ +SINGLE\underline{ }CONSTRUCTOR\underline{ }SHOULD\underline{ }BE\underline{ }PRIMARY & \hyperref[sec:6.1.1]{6.1.1} & yes & no \\ +USE\underline{ }DATA\underline{ }CLASS & \hyperref[sec:6.1.2]{6.1.2} & no & no \\ +EMPTY\underline{ }PRIMARY\underline{ }CONSTRUCTOR & \hyperref[sec:6.1.3]{6.1.3} & yes & no \\ +MULTIPLE\underline{ }INIT\underline{ }BLOCKS & \hyperref[sec:6.1.4]{6.1.4} & yes & no \\ +USELESS\underline{ }SUPERTYPE & \hyperref[sec:6.1.5]{6.1.5} & yes & no \\ +CLASS\underline{ }SHOULD\underline{ }NOT\underline{ }BE\underline{ }ABSTRACT & \hyperref[sec:6.1.6]{6.1.6} & yes & no \\ +NO\underline{ }CORRESPONDING\underline{ }PROPERTY & \hyperref[sec:6.1.7]{6.1.7} & no & no \\ +CUSTOM\underline{ }GETTERS\underline{ }SETTERS & \hyperref[sec:6.1.8]{6.1.8} & no & no \\ +WRONG\underline{ }NAME\underline{ }OF\underline{ }VARIABLE\underline{ }INSIDE\underline{ }ACCESSOR & \hyperref[sec:6.1.9]{6.1.9} & no & no \\ +TRIVIAL\underline{ }ACCESSORS\underline{ }ARE\underline{ }NOT\underline{ }RECOMMENDED & \hyperref[sec:6.1.10]{6.1.10} & yes & no \\ +COMPACT\underline{ }OBJECT\underline{ }INITIALIZATION & \hyperref[sec:6.1.11]{6.1.11} & yes & no \\ +EXTENSION\underline{ }FUNCTION\underline{ }SAME\underline{ }SIGNATURE & \hyperref[sec:6.2.2]{6.2.2} & no & no \\ +AVOID\underline{ }USING\underline{ }UTILITY\underline{ }CLASS & \hyperref[sec:6.4.1]{6.4.1} & no & no \\ +OBJECT\underline{ }IS\underline{ }PREFERRED & \hyperref[sec:6.4.2]{6.4.2} & yes & no \\ \hline \end{longtable} \lstMakeShortInline[basicstyle=\ttfamily\bfseries]` @@ -518,7 +518,7 @@ \subsubsection*{\textbf{1.1.1 Identifiers naming conventions}} \begin{center} -\begin{tabular}{ |p{5,0cm}|p{5,0cm}|p{5,0cm}| } +\begin{tabular}{ |p{5.0cm}|p{5.0cm}|p{5.0cm}| } \hline @@ -564,7 +564,7 @@ \subsubsection*{\textbf{1.1.1 Identifiers naming conventions}} \begin{center} -\begin{tabular}{ |p{5,0cm}|p{5,0cm}|p{5,0cm}| } +\begin{tabular}{ |p{5.0cm}|p{5.0cm}|p{5.0cm}| } \hline @@ -608,7 +608,7 @@ \subsubsection*{\textbf{1.1.1 Identifiers naming conventions}} \begin{center} -\begin{tabular}{ |p{7,5cm}|p{7,5cm}| } +\begin{tabular}{ |p{7.5cm}|p{7.5cm}| } \hline @@ -2216,7 +2216,7 @@ \subsection*{\textbf{3.8 Horizontal space}} This section describes general rules and recommendations for using spaces in the code. -\subsubsection*{\textbf{3.8.1}} +\subsubsection*{\textbf{3.8.1: Usage of whitespace for code separation}} \leavevmode\newline \label{sec:3.8.1} @@ -2352,7 +2352,7 @@ \subsubsection*{\textbf{3.8.1}} -\subsubsection*{\textbf{3.8.2}} +\subsubsection*{\textbf{3.8.2: No spaces for horizontal alignment}} \leavevmode\newline \label{sec:3.8.2} @@ -2634,7 +2634,7 @@ \subsubsection*{\textbf{3.14.1 Declaration with multiple modifiers}} \end{lstlisting} -\subsubsection*{\textbf{3.14.2}} +\subsubsection*{\textbf{3.14.2: Separate long numerical values with an underscore}} \leavevmode\newline \label{sec:3.14.2} @@ -2793,7 +2793,7 @@ \subsubsection*{\textbf{4.1.1 Do not use Float and Double types when accurate ca \end{lstlisting} -\subsubsection*{\textbf{4.1.2}} +\subsubsection*{\textbf{4.1.2: Comparing numeric float type values}} \leavevmode\newline \label{sec:4.1.2} @@ -2861,7 +2861,7 @@ \subsection*{\textbf{4.2 Types}} This section provides recommendations for using types. -\subsubsection*{\textbf{4.2.1}} +\subsubsection*{\textbf{4.2.1: Use Contracts and smart cast as much as possible}} \leavevmode\newline \label{sec:4.2.1} @@ -2931,7 +2931,7 @@ \subsubsection*{\textbf{4.2.1}} \end{lstlisting} -\subsubsection*{\textbf{4.2.2}} +\subsubsection*{\textbf{4.2.2: Try to use type alias to represent types making code more readable}} \leavevmode\newline \label{sec:4.2.2} @@ -2980,7 +2980,7 @@ \subsection*{\textbf{4.3 Null safety and variable declarations}} -\subsubsection*{\textbf{4.3.1}} +\subsubsection*{\textbf{4.3.1: Avoid declaring variables with nullable types}} \leavevmode\newline \label{sec:4.3.1} @@ -3025,7 +3025,7 @@ \subsubsection*{\textbf{4.3.1}} \end{lstlisting} -\subsubsection*{\textbf{4.3.2}} +\subsubsection*{\textbf{4.3.2: Variables of generic types should have an explicit type declaration}} \leavevmode\newline \label{sec:4.3.2} From cea7a7a15667a5e75688b496daa01e4261a3722f Mon Sep 17 00:00:00 2001 From: Andrey Kuleshov Date: Wed, 13 Jan 2021 15:21:25 +0300 Subject: [PATCH 02/11] Updates to the codestyle (#702) Updates to the codestyle ### What's done: Regenerated the codestyle --- README.md | 2 +- info/guide/diktat-coding-convention.md | 8 ++++++++ info/guide/guide-TOC.md | 3 +++ info/guide/guide-chapter-0.md | 5 +++++ wp/sections/appendix.tex | 16 ++++++++++++++++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 314ee429e7..46cfa6a1c7 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Now diKTat was already added to the lists of [static analysis tools](https://git | | | | | | --- | --- | --- | --- | -|[DiKTat codestyle](info/guide/diktat-coding-convention.md)|[Supported Rules](info/available-rules.md) | [Examples of Usage](https://github.com/akuleshov7/diktat-examples) | [Online Demo](https://ktlint-demo.herokuapp.com) | +|[DiKTat codestyle](info/guide/diktat-coding-convention.md)|[Supported Rules](info/available-rules.md) | [Examples of Usage](https://github.com/akuleshov7/diktat-examples) | [Online Demo](https://ktlint-demo.herokuapp.com) | [Whitepaper](wp/wp.pdf) | ## Why should I use diktat in my CI/CD? diff --git a/info/guide/diktat-coding-convention.md b/info/guide/diktat-coding-convention.md index e6e3fbde56..0450dc2531 100644 --- a/info/guide/diktat-coding-convention.md +++ b/info/guide/diktat-coding-convention.md @@ -1,3 +1,6 @@ + + +# Diktat Coding Style Guide, v.0.0.1 # Table of contents I [Preface](#c0) @@ -107,6 +110,11 @@ I [Preface](#c0) * [6.4.2 Objects should be used for Stateless Interfaces](#r6.4.2) +# Diktat Coding Style Guide +# International version, v.0.0.1 + + + ## Preface ### Purpose of this document diff --git a/info/guide/guide-TOC.md b/info/guide/guide-TOC.md index ec5ef6e66d..524e30dad2 100644 --- a/info/guide/guide-TOC.md +++ b/info/guide/guide-TOC.md @@ -1,3 +1,6 @@ + + +# Diktat Coding Style Guide, v.0.0.1 # Table of contents I [Preface](#c0) diff --git a/info/guide/guide-chapter-0.md b/info/guide/guide-chapter-0.md index 7d010dbacf..54774996a7 100644 --- a/info/guide/guide-chapter-0.md +++ b/info/guide/guide-chapter-0.md @@ -1,3 +1,8 @@ +# Diktat Coding Style Guide +# International version, v.0.0.1 + + + ## Preface ### Purpose of this document diff --git a/wp/sections/appendix.tex b/wp/sections/appendix.tex index ef8f2b9eae..e7c8fbcddc 100644 --- a/wp/sections/appendix.tex +++ b/wp/sections/appendix.tex @@ -127,6 +127,12 @@ \section*{Available Rules} \end{longtable} \lstMakeShortInline[basicstyle=\ttfamily\bfseries]` +\hspace{0.0cm}\hyperref[sec:]{} + +\section*{Diktat Coding Style Guide, v.0.0.1} + +\hspace{0.0cm}\hyperref[sec:]{} + \section*{Table of contents} \hspace{0.0cm}\hyperref[sec:]{I Preface} @@ -343,6 +349,16 @@ \section*{Table of contents} \hspace{0.0cm}\hyperref[sec:]{} +\section*{Diktat Coding Style Guide} + +\section*{International version, v.0.0.1} + +\hspace{0.0cm}\hyperref[sec:]{} + +\hspace{0.0cm}\hyperref[sec:]{} + +\hspace{0.0cm}\hyperref[sec:]{} + \subsection*{\textbf{Purpose of this document}} \label{sec:} From 5cb0ce501c185d444416dad1aa2f3a4d14446478 Mon Sep 17 00:00:00 2001 From: Peter Trifanov Date: Wed, 13 Jan 2021 17:59:48 +0300 Subject: [PATCH 03/11] Minor infrastructure improvements (#700) ### What's done: * Fixed kotlin compiler warnings * Updated version in build.gradle.kts for diktat-gradle-plugin * Added update of info/buildSrc/gradle.properties version during release workflow * Run gradle functional tests in parallel * One-phase build in build_and_test.yml instead of two --- .github/workflows/build_and_test.yml | 4 +--- .github/workflows/release.yml | 2 ++ diktat-gradle-plugin/build.gradle.kts | 3 ++- diktat-rules/pom.xml | 1 + .../diktat/ruleset/rules/identifiers/LocalVariablesRule.kt | 6 +++--- .../kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt | 4 ++-- .../org/cqfn/diktat/ruleset/utils/search/VariablesSearch.kt | 2 +- .../ruleset/chapter3/spaces/WhiteSpaceRuleWarnTest.kt | 2 +- .../diktat/ruleset/utils/VariablesWithUsagesSearchTest.kt | 1 - 9 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 6dbc1c6113..5f3983c7f5 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -22,10 +22,8 @@ jobs: key: ${{ runner.os }}-maven-build-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os }}-maven-build- - - name: Maven Package - run: mvn -B clean package -DskipTests - name: Maven Install - run: mvn -B install + run: mvn -B clean install - name: Code coverage report uses: codecov/codecov-action@v1 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c2260a5bbb..f864cb1cd6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -78,6 +78,8 @@ jobs: sed -i "s/$PREVIOUS_VERSION/$RELEASE_VERSION/g" $file || echo "File $file hasn't been updated!" cp diktat-rules/src/main/resources/diktat-analysis.yml $(dirname $file) done + next_snapshot_version=$(printf 'VERSION=${project.version}\n0\n' | mvn help:evaluate | grep '^VERSION' | cut -d= -f2) + echo "version=$next_snapshot_version" > info/buildSrc/gradle.properties - name: Create pull request uses: peter-evans/create-pull-request@v3 with: diff --git a/diktat-gradle-plugin/build.gradle.kts b/diktat-gradle-plugin/build.gradle.kts index 08f576145d..5bf9b08466 100644 --- a/diktat-gradle-plugin/build.gradle.kts +++ b/diktat-gradle-plugin/build.gradle.kts @@ -20,7 +20,7 @@ repositories { // default value is needed for correct gradle loading in IDEA; actual value from maven is used during build val ktlintVersion = project.properties.getOrDefault("ktlintVersion", "0.39.0") as String -val diktatVersion = project.version.takeIf { it.toString() != Project.DEFAULT_VERSION } ?: "0.2.0" +val diktatVersion = project.version.takeIf { it.toString() != Project.DEFAULT_VERSION } ?: "0.3.0" val junitVersion = project.properties.getOrDefault("junitVersion", "5.7.0") as String val jacocoVersion = project.properties.getOrDefault("jacocoVersion", "0.8.6") as String dependencies { @@ -98,6 +98,7 @@ tasks.getByName("functionalTest") { dependsOn("test") testClassesDirs = functionalTest.output.classesDirs classpath = functionalTest.runtimeClasspath + maxParallelForks = Runtime.getRuntime().availableProcessors() doLast { if (getCurrentOperatingSystem().isWindows) { // workaround for https://github.com/koral--/jacoco-gradle-testkit-plugin/issues/9 diff --git a/diktat-rules/pom.xml b/diktat-rules/pom.xml index 2c166e9909..280f6d6ceb 100644 --- a/diktat-rules/pom.xml +++ b/diktat-rules/pom.xml @@ -110,6 +110,7 @@ + src/main/kotlin src/test/kotlin ${project.basedir}/src/main/kotlin diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/identifiers/LocalVariablesRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/identifiers/LocalVariablesRule.kt index dbcd5a8061..9c4676ccf7 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/identifiers/LocalVariablesRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/identifiers/LocalVariablesRule.kt @@ -91,7 +91,7 @@ class LocalVariablesRule(private val configRules: List) : Rule("loc val declarationScope = property.getDeclarationScope() val firstUsageStatementLine = getFirstUsageStatementOrBlock(usages, declarationScope).node.getLineNumber() - val firstUsage = usages.minBy { it.node.getLineNumber() }!! + val firstUsage = usages.minByOrNull { it.node.getLineNumber() }!! // should skip val and var before it's statement val offset = property @@ -184,7 +184,7 @@ class LocalVariablesRule(private val configRules: List) : Rule("loc */ @Suppress("UnsafeCallOnNullableType", "GENERIC_VARIABLE_WRONG_DECLARATION") private fun getFirstUsageStatementOrBlock(usages: List, declarationScope: KtBlockExpression?): PsiElement { - val firstUsage = usages.minBy { it.node.getLineNumber() }!! + val firstUsage = usages.minByOrNull { it.node.getLineNumber() }!! val firstUsageScope = firstUsage.getParentOfType(true) return if (firstUsageScope == declarationScope) { @@ -194,7 +194,7 @@ class LocalVariablesRule(private val configRules: List) : Rule("loc .find { it.parent == declarationScope }!! } else { // first usage is in deeper block compared to declaration, need to check how close is declaration to the first line of the block - usages.minBy { it.node.getLineNumber() }!! + usages.minByOrNull { it.node.getLineNumber() }!! .parentsWithSelf .find { it.parent == declarationScope }!! } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt index 9acba46866..157dddcb5f 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt @@ -603,7 +603,7 @@ fun ASTNode.isChildAfterAnother(child: ASTNode, afterChild: ASTNode): Boolean = * @return boolean result */ fun ASTNode.isChildAfterGroup(child: ASTNode, group: List): Boolean = - getChildren(null).indexOf(child) > (group.map { getChildren(null).indexOf(it) }.max() ?: 0) + getChildren(null).indexOf(child) > (group.map { getChildren(null).indexOf(it) }.maxOrNull() ?: 0) /** * Checks whether [child] is before [beforeChild] among the children of [this] node @@ -637,7 +637,7 @@ fun ASTNode.areChildrenBeforeChild(children: List, beforeChild: ASTNode @Suppress("UnsafeCallOnNullableType") fun ASTNode.areChildrenBeforeGroup(children: List, group: List): Boolean { require(children.isNotEmpty() && group.isNotEmpty()) { "no sense to operate on empty lists" } - return children.map { getChildren(null).indexOf(it) }.max()!! < group.map { getChildren(null).indexOf(it) }.min()!! + return children.map { getChildren(null).indexOf(it) }.maxOrNull()!! < group.map { getChildren(null).indexOf(it) }.minOrNull()!! } /** diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/search/VariablesSearch.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/search/VariablesSearch.kt index e873f1dd83..fbc1789e8d 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/search/VariablesSearch.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/search/VariablesSearch.kt @@ -110,5 +110,5 @@ abstract class VariablesSearch(val node: ASTNode, private val filterForVariables * * @param node an [ASTNode] */ -@SuppressWarnings("FunctionOnlyReturningConstant") +@Suppress("UNUSED_PARAMETER", "FunctionOnlyReturningConstant") fun default(node: KtProperty) = true diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/spaces/WhiteSpaceRuleWarnTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/spaces/WhiteSpaceRuleWarnTest.kt index ad68718a6b..04e850c62f 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/spaces/WhiteSpaceRuleWarnTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/spaces/WhiteSpaceRuleWarnTest.kt @@ -351,7 +351,7 @@ class WhiteSpaceRuleWarnTest : LintTestBase(::WhiteSpaceRule) { @Test @Tag(WarningNames.WRONG_WHITESPACE) - fun `there should be no space before ? in nullable types`() { + fun `there should be no space before question mark in nullable types`() { lintMethod( """ |class Example { diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/VariablesWithUsagesSearchTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/VariablesWithUsagesSearchTest.kt index d0369f181c..5264de2399 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/VariablesWithUsagesSearchTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/VariablesWithUsagesSearchTest.kt @@ -332,7 +332,6 @@ class VariablesWithUsagesSearchTest { val var1 = keys.elementAt(0) val var2 = keys.elementAt(1) val var3 = keys.elementAt(2) - val var4 = keys.elementAt(3) assertEquals("var v = 0", var1) assertEquals(0, vars[var1]?.size) assertEquals("var v = 1", var2) From 9b295417736b23a8ed34374514558ce3671c5031 Mon Sep 17 00:00:00 2001 From: Peter Trifanov Date: Thu, 14 Jan 2021 12:39:55 +0300 Subject: [PATCH 04/11] Check whether @since tag contains date or version (#694) ### What's done: * Added logic * Added tests * Renamed warning * Updated docs on chapter 2 * Pass version regex via configuration --- diktat-analysis.yml | 8 +- .../src/main/kotlin/generated/WarningNames.kt | 4 +- .../cqfn/diktat/ruleset/constants/Warnings.kt | 2 +- .../diktat/ruleset/rules/IdentifierNaming.kt | 2 +- .../rules/comments/HeaderCommentRule.kt | 20 ++-- .../ruleset/rules/kdoc/KdocFormatting.kt | 67 +++++++++++++ .../main/resources/diktat-analysis-huawei.yml | 8 +- .../src/main/resources/diktat-analysis.yml | 8 +- .../ruleset/chapter2/HeaderCommentRuleTest.kt | 22 +---- .../ruleset/chapter2/KdocFormattingTest.kt | 97 +++++++++++++++++++ .../gradle-groovy-dsl/diktat-analysis.yml | 6 +- .../diktat-analysis.yml | 4 +- .../gradle-kotlin-dsl/diktat-analysis.yml | 6 +- examples/maven/diktat-analysis.yml | 6 +- info/available-rules.md | 8 +- info/guide/guide-chapter-2.md | 39 ++++++-- 16 files changed, 236 insertions(+), 71 deletions(-) diff --git a/diktat-analysis.yml b/diktat-analysis.yml index d6f4e18929..c139b4c94b 100644 --- a/diktat-analysis.yml +++ b/diktat-analysis.yml @@ -115,6 +115,11 @@ # Checks that KDoc does not contain single line with words 'return', 'get' or 'set' - name: KDOC_TRIVIAL_KDOC_ON_FUNCTION enabled: true +# Checks that kdoc does not contain @author tag or date +- name: KDOC_CONTAINS_DATE_OR_AUTHOR + enabled: true + configuration: + versionRegex: \d+\.\d+\.\d+[-.\w\d]* # Checks that there is newline after header KDoc - name: HEADER_WRONG_FORMAT enabled: true @@ -130,9 +135,6 @@ # Checks that header kdoc is located before package directive - name: HEADER_NOT_BEFORE_PACKAGE enabled: true -# Checks that header kdoc does not contain @author tag ar date -- name: HEADER_CONTAINS_DATE_OR_AUTHOR - enabled: true # Checks that file does not contain lines > maxSize - name: FILE_IS_TOO_LONG enabled: true diff --git a/diktat-rules/src/main/kotlin/generated/WarningNames.kt b/diktat-rules/src/main/kotlin/generated/WarningNames.kt index 10842cf258..826f16ba87 100644 --- a/diktat-rules/src/main/kotlin/generated/WarningNames.kt +++ b/diktat-rules/src/main/kotlin/generated/WarningNames.kt @@ -86,14 +86,14 @@ public object WarningNames { public const val KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT: String = "KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT" + public const val KDOC_CONTAINS_DATE_OR_AUTHOR: String = "KDOC_CONTAINS_DATE_OR_AUTHOR" + public const val HEADER_WRONG_FORMAT: String = "HEADER_WRONG_FORMAT" public const val HEADER_MISSING_OR_WRONG_COPYRIGHT: String = "HEADER_MISSING_OR_WRONG_COPYRIGHT" public const val WRONG_COPYRIGHT_YEAR: String = "WRONG_COPYRIGHT_YEAR" - public const val HEADER_CONTAINS_DATE_OR_AUTHOR: String = "HEADER_CONTAINS_DATE_OR_AUTHOR" - public const val HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE: String = "HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE" diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt index 156d662dae..0d43046e44 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt @@ -67,10 +67,10 @@ enum class Warnings( KDOC_NO_CONSTRUCTOR_PROPERTY(true, "2.1.1", "all properties from the primary constructor should be documented in a @property tag in KDoc"), KDOC_EXTRA_PROPERTY(false, "2.1.1", "There is property in KDoc which is not present in the class"), KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT(true, "2.1.1", "replace comment before property with @property tag in class KDoc"), + KDOC_CONTAINS_DATE_OR_AUTHOR(false, "2.1.3", "KDoc should not contain creation date and author name"), HEADER_WRONG_FORMAT(true, "2.2.1", "file header comments should be properly formatted"), HEADER_MISSING_OR_WRONG_COPYRIGHT(true, "2.2.1", "file header comment must include copyright information inside a block comment"), WRONG_COPYRIGHT_YEAR(true, "2.2.1", "year defined in copyright and current year are different"), - HEADER_CONTAINS_DATE_OR_AUTHOR(false, "2.2.1", "file header comment should not contain creation date and author name"), HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE(false, "2.2.1", "files that contain multiple or no classes should contain description of what is inside of this file"), HEADER_NOT_BEFORE_PACKAGE(true, "2.2.1", "header KDoc should be placed before package and imports"), COMMENTED_OUT_CODE(false, "2.4.2", "you should not comment out code, use VCS to save it in history and delete this block"), diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/IdentifierNaming.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/IdentifierNaming.kt index cb37fd2937..a393f46bcc 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/IdentifierNaming.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/IdentifierNaming.kt @@ -451,7 +451,7 @@ class IdentifierNaming(private val configRules: List) : Rule("ident // FixMe: this should be moved to properties val oneCharIdentifiers = setOf("i", "j", "k", "x", "y", "z") - val booleanMethodPrefixes = setOf("has", "is", "are", "have", "should") + val booleanMethodPrefixes = setOf("has", "is", "are", "have", "should", "can") val confusingIdentifierNames = setOf("O", "D", "I", "l", "Z", "S", "e", "B", "h", "n", "m", "rn") } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/comments/HeaderCommentRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/comments/HeaderCommentRule.kt index d31bc93ee3..ffe278ba89 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/comments/HeaderCommentRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/comments/HeaderCommentRule.kt @@ -4,17 +4,18 @@ import org.cqfn.diktat.common.config.rules.RuleConfiguration import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.common.config.rules.getRuleConfig import org.cqfn.diktat.ruleset.constants.EmitType -import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_CONTAINS_DATE_OR_AUTHOR import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_MISSING_OR_WRONG_COPYRIGHT import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_NOT_BEFORE_PACKAGE import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_WRONG_FORMAT +import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR import org.cqfn.diktat.ruleset.constants.Warnings.WRONG_COPYRIGHT_YEAR import org.cqfn.diktat.ruleset.utils.copyrightWords import org.cqfn.diktat.ruleset.utils.findChildAfter import org.cqfn.diktat.ruleset.utils.findChildBefore import org.cqfn.diktat.ruleset.utils.getAllChildrenWithType import org.cqfn.diktat.ruleset.utils.getFirstChildWithType +import org.cqfn.diktat.ruleset.utils.kDocTags import org.cqfn.diktat.ruleset.utils.moveChildBefore import com.pinterest.ktlint.core.Rule @@ -29,8 +30,12 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafElement import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl +import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag +import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag import java.time.LocalDate +import java.time.format.DateTimeFormatter +import java.time.temporal.ChronoField /** * Visitor for header comment in .kt file: @@ -59,18 +64,7 @@ class HeaderCommentRule(private val configRules: List) : Rule("head } private fun checkHeaderKdoc(node: ASTNode) { - val headerKdoc = node.findChildBefore(PACKAGE_DIRECTIVE, KDOC) - headerKdoc?.let { - // fixme we should also check date of creation, but it can be in different formats - headerKdoc - .text - .split('\n') - .filter { it.contains("@author") } - .forEach { - HEADER_CONTAINS_DATE_OR_AUTHOR.warn(configRules, emitWarn, isFixMode, - it.trim(), headerKdoc.startOffset, headerKdoc) - } - + node.findChildBefore(PACKAGE_DIRECTIVE, KDOC)?.let { headerKdoc -> if (headerKdoc.treeNext != null && headerKdoc.treeNext.elementType == WHITE_SPACE && headerKdoc.treeNext.text.count { it == '\n' } != 2) { HEADER_WRONG_FORMAT.warnAndFix(configRules, emitWarn, isFixMode, diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/kdoc/KdocFormatting.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/kdoc/KdocFormatting.kt index 1696aa5e62..fefdfe34cc 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/kdoc/KdocFormatting.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/kdoc/KdocFormatting.kt @@ -1,7 +1,10 @@ package org.cqfn.diktat.ruleset.rules.kdoc +import org.cqfn.diktat.common.config.rules.RuleConfiguration import org.cqfn.diktat.common.config.rules.RulesConfig +import org.cqfn.diktat.common.config.rules.getRuleConfig import org.cqfn.diktat.ruleset.constants.EmitType +import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_EMPTY_KDOC import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_NEWLINES_BEFORE_BASIC_TAGS import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_NO_DEPRECATED_TAG @@ -43,6 +46,9 @@ import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.psiUtil.startOffset +import java.time.format.DateTimeFormatter +import java.time.temporal.ChronoField + /** * Formatting visitor for Kdoc: * 1) removing all blank lines between Kdoc and the code it's declaring @@ -50,12 +56,15 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset * 3) ensuring there is only one white space between tag and it's body * 4) ensuring tags @apiNote, @implSpec, @implNote have one empty line after their body * 5) ensuring tags @param, @return, @throws are arranged in this order + * 6) ensuring @author tag is not used + * 7) ensuring @since tag contains only versions and not dates */ @Suppress("ForbiddenComment") class KdocFormatting(private val configRules: List) : Rule("kdoc-formatting") { private val basicTagsList = listOf(KDocKnownTag.PARAM, KDocKnownTag.RETURN, KDocKnownTag.THROWS) private val specialTagNames = setOf("implSpec", "implNote", "apiNote") private var isFixMode: Boolean = false + private var versionRegex: Regex? = null private lateinit var emitWarn: EmitType /** @@ -69,6 +78,13 @@ class KdocFormatting(private val configRules: List) : Rule("kdoc-fo isFixMode = autoCorrect emitWarn = emit + versionRegex ?: run { + versionRegex = KdocFormatConfiguration( + configRules.getRuleConfig(KDOC_CONTAINS_DATE_OR_AUTHOR)?.configuration ?: emptyMap() + ) + .versionRegex + } + if (node.elementType == KDOC && isKdocNotEmpty(node)) { checkNoDeprecatedTag(node) checkEmptyTags(node.kDocTags()) @@ -77,6 +93,7 @@ class KdocFormatting(private val configRules: List) : Rule("kdoc-fo node.kDocBasicTags()?.let { checkEmptyLinesBetweenBasicTags(it) } checkBasicTagsOrder(node) checkNewLineAfterSpecialTags(node) + checkAuthorAndDate(node) } } @@ -307,6 +324,17 @@ class KdocFormatting(private val configRules: List) : Rule("kdoc-fo } } + private fun checkAuthorAndDate(node: ASTNode) { + node.kDocTags() + ?.filter { + it.knownTag == KDocKnownTag.AUTHOR || + it.knownTag == KDocKnownTag.SINCE && it.hasInvalidVersion() + } + ?.forEach { + KDOC_CONTAINS_DATE_OR_AUTHOR.warn(configRules, emitWarn, isFixMode, it.text.trim(), it.startOffset, it.node) + } + } + // fixme this method can be improved and extracted to utils private fun ASTNode.hasEmptyLineAfter(): Boolean { require(this.elementType == KDOC_TAG) { "This check is only for KDOC_TAG" } @@ -321,4 +349,43 @@ class KdocFormatting(private val configRules: List) : Rule("kdoc-fo private fun ASTNode.applyToPrevSibling(elementType: IElementType, consumer: ASTNode.() -> Unit) { prevSibling { it.elementType == elementType }?.apply(consumer) } + + /** + * Checks whether this tag's content represents an invalid version + */ + private fun KDocTag.hasInvalidVersion(): Boolean { + val content = getContent().trim() + if (' ' in content || '/' in content) { + // Filter based on symbols that are not allowed in versions. Assuming that people put either version or date in `@since` tag. + return true + } + return versionRegex?.matches(content)?.not() + ?: dateFormats.mapNotNull { + // try to parse using some standard date patterns + runCatching { + it.parse(content).get(ChronoField.YEAR) + } + .getOrNull() + } + .isNotEmpty() + } + + /** + * A [RuleConfiguration] for KDoc formatting + */ + class KdocFormatConfiguration(config: Map) : RuleConfiguration(config) { + /** + * Regular expression, if present, against which a version should be matched in `@since` tag. + */ + val versionRegex: Regex? by lazy { + config["versionRegex"]?.let { Regex(it) } + } + } + + companion object { + val dateFormats: List = listOf("yyyy-dd-mm", "yy-dd-mm", "yyyy-mm-dd", "yy-mm-dd", "yyyy.mm.dd", "yyyy.dd.mm") + .map { + DateTimeFormatter.ofPattern(it) + } + } } diff --git a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml index 2681f665db..dc4b98a7df 100644 --- a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml +++ b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml @@ -112,6 +112,11 @@ # Checks that special tags `@apiNote`, `@implNote`, `@implSpec` have exactly one empty line after - name: KDOC_NO_NEWLINE_AFTER_SPECIAL_TAGS enabled: true +# Checks that kdoc does not contain @author tag or date +- name: KDOC_CONTAINS_DATE_OR_AUTHOR + enabled: true + configuration: + versionRegex: \d+\.\d+\.\d+[-.\w\d]* # Checks that KDoc does not contain single line with words 'return', 'get' or 'set' - name: KDOC_TRIVIAL_KDOC_ON_FUNCTION enabled: true @@ -130,9 +135,6 @@ # Checks that header kdoc is located before package directive - name: HEADER_NOT_BEFORE_PACKAGE enabled: true -# Checks that header kdoc does not contain @author tag ar date -- name: HEADER_CONTAINS_DATE_OR_AUTHOR - enabled: true # Checks that file does not contain lines > maxSize - name: FILE_IS_TOO_LONG enabled: true diff --git a/diktat-rules/src/main/resources/diktat-analysis.yml b/diktat-rules/src/main/resources/diktat-analysis.yml index cf353c0ce0..0c9e986f18 100644 --- a/diktat-rules/src/main/resources/diktat-analysis.yml +++ b/diktat-rules/src/main/resources/diktat-analysis.yml @@ -111,6 +111,11 @@ # Checks that special tags `@apiNote`, `@implNote`, `@implSpec` have exactly one empty line after - name: KDOC_NO_NEWLINE_AFTER_SPECIAL_TAGS enabled: true +# Checks that kdoc does not contain @author tag or date +- name: KDOC_CONTAINS_DATE_OR_AUTHOR + enabled: true + configuration: + versionRegex: \d+\.\d+\.\d+[-.\w\d]* # Checks that KDoc does not contain single line with words 'return', 'get' or 'set' - name: KDOC_TRIVIAL_KDOC_ON_FUNCTION enabled: true @@ -129,9 +134,6 @@ # Checks that header kdoc is located before package directive - name: HEADER_NOT_BEFORE_PACKAGE enabled: true -# Checks that header kdoc does not contain @author tag ar date -- name: HEADER_CONTAINS_DATE_OR_AUTHOR - enabled: true # Checks that file does not contain lines > maxSize - name: FILE_IS_TOO_LONG enabled: true diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/HeaderCommentRuleTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/HeaderCommentRuleTest.kt index a427a349f8..52493bbdfd 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/HeaderCommentRuleTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/HeaderCommentRuleTest.kt @@ -2,11 +2,11 @@ package org.cqfn.diktat.ruleset.chapter2 import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.ruleset.constants.Warnings -import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_CONTAINS_DATE_OR_AUTHOR import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_MISSING_OR_WRONG_COPYRIGHT import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_NOT_BEFORE_PACKAGE import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_WRONG_FORMAT +import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR import org.cqfn.diktat.ruleset.rules.DIKTAT_RULE_SET_ID import org.cqfn.diktat.ruleset.rules.comments.HeaderCommentRule import org.cqfn.diktat.util.LintTestBase @@ -256,26 +256,6 @@ class HeaderCommentRuleTest : LintTestBase(::HeaderCommentRule) { ) } - @Test - @Tag(WarningNames.HEADER_CONTAINS_DATE_OR_AUTHOR) - fun `@author tag is not allowed in header comment`() { - lintMethod( - """ - |$copyrightBlock - |/** - | * Description of this file - | * @author anonymous - | */ - | - |package org.cqfn.diktat.example - | - |class Example { } - """.trimMargin(), - LintError(4, 1, ruleId, "${HEADER_CONTAINS_DATE_OR_AUTHOR.warnText()} * @author anonymous"), - rulesConfigList = rulesConfigList - ) - } - @Test @Tag(WarningNames.HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE) fun `file with zero classes should have header KDoc`() { diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/KdocFormattingTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/KdocFormattingTest.kt index 732797b566..02f2f092cb 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/KdocFormattingTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/KdocFormattingTest.kt @@ -1,5 +1,7 @@ package org.cqfn.diktat.ruleset.chapter2 +import org.cqfn.diktat.common.config.rules.RulesConfig +import org.cqfn.diktat.ruleset.constants.Warnings import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_EMPTY_KDOC import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_NEWLINES_BEFORE_BASIC_TAGS import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_NO_DEPRECATED_TAG @@ -321,4 +323,99 @@ class KdocFormattingTest : LintTestBase(::KdocFormatting) { LintError(2, 16, ruleId, "${KDOC_NO_NEWLINE_AFTER_SPECIAL_TAGS.warnText()} @implSpec, @apiNote, @implNote", true)) } + + @Test + @Tag(WarningNames.KDOC_CONTAINS_DATE_OR_AUTHOR) + fun `@author tag is not allowed in header comment`() { + lintMethod( + """ + |/** + | * Description of this file + | * @author anonymous + | */ + | + |package org.cqfn.diktat.example + | + |/** + | * Description of this class + | * @author anonymous + | */ + |class Example { } + """.trimMargin(), + LintError(3, 4, ruleId, "${Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR.warnText()} @author anonymous"), + LintError(10, 4, ruleId, "${Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR.warnText()} @author anonymous"), + ) + } + + @Test + @Tag(WarningNames.KDOC_CONTAINS_DATE_OR_AUTHOR) + fun `@since tag should only contain versions`() { + lintMethod( + """ + |/** + | * Description of this file + | * @since 2019-10-11 + | * @since 19-10-11 + | * @since 2019.10.11 + | * @since 2019/10/11 + | * @since 11 Oct 2019 + | * @since 1.2.3 + | * @since 1.2.3-1 + | * @since 1.2.3-SNAPSHOT + | * @since 1.2.3-rc-1 + | * @since 1.2.3.RELEASE + | */ + | + |package org.cqfn.diktat.example + | + |/** + | * Description of this file + | * @since 2019-10-11 + | * @since 1.2.3 + | */ + |class Example { } + """.trimMargin(), + LintError(3, 4, ruleId, "${Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR.warnText()} @since 2019-10-11"), + LintError(4, 4, ruleId, "${Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR.warnText()} @since 19-10-11"), + LintError(5, 4, ruleId, "${Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR.warnText()} @since 2019.10.11"), + LintError(6, 4, ruleId, "${Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR.warnText()} @since 2019/10/11"), + LintError(7, 4, ruleId, "${Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR.warnText()} @since 11 Oct 2019"), + LintError(19, 4, ruleId, "${Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR.warnText()} @since 2019-10-11"), + rulesConfigList = emptyList() + ) + } + + @Test + @Tag(WarningNames.KDOC_CONTAINS_DATE_OR_AUTHOR) + fun `@since tag should only contain versions - with configured regex`() { + lintMethod( + """ + |/** + | * Description of this file + | * @since 2019-10-11 + | * @since 1.2.3-rc-1 + | * @since 1.2.3.RELEASE + | */ + | + |package org.cqfn.diktat.example + | + |/** + | * Description of this file + | * @since 2019-10-11 + | * @since 1.2.3 + | */ + |class Example { } + """.trimMargin(), + LintError(3, 4, ruleId, "${Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR.warnText()} @since 2019-10-11"), + LintError(5, 4, ruleId, "${Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR.warnText()} @since 1.2.3.RELEASE"), + LintError(12, 4, ruleId, "${Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR.warnText()} @since 2019-10-11"), + rulesConfigList = listOf( + RulesConfig( + Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR.name, true, mapOf( + "versionRegex" to "\\d+\\.\\d+\\.\\d+[-\\w\\d]*" + ) + ) + ) + ) + } } diff --git a/examples/gradle-groovy-dsl/diktat-analysis.yml b/examples/gradle-groovy-dsl/diktat-analysis.yml index cf353c0ce0..e3fcb8b435 100644 --- a/examples/gradle-groovy-dsl/diktat-analysis.yml +++ b/examples/gradle-groovy-dsl/diktat-analysis.yml @@ -111,6 +111,9 @@ # Checks that special tags `@apiNote`, `@implNote`, `@implSpec` have exactly one empty line after - name: KDOC_NO_NEWLINE_AFTER_SPECIAL_TAGS enabled: true +# Checks that kdoc does not contain @author tag or date +- name: KDOC_CONTAINS_DATE_OR_AUTHOR + enabled: true # Checks that KDoc does not contain single line with words 'return', 'get' or 'set' - name: KDOC_TRIVIAL_KDOC_ON_FUNCTION enabled: true @@ -129,9 +132,6 @@ # Checks that header kdoc is located before package directive - name: HEADER_NOT_BEFORE_PACKAGE enabled: true -# Checks that header kdoc does not contain @author tag ar date -- name: HEADER_CONTAINS_DATE_OR_AUTHOR - enabled: true # Checks that file does not contain lines > maxSize - name: FILE_IS_TOO_LONG enabled: true diff --git a/examples/gradle-kotlin-dsl-multiproject/diktat-analysis.yml b/examples/gradle-kotlin-dsl-multiproject/diktat-analysis.yml index 1dff285a5f..7c503cf769 100644 --- a/examples/gradle-kotlin-dsl-multiproject/diktat-analysis.yml +++ b/examples/gradle-kotlin-dsl-multiproject/diktat-analysis.yml @@ -71,6 +71,8 @@ enabled: true - name: KDOC_NO_NEWLINE_AFTER_SPECIAL_TAGS enabled: true +- name: KDOC_CONTAINS_DATE_OR_AUTHOR + enabled: true - name: KDOC_TRIVIAL_KDOC_ON_FUNCTION enabled: 'true' - name: HEADER_WRONG_FORMAT @@ -84,8 +86,6 @@ copyrightText: 'Copyright (c) Your Company Name Here. 2010-2021' - name: HEADER_NOT_BEFORE_PACKAGE enabled: true -- name: HEADER_CONTAINS_DATE_OR_AUTHOR - enabled: true - name: FILE_IS_TOO_LONG enabled: true configuration: diff --git a/examples/gradle-kotlin-dsl/diktat-analysis.yml b/examples/gradle-kotlin-dsl/diktat-analysis.yml index cf353c0ce0..e3fcb8b435 100644 --- a/examples/gradle-kotlin-dsl/diktat-analysis.yml +++ b/examples/gradle-kotlin-dsl/diktat-analysis.yml @@ -111,6 +111,9 @@ # Checks that special tags `@apiNote`, `@implNote`, `@implSpec` have exactly one empty line after - name: KDOC_NO_NEWLINE_AFTER_SPECIAL_TAGS enabled: true +# Checks that kdoc does not contain @author tag or date +- name: KDOC_CONTAINS_DATE_OR_AUTHOR + enabled: true # Checks that KDoc does not contain single line with words 'return', 'get' or 'set' - name: KDOC_TRIVIAL_KDOC_ON_FUNCTION enabled: true @@ -129,9 +132,6 @@ # Checks that header kdoc is located before package directive - name: HEADER_NOT_BEFORE_PACKAGE enabled: true -# Checks that header kdoc does not contain @author tag ar date -- name: HEADER_CONTAINS_DATE_OR_AUTHOR - enabled: true # Checks that file does not contain lines > maxSize - name: FILE_IS_TOO_LONG enabled: true diff --git a/examples/maven/diktat-analysis.yml b/examples/maven/diktat-analysis.yml index cf353c0ce0..e3fcb8b435 100644 --- a/examples/maven/diktat-analysis.yml +++ b/examples/maven/diktat-analysis.yml @@ -111,6 +111,9 @@ # Checks that special tags `@apiNote`, `@implNote`, `@implSpec` have exactly one empty line after - name: KDOC_NO_NEWLINE_AFTER_SPECIAL_TAGS enabled: true +# Checks that kdoc does not contain @author tag or date +- name: KDOC_CONTAINS_DATE_OR_AUTHOR + enabled: true # Checks that KDoc does not contain single line with words 'return', 'get' or 'set' - name: KDOC_TRIVIAL_KDOC_ON_FUNCTION enabled: true @@ -129,9 +132,6 @@ # Checks that header kdoc is located before package directive - name: HEADER_NOT_BEFORE_PACKAGE enabled: true -# Checks that header kdoc does not contain @author tag ar date -- name: HEADER_CONTAINS_DATE_OR_AUTHOR - enabled: true # Checks that file does not contain lines > maxSize - name: FILE_IS_TOO_LONG enabled: true diff --git a/info/available-rules.md b/info/available-rules.md index 085763b398..550983f0cb 100644 --- a/info/available-rules.md +++ b/info/available-rules.md @@ -1,9 +1,9 @@ | Chap | Standard | Rule name | Description | Fix | Config | FixMe | | ----- | ---------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --- | ------ | ----- | | 1 | 1.1.1 | CONFUSING_IDENTIFIER_NAMING | Check: warns if identifier has inappropriate name (See table of rule 1.2 part 6). | no | no | no | -| 1 | 1.2.1 | PACKAGE_NAME_MISSING | Check: warns if package name is missing in a file
Fix: automatically adds package directive with the name that starts from the domain name (in example - com.huawei) and contains the real directory | yes | no | Domain name should not be hardcoded. It should be moved to extra configuration.Recursively fix all imports in project.Fix the directory where the code is stored.Make this check isolated from domain name addition| +| 1 | 1.2.1 | PACKAGE_NAME_MISSING | Check: warns if package name is missing in a file
Fix: automatically adds package directive with the name that starts from the domain name (in example - com.huawei) and contains the real directory | yes | no | Recursively fix all imports in project.
Fix the directory where the code is stored.
Make this check isolated from domain name addition | | 1 | 1.2.1 | PACKAGE_NAME_INCORRECT_CASE | Check: warns if package name is in incorrect (non-lower) case
Fix: automatically update the case in package name | yes | no | Recursively update all imports in the project.| -| 1 | 1.2.1 | PACKAGE_NAME_INCORRECT_PREFIX | Check: warns if package name does not start with the company's domain
Fix: automatically update the prefix in the package name | yes | no | Fix the directory where the code is stored.Recursively update all imports in the project.Domain name should not be hardcoded. It should be moved to extra configuration.| +| 1 | 1.2.1 | PACKAGE_NAME_INCORRECT_PREFIX | Check: warns if package name does not start with the company's domain
Fix: automatically update the prefix in the package name | yes | no | Fix the directory where the code is stored.
Recursively update all imports in the project.| | 1 | 1.2.1 | PACKAGE_NAME_INCORRECT_SYMBOLS | Check: warns if package name has incorrect symbols like underscore or non-ASCII letters/digits.Exception: underscores that are used for differentiating of keywords in a name.
Fix: no but will be | no | no | Add autofix for at least converting underscore to a dot or replacing itFix the directory where the code is stored.Cover autofix with tests| | 1 | 1.2.1 | PACKAGE_NAME_INCORRECT_PATH | Check: warns if the path for a file does not match with a package name
Fix: replacing incorrect package name with the name constructed from a path to the file. | yes | no | Make this check isolated from domain name creationRecursively update all imports in the project.Fix the directory where the code is stored.Add test mechanism to test checker| | 1 | 1.2.1 | INCORRECT_PACKAGE_SEPARATOR | Check: warns if underscore is incorrectly used to split package naming
Fix: fixing all nodes in AST and the package name to remove all underscores | no | no | Recursively update usages of this class in the project| @@ -38,12 +38,12 @@ | 2 | 2.2.1 | KDOC_NO_EMPTY_TAGS | Check: warns if KDoc tags have empty content | no | no | | | 2 | 2.1.3 | KDOC_NO_DEPRECATED_TAG | Check: warns if `@deprecated` is used in KDoc
Fix: adds `@Deprecated` annotation with message, removes tag | yes | no | Annotation's `replaceWith` field can be filled too| | 2 | 2.1.1 | KDOC_NO_CONSTRUCTOR_PROPERTY | Check: warns if there is no property tag inside KDoc before constructor | yes | no | -| 2 | 2.1.1 | KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT | Check: warns if there is comment before property in constructor | yes | no | +| 2 | 2.1.1 | KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT| Check: warns if there is comment before property in constructor | yes | no | +| 2 | 2.2.1 | KDOC_CONTAINS_DATE_OR_AUTHOR | Check: warns if header KDoc contains `@author` tag.
Warns if `@since` tag contains version and not date. | no | no | Detect author by other patterns (e.g. 'created by' etc.)| | 2 | 2.3.1 | KDOC_TRIVIAL_KDOC_ON_FUNCTION | Check: warns if KDoc contains single line with words 'return', 'get' or 'set' | no | no | | | 2 | 2.2.1 | HEADER_WRONG_FORMAT | Checks: warns if there is no newline after header KDoc
Fix: adds newline | yes | no | Check if header is on the very top of file. It's hard to determine when it's not.| | 2 | 2.2.1 | HEADER_MISSING_OR_WRONG_COPYRIGHT | Checks: copyright exists on top of file and is properly formatted (as a block comment)
Fix: adds copyright if it is missing and required | yes | mandatoryCopyright | Allow setting copyright patterns via configuration| | 2 | 2.2.1 | WRONG_COPYRIGHT_YEAR | Checks: copyright have a valid year
Fix: makes a year valid | yes | no | - | -| 2 | 2.2.1 | HEADER_CONTAINS_DATE_OR_AUTHOR | Check: warns if header KDoc contains `@author` tag | no | no | Detect author by other patterns (e.g. 'created by' etc.)Detect creation date (no standard tag even in javadoc)| | 2 | 2.2.1 | HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE | Check: warns if file with zero or >1 classes doesn't have header KDoc | no | no | | | 2 | 2.4.2 | COMMENTED_OUT_CODE | Check: warns if commented code is detected (when un-commented, can be parsed) | no | no | Offset is lost when joined EOL comments are split again| | 2 | 2.4.1 | COMMENT_WHITE_SPACE | Check: warns if there is no space between // and comment, if there is no space between code and comment
Fix: adds a white space | yes | maxSpaces | - | diff --git a/info/guide/guide-chapter-2.md b/info/guide/guide-chapter-2.md index afe3550248..8a7c5c9d82 100644 --- a/info/guide/guide-chapter-2.md +++ b/info/guide/guide-chapter-2.md @@ -94,7 +94,7 @@ When the method has such details as arguments, return value, or can throw except /** * This is the short overview comment for the example interface. * / * Add a blank line between the comment text and each KDoc tag underneath * / - * @since 2019-01-01 + * @since 1.6 */ protected abstract class Sample { /** @@ -136,8 +136,11 @@ Therefore, Kdoc should contain the following: Kdoc should not contain: - Empty descriptions in tag blocks. It is better not to write Kdoc than waste code line space. - There should be no empty lines between the method/class declaration and the end of Kdoc (`*/` symbols). -Important note: KDoc does not support the `@deprecated` tag. Instead, use the `@Deprecated` annotation. - +- `@author` tag. It doesn't matter who originally created a class when you can use `git blame` or VCS of your choice to look through the changes history. +Important notes: +- KDoc does not support the `@deprecated` tag. Instead, use the `@Deprecated` annotation. +- The `@since` tag should be used for versions only. Do not use dates in `@since` tag, it's confusing and less accurate. + If a tag block cannot be described in one line, indent the content of the new line by *four spaces* from the `@` position to achieve alignment (`@` counts as one + three spaces). **Exception:** @@ -172,20 +175,38 @@ Other KDoc tags (such as @param type parameters and @see.) can be added as follo ### 2.2 Adding comments on the file header This section describes the general rules of adding comments on the file header. -Comments on the file header should be placed before the package name and imports. If you need to add more content to the comment, subsequently add it in the same format. -Comments on the file header must include copyright information, without the creation date and author's name (use VCS for history management). Also, describe the content inside files that contain multiple or no classes. +### 2.2.1 Formatting of comments in the file header -Place comments on the file header before the package name and imports. If you need to add more content to the comment, subsequently add it in the same format. +Comments on the file header should be placed before the package name and imports. If you need to add more content to the comment, subsequently add it in the same format. + +Comments on the file header must include copyright information, without the creation date and author's name (use VCS for history management). +Also, describe the content inside files that contain multiple or no classes. The following examples for Huawei describe the format of the *copyright license*: \ Chinese version: `版权所有 (c) 华为技术有限公司 2012-2020` \ English version: `Copyright (c) Huawei Technologies Co., Ltd. 2012-2020. All rights reserved.` +`2012` and `2020` are the years the file was first created and the current year, respectively. + +Do not place **release notes** in header, use VCS to keep track of changes in file. Notable changes can be marked in individual KDocs using `@since` tag with version. + +Invalid example: +```kotlin +/** + * Release notes: + * 2019-10-11: added class Foo + */ -Regarding the **release notes**, see examples below: +class Foo +``` -- `2012-2020` can be modified according to your actual situation. `2012` and `2020` are the years the file was first created and last modified, respectively. -These two years can be the same (for example, `2020–2020`). When the file is substantially changed (for example, through feature extensions and major refactorings), the subsequent years must be updated. +Valid example: +```kotlin +/** + * @since 2.4.0 + */ +class Foo +``` - The **copyright statement** can use your company's subsidiaries, as shown in the below examples: \ Chinese version: `版权所有 (c) 海思半导体 2012-2020` \ From 8344d7067e9d21c1ffce4616cc409c328d7b6b5a Mon Sep 17 00:00:00 2001 From: Alexander Tsay <48321920+aktsay6@users.noreply.github.com> Date: Thu, 14 Jan 2021 14:14:46 +0300 Subject: [PATCH 05/11] Bugfix. Problems with year checking logic in copyright(#688) (#693) * bugfix/new-year-npe(#688) ### What's done: * Added new warning * Updated Tests * Fixed bugs --- .../diktat/ruleset/generation/Generation.kt | 41 ++++++++++--------- .../rules/comments/HeaderCommentRule.kt | 17 ++++++-- .../chapter2/HeaderCommentRuleFixTest.kt | 11 +++++ .../header/CopyrightDifferentYearExpected.kt | 4 +- .../header/CopyrightDifferentYearTest.kt | 4 +- .../CopyrightShouldNotTriggerNPEExpected.kt | 19 +++++++++ .../CopyrightShouldNotTriggerNPETest.kt | 16 ++++++++ .../header/MisplacedHeaderKdocExpected.kt | 2 - .../header/MisplacedHeaderKdocTest.kt | 2 +- .../header/MultilineCopyrightExample.kt | 2 +- .../MultilineCopyrightNotTriggerExample.kt | 4 +- .../MultilineCopyrightNotTriggerTest.kt | 4 +- .../header/MultilineCopyrightTest.kt | 2 +- .../header/NewlineAfterHeaderKdocExpected.kt | 1 - .../header/NewlineAfterHeaderKdocTest.kt | 2 +- 15 files changed, 94 insertions(+), 37 deletions(-) create mode 100644 diktat-rules/src/test/resources/test/paragraph2/header/CopyrightShouldNotTriggerNPEExpected.kt create mode 100644 diktat-rules/src/test/resources/test/paragraph2/header/CopyrightShouldNotTriggerNPETest.kt diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/generation/Generation.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/generation/Generation.kt index 93cd94ddbb..946de2a73a 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/generation/Generation.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/generation/Generation.kt @@ -57,25 +57,28 @@ private fun generateWarningNames() { } private fun validateYear() { - val file = File("diktat-rules/src/test/resources/test/paragraph2/header/CopyrightDifferentYearExpected.kt") - val tempFile = createTempFile() - tempFile.printWriter().use { writer -> - file.forEachLine { line -> - writer.println(when { - hyphenRegex.matches(line) -> hyphenRegex.replace(line) { - val years = it.value.split("-") - val validYears = "${years[0]}-$curYear" - line.replace(hyphenRegex, validYears) + val files = File("diktat-rules/src/test/resources/test/paragraph2/header") + files + .listFiles() + .filterNot { it.name.contains("CopyrightDifferentYearTest.kt") } + .forEach { file -> + val tempFile = createTempFile() + tempFile.printWriter().use { writer -> + file.forEachLine { line -> + writer.println(when { + line.contains(hyphenRegex) -> line.replace(hyphenRegex) { + val years = it.value.split("-") + "${years[0]}-$curYear" + } + line.contains(afterCopyrightRegex) -> line.replace(afterCopyrightRegex) { + val copyrightYears = it.value.split("(c)", "(C)", "©") + "${copyrightYears[0]}-$curYear" + } + else -> line + }) } - afterCopyrightRegex.matches(line) -> afterCopyrightRegex.replace(line) { - val copyrightYears = it.value.split("(c)", "(C)", "©") - val validYears = "${copyrightYears[0]}-$curYear" - line.replace(afterCopyrightRegex, validYears) - } - else -> line - }) + } + file.delete() + tempFile.renameTo(file) } - } - file.delete() - tempFile.renameTo(file) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/comments/HeaderCommentRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/comments/HeaderCommentRule.kt index ffe278ba89..2f799d34a3 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/comments/HeaderCommentRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/comments/HeaderCommentRule.kt @@ -16,6 +16,7 @@ import org.cqfn.diktat.ruleset.utils.findChildBefore import org.cqfn.diktat.ruleset.utils.getAllChildrenWithType import org.cqfn.diktat.ruleset.utils.getFirstChildWithType import org.cqfn.diktat.ruleset.utils.kDocTags +import org.cqfn.diktat.ruleset.utils.log import org.cqfn.diktat.ruleset.utils.moveChildBefore import com.pinterest.ktlint.core.Rule @@ -142,15 +143,24 @@ class HeaderCommentRule(private val configRules: List) : Rule("head return } + if (makeCopyrightCorrectYear(configuration.getCopyrightText()).isNotEmpty()) { + log.warn("Copyright year is not up do date.") + } + + // need to make sure that copyright year is consistent with current year val copyrightText = configuration.getCopyrightText() val headerComment = node.findChildBefore(PACKAGE_DIRECTIVE, BLOCK_COMMENT) - val isWrongCopyright = headerComment != null && !headerComment.text.flatten().contains(copyrightText.flatten()) + // Depends only on content and doesn't consider years + val isWrongCopyright = headerComment != null && + !headerComment.text.flatten().contains(copyrightText.flatten()) && + !headerComment.text.flatten().contains(makeCopyrightCorrectYear(copyrightText).flatten()) val isMissingCopyright = headerComment == null && configuration.isCopyrightMandatory() val isCopyrightInsideKdoc = (node.getAllChildrenWithType(KDOC) + node.getAllChildrenWithType(ElementType.EOL_COMMENT)) .any { commentNode -> copyrightWords.any { commentNode.text.contains(it, ignoreCase = true) } } + if (isWrongCopyright || isMissingCopyright || isCopyrightInsideKdoc) { val freeText = when { // If `isCopyrightInsideKdoc` then `isMissingCopyright` is true too, but warning text from `isCopyrightInsideKdoc` is preferable. @@ -177,7 +187,8 @@ class HeaderCommentRule(private val configRules: List) : Rule("head val copyrightWithCorrectYear = makeCopyrightCorrectYear(copyrightText) - if (copyrightWithCorrectYear.isNotEmpty()) { + // Triggers when there is a copyright, but its year is not updated. + if (!isMissingCopyright && copyrightWithCorrectYear.isNotEmpty()) { WRONG_COPYRIGHT_YEAR.warnAndFix(configRules, emitWarn, isFixMode, "year should be $curYear", node.startOffset, node) { (headerComment as LeafElement).replaceWithText(headerComment.text.replace(copyrightText, copyrightWithCorrectYear)) } @@ -233,7 +244,7 @@ class HeaderCommentRule(private val configRules: List) : Rule("head } companion object { - val hyphenRegex = Regex("""\b(\d+-\d+)\b""") + val hyphenRegex = Regex("""\d+-\d+""") val afterCopyrightRegex = Regex("""((©|\([cC]\))+ *\d+)""") val curYear = LocalDate.now().year } diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/HeaderCommentRuleFixTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/HeaderCommentRuleFixTest.kt index 65628ffe74..d33e1c7440 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/HeaderCommentRuleFixTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/HeaderCommentRuleFixTest.kt @@ -71,6 +71,17 @@ class HeaderCommentRuleFixTest : FixTestBase( ) } + @Test + @Tag(WRONG_COPYRIGHT_YEAR) + fun `should not raise npe`() { + fixAndCompare("CopyrightShouldNotTriggerNPEExpected.kt", "CopyrightShouldNotTriggerNPETest.kt", + listOf(RulesConfig(HEADER_MISSING_OR_WRONG_COPYRIGHT.name, true, mapOf( + "isCopyrightMandatory" to "true", + "copyrightText" to "Copyright (c) My Company., Ltd. 2012-2021. All rights reserved." + ))) + ) + } + @Test @Tag(WarningNames.HEADER_MISSING_OR_WRONG_COPYRIGHT) fun `copyright multiline`() { diff --git a/diktat-rules/src/test/resources/test/paragraph2/header/CopyrightDifferentYearExpected.kt b/diktat-rules/src/test/resources/test/paragraph2/header/CopyrightDifferentYearExpected.kt index a344438ff6..fe33eb4e52 100644 --- a/diktat-rules/src/test/resources/test/paragraph2/header/CopyrightDifferentYearExpected.kt +++ b/diktat-rules/src/test/resources/test/paragraph2/header/CopyrightDifferentYearExpected.kt @@ -1,6 +1,6 @@ /* - * Copyright (c) My Company., Ltd. 2012-2021. All rights reserved. - */ + Copyright (c) My Company., Ltd. 2012-2021. All rights reserved. +*/ /** * Lorem ipsum * dolor sit amet diff --git a/diktat-rules/src/test/resources/test/paragraph2/header/CopyrightDifferentYearTest.kt b/diktat-rules/src/test/resources/test/paragraph2/header/CopyrightDifferentYearTest.kt index fb10f5bcf9..89caa66aa6 100644 --- a/diktat-rules/src/test/resources/test/paragraph2/header/CopyrightDifferentYearTest.kt +++ b/diktat-rules/src/test/resources/test/paragraph2/header/CopyrightDifferentYearTest.kt @@ -1,6 +1,6 @@ /* - * Copyright (c) My Company., Ltd. 2012-2019. All rights reserved. - */ + Copyright (c) My Company., Ltd. 2012-2019. All rights reserved. +*/ /** * Lorem ipsum * dolor sit amet diff --git a/diktat-rules/src/test/resources/test/paragraph2/header/CopyrightShouldNotTriggerNPEExpected.kt b/diktat-rules/src/test/resources/test/paragraph2/header/CopyrightShouldNotTriggerNPEExpected.kt new file mode 100644 index 0000000000..fe33eb4e52 --- /dev/null +++ b/diktat-rules/src/test/resources/test/paragraph2/header/CopyrightShouldNotTriggerNPEExpected.kt @@ -0,0 +1,19 @@ +/* + Copyright (c) My Company., Ltd. 2012-2021. All rights reserved. +*/ +/** + * Lorem ipsum + * dolor sit amet + */ + +package test.paragraph2.header + +import org.cqfn.diktat.example.A +import org.cqfn.diktat.example.B + +/** + * Example class + */ +class Example { + lateinit var map: Map +} diff --git a/diktat-rules/src/test/resources/test/paragraph2/header/CopyrightShouldNotTriggerNPETest.kt b/diktat-rules/src/test/resources/test/paragraph2/header/CopyrightShouldNotTriggerNPETest.kt new file mode 100644 index 0000000000..a0e91a476b --- /dev/null +++ b/diktat-rules/src/test/resources/test/paragraph2/header/CopyrightShouldNotTriggerNPETest.kt @@ -0,0 +1,16 @@ +/** + * Lorem ipsum + * dolor sit amet + */ + +package test.paragraph2.header + +import org.cqfn.diktat.example.A +import org.cqfn.diktat.example.B + +/** + * Example class + */ +class Example { + lateinit var map: Map +} diff --git a/diktat-rules/src/test/resources/test/paragraph2/header/MisplacedHeaderKdocExpected.kt b/diktat-rules/src/test/resources/test/paragraph2/header/MisplacedHeaderKdocExpected.kt index 44ca966073..aaed183d0e 100644 --- a/diktat-rules/src/test/resources/test/paragraph2/header/MisplacedHeaderKdocExpected.kt +++ b/diktat-rules/src/test/resources/test/paragraph2/header/MisplacedHeaderKdocExpected.kt @@ -1,8 +1,6 @@ /* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. */ - - /** * Lorem ipsum * dolor sit amet diff --git a/diktat-rules/src/test/resources/test/paragraph2/header/MisplacedHeaderKdocTest.kt b/diktat-rules/src/test/resources/test/paragraph2/header/MisplacedHeaderKdocTest.kt index c9437d5cc1..2417795db7 100644 --- a/diktat-rules/src/test/resources/test/paragraph2/header/MisplacedHeaderKdocTest.kt +++ b/diktat-rules/src/test/resources/test/paragraph2/header/MisplacedHeaderKdocTest.kt @@ -1,5 +1,5 @@ /* - Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. + Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. */ package test.paragraph2.header diff --git a/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightExample.kt b/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightExample.kt index db771bc4f3..0370a2fd65 100644 --- a/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightExample.kt +++ b/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightExample.kt @@ -18,4 +18,4 @@ class SomeClass { fun coolFun() { val a = 5 } -} \ No newline at end of file +} diff --git a/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightNotTriggerExample.kt b/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightNotTriggerExample.kt index 3b9b0af741..93186bf742 100644 --- a/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightNotTriggerExample.kt +++ b/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightNotTriggerExample.kt @@ -1,5 +1,5 @@ /* - Copyright 2018-2020 John Doe. + Copyright 2018-2021 John Doe. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -12,4 +12,4 @@ class SomeClass { fun function() { } -} \ No newline at end of file +} diff --git a/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightNotTriggerTest.kt b/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightNotTriggerTest.kt index 3b9b0af741..93186bf742 100644 --- a/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightNotTriggerTest.kt +++ b/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightNotTriggerTest.kt @@ -1,5 +1,5 @@ /* - Copyright 2018-2020 John Doe. + Copyright 2018-2021 John Doe. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -12,4 +12,4 @@ class SomeClass { fun function() { } -} \ No newline at end of file +} diff --git a/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightTest.kt b/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightTest.kt index 481563563b..f4a1441370 100644 --- a/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightTest.kt +++ b/diktat-rules/src/test/resources/test/paragraph2/header/MultilineCopyrightTest.kt @@ -2,4 +2,4 @@ class SomeClass { fun coolFun() { val a = 5 } -} \ No newline at end of file +} diff --git a/diktat-rules/src/test/resources/test/paragraph2/header/NewlineAfterHeaderKdocExpected.kt b/diktat-rules/src/test/resources/test/paragraph2/header/NewlineAfterHeaderKdocExpected.kt index 17d54923d7..84cc556f19 100644 --- a/diktat-rules/src/test/resources/test/paragraph2/header/NewlineAfterHeaderKdocExpected.kt +++ b/diktat-rules/src/test/resources/test/paragraph2/header/NewlineAfterHeaderKdocExpected.kt @@ -1,7 +1,6 @@ /* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. */ - /** * This is a file used in unit test */ diff --git a/diktat-rules/src/test/resources/test/paragraph2/header/NewlineAfterHeaderKdocTest.kt b/diktat-rules/src/test/resources/test/paragraph2/header/NewlineAfterHeaderKdocTest.kt index 455c530d4c..12b0028ebf 100644 --- a/diktat-rules/src/test/resources/test/paragraph2/header/NewlineAfterHeaderKdocTest.kt +++ b/diktat-rules/src/test/resources/test/paragraph2/header/NewlineAfterHeaderKdocTest.kt @@ -1,5 +1,5 @@ /* - Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. + Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. */ /** * This is a file used in unit test From 241f45e578d5afefa16a981075b08b2f486d90d9 Mon Sep 17 00:00:00 2001 From: Alexander Tsay <48321920+aktsay6@users.noreply.github.com> Date: Thu, 14 Jan 2021 14:40:20 +0300 Subject: [PATCH 06/11] =?UTF-8?q?Do=20not=20use=20!isEmpty=20methods=20fro?= =?UTF-8?q?m=20the=20collections=20=E2=80=93=20need=20to=20use=20isNotEmpt?= =?UTF-8?q?y=20instead=20(#704)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feature/check-isEmpty-method(#692) ### What's done: * Added new rule * Added warn tests * Added fix tests --- diktat-analysis.yml | 3 + .../src/main/kotlin/generated/WarningNames.kt | 2 + .../cqfn/diktat/ruleset/constants/Warnings.kt | 1 + .../ruleset/rules/CheckInverseMethodRule.kt | 73 ++++++++++++++++++ .../ruleset/rules/DiktatRuleSetProvider.kt | 1 + .../main/resources/diktat-analysis-huawei.yml | 3 + .../src/main/resources/diktat-analysis.yml | 3 + .../chapter5/CheckInverseMethodRuleFixTest.kt | 16 ++++ .../CheckInverseMethodRuleWarnTest.kt | 74 +++++++++++++++++++ .../ReplaceMethodCallNamesExpected.kt | 25 +++++++ .../ReplaceMethodCallNamesTest.kt | 25 +++++++ info/available-rules.md | 1 + info/guide/diktat-coding-convention.md | 24 ++++++ info/guide/guide-TOC.md | 3 +- info/guide/guide-chapter-5.md | 24 ++++++ 15 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/CheckInverseMethodRule.kt create mode 100644 diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/CheckInverseMethodRuleFixTest.kt create mode 100644 diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/CheckInverseMethodRuleWarnTest.kt create mode 100644 diktat-rules/src/test/resources/test/paragraph5/method_call_names/ReplaceMethodCallNamesExpected.kt create mode 100644 diktat-rules/src/test/resources/test/paragraph5/method_call_names/ReplaceMethodCallNamesTest.kt diff --git a/diktat-analysis.yml b/diktat-analysis.yml index c139b4c94b..9ffbf8021f 100644 --- a/diktat-analysis.yml +++ b/diktat-analysis.yml @@ -413,4 +413,7 @@ enabled: true # If there is stateless class it is preferred to use object - name: OBJECT_IS_PREFERRED + enabled: true +# If there exists negated version of function you should prefer it instead of !functionCall +- name: INVERSE_FUNCTION_PREFERRED enabled: true \ No newline at end of file diff --git a/diktat-rules/src/main/kotlin/generated/WarningNames.kt b/diktat-rules/src/main/kotlin/generated/WarningNames.kt index 826f16ba87..61bc1fad94 100644 --- a/diktat-rules/src/main/kotlin/generated/WarningNames.kt +++ b/diktat-rules/src/main/kotlin/generated/WarningNames.kt @@ -229,4 +229,6 @@ public object WarningNames { public const val AVOID_USING_UTILITY_CLASS: String = "AVOID_USING_UTILITY_CLASS" public const val OBJECT_IS_PREFERRED: String = "OBJECT_IS_PREFERRED" + + public const val INVERSE_FUNCTION_PREFERRED: String = "INVERSE_FUNCTION_PREFERRED" } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt index 0d43046e44..981b21b565 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt @@ -147,6 +147,7 @@ enum class Warnings( NO_CORRESPONDING_PROPERTY(false, "6.1.7", "backing property should have the same name, but there is no corresponding property"), AVOID_USING_UTILITY_CLASS(false, "6.4.1", "avoid using utility classes/objects, use extensions functions"), OBJECT_IS_PREFERRED(true, "6.4.2", "it is better to use object for stateless classes"), + INVERSE_FUNCTION_PREFERRED(true, "5.1.4", "it is better to use inverse function"), ; /** diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/CheckInverseMethodRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/CheckInverseMethodRule.kt new file mode 100644 index 0000000000..2f11475454 --- /dev/null +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/CheckInverseMethodRule.kt @@ -0,0 +1,73 @@ +package org.cqfn.diktat.ruleset.rules + +import org.cqfn.diktat.common.config.rules.RulesConfig +import org.cqfn.diktat.ruleset.constants.EmitType +import org.cqfn.diktat.ruleset.constants.Warnings.INVERSE_FUNCTION_PREFERRED + +import com.pinterest.ktlint.core.Rule +import com.pinterest.ktlint.core.ast.ElementType.BLOCK_COMMENT +import com.pinterest.ktlint.core.ast.ElementType.CALL_EXPRESSION +import com.pinterest.ktlint.core.ast.ElementType.IDENTIFIER +import com.pinterest.ktlint.core.ast.ElementType.LPAR +import com.pinterest.ktlint.core.ast.ElementType.OPERATION_REFERENCE +import com.pinterest.ktlint.core.ast.ElementType.REFERENCE_EXPRESSION +import com.pinterest.ktlint.core.ast.ElementType.RPAR +import com.pinterest.ktlint.core.ast.ElementType.VALUE_ARGUMENT_LIST +import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE +import org.jetbrains.kotlin.com.intellij.lang.ASTNode +import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.CompositeElement +import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement +import org.jetbrains.kotlin.psi.psiUtil.siblings + +/** + * This rule checks if inverse method can be used. + * For example if there is !isEmpty() on collection call that it changes it to isNotEmpty() + */ +class CheckInverseMethodRule(private val configRules: List) : Rule("inverse-method") { + private var isFixMode: Boolean = false + private lateinit var emitWarn: EmitType + + override fun visit(node: ASTNode, + autoCorrect: Boolean, + emit: EmitType) { + emitWarn = emit + isFixMode = autoCorrect + + if (node.elementType == CALL_EXPRESSION && node.text in methodMap.keys) { + checkCallExpressionName(node) + } + } + + private fun checkCallExpressionName(node: ASTNode) { + val operationRef = node + .treeParent + .siblings(forward = false) + .takeWhile { it.elementType in intermediateTokens } + .firstOrNull { it.elementType == OPERATION_REFERENCE} + if (operationRef?.text == "!") { + INVERSE_FUNCTION_PREFERRED.warnAndFix(configRules, emitWarn, isFixMode, "${methodMap[node.text]} instead of !${node.text}", node.startOffset, node) { + val callExpression = CompositeElement(CALL_EXPRESSION) + val referenceExp = CompositeElement(REFERENCE_EXPRESSION) + val argList = CompositeElement(VALUE_ARGUMENT_LIST) + node.treeParent.addChild(callExpression, node) + callExpression.addChild(referenceExp) + callExpression.addChild(argList) + referenceExp.addChild(LeafPsiElement(IDENTIFIER, "${methodMap[node.text]}".dropLast(2))) + argList.addChild(LeafPsiElement(LPAR, "(")) + argList.addChild(LeafPsiElement(RPAR, ")")) + node.treeParent.treeParent.removeChild(node.treeParent.treePrev) // removing OPERATION_EXPRESSION - ! + node.treeParent.removeChild(node) + } + } + } + + companion object { + val methodMap = mapOf( + "isEmpty()" to "isNotEmpty()", + "isBlank()" to "isNotBlank()", + "isNotEmpty()" to "isEmpty()", + "isNotBlank()" to "isBlank()" + ) + val intermediateTokens = listOf(WHITE_SPACE, OPERATION_REFERENCE, BLOCK_COMMENT) + } +} diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt index 5fc4b700b2..7640a6f678 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt @@ -111,6 +111,7 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS ::CustomGetterSetterRule, ::CompactInitialization, // other rules + ::CheckInverseMethodRule, ::StatelessClassesRule, ::ImplicitBackingPropertyRule, ::StringTemplateFormatRule, diff --git a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml index dc4b98a7df..3e7f60fdb6 100644 --- a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml +++ b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml @@ -413,4 +413,7 @@ enabled: true # If there is stateless class it is preferred to use object - name: OBJECT_IS_PREFERRED + enabled: true +# If there exists negated version of function you should prefer it instead of !functionCall +- name: INVERSE_FUNCTION_PREFERRED enabled: true \ No newline at end of file diff --git a/diktat-rules/src/main/resources/diktat-analysis.yml b/diktat-rules/src/main/resources/diktat-analysis.yml index 0c9e986f18..0caa29ff1e 100644 --- a/diktat-rules/src/main/resources/diktat-analysis.yml +++ b/diktat-rules/src/main/resources/diktat-analysis.yml @@ -410,4 +410,7 @@ enabled: true # If there is stateless class it is preferred to use object - name: OBJECT_IS_PREFERRED + enabled: true +# If there exists negated version of function you should prefer it instead of !functionCall +- name: INVERSE_FUNCTION_PREFERRED enabled: true \ No newline at end of file diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/CheckInverseMethodRuleFixTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/CheckInverseMethodRuleFixTest.kt new file mode 100644 index 0000000000..58d7f86c7b --- /dev/null +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/CheckInverseMethodRuleFixTest.kt @@ -0,0 +1,16 @@ +package org.cqfn.diktat.ruleset.chapter5 + +import org.cqfn.diktat.ruleset.rules.CheckInverseMethodRule +import org.cqfn.diktat.util.FixTestBase + +import generated.WarningNames.INVERSE_FUNCTION_PREFERRED +import org.junit.jupiter.api.Tag +import org.junit.jupiter.api.Test + +class CheckInverseMethodRuleFixTest : FixTestBase("test/paragraph5/method_call_names", ::CheckInverseMethodRule) { + @Test + @Tag(INVERSE_FUNCTION_PREFERRED) + fun `should fix method calls`() { + fixAndCompare("ReplaceMethodCallNamesExpected.kt", "ReplaceMethodCallNamesTest.kt") + } +} diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/CheckInverseMethodRuleWarnTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/CheckInverseMethodRuleWarnTest.kt new file mode 100644 index 0000000000..924fd8f009 --- /dev/null +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/CheckInverseMethodRuleWarnTest.kt @@ -0,0 +1,74 @@ +package org.cqfn.diktat.ruleset.chapter5 + +import org.cqfn.diktat.ruleset.constants.Warnings +import org.cqfn.diktat.ruleset.rules.CheckInverseMethodRule +import org.cqfn.diktat.ruleset.rules.DIKTAT_RULE_SET_ID +import org.cqfn.diktat.util.LintTestBase + +import com.pinterest.ktlint.core.LintError +import generated.WarningNames.INVERSE_FUNCTION_PREFERRED +import org.junit.jupiter.api.Tag +import org.junit.jupiter.api.Test + +class CheckInverseMethodRuleWarnTest : LintTestBase(::CheckInverseMethodRule) { + private val ruleId = "$DIKTAT_RULE_SET_ID:inverse-method" + + @Test + @Tag(INVERSE_FUNCTION_PREFERRED) + fun `should not raise warning`() { + lintMethod( + """ + |fun some() { + | if (list.isEmpty()) { + | // some cool logic + | } + |} + """.trimMargin() + ) + } + + @Test + @Tag(INVERSE_FUNCTION_PREFERRED) + fun `should raise warning`() { + lintMethod( + """ + |fun some() { + | if (!list.isEmpty()) { + | // some cool logic + | } + |} + """.trimMargin(), + LintError(2, 14, ruleId, "${Warnings.INVERSE_FUNCTION_PREFERRED.warnText()} isNotEmpty() instead of !isEmpty()", true) + ) + } + + @Test + @Tag(INVERSE_FUNCTION_PREFERRED) + fun `should consider white spaces between ! and call expression`() { + lintMethod( + """ + |fun some() { + | if (! list.isEmpty()) { + | // some cool logic + | } + |} + """.trimMargin(), + LintError(2, 16, ruleId, "${Warnings.INVERSE_FUNCTION_PREFERRED.warnText()} isNotEmpty() instead of !isEmpty()", true) + ) + } + + @Test + @Tag(INVERSE_FUNCTION_PREFERRED) + fun `should consider comments between ! and call expression`() { + lintMethod( + """ + |fun some() { + | if (! /*cool comment*/ list.isEmpty()) { + | // some cool logic + | } + |} + """.trimMargin(), + LintError(2, 32, ruleId, "${Warnings.INVERSE_FUNCTION_PREFERRED.warnText()} isNotEmpty() instead of !isEmpty()", true) + ) + } +} diff --git a/diktat-rules/src/test/resources/test/paragraph5/method_call_names/ReplaceMethodCallNamesExpected.kt b/diktat-rules/src/test/resources/test/paragraph5/method_call_names/ReplaceMethodCallNamesExpected.kt new file mode 100644 index 0000000000..00606b0492 --- /dev/null +++ b/diktat-rules/src/test/resources/test/paragraph5/method_call_names/ReplaceMethodCallNamesExpected.kt @@ -0,0 +1,25 @@ +package test.chapter6.method_call_names + +fun coolFunction() { + val list = listOf(1, 2, 3) + val testStr = "" + + if (list.isEmpty()) { } + + if (list.isNotEmpty()) { } + + if (list.isNotEmpty()) { } + + if (list.isEmpty()) { } + + if (testStr.isBlank()) { } + + if (testStr.isNotBlank()) { } + + if (testStr.isNotBlank()) { } + + if (testStr.isBlank()) { } + + if (list.isNotEmpty() && testStr.isBlank()) { } +} + diff --git a/diktat-rules/src/test/resources/test/paragraph5/method_call_names/ReplaceMethodCallNamesTest.kt b/diktat-rules/src/test/resources/test/paragraph5/method_call_names/ReplaceMethodCallNamesTest.kt new file mode 100644 index 0000000000..49b999d2a0 --- /dev/null +++ b/diktat-rules/src/test/resources/test/paragraph5/method_call_names/ReplaceMethodCallNamesTest.kt @@ -0,0 +1,25 @@ +package test.chapter6.method_call_names + +fun coolFunction() { + val list = listOf(1, 2, 3) + val testStr = "" + + if (list.isEmpty()) { } + + if (list.isNotEmpty()) { } + + if (!list.isEmpty()) { } + + if (!list.isNotEmpty()) { } + + if (testStr.isBlank()) { } + + if (testStr.isNotBlank()) { } + + if (!testStr.isBlank()) { } + + if (!testStr.isNotBlank()) { } + + if (!list.isEmpty() && !testStr.isNotBlank()) { } +} + diff --git a/info/available-rules.md b/info/available-rules.md index 550983f0cb..6af0e09a05 100644 --- a/info/available-rules.md +++ b/info/available-rules.md @@ -91,6 +91,7 @@ | 5 | 5.1.1 | TOO_LONG_FUNCTION | Check: if length of function is too long | no | maxFunctionLength isIncludeHeader | | 5 | 5.1.2 | NESTED_BLOCK | Check if function has more nested blocks than expected | no | maxNestedBlockQuantit| | 5 | 5.1.3 | AVOID_NESTED_FUNCTIONS | Check: if there are any nested functions
Fix: declare function in the outer scope | yes | no | + | +| 5 | 5.1.4 | INVERSE_FUNCTION_PREFERRED | Check: if function call with "!" can be rewritten to the inverse function (!isEmpty() -> isNotEmpty())
Fix: Rewrites function call | yes | - | - | | 5 | 5.2.1 | LAMBDA_IS_NOT_LAST_PARAMETER | Checks that lambda inside function parameters isn't in the end | no | no | | 5 | 5.2.2 | TOO_MANY_PARAMETERS | Check: if function contains more parameters than allowed | no | maxParameterListSize | | 5 | 5.2.3 | WRONG_OVERLOADING_FUNCTION_ARGUMENTS | Check: function has overloading instead use default arguments | no | no | diff --git a/info/guide/diktat-coding-convention.md b/info/guide/diktat-coding-convention.md index 0450dc2531..c58621e6e5 100644 --- a/info/guide/diktat-coding-convention.md +++ b/info/guide/diktat-coding-convention.md @@ -1885,6 +1885,30 @@ fun foo() { println("Nested Output: ${nested()}") } ``` +#### 5.1.4 Negated function calls +Don't use negated function calls if it can be replaced with negated version of this function + +**Invalid example**: +```kotlin +fun foo() { + val list = listOf(1, 2, 3) + + if (!list.isEmpty()) { + // Some cool logic + } +} +``` + +**Valid example**: +```kotlin +fun foo() { + val list = listOf(1, 2, 3) + + if (list.isNotEmpty()) { + // Some cool logic + } +} +``` ### 5.2 Function arguments diff --git a/info/guide/guide-TOC.md b/info/guide/guide-TOC.md index 524e30dad2..5618f99bb2 100644 --- a/info/guide/guide-TOC.md +++ b/info/guide/guide-TOC.md @@ -82,7 +82,8 @@ I [Preface](#c0) * [5.1 Function design](#c5.1) * [5.1.1 Avoid functions that are too long ](#r5.1.1) * [5.1.2 Avoid deep nesting of function code blocks, limiting to four levels](#r5.1.2) - * [5.1.3 Avoid using nested functions](#r5.1.3) + * [5.1.3 Avoid using nested functions](#r5.1.3) + * [5.1.4 Negated function calls](#r5.1.4) * [5.2 Function arguments](#c5.2) * [5.2.1 The lambda parameter of the function should be placed at the end of the argument list](#r5.2.1) * [5.2.2 Number of function parameters should be limited to five](#r5.2.2) diff --git a/info/guide/guide-chapter-5.md b/info/guide/guide-chapter-5.md index d9623e54f2..294418dce4 100644 --- a/info/guide/guide-chapter-5.md +++ b/info/guide/guide-chapter-5.md @@ -59,6 +59,30 @@ fun foo() { println("Nested Output: ${nested()}") } ``` +#### 5.1.4 Negated function calls +Don't use negated function calls if it can be replaced with negated version of this function + +**Invalid example**: +```kotlin +fun foo() { + val list = listOf(1, 2, 3) + + if (!list.isEmpty()) { + // Some cool logic + } +} +``` + +**Valid example**: +```kotlin +fun foo() { + val list = listOf(1, 2, 3) + + if (list.isNotEmpty()) { + // Some cool logic + } +} +``` ### 5.2 Function arguments From d34ed1c7eafbc8c6b1d3551569dcc0fc5a7737fd Mon Sep 17 00:00:00 2001 From: Denis Kumar Date: Thu, 14 Jan 2021 17:56:55 +0300 Subject: [PATCH 07/11] Final version of white-paper (#655) * Final version of white-paper ### What's done: Fixed final bugs in wp --- README.md | 6 +- .../docs/GenerationAvailableRules.kt | 2 +- .../diktat/generation/docs/GenerationDocs.kt | 105 +++-- info/guide/diktat-coding-convention.md | 46 +- info/guide/guide-TOC.md | 2 +- info/guide/guide-chapter-2.md | 2 +- info/rules-mapping.md | 3 +- wp/README.md | 9 + wp/makefile | 2 + wp/references.bib | 20 +- wp/sections/appendix.tex | 427 ++++++++++-------- wp/sections/compare.tex | 100 ++-- wp/sections/conclusion.tex | 4 +- wp/sections/definition.tex | 13 +- wp/sections/diKTat.tex | 10 +- wp/sections/download.tex | 93 +++- wp/sections/examples.tex | 1 - wp/sections/feature.tex | 81 ++-- wp/sections/introduction.tex | 8 +- wp/sections/kotlin.tex | 44 +- wp/sections/work.tex | 157 +++++-- wp/wp.pdf | Bin 0 -> 1587863 bytes wp/wp.tex | 46 +- 23 files changed, 749 insertions(+), 432 deletions(-) create mode 100644 wp/README.md create mode 100644 wp/makefile delete mode 100644 wp/sections/examples.tex create mode 100644 wp/wp.pdf diff --git a/README.md b/README.md index 46cfa6a1c7..0f3a8f5295 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,9 @@ Now diKTat was already added to the lists of [static analysis tools](https://git ## See first -| | | | | -| --- | --- | --- | --- | -|[DiKTat codestyle](info/guide/diktat-coding-convention.md)|[Supported Rules](info/available-rules.md) | [Examples of Usage](https://github.com/akuleshov7/diktat-examples) | [Online Demo](https://ktlint-demo.herokuapp.com) | [Whitepaper](wp/wp.pdf) | +| | | | | | +| --- | --- | --- | --- | --- | +|[DiKTat codestyle](info/guide/diktat-coding-convention.md)|[Supported Rules](info/available-rules.md) | [Examples of Usage](https://github.com/akuleshov7/diktat-examples) | [Online Demo](https://ktlint-demo.herokuapp.com) | [White Paper](wp/wp.pdf) | ## Why should I use diktat in my CI/CD? diff --git a/info/buildSrc/src/main/kotlin/org/cqfn/diktat/generation/docs/GenerationAvailableRules.kt b/info/buildSrc/src/main/kotlin/org/cqfn/diktat/generation/docs/GenerationAvailableRules.kt index 9585927619..d1757c9c53 100644 --- a/info/buildSrc/src/main/kotlin/org/cqfn/diktat/generation/docs/GenerationAvailableRules.kt +++ b/info/buildSrc/src/main/kotlin/org/cqfn/diktat/generation/docs/GenerationAvailableRules.kt @@ -18,7 +18,7 @@ fun generateAvailableRules(rootDir: File, wpDir: File) { .map { it[2].replace("\\s+".toRegex(), "") to it[5] } .forEach { ruleMap[it.first]!!.config = it.second} val newText = File(wpDir, "sections/appendix.tex").readLines().toMutableList() - newText.removeAll(newText.subList(newText.indexOf("\\section*{Available Rules}") + 1, newText.indexOf("\\lstMakeShortInline[basicstyle=\\ttfamily\\bfseries]`"))) + newText.removeAll(newText.subList(newText.indexOf("\\section*{Available Rules}") + 1, newText.indexOf("%CodeStyle"))) var index = newText.indexOf("\\section*{Available Rules}") + 1 AUTO_TABLE.trimIndent().lines().forEach { newText.add(index++, it) } ruleMap.map { it.value } diff --git a/info/buildSrc/src/main/kotlin/org/cqfn/diktat/generation/docs/GenerationDocs.kt b/info/buildSrc/src/main/kotlin/org/cqfn/diktat/generation/docs/GenerationDocs.kt index f3584d6b5e..483d8973d8 100644 --- a/info/buildSrc/src/main/kotlin/org/cqfn/diktat/generation/docs/GenerationDocs.kt +++ b/info/buildSrc/src/main/kotlin/org/cqfn/diktat/generation/docs/GenerationDocs.kt @@ -5,6 +5,7 @@ package org.cqfn.diktat.generation.docs import java.io.File import java.io.PrintWriter + /** * Adds/updates diktat code style in white paper document. */ @@ -22,15 +23,14 @@ fun generateCodeStyle(guideDir: File, wpDir: File) { val lines = file.readLines().toMutableList().drop(1) tempFile.printWriter().use { writer -> val iterator = lines.iterator() - writer.writeln("\\lstMakeShortInline[basicstyle=\\ttfamily\\bfseries]`") + writer.writeWithoutApostrophe("%CodeStyle") while (iterator.hasNext()) { val line = iterator.next() if (line.contains("## Preface")) - break; - + break when { line.startsWith("#") -> { - writer.writeln("\\section*{${line.removePrefix("#").trim()}}") + writer.writeWithoutApostrophe("\\section*{${line.removePrefix("#").trim()}}") } line.startsWith("*") -> { writeTableContentLine(writer, line, 0.5) @@ -49,8 +49,7 @@ fun generateCodeStyle(guideDir: File, wpDir: File) { if (line.contains("dw3cFWNRb$kiAU(sRYbjq*uItnDx9LFgp zfB`>_Z*X5IpB8gW4dwls+%>r!5!pv4YVL)xXz2=MtY&>{n=HYh!QnX}t>Sw25do6< zt6NP{64TSAz1?v{-+*JaV<(dCXKwxp%N{v)VXZc!H`@}bz3vO_HJw}pgr))7u@h(%dwNJTUPn&F0gmEb+RgK`bXzBmdCtgS@x7HMdVN#t~`d{GPWr~Qg+g%-_5!GHS<6E%0MGh!H!zF<3Y7zC3} z-jzX=wahG0;DvUNmh^bUR$BOB%doZ#V^lsx+#-O}9J42(mj@BF{jM~G{6bhJCcf{| zBENby@8LW?1%jiyHx1q|YqFV`v3HaX_G3CvK&sHUlUYZnN9vhp@&NTcaW2pxjuPt? zX=$vny1MfyJqb$g2|};nVjG}gc1wGD(d9n%TP{_M90n{+7+Tm%v=-JaLR~mFgZ{gn zv>EUM_`H#RGfc!PfH%%~fX(tb@LW?QbzqxC3jow*PIf>BBrX_NX~e8w+OV;?B=7CZ zW|0!;XaO`Sez0bkBMiVb6*Mi=_(poc#x=!3-@ffb=t@##P3L^QQD zSyw{$#-P19E>!dh8k}6;eXDgY-UWLhO9`Uk88jFEcdhBP;j+IJH%1icFvI?{^e9-L;fPqBG8p#LaDQY-W@ zadIj#aUcThg=xH6$h2;2e1-#t^L;7Q0Qxt{iV?2!J*$bU64h$F^}P&$N!bU<9z=v~ zHGlYwtRW#8REiB!K8}_`dQ{a|7OVktKuPY_Sn|SJ4NGpkq+pY3aj!(ygMA!nHQrU{ zpUvbguSypsf^d(mmBIH9H&p?yg%{mjIkm$*5c`Ehy2b2Ma$`)aOm+?zSr(1(37{>H z#Nf(C$@GlCqKwYhsE)R>7IBpeY> z!yGI8vI81QW1?TVfkcocZ7&R8NP4O&+)y*-D$A-_mIc`}NRaRc9j_gJ~tL;Ecuc)u9R2?n%ADPFhhep_nz zfY4e}<%XIxNrmb@9xbetF(+%W2!5-@yfUfNUx>1fAy*H}B#g)TUe!+18AZ{lAG!NE zeoOnx7!Xo-BQYpAGFa`9yf$r?W2skhqr9NTHsKy%+Qaogh?Hn_%1gH}HRIo)ct2z} zWZ^4@-s42#vi~lVnqT9`>s{z!pv-Slp6Ul0Re8rI1Mo=_z4hjXhjZg?3$IH(m7YHO zF2xjTwyrBstoTb$$$B2`p{3Smc51I#P}xgzV@CO)-VUd(_9KBmXSWm5hCw%Wa`u0JmkesU9F=+KDzfsmd z8M{(BT^p9(tdR3&xBq!q);IBso%iOGszNQqGr^5?CdvTQc;AEJ^CQocO9XE}0k?Y< zaH>S3RFMVxS#@+7MSO^-+s_S0J9wU7-vd_N$X(jdtQA4I`Pj=%AWUS1a9^cOfGIHk%i4Kx_AdOePYY06%P*xty5_>$BI$5rPP(Zeim{NvdRIl=^~*JMx`5pb z=hS%WRt#RH;dSz_bGqtEVt2IzRY*@7)rx0AMpF#HxeGES9;%n!ph3U_@(t(dSTl`me zJbYF@C0NmrG@f4F?8`#ZmSK|k1)Oq%E;BWz@Cc%s#N4_a#10uQ+TG}W*4&IZwa^I- zUQt|+&CLcU{;EB%CX~-|F^kcGxCHyg4)xT9v(&s|+xOgeP#X(@_&kwF8qM`_qgtc# zHSO|?fn{7WSeZ)HZYCXC`15)zfqRd(LN^Je`@%ZuaCkq08ujn#y@W|E|NRjqq z02V0NYT>@Jb*ygtflP!Y^9buK>#2d+Nd@%XYfX*LtXdnI;3Urmf5p{ueP@!dkj}8% z!lf+`2oyj7 z#Uefjv-IPJc2#>HQMj6%A}1XEXPxtUBJbK_s9xkazznguughleLCTx3#zlkbd}?hT zU_RvP#^O8(yHEsQ6nBM6)e_n(^%_3Rt+Z3?MdP%mz+98kFk2K%gok2{LH@fLgJ_0w z+0aqzW}aAV`Vb~QROVLrT#1T$89AriS|n~6SvuO*&TkW=j0OQY7atDWEttglTFSUL0#CKLV}=v(9?Nq)_`6RoY>IGr|*(nR(it}25=C9QJp zkw)oq_{~tUhbu>9m(ti9jf9tyez88B?-Ey`J-e-k}448XV~hHYne z9(&YyeF}k=H5+)s_^1+d2X(C_L8U#i=qz?3Ppwox>TZm#s2j5R z7L>-7iZTrg5(#F5{jMR<$UPy!$@ahG!?S$4}y`(ea- z5o8P3XllMn`Jatv)F{-*YejPA%ITvM;Lt^5To;3C zmSud}`YH2M2fi?-`K^emKU=kxL#V}$fdsYIEhoK`Y{X4*8+;I?#q%C%8v=S8o&la& zj7}B19~*@QnErvyt#aKokf+kA9uN6fMu``8@U-F_ch8=T4|5!*g(Yf9CAt4bK!CyvjT6-BI;W-q8YnW z){3MOCo&EQV+bbrlE%!Oz?R8J}FH05}w)J8&)JGK+K*s|R z;N4Sk3Q7RMg&&~FbnufI!fbBI>JY9k1{j(^Hq!q$xDOyzm>qrygXT0>! zS8d7BIbwe+im_TFMkh!wik(mM(F)VuP@~-bdV+l1|aE#W#tm8 zHzqlASu$>`Jo3e*9TM6igU?MU&p0D9=}>4cGE=KtG`+=NYRE&tEq{?y4WTZS`pkHM ze3T2ie^p7xl|v)-_^sz{8>;&c>B{Xz5w+}tz=e}4f3OgVY|=ESpj3KP<8^M^kARkU zAf2e&-WLUneS4(}{u*7POQ@>&ZEBMwO9X5RiTv58QQW+C`~=MTDy17O+&TuI$v;P< zb4+VutUZ+5Z}K86+H=Ts|4w?bF4;^T3Rtu{Mz6>IFjT8~q{H%(GRMy-oksy%ADm}~ zVVV9RzY?8R%bwUG;f%wh3R#E3mc?NyOpm3BMrtvtTHp2qWqsgj^T|T#aI;a6vP-Zf z_x&e&%q#=AX1t_S!J=2>ntP}xV9M}%H8;L5hiD1h2jB1ZvNarpdlYI|stV64(jiU< z-L2Z{i9$gHQWW}{2u*Y~x0AQ)7J^B?y3f`yniHsX4X0CJC(wS9o|d0@z<>{;Ysc_< zPbGNA9J5!u5`T?{ZZaPa2p3BxE5w2ekC}qo%cDT5XM%5fngkfY1B&?14Q*?>|L3Kk z$|rCP_k>mGNl|{2u}B=Q;;Qdz8$3kWUgA=OQ$xPyFCke;RXUXYpLv(68Y?7dUsQt zM8-Eio3j{5p)ujxW&4uYx2jvaHFi+6;SWP0*G#=i zcgr!?tLaHF_G6XWS=(0lc7aSAP%K1-S1GnBR)KAVA;lPg-*G-+dxzM5j=gC;+8^Ud z=A2Ywv@J&&OmjAXWoqU5v}WjQ>e!o%CT-X^u4D3k?=^G5Hur)l^qma?_bM?(v{{(A zsx7O=JN5!uQ(mc3=bi2~&JWjtJ!`|S2xPA1ab(o@o{W3&Zsx;(@(GeFzi7$irYRO+ zS}c?oXcw(1snLmUFca%Y^5 zOi5=&W#bZ6#_-edo5tw5O8$+?gNgjE`<%F{iC|Sk zt&v<1EW_E6lYE=d*bHnFY}zEDlFC=m`O@WHFPw^;EN8umc+5EXSm|M4OylJXUTqc@ zdt8HW17$XLNFdmcZFn@4*OB76w-1u&F)ivLvHU}So4xZ@StI`&qn`n`6cHVp5hlP_ z4?XgynFT!VWaOn;)G22FDRZL)QJ7q?;30A1_!hk7(cdDCtreDUGq|ALw~POYGWzkb z6`ML(%0Uaqv{^O9sp|$NGH@W+ePLzK`0z~J&zegZI8w#ldjiY9@|&2<6L%=tUEE^Y zvBA!{E%he9k!+mX-L`B7al)S{J5stpq{NV0snD7j&YpueD(E*>_E&P-J=>wYYlgfZXa84hzM)LXn*Y8lA(h(Y4b@r#E5 zyivyJr?N{HGZh6ktz~^VHPB#{GbKk z8!`4D%`u~M5xYRpFAgOL@cQp5GvzKq8<(XENp#Evcga+U4Hvr3&{V6tfDAx;^)K!~Y)q{4)xbeHB`^y8)>9r|z;wGr)&q)D1KHk*fy4cA$z$`(4EtWl zv$J6+{x=B*pG8i=XJgc)$;G<033UE`f6^sJR|N%5 zSvzZy>;7WKD0H+Uu7o%b*Ev?l&ab5=!aen+fGIHbo?(C!mQ|bK8_`UmMG&SUHsyg4 z(b%!XTi$uGp`opzXsmLV-8^h+cqLt1` zQ0LJwq7Psmb;XL$(UkGQO@B)$wQTuJ)FpfSkuzl(%ip2{I~Bzx$e>whguBevmye<- zHnkyfhfMYV>n7y@MZO_ROD?>vu$2aHb{>PNFBUyXH9<&KNMd1@UpkL@ClfoqeUq$ z;!)xYpws9vHLN4f-m+IA+q20O%aOH1O$*b@k4GrovGBDIPOE6M@6vs zDVd0V=(aR{M8R1l`wU#S>yPwQ!k;7&d*4rvO93=kT1cOu883<|)Z4k(Gy+zp%U<>W zp#;Eq4x@6}9$}i^%z_6G%SzfmNru`82FJF=KO)iRTWqc&c^r;He&H~i(t&Q}r=#$G z-y3W#vfpgcLNfE}z_E@<6tB_FLTVQlg0!KuWz~Hxsbd5#Z24ATi3D@`jAg3+S$28Rkq3#`JhY>C?tM1 zsQnc54vVO^(jc&YKamHY(6OoNl!YA@^CPR!Sng#O%UY8CSO}WyDTHxWzfK9R@#ay*ozsm3+hXvLf)D?xEAO1pV@|Jp);emZ zHR_TN5MIj!wLy?t_}G7w=F$edJFER+`d3~0a~WLK!ZGLO15?-o70VD!!#}``SQAp& z`G(M|n~jXE!CU@yvm4rq!`73i=@I}5^owV z6FP`|Q3Wl<&Q!&GaLTJWfa2^1aP-}LC^nf3lj7vJUY5K|PR_$N%eOn*zD@88m24m@ zIUW&Uk2+gXJHT+1GW0xshhs`#U9(?NrTv~tN6UdWMP>Sl6ZC~6xtNh(4=rxK z`dLmP=k4=pd-^HozO&$>)Xz_2(BDnwXK7$c1&FE$7SN;@43MfW=FtErmSRem&H+@n zLDZXz{&jJ1*j8dU4qnO%T9$&V=4~n>DBH|;>=8Q;OXM(#0(uZxrS4& zb`iX!Og6^6`HwQw>k#*ldoO|Ptl0a|{4)(}6}$rxT&xi!KPYH;P3vfu=DXr7y9MB~ z(GA7r$!zHah<%>F7LtGaJ;Ord_*IZgWvS*PPw|NOPQU(L%G0T-A%qqjyKhi?H|VaF z(t#Z7f15JwEVfpu$IRzo)p@NtVAh)Tqp1KD@v*e4T9SqXmJw4TK0b%!)i_&>S={NK z86UGy<0|_{EZR*wC06|O!L^Xj=YVGK=_RFE7-HJu0VfOO1@i~R%%x;!3&5N4F32Is zOU3TnCvrL(F&l)Ss*y%T@U+1wL}$`Hm=L6b-E`i%7wq>>5w; z>gY&>YuiW<&qMU%hS|gQT|5KM>-7panfdOjAgfB7_(okv+Pd%671pfx!f^3m3be>- zIeRs_rlsjPSMZuaL4dVi1axr7nZ%9QT8N3R-1M$l+ixc_Hj_Sjc49L?re?3Xt4~Q~dSgko z^NOc%p}rFO!nf~=4Dc_j-*hOHtbd2Yb@dq#lMp+Cpf&-Zd~C8S`w0_m1sJ=D00-MK z!;98mr7Lu4FJ+;A#Y!~-vqrIs40sk3UKZ9UlEHml7=cS=$^;!QsqRt3W}~hIy`sd_ z+KdMzL<8?<6~~Dg(F_XHQ=vrV>7`4 zeq+NEo;)aSbsa9jMBa0erZ)Ky@*6IV*IY28WA)QYjf;ny2t(w&@X*B!V1rcl`geAo z?y5j>81s|RgbXs}08KupjXhwFe!GA^)Ckwez5w(@89mRfd-1tdjr-5;Dr|x z=NO8hcK{%Ch;OV#1FwyH0F5W*SxM1wto5qQSz>XP<&N@~%87!uFXPMfn7&z1FrEz1 zmtf9(c({=%K2Ri?KswHCvFpYtW+qCWAIX9}t`qu*YG)VnV$*u%D%n}_bnmbGK?GS> zIT8#sDN)6TU4yv}@fX89kN&a~9SXPyPRv^PV+kPWY|4CV+V+l=xzujuvLmBa4bLEpd%bEi zqGP~H_0$*|DS9JBqTfl1iTqPgt3jKt^4kVK>aPYic8j2f)j?uD+{#4jd|vqMDm^t6 z3=65D?*bv~jaUvT0+A?5a_x(=9o+5kZ>KmlTk`l72#3Tk({of5d;zn=KS)FNI3vw5 zjPBbwr=H=!<{mdJb*a%3l7OQEJger;0IwhQo&5yCMT`tBZFAF<42YsLF3{JcJ}~|z zWd<=&2)8TUR&n~%kfS_Bg6mmJwEtTRC1V}tMFjjKQ`fLuhO?J>A@wXP3^cK0-^QlE zDp}If0dAdO@*PGP3H59fcrTEXlw)D*v;06Ji{)o^M_=j$bwnlD5VPUx?h7T2iQtM$ z)(wXk;8_1=FInRcp6D?aL~$TdvXh^V8qXt}aTbzW993#%e`Y=u1$I|>Nesi34uH!p z<}kObT)~o~)L}}eiMJ!O=i^=hjYbUG4;C3*fr)LU1rewHot^?3p=AJ)fNMFG$wnj!OR1p)#a0;0oX<3-^AuiAY!OPd zsJ(_MuGXW9Q8&!6Ba(cr8Ku=63?1Vd+l5doyoE?Mm~%)`vH9p_=c$euel=coQ%opU z^`g$iv01dx$dZ*bNhA|ULSb6_u4xbMjpptimusC9thLH=yOBuyTm}9`aZFrGsyDhm z4fuD?i;w`2lqhvc`&hB>b_kiZV@aq#?nv$ts>$uls&mql@YiU#aH%R0a2FOzPqnZa z8oQlgP{`TR!EEtcnJ10-0N%XM042Z)`L^^qaX?_QC%AK8`Vvq+p8`^f2{+-{)7WuD z)#9gWz2ecC-W4P1aEl`|A6XO>sv+OEFKr}C0W3R)j#47Qu7v0ir}$h>;mg|`nUf5> zD-M9vNU;DTgRcoc#ILTO=psmE4&Ux(s08Z0uRH2klw~ zzqa~IX*m&YxjLBVh`$Pj3yt4ahHmGr(AZk$O_bp}>9`r*xVC`N7torte|jEiX$M79 z2VsF6$T+fgyZzOL3c1$sV!irdyX^9%=?oM`3!b(aH+gEt5fc_m0#V3I`P$jZCRm{+ z8L(??b>>p&iMkXOK94P2-HQ-uw^eEP<2V46BMqo&GVUKme8;Ta%gIdl4q@@pBq|Mi zn2K9pU4{&(=T3tD+W?s@a|wsww^ZJZ-FLW_lVkugx^a+ZXW|E<{5V%5b#C%WknpY~ z#UJgvcjLc=Bh~l|LefX7T23B2Ba#>5Ojab)ucE(?B?H8u=BP`VA8{f|JIX16HA5=mWm3Pch0IcZXjv}{67yg#ouPI< zpfK7t9deLk`)|T3r$1wk<|;Cs5G@4YeFdi z8pOiQ*1c^SfgFAGmkt$sz-j{cQ4)ebq5c8poC5P%OHcoJ%pqJb!_LBT8{#}Jx@;|S zqr|E66MKKIDR}{6M6PVGeyz&ofW(wT^7D_uQn{->0YPVKkh6$YPQQFL2$%J*`P?7f-Hm-M^Dx=3 zbF|P*?mZ3!%SU_(**6M}cA^{gr9|{&TUU*BFF@GlRu!u>2aqizl&odfS_=A;FLKPt z;cfRC4XP57vtlh7h@>Ac>=jD_h`1BS=VV4+$~z37em+qW!erjc-rFq)|7h^oX7&C% za_WHex$MWH9_z3ZCJ7=fYyx;5CjCm+s_-qQKJF=q=aUb>w`NLpEp>KVOuY&IZCNsxztE|>w)fa*@f<@jL<2n? z+Mi-dZ?vX((yq=8@LT{zq^mBr3dda3`i96|`@9GmEnod0Hv7)m&)8HDz8pfxwYA$|)Tw|7Y)CE-c?mv+s$ygu8=x_o2WuV-+k> z@Z>FfNdpoX{5{@YPf+7u$_eE^aV_(P0C)Q=--eV!2YbE7`4dQ?saYO9Td-TBx4;MJ z6R!c--AXky?vf7b6sX8(0R)DciVh)$48YO~B3Cfn60o_rl0vRD0 z-+Th9rFoK3{>VA)x8^~4%qP_)!>h4CymI`@$Cj-*p`s4ik<%Mv<+Y!}%WMjWX-dj7wP0grV z<+4(FO2DP8Yor77(Iuf$%K}m$9`U>7WL#&|x|pLDn_EzBY$;Eu91}eEMV#@;J#*p= zJjKHb2geh+og+TqDnTJ-PhyOX4@C<-X3i>Al=O`LD>(VC?HL|~a=4^3v7rOrQALje zqFv~`iYGJ>P!Z%?R@};^b2cHAdebC#)bG{iTN|r3N?{1p;epcZ(qr#f)Kw0@wKn;b z8okrK{jXFxHievB#Tj&_lpGzaK9gKB7fvH@``X|g`&|k}AeP(LKlZ}ir`jqSbj|=N zzXYzF{|;pf_CBcq5cf>9rbx4S2+Mm=pfmLuv=e#NN2-(O!bwxLM+k?C3@1|`RuhR& zNufc*b$BBqU7#Z3Gpgt<*k>TIx|eVRjg(y!;p&vVbkkODOiB%}V2%rjmESE@+o;&? z?Yqj?Sq}%I@|*=e#vG?SRKXpLt;h0>G*G@4c}Pqk%UU}t=LtNz`(ErI+|c(TKf6Or zTx%Nu^*K|8&TZ$$ZHwZJT=UO8$N*rGoVb;1b_s}n^&a}+>vlcA{44ZrwOjSWnIGM} zU&y$1st_$QXY-_WqqsP>;a8+Ys$Cr7OKRHhsS>M14r06*vH7MMCy|BE4ILqpel@Qf z5LYc>jEG_bi;+y=(-aC8flU|XtloJ3L5ceY6YcGzAoeGGiCI74g{t@haFu%E)n~gASn*`e`LENIOnmG$sTRpcRQx6Jzk( zXqgh#lnX$!0_A4WO7R&k$hjybt3Fm4nuVB)#CbXzsuT_vCRI{;x_zin{HEUFuioGrQaq*wN4PnpFcZt|b3Oj`O80l)4i5Li3gzG?iW3bn`B zkLznC5(aYI+g-ZqEDhu78VY=>z?gt?DNjBG(Q&s)m<1v{mj!?;;jipie14NqGlAs^ zAIwi8FUU>z6NFmb@~yVmTlp^dS_$77u$4dq0C)CxX!+n_enJc9il(*DIW>Ng8)%Da zr3@DZ;SnbYm&hEk8y9@l*5k3Su#>U?;%`beo?k4uYC?tJi+@43(%xet5y$V$K+7FwlV(3GDoQQ<)YO$tLFoM2cCNU1@g(ed6WWGCXR?wv8G z9`?$H;=pZoI4h$REOZ4hx=M{fbBZapZJ!!;ULYl?G9Y=)Fa2piq&5M5r1NT5yJ(ul zlcevyp-V@R%n71g6K(zNDi6N#Cij9$2_d+U^hDwqyaKs{RD1V7%W4ob)GNt||0`l0 z814C?p8$3cpm~bGE$dsFStaR4M6C5>NB0*xvtH3W`il!ar;=_b+P~CArI+W=CkhtY z4a@@6pCqfl&9y3@v6pC3-s&4CA`1bm-9DPU7;55e!fzc&_nI9@l9)F)F%N+TrN-OJ zOKKHLsp?w1jDIrtY?hGq^VKZaomka}bf0v1{!7;3?+iVpD@RFJG9?tB(D|YjsBe`9 z9q(c8sorCz5%`(}GpQ0dE#S~Bn`N?#*N)e4d8r!435D*@;+p-Y%p&2HCRqcu+qmm6 z91|yxA}-dsDc!&{xuu37OuYkiEx{5t8rwRttsUF8ZQHg_Y@Q@1wr$%^PHfxO%f0u1 z|9g9_+4EJ`o~iEYnzd&4>iTLB-lKD-M!07A^YVS4{)vf@@n06S1mkA&ubCbe>8_@K z_MF*jl7aHv?l`ZDVSt-)i!G&x76lLJbTzmym0l6o#8RuYKw?7Uo7(U)Mn{rXAf509 z)f>EDy5y(PI^>!U&VAa{z^}^(u`-8k!%JoO^Af*~`>35+uN@D2mM0L0qpFpg=*!}= z9*GDx0E?xCzBoZEW_lNo4*ZU)%WeU7K7n}TrG$rTEy+clUlh@woUJ|QeMbj$Lg9XU zTdtVLd+z86HuH1k?5HG0`9SB77S}}h7T{A1o8|6|+nLit_qo8$e^)nNaeh)-E0gRA z&_J?raoT`!P-!a##_MQe%$>?PfjL=J_fEqnAv7QzhOaZ`LMZ2+)U-Ktr9riq$c#7L zoS9gT$w95c?`93L5Z-U;tjg<7ps+~C>qob2-Jpu4U|Z>{wq3u;VIMa2eN>x za(EzA;?6S-4mD>zmco1*Wl{TX=DLxFCpiu)Fp>GNV$3ahY>L8(s=6$w!jd@;4?dA9 zzJpG^94F=>0(&q8&%Y*s=xfFIO=>Qzn7H~OxbKJd#Tc%Om(a4l7z(HzZ{QRlmc@6b zR=1p%Q?1iE@|ioipBd!5#d`C?r))!!|I!;v&_O3E>6S&p8FIq$!Lf44;F-^?ua0X* zUh5*y*m#FTtQp-}Y7GW5@U)mV2gZ(_+?3?99*fdyBWWW^@<7^um}H^c&!t2B#0?nV zOAoLU2jtK^li`#@Olg>M08dQPk6J`+l#CgYzDttD%no2whVcJBK=k5f`}3V^2Hyp) zJGYdmj`wwX2W2mJjz%#-3u!c+39u_GKb2{t4j(V`Mt)!1RV`Eb2P*ZuoJ^wKSm@a- zuX|mOJj=+xVt@M9Y&0?XJr9|V^>~n2(-q>IkruQiK-G-{ING7rDS_dm{!+bE<@~PB zOPJF}7sjbh_8fDSn4>8*yFp(!vXxWm4V196;7)4rb!HAWJ2S>ppPv67r(`EaA6+dE0_YBAfxc*j(35>r3Kxzj ziJ*MTIQ}V{!f(-=x(3G2{d_B=QsaPe$d1ul{QEiwg)KZ5cRIag2-_0gvW8Y|31S^#xm+bx40uYX zlX;@a1yK(FxB;`40^2nTn9a1BSdBk6GFAC{9)^e1;v;ECAj*gVVzxd0TYzs~vQdsu zSBeuOqQ(IO8^wg6aU&b0%B>rv+sk{#O0)VNhqL5xafN7HgJ22H*O z7D7av@_zu-`7j_()16KMB#G<6KEkWR%Dd2M#KNQmp`cK0lDjOyY=AB-bv&=Rvg5$& zDM@3~J;Lh*%&OgvB}_pIHLAgQanjeaMu?6##gNAvbEstF85elZ20|O7F?F{oA2*Ex zhp>>{Y=CuXd1H8zY>GjIwv`N5{3A*&WXhN==b)?qvYJ|6i3xM3XHxe z0B75RLPKQ73pU>kT`y_lRTp2MeANC3Kk=da$S<{vq9Am&bUo`7=h?v?RHT0prsN1| z9UkH|L~uh)p>9XjNq=s+v}h;UMH{Tvd4uL_nl-5)Q|$}KPNMGhLrZ*FY_*w#$A+lh zbeQoPm?dyCK*1K-1EmhzM9rqn{vl4Y!`2?^KG^al zi!OJln<$>lxzwH=r!tKXgbxdaIi~!^f8f496<^i0CPbirFL#+uGv&zB3#1?F0Ac}c z+m4CNj9&ZD-FdEBatm_K^2<<)YtY$@$^O1#Dwk89+}45DwxIAh&S~g!5!o=Uoux7gDC+3g*` z*naSVo6`)d^GXiY?B;5lFd(}DoC1FgK#u-MW9dsP7%|_SzIGnZi)i6=sXZMi?P2o{ zY8ohN4ON2N8mW}eUco*i`^~kF>aIQ9-XM2P1lNjh5Vov#@n?2b<+8S17(_~-McLp4 z)asiKUHoERitVO}cpNvrSLv|D#Wb}dWx5}dmCW6xb#P+uk;h812e>Jf@3}G@M$*@t zmG`u?aOpdv?ajVI-J0NFc*p@ucd7Xh`qy6oL#(v^x6vVRi=L`o_S@d^QU5>)HU}9a z8huzopPoPNNHq(uj}?Zhx*cse9`y;@D5<=Y$s7fCxUc&h_}pbY0~}%IAau<9i7TLF zN%;Wkl?k$T28UMM=>p`9d+HR&m3EU-wc9Q_Y`M*)43WOBAj;Uh6Yp|GG!`+QomFxt zM$+l!0d4xe?9WPB`lf=+We9Y)FtrZDigKt6 zh!@mLsee>OQ}pMaYeZ*LE_r)3dBUXA!|vhltIyijV|Maw85-Jvqb=(vi?XgUaV-NO z|3BKQ_oX=V!5qZZ(v5Pi0md+((40_W)K}W?u9nH{@uIaEdG5se?7y{y)ptDquy1}k ziT5L$GyMKobWgax8d`(DF`{q+30h;q^cF^09NohRSRz3#6R>t>Nam3+tjV30uC)VF z87V9^ky5Sf8dAM1$PZZKBUL=f3~qz7HsGUzjUTnR8XO5ko^t> zLB)(DvFfyqFgzk3a^r@g<_s?u@YP;b$lg#7{MSC-im-pTwhf;_QeWqgdyJE26z=dt zAG9!RfwmQLi%3ww+o6Z)#J+o!DB4B&=tf9=Y+pBU1N!*a&(p*cV3EF`V)el4dt$<= z*02b^GmKmY@6kW@s{pr_f}g%7L>UmBXVW}ND&>xI!JHc!*H(c^n42QA{g$PG+W0#< zil>W4KMq{SHfFa2R9GIRcbXfE+e1-cl92BuKca^rJB=Ke|ppHge;&^jhFenLQ_+X-? zkKuAOoYulv4NyC>X>P#8b_%m>lH_a|bP{mj%|K9jE2)nQD-f_mIk1~F96Ces_}@!D zl}$*0nW~L)ko>MRu%@SX4$mt?!d6H2+?{RBku3*~B%KN_{3lS(-nS{YhbQDHz(>zL z#;_tKL&zX8gY@gCQ|8;O_~k^El$;mM<44r|zT2bVkag-YLPyn2?DXGV9KUH+)q;GD z>l*}(WgbtIM)nL(IT9hD;&Ti6QBc*bqedBL+Aeqohse4g0Oe_|5(LVeyo#U)%kA9f1MyOU=djE0y5(_2NuKUDmj^7~}QTB9g9bTeQ<@D%_-Q=^9{8&Iv7YveOqlTprfdaJo zeri)JG4o|fCJJkCq0&1K5I{A5=NtS>M6;qoV_*Orz%-^a;hPUJ;cL$R*J?64y)dcG zN)DQ}VbxsJbCC@0_N#}SPF)*ZpM+~6s@HJ?Nkc-}Qyx_#69KLIz%?p;F4PVA^8OK;-~98Qye$cff)(423sXZZ+*W(zVY0Oej8G1 zfnY`#!HqqmJjBu2`!3Kz6UfFe5U=NhJA-;Wr-Yw{kax#-LvKoz0L02{!HJX{VjYeY z%Y2CU+vnHbtdh3Yo)`uQI}z>L-W}!6-kwmJR>U_OuV1{QOFmY zm@~uj=4u>l3-wKECD?#3Ba;}VDM{-ivyVt+9Ldf3?r{2xuU|N!$%lq>VWOKocdfw3 zXo#PC!OqX5>SFIv;)_8nD7b%lizrv04ij*?u7z*HD-uhS(VqgYKz`4-w9+&ZOYx*k zR+TBnB+`!%8wgJAAsDRL=&TT-heQ^nFxixF<=(~HwVJRR#u?pLwPx_@q-&e7^qbCRwDo4e($MxZ1v7o+Z}GztDC=!a3lUxPI12ZCfb4c5|+M&}Wjxnb1RI z$8SC&R&)dk&djE1>RMxa#hG=fbGCeqz_@kPn|3at<0u)$thgnzlFYsf!XDyyM?vI2 zDJTBr^SdLY7v{{5O3=_-Y8#+)1H6yvB)!Cs^D{NX~r z!W_Asl_eoKiyQm9p3*U&J~!zd51pz6Z>*PTAh5V$ST7CnsgfJ0qPSZHGTQk~{^*5s zv`rRADsEzpBHL4R0>U1>e0ycT3d;^dOTVCv!-?Y)-Ooqh!<$b+JSJx&xJAF&Z<0_4 zNTmLRAWT}vrlcJ0Z_~%=>`sWXa}~wzhNYIPZ3^_|$3#k!o%Jy}LfmbB`YnWcs=%>m z1bW+aLbRIP=Kf^4hQV%#8+JOT)XL&iAfsarFyqbx!8O;kaPf7$`ZFym~6U(az9 zm8WBkLu?{mFiO9?BOaOCO)FhetCB2`VIdy``Wfhx4b^Kkk~LJJM4_Q=JeyT7>QCZV zRya8{xITZ#{Zs21@5C6LRXZmnQpQk+sBh5n!8`&Zn;y?!7(Ph-1s#Z@7;vbgWd)Hh zdL`5&aX(eyn#FJEEf}IlcxSHEbQXj7-B5E;h-aN+Vn#R-9}ESP)j+4&@;SXHiW{r( z7c^`b6cQ&T**v;aS`SB+!GBa?54g$GuSMqpD<5F&ZADUf(t5Ye>E!(Cf?z0KnIQJf z5`TqoOlc-1(%!LQTffrf7!|-{`q#g2hvwWwg#08@Qpr6skehfuA-q#;WD;hbZ?kmg zNy&aV0rkAN1!|`y)>^%9__dA@x1s+}>>a%6(S+|Kc=>2LDyWSOKT=L{9 zZbno3HxGpNOich8vSmP4z3R;85jcb-1Nygw9JHR`=rBL;f768WLGFCv5A7ZIz7{EpNxLIFt>f+|w0*+T6fn_AB$S+Sb68bgi+ zxdizxC2ZaV?$4o7SrE^YKS<4~?HgxJ0qw$#D-nN&jZCMYqMrOCh#6gP2IueXZKNdY zFeN5)92CYtUAy~O3|)U3H}wUJjtFV97fkuQD$dFH5;kd%dFFNi7>N|-`pZ8P>s+W7 zbPzt)Nth+iq)gZbc4!*9eoU7AT#om=Ini%;ai3+wdv8d5)lV7oT4jEn_s1{8Mx6K6 zW;kqC%)he|PY)G59$%Hs9Y_CB _1yu8$CM7HE?1oZLx{7hOT$~=8qSpsO!r8Hk zwGCQjLM9^bzK+i6h%qthM?sUw9q%m(*{U*qj~7#g))t|eEsD)&Jw}RcPk^`9S3JRj zulgHlx>)NC?Jb9nj$@6v!att10SI0ls?u4V3L>l?oAyf2{X$2)?*5U#{wCfnkX8q1 zId-BZTd{H$J5wG}m}o`J$XP_L5^QWWKM~Pk)`<49uwh84-E7yv2N4?lmXLb zyGLf2wdB}1NP2BVk?_Lgk(6ITCg1BCjQ)pz{k$5XZ~38X5NNW6fOK(%CoMPn{m zCsE6?Aq@Y>>nmH$m`DMd=1RfXl;EE}fn*88JiD7~nHYj1)zE!&(?`rJYg(*2n+I_G zFU?=`dyNDI2~SfS>5ri7RONBPyx%%e9W<02wh<&ydSmDZx%V<5jGkV@_nn8zK=~<` zvQQIQ$mR-L<9cDJ`G~L6PcxGV`I2`Csh>!ckEDjlgCCJ=y$8f7Hh~3!zOc&lq;(=_ z?(I;cKER!JRHLOwh`qS%egdr0S57}=2@-NJM3#1g9#YG4bJ)wJS6sG5P(|5QjNZbm z?_fqUtK|_L9#N+;(^e1DvP!Sy!mJ1X99aV$F|5kd0{V{sB{W3Ywl&&`OPd{EWgD&d zPMoDc9ztx+Pl^<1u7AZ_eREOMm)%n9-ZbWI;Z~d|nljHBfW8fk9jBJ%0UdN44&n36 zP$?*bFLNbX6V0DLzx<<|_!Y}=y=aP+hs6k^@t#{YMD*apQkKf7_a(N*sM^FFsh1_P zZ?yBzvF7!z5J?dXX%V39nm*KKCzZNHc;Wg~%%TF)x_)ed#6m-|u%c=? zYm=I#Eh+M*yqt_krO;jY*OUZ7;0ubPmdm}4pn{TYzE3MmGtS~$5rUkJ`)&CUBDaVU z8J8Gj=0NFcel@DD7}jR^afTJSB`K`43P-{gKURQiVuG+J_P^#|z63U{yY(qEZ-jUC zN!Fgf*PF$H>>@IwiYxTK9kMko1m}OsI|yV}jy)8`sL_&3T>JLu>cn-`;aZq}@zn!A zw9(^1T9+}#(UXh?Km#is;%b`S7=kGm=5hDFtc7WSICO0cgm*_F2vk zSs(}CS3sQ%<{D-QJd+n}ZKjvz=R;We#?ek{|aegs7qEMPuY@n%<%hOe&R7;Dof#Dcg9)>ucgd z(yV6k`?%3Np|x6Be#;W?|h@L(_tYLW8?#))H_iBB7+J$Njg2#(gZFCrZSfDZVd>hZGrbt_W6SN9+B?lYnkj1tf^@i9B zYD%X1=>(FZmf&Pt`Qd@e11u1$R4A!}()^2TE#EGcoJbyiFe98wc@Kx@r!a^Xl;?GL z-pV1iuGe`wL{r9_BKlZHSH<1qbT(70g+$c0(m%!&TbD*W>>kseI_7(*4(z#)ASHzE z>u3?xxr(!rZR|jf;omC2f3n&GbTZ`Zr|`GBoj`f*9t5BPQ9u{ZM}rKlfFeaF7H_d9 z+8AIjb+?$q!dFA1kvf<2XwVJ7nXD#hlB!E{fv`q1Ehq6n$G71iFQ*USo-P>$&Ec0mfBu21; zK2;o&3H|C|T~zqkPNJ+psy42Ew6Gtlbx;lTEvB5-sJ`eCz?6bLw2Kt$Xm!dRZA--b z7^;d(f_H7gVW#dFFLkLIbRQZP+fo-9qVv((hc*ua+h@3HF&ER8@9nJg`+Mx&p$xXXl-C&d6(ozyLj+) ztv7z}SFP&!rj`;+gK+D2TR~pSw6oNmXs_AZY||>qR2mgW&z4L#m{tS&vw@vb==^ZdlFePS!Sp?iWUm<9Jj7{)NF-o)Z;xgFL8wi~$iTrwNXNv=PRPc{ z&Pd3}$i%7(0}ymJHnnphWaD6m0SFs9NSIohTl|QuY%qZT82pcpj)|E81|aETXk%$C zXlHI?O86rxyO`Rl5wdf_05ty3H7ra&g0O|5ld`D`AtgW%AOsKwhyX+ZVgPY~1V9oX z1&{{F0AvAj0C|7{KoOt>PzI;~Q~_!Lb$|vy6QBh!1Q^;nm^wKd+L-_hosBImT`X-( zOn;z@sgtF%HNemXU<5F7GBh@|F*WF|G{wW-VhZT`XkQy2q`?QQJse!gvO z4FM(qQ^0>m2r#uZF?6;7{5bu;Cr4L98-S^Yv5lcEzzkrf|KCI3@(2CrumPA^x|ssZ z>|LDz<^c1b>H6sqz}(f+#>Ujv{(n~guk=5=761!R2Mbd>fF-~RU=6SV*qAyy18f0y z0K1+xMrMVrz9$^2|-~ezibTYO3?*RUb{&$-nZ~SKt06%9-dlP_zjjJ=j z5#Z=*>g;0qGb%^dpAw8FMmGN!{P+6*xAlLw_^PNt>+7k7JrE5OyxRS$d2l?|3R^(qi?o~R{x&zvuUTrRG*?Nf ztu@C;t^df)w(HF?>ciOsljdScMO?7UC zriI2kU=o>{(wV0?tK1oyI8?A88mE}28U_-QDO0#~F<;IHWH>)ED($k~8UK`EHIDQNCQn!v*sfDdeG=`6qC0p`{w@Gs}MKor)(B=7u; zmsPkxY{NkN{0ca~n5|I*O1lz}1;&O~=0s<Nvt7BAgBFdNyq{4xk$|QZ1u|x zV58ip+8J0MsFKhQjLs~dsMm<cujQpIQi9+i1{_4+rPE~(R&*=4xeT7t=VklS@tYmmm5j=RM?qE-l*i zhf!6T8K0cL?74lBuPvX`ZvhS1`$m)KSG-2l1^Gvw`kjH#45`ShP9p5dEFR21d8)~U z`Dv_sSTn8hHAZN^Z}7w(*ND6QZ7jXIIN963HrfZ=dlzRR=3n~t98LTWf-TgaRb}i} zp5WmE{=4aBxj8VY>oZ6D_`2?M|9!^YxPku>3#$zqtGAMN4buTUV;Q2EUmbR*brxSH z0Q%C)vreL85?q=5)~Uw_{yNtq4n+zoII6^zvt<}knpOaNn3-4g1i^V@K^O_rE%|e@ zcUG(2JDT%KJ^&QuC87vw`+4igAW=&ytgwv;pDLSum@P?y5g;UN?*e_0MUC%*1d;f8 zPxiD(-89vn4lUSLwh21pm#5)lcW-H65Kd(kgj{Ll-^;{2=+Q0(Qsz=U?JD{pl*xDc zxwHlPQPL|4h`%*7=U`5~onuVBg+62WX4)gr^x~y|tfnaACrN0mwqoz_G zU(j9C7?A@ku18`K%u;NgVb^Fuf>*Jx6?n^qFEs+B*&GO=Pjwl#pW(!kC1G2aLn=!_ zD+TVi6(_1*V`#6TPCY(>X3@y!n?$(~sj8%H9lJa3=oq8iXbTt4m5)T6Qfjpm^_2C) z2<(%eM%{ZNttdNdjF?=Tq1CRO4$YaQYBlOK<$x}y_mf?DJMQh%4}(R&jobVhrAi#D zG#AB3=lx9dmqwDIU!mMrJFldsZVb!;PVksPRl(_8u9o#4vFz(oH+^%0_5zb<*sGW+;toGU7cZ|7 zN$|4O#X*{q4~qXEP)`FXin`qVAh^}KwNF*~+`C8K=AP?q8e9v6B`vfD5JuT+JHhJx zu8iWPysJ3`Vi^#g(4a<1He}Cz+$(r)pzQ7bb@rZEI-!nxEf)PbYj>r2p+`HF=?${5 zbv1?1lGb>HJ4`PyMaD?Y2#=G>0~#=PimoBdhs71+F1IE=oz%9HPGD)(f&hKTKySf1 zDn!Ko*5+zX@4V>#XFO$WuS}8YJF<0v7mw`K?oIBGQDLQ@^!2J4_-O$Xe8R z58qt#KB?SLL_fG(bpG+&xu(Tm12mBjfocu=hT3(-ojL3%XGyzaWWl`$V9eq`Gc-N2 zc11oHzu*0w|In?I%alR!*2Q9{MTWbW{w2{uB?O zM4(8J9ay4E4~mj6m4=`)cABgX;NwH06NccxK?`B0}LAZZn_@;>GClZ+uZ z3Djj*I3xbcSG$e*CYJhE>)rXYo4dO`*>p1hVF>I+8(u!04=in zW5s7BH;ISMx6ygnpt=(UUX-yE0(tBZl6&jSWXgDqFm_@~Od%528!*3NedVrQl{7A8 zTj)}7f~?cofuR@h=kTlVv|3|^8(hI=7Y()Y66>E_%KD$;$-T=HLTV2gjVOY|Vw_a5 zqke}u6)y7^K2S|~-o}cR#&_t)&#_b(kVbXviYlkB*%^fZs18_os-HD3y=wk}Gy=uL zVE!qw1HJ2CMw~@ieM2=S27v3%+hMtCVzxBfion<-cXyQhBTPIG4x#O6T_wmAm7Ung zDH7$kH0Se}2c&aEws*}GF!>{F?V}RXfG(Mnn^oZ{+I)s9c zR&kY-_#xnpOY@n6dDV%Bu!7{Sg)vjA`6J4BHQQu7;vUGUApsgHzy0(@BECw`wMX*_ zzo{Ui46}Ga-QNZ*nAd5J%?L6MN<>QP*yTxr_3FcT6+eO;Mhy8)h^@23Lg zs2oTg66{R|34zdRQdT>@TBKt-qjsnOODdw_bIdLT!9U3-1@5676X8TFACZ`64mE~% zm{xHap@vBFsHf%n*pW4)FGna)zOP|D>+rGQvMP|OH~dc^a;hF+#{JNGjyvhgC5NJc z%P%N)b`3*wB)cZA=0+f;Q|eE5_q)8ZKb+6ms}%{HArwm)mp#bBr4n>&rEST za&JUUizS9p+Nirf8n^JA4>_;y?vfI;jXz^&;v|u6O;h&+;T92u#Nm^Ng^-sh;Ke-G zX2;|8`Q&k$*Y3o%J5UfyW-vu=)E*j#HxZ02EK7*aENf_U;aKK`+5hmxs>$a4kVtVp zG1jElMOKz$iUrMU{azLPJj!(&sJ)y{RW+~qlBT8&Uda%lf?a@FF=H;kx4L7~2_K&> zpS)7tIcbq@DYx@|$Y8>T{!^eD(@LcG0nblqa5j#IHGYspis8;k9B~h&i0~d1x2;30 z)2nZ>fy)YcNlt1oZBCKFO7=w2QJZ%)EF2tR!iq3JO=8Wg*n)St@HUxHv2;`nN=#!$ z&|F!;_tH#Rs8O21m{^&Hi}s8Cm#@p73JG6A%-V)5g?^aN(nJdZ_T#qHKPNX170M;# z8~mv;{j;-2`9E>iy=I?VVy|dKm~LJa08zU?ny6mp3!QdE-b|J9gbEMhPF5NBx;cYS z=+gma8*>`faBya|nKY;c@M2S-^s^*+UWvW9UL$>xj{KEbK?O0Z&A)*QFdA$RZJv8l z_ai9yZJ7%BD~$Z}9&Mi}{ev0w_Ke`lmTTB;H+GJSckLAU@-49+usK{DaS|f=zjN{Y zqBl>nUFqsH7&!@X?V>1YZ$d>cWBrnogJjQJ&l36Eq6^d8-b*tp)MOi!*UymD10$6x zf+u)=OX=Gc>|xA;4bPBO?09!)Xp~hvvq)4s;SI-(w6ysj%Twe)U73Pj|L`MMO_VM5 zV{4Sp2eFRXl-~<+#1!(18J>;Yi7lht;-L0=rvh(Trmh(;32?}w+jkE?h_0=FgM+-6 zokU;8r=7ytqJ}guxnv}jNbc1Jh}m-~hKV>sa}H@mZ0eE&UCVr{)jHQ~Z!cw|an;4x zNy`@3@_Ul|D(<0QGMrKW6RqMzVM6tbCJ~ruteIxw8C%E6Z+NyQ+!c%CK;uzC_g{In z$kIrs{t|M5TMwa~3W@?+Vapd1KjBkfnBpi9mSMlCm}r&HyV7JL0<4q&rQYgZ8Mq~p z>3Rzm3<3seIjiy$1Oba=Xn@4W)R!>Bd~IXSQ-b9VXp9%`NB72ZoB%5j+_*kO^O3?8 zLV_tMNpuqdY5-Qcem#bwplB=ZZ{^6w<$fS}WnigvCi`7n#E%}p|$v4$+<{O@=BB;#WA_56!H==hFy zi$617GzaK{?+tt^Fn;|vqNN^kBLbN!0#>gVW4{ti|Kg9O|E|$AV9w|vh=&h7a`m3q zI(w^RW986?GHh|*JtIC10E-FL;6pS!bT!>kpZ*JTSewPcsVQ+J2NwU2I(YBsa$e?@ z)UviHml0_cmkFzXR%Tk8fN-#U-$Py85Z%LYRD&SGJPGmzh`s0v6)JE7C;eZdvf#-+ zL0&=?5%0F-ZZa(2={^JWMcA7N>v`BL0{yuAU#k>?fi9eOHsxbw9;{we{m=syLhwTS zXTGBB5oBR__ts4To>rI*kz3@x7#+|?TYGE=Y)9D+Kzo0NUAMRjW35`XzMojVc8mU^ zDtndV>k3|MFy%DgS+mDYjTe+U00%9XWtgacE0TkfhO*U#tJ}v)jW};=5J|q~eRR$F zx9)D#a9e&MLb|2nQ(2=9Ma=DTyaMH2h22~Kp(v8W^dsL`g3Wh$vchsWG~zEF z>O&ZFZ~N;ws_VaI7G}E^DIupGv;X#?3FieCD9J$f8=mu^_1;X*e0%7Kt@(KmIIa+0 z3+ZdG&3f23WL+I&eCc11@h}5BQP5XR^|>=IKkh;?(GDK9;j}SKib_NZ(uC;)ppX@N zEK!iJ+7oPMV?rkT1I;#4VJ6VA^?P0|;P6Tg;dTDpSZwReXsYW|H(a5^TxGEng>f_; z{#r~95>hBZd0E9zBT*ihzyi-Dw;RT|ZkHtO`};1LrBw(l)mA>X*DRcue#x_16&=S8 zx=I15Ue=r23w+W|z<76|U8sV}u6tMqx$v0Baq<>h>#3d7dkglYaEmi=9k3F(re;c> z9|5y4JZ#?8ArwO~qkk`(wmnr$S|+TPL(7H|x%mfMpWxv&*%yz;H)HM5ycS3ZoBQOh zRmLh}vjoo%rs)D^rwlP6s)fs}y=f-Nds?>7C|+eG!{9b5gv^Z~sIsx9Sl zfxQ93#1b*6F1R&r?c-ykS*%c!w)@QzoEz`-{tYkM>l)a@yHq0O62Ld5?a>Flc6{n zqrfYwThrbMqx6!9g`36Kcuz3A5XNIx3URGeZ?WT9A$6lv?*sO+V&3x)j&dx<8Jx>*fandhDT6=8UO8b zTxys@`l%V-FjVeH$??UHtLuicJkNJau7~?C@q^K1Bb*W9d{PdsxME2lS~J#ScJ$%D z&~ATUj&(MSR4YeGZl=xa^@^ycUY|^jrTx7mFs^7shvBj}IB;%eojAEDdJP6O-lcdw z1+Z0n`frnTGaojNdyW~l(9kAHyrt6-@cAeFbx3@TDa8@z9p+;>v&?I~|GZ*Anz*B+ zN_6LQGlRw6yr-?jHx~H@t$J~*zI3Uio|{!zF-$~}$ddY+J{?Hz>p~y6#AA`P`*n>A zAL!^u3c{%{?|{fxe`@kIMvZ*NsysxlNvO)`m_XHfMtdt!q)UwHA;g=X+5PV^>HuEE zBti;I-ySEk18Yxhbg5F&lNh9%@4(w@7g!}9KG^h7@X^E=irQO*B~SDgADMHR#j*Ra zx-7~`t)Z&?FuY_9N=mOaC}qt&3?g`*jn*$yy>q{~n!1^+k_a?5|Y}6aI z!rhOJ>{6_}BfIIIR%L1-F0dF~+bmmAHsc4_tAyr|>FLyP7eqaa|EdMr)Er(S1tF~4 znyC%FKTeKM~@l4{$lS|kzb>c6HU=;}NOJ>jaUP{@NawgF5-GsY*IJlhanduQ5Vb27``shkdI&@?#>(3; z>fB%Kba=+usHXjG;)Wc_RYQ5v`O*+14eDiXM&ftqQH=#4d1Yg9;c4sm+z}0*0o#Rm zgF6FR8}05FI0GRm<0eI7{(0n*jl_$pKx|PBxU|w;8x!sw(?+9ZvMsKB7#GAxbgFK} z45>Cq+2x;qTkNnbVJ;ityGx)~SNr}qr3U?>X(u8%Qcf7D4YcrfWEHb|0Y^LPRZ}}* zseg9AwHgxFnz}y}y9=h{!)jR9F@n8k{w6JUE`A;j%_R~LQko>3Orp_nNTB#;b~D@i zE8DP&_DqmnHAo=Hdv7h|RiNTOwBwofvK3)}_2Q3Ly67Trr^OJ)%vQWLk^CmeAMB5Q z!Vo1Y?%TnmWxQYTV--=cR!UQ=D=TAJ?R1g=svBc z3oqxHompng?l(@`Dv9oN_f!`$HwK}bAdHRJ7VVF#k(;`uxcBZ7Idi1L@$mjrF^@gs zGD97j2OW%OyL9`ZBrLG0#Jbz;|E4}a# zU$r3DUiG*xpN`t3vVoq4U88^a7apn5C8p>E95DmiKHz))k-xg5ds<9 zC5O3UCqIc%$9rgKZ0(^BmMokOfTH$^UQ01;Cs`?*1(HJ7i~$+Q1}2$tHH;r9Bxn%h zluCF;rkeZor=&5SQw2iE%}yWQT3W1&i-*x2$pF0CBxkz&`;lv)zF6cX2>v3poLF=s zQzoM1*m0gJR@qF6-0j9y zZQT5y<>!`zY>7l9X{gcCv_w<+lR@<^{CX~# zu&aJ4p}Ughjo`elgBU2c15L_S?xg0-n-=~VKH+qZ$e=kr*YFj{qLU)U#+tUr+_BEn zHrs7Jl}lC6t0)`7lo1mi+!qsaIGj%kV2U?>KFMxvPz@0#S}EY*hy3(b}w+VHEOO3x;6jv+#-ED9Q=B=JW3q%K~Z^uj|doGMhE4B`HO zUm#HW$%%MSno7<6i!rn0u{AU(t)oT%mlmP*uUT(oc(?T$bw-+tHSM6%c!FUk46=!0 z-!U>TAp1r{pd`~~)$dAy2M7JOHBe+eyAzGCQoDF7jOtlY~4>eP7q-`7xJxV5$$ zA*U+3UoiKr^)MO|tS{4QNATSId`C)%1`{;Dhinq*K7`(c?y@z^>u5Ilupq;};W?XY zt@z$>;PyZwqA!&0daqcoFH$LMw>HW!o;a0tkz*QYFRlP{I?@%3mcKwY;$Qy|-^Q!T zZgv#nY5$wOV4aQ1Ny6iB?=bjN-@E!AY2jj)PV$F`X4QUp9Vss|+GCmlOtQNF5aIKx zaI11n;Y34t-K>D@%^E<^LVJPT^SThxaEs!&7`kZ?u*ZE#>uaGXb7p2QnI`%PqYOn( zg$!x#%_mB_od_i}5L{w#TC712E8&vi?M0dCJBO|OFExjZTp8VyOsrAO4(>XTJ1HJi zfYcxK;hHis6grfYsIS}1^sjx~o-Ry=TY~}3OSJ;y>r8`4@>wT8(Z|eFIJ)W;CWg;$ zdu+PDgQbQR&yr-O6W3JhE%Iquqq$MT=4bM-UxFctiSoHOcSDq0W0I&2cMH)@uA0kd z`VJ^Lb#YUf9e$Yx)EcF;&N~M>7$;oila#`Sx)WZsgFDXj$;s-ut(t`zI=WP~%-cqPsJlj5@G6@}>|y)q(AF>5ag@LyKdm1OvNhaU&; za%{D-P1RVn#r{$>Mv0ttO1Y-HrPOO_A8vS3Oby*Slq$%EViOb!4gY6zZ*>h(c8{O! z--$)VcSXnR1RV5CuCXI9N$ma+ z*C>u&%|Uer_4hG6w2MV@NspS{nw+qe#uF%?vTM7$3-Cp@&VEw%!uFSKr@az0_} zInRE!DXiYa-RgDrh4T?SY;I>hNy(MTyHchVYxjMKW|+QxZEPi5^HDMGNokISte^VV z5c!vFGnxBBIwt)rV{ZU^{V1fdTUCSc%l-yqWx_5`UcN%Bv1*8*zk_sr2rDq}vcpbr z{B!ME-3Qk5$cnzQXH#cCy~RMe&iIRHDWjwJRUXv3i_9#*+-{|q|8{NN@SG;nlPF+l zRYR^^9A%;?=Ws}O!5vxHF}iD!uq;UmHXoLJf?11Ut3DrblOqR1jqoPd#Eedf7Ng;~ z9xiGXb*itST;r}=+jLMocyWc9RZI$>lM|Z9!j}}$CaupyH{1*pqn?=Ty|YJW9Fwgu zxn+=(l9g~I1GhqweVIFkBLC2}6GtCHwEjwizjge{?)cmd!EEV*_sZO%|IjR){`DI| zmuTDoeZH3^WopWVev2?}!9f1_Zl#mlP3ZFgC$1!rapU=ClT0R$50=D8(u7yGHku@W z_-hVAp2nQ!ORj(d?^^QTucADvgwe?be4y@*#Xq!f+T8(i4BBN0ypa6A4Z0JtwCJm< zw?DMbKm%RNULj8$rn6e8rK&i3uF@*}XgKb_ra#mY4pZ06VS#ah~x+3LoR2D&EpS5_D`EDbdf41h~|(SNEEXtG@@!xMmraE?7d7f;m&~f zB`O9X72(jV^nT*9lshR}LhiV1N&0gBI_OyTh-|iclPAz%0&kQk8yunY1+olD1S->m zp}>r){=3vIY^96A=hiRT(p6$Ec$ByRDXOf*$}6(HR;PZ`Rz?#!{=U|$q=K>Pb~fvX z18To1;ng3{VW2+z);a_wT_ZfbJg<8NVb~nt{Du3}wS?*sgg4iBb?n@4@lVGIeg{mZ zIx-tJfvYVB4}|QFkL*TZ=JnhLXv$pO+$YEu^|^IvRU$Y_py4`T{uhe;2-3L>h0I_H9z9n*Dxl zaD@^}6s2v2(WMv!hgt^b1^ALr^Ua4-LV? zw@I5xGKCOB?fEgt`vIzmND@$b{t*$Q^YY`;yfwu#?kHPR5kn)ItR%xgi z{vxFQjjuT;a>&Pas>`nMg8`o8Bt^%$_XRG}W&J~X@uATE@n;e;{@69uv)i2nNK`$$ zb0DTsE-m$0*L}+w1xjW(GPS;Na#+Unh35CwB8#;uNE`&on_jJE6p>ZuQ_zBP|8E!Q z+VR%?Qz~A{#^%M0n9&YIRidhL6Fbd4R_xzfWvJpNxWI{TLWI|H(9^`^TSqZlfl5O=5My`K03wdhTq;x|}UI{d5r^mc&j9`}0G&qZ*v}?>qb_jMMs6e?k(QVn6d+^HkZ`uu z#HBcmqvy#wrHx=0r)Pdo?3~>uDGRGwI5-GZY%?u5)p?=2Q5G<2*>d+=mN(9)w4+e% zBSTp7Zq@Q{^w703ie=b2^`C+Z9sbBS&Wq9fqPDoTtKa9@0{6$t=6fC0c6~2GP0sou z>#$ZQ(Mj9=F;!Yp5`F^yNUJ2QECCK7sMau3cxwi!5@ z#M+wRPlPF|VdK7LDVTyrL2E#447tiVd_ro>A*oQ>kFpfSg9AcM6JZIFMQ}xN$2ms4r!4Is<ctyiYKkVJiJu`alokSEx(8|rH z?#_GIybu)=;$o72FP1gyP0h(Im2{`_$rP+2Kv%#g(FH@&3^7yhH ziNCugaHWXELs}^d3jhP)`Xto6@3)3}FPZSDWjZt?^S=1ljxo{R55VC$E#G*MMQSNA zJ&&qn>>E5f90)0RaCctA(@}bXn``OWY*v6fc+U$oal!r$i&vr8p3)nZ6QF_ zImECGdd+v0$A<^rlOk80Tz8iU3fZ@LBlmD&uQ6)t9b` z@30z7N8VF2`-~>ME$s0RRMex0eQqM01_{QokB)3qw zkQBmR8dMnxWoS&uV!U{Ii|xE#Wp#q002Bg#qHQ`2eJv@Gs;=rKT@84oO{R&JQ;JAg z20zwrlxD>-T%fpwE&@mZ`t<4uq^#8>UcQ#Ipb(^bC~ZM~tlFE8_8T$%*xnFX|2_BN zb2qf}H{J2-GUZ{?A1=lCyX-=@N<>5~bkE zS0~Msf|j`@ZS%?|_Q3Sf0zJ!%Au6&rGjG-oyt@F1sB>M{AUe(;HABS_-ol8y^LuV zoOugn$0kdc0%N0&s%ceqL(A^CV7x^|A3(jetd3%#_j9I>*-zc{vW>}4r8u1z@lYUkHW1wVQje**2=o^L+m zd6YxcloM8fqaR9;m)VKGP%LT#I(R6!cB>M*e#6mztv(!ylZE2IiMmxMeK*JUVf!`B zGp6mbLNoGM65uW%v5qD{Wd?h_*$sO+_v3rsF`7ayeEk$0L|DUW^2V$FR9g3lQ~v=( zr7%kwh@4!EuknJFK?~yDBQQ)72m^?b!0b7io*)JQue;K6GSVk(pAx%pPV*;d*8`^#{*HzDN^4mHxQXIlW6Pvf{zIi44)ykY0mzykvm144;WV8uE7CGIor?D zIquXF1m~&mWg5xW5it4y!tMS%h3LJya$|oac`kPK5RX8;fp`7z*)pj^e~Z(<&Vkyv-~{O1GWM z6%>$X>cSuz0Y4M=KHV;Thm~nWwEF zphtZ4Fba!F7}1egeL9GjCcn42kSf{8TY1ZDLo?V>c8h?u?oSoff|>i*cBs+Baz8*9KZQ0s`%KKHJH8vxYe3j_sU~b>Vfx};nznZq z3uGN%4M`LI{Vx`B!Ow7+{@S$~`lm8tN*74;08&qxq{JD2iBQ0kx@kmS3;)JLOwR!do$DC@NuJ7g@qN*-1m zM*l#i;p4ip{F$&CJC5B;9)Pwz^tW_+l8Zyq2vruCkMC-gQC=mU^d{~WgV=&Fawn9b zeWB}EI~j#r^byNVEb?~;?w5_lYBo4_(_O)t=;v70qdfA8=x3@LD=hsA=--Et&($63 z5667r<%vo{DUcRuE4K;eQrSFhZrBR|1 zb#4t`HIl=goiBz`e^A3alt`H>bU(O?olV+zjHTM&z@iFXxz*gk4}hL&a(r5MQ#>&E zY0}bm(R$ehXNe2jiV99)N?&dty6VvoqBDwTOc7h{cM{m(^x+rHBv<2<;@rx{rl8L>^n@p4O<>W?55m#5g zuVWGwvAs<55y5P1)+Ah_U7I=qMWimXe=~}Cl#6m#W!ecidx~?wb%`QtHgf300Vd;-- zvRy6}KJH@Nj>0()oOI$$M|~*L(Lp{h9z?OCDX9yf<{;`n6}k>mKvx+slVK+NO)*$Y zxmkI)zgu`uB|_)G&V|qTkJVfE^S!cDo(`rWqM{tz)iXbrIk;rw z$EH#)0v)_dGEgw0n%@z1Gbe5#C-PP}dqo&KA*xHV0>|Cb&6fhIzME@^gQ*NK`dHfg+)0wL>xLm$qRq%_5kt;Jm!V%p_h{Y#SmH62lb!F-ZiGu zi&w?afgPWGxqlpwprG>K0edGzNYs7rP={$NR>MZwiDrsB6-8mjoa)iH8~+4}AWH;! zmdymG)}~uy&Ekw_zZxMBC#xYg?KwJC4f#x4<|utiP|nylEC}$i0=&=EiEcP25eV+S z>L)L#ObmUQ-MX4jH%4RCFTL|.l_CN|8o5D~_X!mp;c-Xr!2^36E~Ig?5-{BRHU zjPw=tk&9PePj8MH$k-HQW!A2X#j9ahOEYKMwqj1Tu6|NP-J?z}Oj-_pA-J|Cu#d|Qr8erh&p;sSSK>J@ zKPu_$2;sLOttxt;k~9GiwQcy7uDsLbH)$o`U#XSbmjuGGx6MBpU$MRuO&}A)f68Mw z#@vZO7bTeK=^mRfjq;NN?SItX!MB8PX29c6w>`Hh%x*)K_afxiC*WB zf$`uf^cl$KAC|iS-u?`nx|;b79unDmkXHy2sN(N$;rP{Ft-KrRj@7@O0VEx{}%_TtnlnD=C|%Q5g6D@K_Y;t)I+)#I@o zzm`e>(|m6oAtK{8-|_q0i10o%J(-I(WwL$%A*n31t#!tyOdT=XH{wg9o6`Uv8%T#Q zQ~*mMsVYuwih#4{LSVOo((qn~e1sAexX--8L|diM4;$!iF$BKHc#|T9f^=O_n-p45 zpT8`1NmjY>v>Z^ykxof)P|qX3#o)1*-c)XR#{F22HcJA2ZfC&qIo-wmrNO<^T_bDf z|81ZquuJ~RTP*Z2KyPD!5yLkWPQOXTFC?By&>bu+^5FoDq#Mfm1XHD8*{w~h6Jp^W zca=TO^F0O#=sMo@z%4=SEsif$==&3ilt-~rkDwA%lEj1%)4a{0a~a2NWHQ-)59C_d zbK4D^WO>ioNlc#^B0QbCxk|U%p!S{tPr-z*l+qd{PVJ+UOk2tl?E7s9yv`DdFNyaK zcQ@tWfs$cnKMtxr_`&@&@AztHfV1V~^t)T=r30pu_O|DAmQfaqUy+1aho=1Whdqr5 zRV7rQxMIy7$UOzt0)RvAH;Y^ASK}|S6jG6d<2G{eI|&yYjJ2Jncc{+rX~jW=9vUnt zk=f%`Ds0j;Dy#Y+)FvKT-08N-CE13FocfmMG$tYx9Qyu%h!9+t2*=9|%StJD`eQze z&oY6#S_?bjIiVow+(jv!GPyFX;af5y8sowl6S*iLOy60TkmMxPplT%vozHuUH(sdq zT;I_cI2hDRKgma(=+d_(tA{8$xJE(4z5=<+MRC5aYu>Lu%@W+`By0sao5d2FHl+^Y zrqPCX3)}u=_$T-jq-do4{!t*DldX6P8N?v0TZnfdE=Tc?WEE-IW_yvMB$Uqt6#`VKa3Pra5DE~9X^p3xlWMp0uB8_aN(}zEWTw0d^c`+ zxy0V;eg*%f8Q&8nFgA_}_&r?1i$ z;oXt`Ef@8rh@=sT4_3Dwg;iDO9j5c1uW$Oq3E>R{CT3ia`t=spd2wQTt-N7~I50qB zEvj3(-AoxF79WJmjkT!#trFjluQ&f}Bt2e<_x+0)-pVRp94?B?i??=FKyJ!*#NXr_ zeW`zxra*%^Ei%HkR3u;MDtK!}RdLJ8Pkp#jA)94XeSX*5$vtw3UNYdSx!2k6NW6Gn ztlfgRD_A}{5}!iMqfi}O@_MhxWTz1mp&sPgPfvD@>$HpW9Y^A(xX-~31hq)NnVB)v zh}X6QF@I#6^xaNfnWes@<>WBho!baz@Jgrjv`JnpyU)YVL%3r$T;kFzIvi$qD86&5 z9m;R7m+<`5qKI0|IOa>9D<;}mdw!e^A^s*RQPH^tZ0wLeuR7xC)u(lDo`r*KFWuVL z9eBsS^p3uTD>Y@VB>SoFz;rR z(A+sQv9nchVg!>@c~Z`I>IOF1|3wmYtrS0{f)i0G9zs$lh%p1)nh!=}Cgq1k96uNu zNs9u9q8aVf+d_*4XR*&t?ysWk7gE9o>2?~nh;KIjB9Mr(kxx25C&e&I)l=xu>x5tP z@*Kf$a@s#c3=vAM$!cgB64z3w1ZhU`^2=j0s$LijUU_qs-YiFDxC*yVJSEZxj-&%) zo_5s&h9OlNk@3{y1H8JqHAaP!ODUVzF*tQTgTWwp&nCX{=a}F?tpE?=5{MP#mmGjSldG`!zxV86RG zUx0(Gw_z_UwXC!%DWO8@{| zxQLsN+}UKjorh;Z!IfDi;w~K!4G(8S(LNfy z#O~FVd*Be7R=CUGO`!uqNkr3ja6iD?gOtM?DjPJ%h}@?@PeSqNf1rUaOReMOkyta) zpktd0y)Ca8_%z5hCHecE81OJsA^`V}uG`&hg*A^PYA$IirbzlF&>j29JmXi2FZ<&^{Fx>638Y;4GQ@v7^_V7B{V)x|0hlZX*p*#`ERdaV7D z{zU9X%ZD}t4>kvv6^)tF^oGVmy0Yb(JUMdI$xjBuW0v%Dmj3fqs>_~QC8!>-QDPQ9 z)LER^`sy-OTlT?JOydzD*y*iKrhI|~nN3JgrbvDWgcEUg@g_FQGuI43aN1-ZBr0ub zZs1ZR{!yC?qjz&b9IPMJzsE=^>1szW;|)q4{UgVdg}86}_bfhma~*X@j$y#_2H0~_ ztt##yInmX*E?9B&j4Db2d35P7N?7#A=CIHigaaXcsApw^_Td2Ny4xqGe$h`=&?z++ zfM)y$*RMXa%2#pz!jVFKF34oQ1&>wrfFBn}LYMi>(VfLE1gLWPu8*OdDPDP}cu){7 zkK&=TSeXW#p1blG0!`W_!*BMg2Eezx1#C1oz_X#Q!8!qvQ;8Yr*^1Y%AJ&izK-JI% z_$IICVd%e`G#r~$f0~4}p9RbK+Lg~wdaI4Cc|?@f-+!D(vbpwrDs8&P`cxadlKEEh z3)*uhj+X{*No(1$t@{BExn3G^IgCp{1W}hd$Mm8ElGT5@7f-zrD2qwc_;g5LaeHP} zHY>rc1vnp&F&3;*BuRP=;F@Jhbi-?tS@F5J$S;1$#k{~@HTIydKe93I_U)v9n3fbi z{?N=+XWk~UM>>+XB~*SCXqoW9?1L_GofIV`#irFa){CSxTAJ@SP>x9fW6Z{9A5u71 zyc`3GPO(t%kM-7@sDTmd!nFz=4rUaUQ(8&rXQGqSe$t5VJ+R1UHCzq7rl*N`Zg-$( zmSDMbx|x&Ci3i@ha54fdmJx<74uy>v z_^s#~3^b*L4623iRsc29fj5m*5eUqAp0(SLy2+02`0{Ho&jtt+2a>$k*FKQg!5gCS z(S?0#XMCFysRq7%8yuf&HnV^9H;D$FTdMvAR0T?;xcX7mXs(fVV}Bl4&J^>cj8-4D zvPexKH%2Ojh)A*~?fNi)Z$S*S6Mu~A79$T6Z`%Zf^a_#7aZg2e3B&GC%_jzqYMcrK zs;1QRjOh+%XmfIpiDKu1Xi4c~kW~+RSURnO2O*2_5zZ?GMmy0_Gjw~}NV0WY636GCb1 z0?5g>A^?0tR4H==AP%F`x&KARH^hnpC`%sOwr$(CZQHhOTld(uZQHhO{P!1=nY`Ke zrjqVds#4V*i~vRihFAvjewkvOuCdc6&G%wzO!c!Xr-5gSHefHMhw>w@)de5cC!taf zz=J`>wX(^!5Z&915PPmFTneqb6`?#hZNw(Ah*+(&6IUG|1H3>Yel={FY5ZST#1gXk zAOT2LERMUqdjzbVU`Mgur7Tdu>2GY@s-uqzZ{{V8TME5_DjY?_mVThA)qUY z@Qz_OmO`Zw(b(K7B0!OCOa2%GD#{jhHg~INB9HlyCuw5I%2NLkTG98fw1>f=M&33s zaBmor&TfA`0mdQ#Pe9#FF=}0b7$STlEThnd56vh^Oj&@6J3rX+hvMQIi|6=2OaY~Q z-W|P>0v@4*(i{!Vu*&D1zm`E|4Tn2xq?x^xBQhd@*tM~&w6C8FsQZr|TZAr2u@W2g zPl5eoXRJkKG6l{F|3W7#K`2qT`wn2Np}*FtA&|jH+u(oOVK2u5}ZQ59eksuYM`oWJSE3Xe&a}Gh( zhP{F-O&5+7Xg6Xl zff~1wHixcwxQV&u%nUhiG!m<{E4Z>{J5S`hiZCmv9L#`vPhWcR_%H@vBF97CsG-v2n zXW_p08Gg#5shtq`lUjo}w8HL@tU4;qawwYJX9I92JlRho(><)KJKh8w30U($n`5r_ zEsVUYhCMEL&0okIy7&bGT=EfZ&EHD5namzKqw~PDAmsR+j7iX*pzFkdUH>ebWHGKA z;=aYp5q+T3jvJohDn2`>DyP;dqZ%?F0Hyu;jQ9GKWmn`Q4NPHXK%1Q zkPs9{r~?Y&sJ|vdM~%#xoidZ3Oo8DrZbCydiK}!c0RGW2b)Ao6fEV4cNmi2v^WI3jllpC%o92 z&26O7Gy*)XI`!2?+!u;3aSVKQb-CF(_l`ce#aT$k6xRUxa%~T0O37peQ*R)I?Sht& z6ah`=%kST{9%Nl!O(Cx`4Zu6&3~bQ&GkW70%h*bWZr{BN;yWAMtZ%JA8o9o$mSf-o zcND^}u8S+Ams-5H9}4}B(g^H)9iiw@KH4ZFOrTNGs+58N2eP4_2kfy95m8d_XFmDE zS!B$kpf?qC%>pg$avsZP4gVg;XDO=8KFmox`@iQ@uwT?z(U)_v%!T0lvX7_cJr-g% zW-4S8!$v<`)8P_pDZ|7IH}$EiO`&UtG+cN{LkYWmV|K)Zlvtb7Kb0KxTz(Fbg?C<+ zqM+V%sVj3RzZXzl&3tr&F~njJ%|oo)h5oz%c&oi}L}5Bq6x$$Z047;Ids|@hm@jL4 z4=VyLHuTf_hW))8C*#b!-%d|bAA5>VA8PJKARQzgxK(~PU>aWmeEf;B)`w(bbgd%G9!-%t2XMUX8jRikh(C|A+&%a8IFLThdo zO5#{MdQxDcUfW-Y>x+Frvwn>2tLEW$0w_;mq^v0W2AxhOl1dmDYzm=-|e=y^Z#=@u6bvF1QiZPl1075IYt);Qo@0W*YZtwW22>1VP5y`PZ1EzbC zl!;-LEXaXpK2br}^%oZ##IP9r2yk@z0oVq20KxPNE#LkqnB?cnrQBD-G*r~93D9** zOH-9!T^Ui63N~_5S4bRO3&F%JB+b)SD02J;`({YFA%*n^d#$%}{Foy}nLqT`qa3zs zYlBn|?~W<5=qdjC^yWxg%8!O=Bu~Q02+{}{zIj7ZZX}5{HVu?f$8Mh!tpsq|x~|xL za-W+qSnci$A7nr*#fUwN1GkDEn$%fuj01r8q}EGVcO?tBKi52Z_m(w$%{0C6&gLwD zAQ0h*d#)i%@8&?R8hFedQzdCFQv~P7a!!d4cP!%wHuEKgKrd!E5K}YvX7&NWMrtQn z7&}}=FQsdB>c>OkD%bK1&Wh>(nB?$;wlH@S1_AVa9^IvB!qUnXn+w){gx%T;jL23~ zWuJuT>}*09tzs0`AkOW^RPP?&{|jm2P}08(N*(o+yZq-c2xD*qH9gDI zg?lRyNkrp=?iQ*@$7nq&EEN&9s~2zdl^+ebol?TB829)b4#e{eQcYS4bXU&8*D8WKPR7`nG^CV)?-i<(U`s^6OecgH zx2DWF`bh%!j!FLz=P#^y*Nw)=Jt8Pys{EyBhwFPBj6 zO^znn16i~Nr~nyQx{xkG3Tg|~U+@xyJjO;sjUn=rTDMin&hvc#(o$i)tXTs%{ubJF zcqUhY|7op1T4CqIT4f~*x%2vS=LrNTtUzC~e4L9mVqhKGRMJABq~Rr(YwG+>Z#Np) zt~H#m!f%faTDBp8j|Y{q{-5%y+sjIMmx7wOq+uVrBw3j61t0PxsdOiPo}chGSa#to z&XYhN1Q34zKYtskT7%VZIKefN*C$Tk?exe|KU@ZZ@qLZrC|%eVBTCE}P(lG&CtA$V zk@#;O#a^s3@|dE>`d`@68|j^D-NXFn(+9cWG}S|b2o~*0XMAvqFXx8AJvC6chf`zO zI^0J=Pp|Riix4UjpO|sJkdL~9DQQ!Gwy=Gl2z|C1?~hnVa96J_(|sFKpIz8aOq#VY z9e*0hnRqEElHu;Oe<20=RutitQ`D&OQBK3uCEO@7y_1J7iK-NPx&spom>3-~O<)hb z+qO7(6++U|(mKizu`}8hg|=H+2*Ai_^vkw zBV2@7U{$3RLSg+wWz_{<0SC`L_Adf4pTNf6dAwYW z=Mz2?y&ABv!61N)rc6@Sk?d}j$@C0e2M6Dnc)0Ii2A_b$rm{Ev^h<3SYx?Hc?4&=A z*hNP|5mjwP7;r5vc0XJsC-X+NMs|9B(KxXZN&vj&een!gl%*JTURhi4*MgMiGWdK} z-}4_$Nt6TpJb8tY8iXE(dm}amJW%;yeqFl43u9Gt(&_1oLu zJH?Sx_v|?rMQ`CA`z&f0ZZLYL`Rn>l(xEzr;P8(_;%uF-YO=`DpaLP z3ERrlCB_r^`=KBb91?a{)mfRbR%jcvJl@HtSaqN1f?@4Ik?ll%I9apCBw$c_hPi^s zMjCV=yDCkx(yZpV=!);2I`K*3VUD(MN!OFjZBKx-47->jvP4oBVbO(%B=pj`Ytc2C zCi5Uz$;Ps4tLp&sovopdbVrK{iKy6ZhRHzB$clE#PTGQHVg!g1K}_xUde-3X>0FeRW)O@)Q0NZ#LUy11K?FM2-O+@811_{|MZo%IIy(;7 zH)Q=ZkFi~i^XXfyD0~Uf?0?NgeFzg{v+uJTzk(VT4v(c5gn2Jns{)AJ z-7`FYK-gW$f-oeey{)cXSwllzpxZJ;avn#JVd|D`mZr|4k5V`#8>Zum>f=q0(7PK8 zZ8I!u!B`(8B7Vv#XL15f85fduJ^in9qU7PO908lHM^C77=qkGHwc`-S#Jqj-EN9+H zP)mgdcGTgZW}a0N@pF$uCA)w8T$Sf=DUupuM)2fGnvG@+Q=`@68Lxiyx=jS6>gUE3 zdL@P|%ni^bQ?YdXkvy5W|3lT0&@TX830^q;XGt2lL%XeqA)uSiJVidg zo+;~P;<=e>MmI*X5-!=kq$(iYnNuDUlDIF^pHr$(Yw|TWAy6&h0^4)LNI^Qr?4vC{ z_`4}9-bOwT)4Q#8_;t@0v1F)WwY$LBtE0>SWF1krJn{5}I#yRztXy||?GbCcr(jvq z?9#OcdoVR{NlLV{EP@2J|DnW-+tsC>Zx$;Bp039}UizicH0xHjO0SWE6kt7eGeD6R zsJImOG&e1ocUmxC8Mcv+~GpfM)$0$0pA^j!{#-YOMjFvWGe{$Oat}u3 zzo3>?4YR9lW#sP1P5&ha7U zdi-!yp!Kvewt_GCxE)aIsRh#&-ml@t^jX+FN$5ICQ!H0*vU*cHO)CJrPB%tIAY3N2 zW`$TTXw%l%jcXF3f))=t>}`+2OycNLXhQXbCPCfks?wC;EVUjz4oNKKcyo&0GGoya zAW$?E#-hS-BdA20+Y$-O$^q1;o+}<{=zV$$KKV=EHn?4HnH-&lCV-0Yhc!=hP{faS zCL!1pZEf~HoieosfU0u4c4xQ~w*$!Ff~7Gtn-8_?P|*@^#|tPrUkF=X0a?!F3XXc} zgIAS|BQEG+?>JPb&oU_CMeJ9{;-&FedC>(-@z1Dw2rZ0mTr*#_Bk&Hh8Usrk#lTo` z*31ENU!%ul48j7>>cQMc0SxEgp1`D*#k3#62jIL9+Qd^u7FvTBXiZs|k~Z;WIcyiiv@35Q+*8xqtkWMKjg|wGYW=e zcA`e3hrVk%Z5m;rhQ4PG5#U#A6Y2Eom1l??SIoW)H0R5;8nnc>RQz~z2zS<2yz)^VnWfh1JLJNn(yjq?fv+vt69u6D6 z?T-NI0Bid+WZypZ_+IJ}kP(1oBK81+PRnOeKZz5~B`vW*2W%xKP^nT|$qy5T^F;Ok5f?Y(;zMFCFTDFo8hp@!?p-g zDoMFvCRa0ID-VtCT?}--YR((q^W9qk{fx31;7tU_93`qL(`p(IQM|sd0naqAvJX|j zON#RE6y`(o-re{?obMg~qA#XhZ+~3kW$LUZW-TY3>KW*xI8BDnOHblo1BS2Kj`D5T zz0N6OuGfni{p(*nT9FVlowuc+66QmmVAyC86y@b*g!T{X%mTp>gDb3Kp0D3}YW_G$ z6hi9c@Qu8fKTf&a2&QGivt=^=%1f{Pd-?u2Ipb^$0qb0-*)_z>;XZ|Ar)P`S6o< z?rg|Vb%)A#?9R?C%U04-Lz=*N%$tMs=1n9%L^f14bvRzbK6Bds&#L<~o`**NDn6Fh z3vAySc?BL+k%=tM| zg>ZIiC{ZR>MglJSRr6i#v-OF*;|pKFyS!U%c1v>(!=BoXoFVOVkbDKdz}rVmJf4VN zhZ*C50*HyzJ(qRTI#KP@r<&~B!>1K+Pt`(?ITRyF1)RPY71H8oUL|?1R1bEvCm39 zl&vHK49oq*q}+WApY1|7I}Py5I^MkT8s=NU{JsaM!gr~s`wx=0mu@Zv-5=(P;s7)Rn;b$uS-SSTXcN83VHM9o#z#=P9 zN+SyM{P7|0v8^e}E{$#r0ZodUFbv-tpSu<5TC_yX(JDwV+%q!&yvxBe7v2o($%|O< zlCg61rjsxicc613u$JbY!V)Q92-bnO&|IKwZ0fJ-Qpx~0 z2DS~3fAeWxdm&QFKO%6F^~gp}Crlu~xqVHW-%M%U+wIS!;{g}HL>8Ea^pZ9$GB=lx zjjVHX-7U`u4!TRd!%qqZ$6QIo-umFm)dX1y zw>BA8uH{Sxx&~^(*|NHgP1FqpTGaZ&RPUYbEM&rNG!KmK0ze)s_V;deNecL6VKeSd z`@_$W3gJ=iE$3)yiXu2`iTud-X=MNCpl;Z6?rw!b()Nz(f+0R*VPl{1q6a(*vpVzo z|6S}hFodzNn8SGNa9NM|qb?^@XVkJt=Dv?3eP+g1ypqGfoHQw4d)G`gd&N~=i=l8T2kvM^k~CA*+VW8eAXvBw z$X1n*?fvmjv@lM~mU7$c#IKQlUS*{{(aflV8{O?Nbm*2w=V?S%Y?GW6uzo2c{Z#|f zMcv2+5)a9+Gk-DnkEsyYWM_CvO!Egujogdr9$WM%SlR6IMj)zaOd-)eD_Z;dFeLt} z`LJ)$db7J@2Zd8!wZSz6wt6feeDc+r7Yu-1;DPTBg4EQsykep;1wAw+OTDXWTag`_ z<2?oKUb{9~;y!OBJ~*hHS2SICq{fEiDHFXC9TCzXSO{^D31i_J3Wg2+FO{trhfqu~ z^NaUU)5CG1>#6vQpN1Mt?8Vp`J=w+EKS;u5sP-UoD7_|m>Zem58@hPIiCv(43?X}r zytMo3nLr}lN*~|#s`0Y;SsNxc9WhQCK;ah_F=ugJAkDCTB<7jyzB`9LB&RUw8*nZmWl04%q9842S1H?m`WF zcon)mx@?+Av5oPmG1Dpb`*PnfR2_3^>AmrDD+*ouUKr# z5do3;KbX7xC2~Mvsz#WZl1LYogZ90Exg}MGJI`-prqDETJTg>`x&B?Q##_g01P(Xn;+|J~W%0We>XMt5p3&_+*`!+Q?6qgD(%u0x}r`-A_o|}cB+e>AR z?QyBMnxtH0n?ze^3uJi>PSRIcglMo>BG?F@>Le%WCQ0D5&WnAgWIRy^ZWGO{r)e>u zp3V0TJjN1Wm2hYE$zk1@lL|#|C2$4VSVnXWyX0FH*T9_~358 z?Brqm5Un!@1MzwK;$o{7uAoXiz7fL@9f2s;QmcvglW4k|&10`*g--?m3BZFRa=cAm z-J8B5)I)2?QCD}^uUnFvJ_=03eJKbFz~pg8bF7dv`g3PXos);jEX;RkW^aw%wQykQ z&OCE%$?016GdSd2+MNW*DK?~+N0lYdkTgfml=Mj0 z3!z?T-R=xfal?fDDrcM&9D;6!qzds|GUaHf8l=uE_XpvAhbG@RsH9EGLpr!+ zG9Ky+1fD!1anRm(MUGPT5sAE)x#c_Pm#>tKNWH9gQJ5v=ga#PeZr;Iy- zA}^R<8Y!CJ2!}6W?+|K+(?l@CPyeHc{tRe)keov<|WA z+(Scp0VZNvO#$TUMt2AsWkq*MrvS7zEk!?VYA(dT6Y<(R4=EKKoDXq>@5E+vcwElP zin&@mFZxMR6Gg-dY@}GM3hstRQNs7uP*vtv35{lSxditT!q<8#5WIG&mkR2wvIf@k zlw42+#0TP6C2UH!^gAs+l>7g*>ICs=PU?W9IV`3O6tv|NDa0XwrUm=pT(E{Bz8;xf zn2N}*XI=etfoy|pQr(V?^D5_?bMXK=+x)^KWuYUO_@L)ZTA`<%{BtX1YRKspUjMaU z7|h#*n_->4%4k_rf^!MLxwEH`bU&>BL?&~*uA=D~%Q!yGfMG~oOo*}wcVw*62X`2> z(z`pAM80p#>}S_YSZ>;Alz&PI@#lHcv<(srls13W!DQVF+7iXhg$q?swWHdy;Y;|- zx22v<%H{n%3L8b0h>vwy`c-on+7+lz5<(;|Upm+nL-5pKVspQB0cG-Fyb#4EN4A>? zPg0J$R8Yr^;dP$BE{-9dW^e6uK|U%5`Qv9i8lV&lb&-YLdNf*I5zpvvs;R$&gRJ0) z6ntLvi;AAT_POngo(D<^zI&nN8E{F2Q62F)0RyV1e&#-|E5RAG7wx&+=^P_0Rv~1E z&uQShe5UY!6o%q$i;yIIo->cwslAU#oT_eT6j(am!`?ECQy_X16=CL`6*V zni4hFJulluYc;DNtAI3Wvv9}=PaQ$Pn@?fgdHBZ|q*F96oMf;P9gFGw5gu-#8L%R*}t* zIEoQn&pt^1fgtp|>$oH)xmKRQYK`6{5>6kHY_0GP&ebnq&Y#~_pnlq4%-%pKy z3q-fsFX~B@YKQ)2KiknoGYL2^#Y)s&vwq$oju#WaHCTBPCigw_9&#rqHTGqbmC8Y( z8W_zDxSzjNs2j#pUH^!~qD~LVAqy5Q+sew)Np@bfy1C;LQmAXk+Qqii)9hA<_(cp> zz%G{l1eX#VuE(-0t}@esI1s;HLxn2_3>qNx?A8&jHwf?I$cS+jy9g*uuTb9aP0Q1G zDuZ$XKi?HMYfVW{DA%NMqi74rv0QB({t5V=j#oM^)``t=3u>I;w|1UZU_?zAC4B?aJ=1+0ky(QIh0fo(*O zZ4mC!5rTrSjuJS0S!xTu2{bJARBkRejH0@6F> z5#~B>;#2ZlH+$6XZrI+#JV$kGp%O+7$wE!s`-H67mIv2)gh0ZiWKI(LN|VzxLt9Gy)(GN`50TC}loU!5P;-1S z_L6Qf%o7lt1U}WOLUCspQt&p_RBxhQy|UKz2a|=5H!}i#1Zv+mm$@-Tedl*`VsLSd zme$p)>D13{y9<$#TQ`w^9wf9X9p(Z%|DJYnrNDSjK_>`%{j2fKkZ-qLhu}ogWgva` z=eR$;6QFIon^8&h2S$;aaJ;0FByGdXXR9t2t^eW`Ae?^FaEvnbMkVB`XN&`0;Dl!) zOT8!c!N$|(=;_F!nqz~HI?;DobN_`0!V%;D@gSXzecup=CV#R=WU{>zZ_F=iXU&F% zf#d(>d6|N6)R94n*Y@cPxE?n@6qZgM_%7rJHX`XK*OH`{-q^UiaeeC2q;jwK4De$O zjiAyqF1&C+4zO|A^hCY4cLt!?&XdJ~bC7N%0R`jEZ*#WqySz{-Lf-TAendLpq!PDu zG>G=vMt171za1PDnQm2PamvC$Ajc`Yy5z!tN-I!A4R^CPNpg}OAu(980-M2RN3q&S z0h|#qT|Ud;3AFo+@`Ll{Z4zAQX$Y-+d8t-VB^}`2Vym_q^JX_7iwOUHU<{NCpuBf* ziek;fVsIZ()tYXHboE_1Bq0EXCrzq~Z@7Ycv(G`^si-kaL%sf@KpAr2sJYvce`u8z za>Q9J`!Xq4KTk(YjTI5MHvabn}0HVz;-Bj4z})L9Wq9XTwjMRbbtw^V1@ zwIYbisc(Y!8g2vrV4pc(5hNTClPkByiL>K}ioY-@Wv^aj2sAcZIg{d9rr)bfo*C^U z(rEibGaqyD`7yj(m!l>Y%UWJ1vTN+HSIg7F+}5$#dYWz#YlPP*=kE>^8s!KeA*5n- zbZAz(kq?GU{_?n8D{7{c2C((cYTqse4=y$DLLZqDp5$o#WIkKu=}AQS&1cArwEf1) zG~;N%ONv6&ER)(@zRmiVr7cjURMZGt>LCvEQqU0htmu5IP`@z(3g%D_?Ea-8^SKPJ zX6clB^MNViiHZ@Y*PxPgR-C}?dzx>(0t);AH(WdCplQa}FHuXw(Mml7Wy%=}nfCN@z3S$V&j6BcUA04C;!0hH$=^7W>U%O+n~R=VPeB~J9a3zvDeLT= zk4lVPuJ{?%0QJ=vtjPsz;*K4)F)-Z-o*E7>43V*bJ-RlOgEJJuX-SxWfK^{+z%$rN zJryLM(rMp}vHB`q+$@j$P~4YkN3nyaSdFawHZWv~fe@%3#XyEZVo;ps`TNf91=6v< zo!+eS{J`q+A%F!Vu8RxeSdo7Xs9pVJf|?z|!K^HeTF%1OTb6iu_^UpWxBGk)CBz!W z(f(xuHq{4(*8oH zfU$^pgyOBs{uUU?D{y@WnaVI)8FqF$$}L} ztOR{T$JE=c6EvSgzoB+T*y?r?9qf8j3wC!(K%OEw>yFC_W2i}yX{Ca)1C>0WUfGjOU-Z%>V0;4eOYx=g z$$jN-(gb+C8R+7_Xf|gzw6dqiIJvkAC(-rTs;>*mJxskBQamVjftDNmV-y`=8+qoO z>>frkB?65N!UeRTop1c9gX9ruW+Tbf@f7|A{P3>SS2$EF6?CQ&U{HmtICLx4dBSTM z$4~8FF5piwiUxaYMoo|=s1NLBsK#g=)P|e5dBasHk2DkXt_3(05zMH+z4h_;f#&k0 ztR}CACVT`ScJ89+uGqL5Wf4Am5|&NBr7*(BOL9T&DXN+_{G#ZSO(Yo23{6s?#A-mV zz0wmh51Ti<*`~&`r&Yx%!gp6nlxo4O5mR%MHqj$G^Uck1AQ@S5mZ_kUy*>9x@9GYM>l|p4OIMzm z`tra1wdbD=ep%$ad+Z0zoB8tEiXLLHvIpgU0Ue zb`4i_^(+95@Zs;SW!0YlCPcfm);GeIt~Z%e4PAQDuSy7}2frVx#=pG|^sJRs6P$!2 zSEVl7q9^h#7#4Cdr|8p}=K&MJYme;ru~_>oq9#9Hz1aNF1=Lx({q&xsIR*=6j4$OA z!L8P)hKEUQLme$@xDV_(`&)7me6gi*f8UA0a^E-k!^{+YKbElY6yfOI!43f~mw)EV z@?jkh=S^37>p?;A+=w%BK{HjshR~Vsac1QM-=_FqF$2Az?O+j*EvVVIP{p*E%n+Q( zcY@)99o>3QPs?9B=^Kki#Ze+_?4tHsYo9P0Ua$){RE|I07QDW?arnZ4WJvOX@(*$N zpKE|v==>{Ql8#)2Tk`BwZQ)~GH!8T;bwGDb70o&7#-S$GGLjNzCZ*8+&La}C_UNHR zrpcDd#Yyn^QOg5g3qL3$k+IbSCoAeIz4vaE=@F28(kK}QXirt}CD~JOj6?Kdw1aS_ zYOGpQQ9+^K#_`qCVskzN_f;`YS)>rl^GeRME6~Km16&U^uVMoAYR~D7OfstA(C@^d z$|OHEw2-F*HfTEPZMpv3jAIK&C9>de;0!Dw`CQ``j)5+%*7c8B-NU8 zC-G!=uNmk_cmd4N3{+gMRjHXPnTl?M-@St%WwaGq=>f%yg(?3&V}bA>l{|AWBNYor zJq#$!Ro?J$J7jBC3--v7nhN*#K`?%P+*P>0cdBeKwv?k+uQDV=(Ued=+rLEo#kk!e zal-2AYj_e7wv}YD5!~VRCVJP`g4@u95b2%j)2H&t~0*ZlMA$ED1SD9YHnXrdqbb?KoS9F+<-06#yb3Wwip;rGxYTt^jFkuR&h z!J({P7&=!@^GM`ma69q)r@@mT-MYU*R-xM^g1^{>5lCfX;>yKNqhwS@SUZNBJ~S|` zc_UEaq(A(xAK1I9cpu5<`xQL7;QHi6$lDI@s3N!y?9JRa3O%XOq1d|9Thn=d+o??q zS&~B4jDk{Me@bB%#R~3wb{WjbPPeS?9YsZ?xIq_)@diY5ABtqy^sUP0cl)Ny3Ln&a z;yC~JSR}|P;XZX!f=c#6r}tH;yT{dy(*u-thBEIeg&wNYsdQR^ET1{7PByW2i;=#D zpq$vxBX8yO)r50bznP;t*{o-+E4Ta;*8BOQ2Uh9ED=Y9Ruck2P-7t}~DmkXptYjW= zaOjv=;fjcnBFe2_KEe%SW5$7y43{Pl`OjS&>k-Yvs3Jzqb5WQ;w7ch<-Kx%k`3Sb% zFaRM}BdjmyLN5pL$~|9zu0$UB()0wX=>%{}*G*QA_dx`t?{A3MctF@}rjIA^l_*WI z)20I*#nUJ{18zs>lU9yd()v22d>uoLB4UszxzvmR3-OL1uRUGa)cd$|-oW0zD;6*7 z>RUYqlE>)CrSi&bD0DC#er|@hWXp>mN)eZxY9-DLi)B)L5-WL7s#JZzAr?0^G5u!e zcle-DR9S@SL6+JSAe;4DBsx$!rL7lApLjTG(Jca$Fm@*Dn-)0h(bzUG{fJL3O1X>r z1IC2pavP&Wg{YGB%1H1COFe*nKMAAP_a4=1M{;NpTkYIZ@gEB?rzM-U;gZ+dZAj@# zAGhyg^({)6X}MoF9l!7PEurMM$VJpyt33|#&^H5jMG0uIz zMCNfw;ng;>L0dc91vOK~%6B1B;~FN>pR|k)kx>X{1B!l|z!1<*3=N*NtB_joN-sm9 zTcQoME8<5$>t}fc9O0zD5r5uYDcIP6DaaSPQTwr`$Efnmk)AB%7 z1o@^C&Sh^lqWyWcTBx>o^@w3kjE#zfji}b9uQ+G2f|R=>dA1w>UN=jls*)O8g0;1f z;w2OS1A?0yf12c95Ze*t#4;0lo~CPs?%L+OO=+*L5? z(kxtKQ(pS~qu<~EoeIWt_2G%&y^>#&IAeuUMGsM{DPARqcDKu}`XjDCYHS@wUyqD_ z-Yi&K!pb+$a)JACB8nQ&<8$yj@ncBwunPDw{Zcm|DNaBTYT-%QvK!1xm|}dEyIVJP z0yY_Q6ZgawysuoMX}YD{^bo^tZxgXme1Kf+9ONlv*kU0Z|J^^WC!3?(O!Mps<`cK= zyN`Xv4w%CsdNgEj6u^dJe3!WuAsvQWVXqi=AJnO`g^d<8JA;}Gm(7Ba@(wZ?pd2ym zV?PVV5p(-ZNn~an(t15h5J*~k-a0SZBtI+tMjpO>{ zoo?!A2i6R{uaPwDhEf5n=h-^DsGPSgdZMONwY^C>iqMVL< z39QV96F*(EwyT8lxak%*p`M+?$?EcxfNL%xqFb;3a0vObLokDovPFyhjD1gy7nu>rdP9a%V#W z-Nww8W@;@h29wU91$cnyi0GCDY)J2oX4%&!fb(kYTUmWx+%s>)O$(`~q}X2oZY)nw z`YjRqJIWtef#5|3>|)gM=S2D-kBxm;QL_&YhamvYBtu6@8o;p^LM%5neJ}wftC=1n zl~5mX?n~iz7oA0^--KKQ7))_6qs)}56?^gz{exAT_lJa@CHlzqe?O|XwRcZW#{wJt zT^F>t;7P)t{AvCxPZl{BvimAdKdW2wE2t%Y>~5ZG8O8d2g@OIOTCjc?LJCrCOu5(AUcDO(U<^HAg3SpXL=)|w)O&mSL)U-{> z&_}tA(Ku8zzbsp9;6NycFj{iOg9TuZI@N?Dt$L z-F_OMLTf5v3%93l>~}~z@bx%+Meem&usW5a#`pv?D5VMbrsC9RpjX$1RNZ*Ham}Xn zWPv5(Nty<1U}*Kh@)RRLQZTg(?i26@EBGYE!RN*e>wK^K=Lv2!?MqJ$vCB4O#6~7K ziFL7yMEv@NRHPr-cErKXjS@R7V5k%fKq{gPbCcr+$u{K47G=YQBp5g7o*p*%x?$mq=21}{ zo6I>I*IuUEut45i>swA=f=0$J(ujh2QsZ7!#Wb7aEgE$V7jck8Ns!`ixgk)$<=7s^ z0a*z>Jp+K*03dP6FaS6FtE$geP@}diGc8Rfc9bJ`EPY(1anby`U(=Hd^4lJ;#E*C3 z0yPl=im+r%F_UE|jbRiqX^jKBCB#m9Hb#9{PUCnF#Bm{+VLAJh(im?h&?U}tH~9Li zQl4OC!ZQ#Xc1Ff`KDwAJPag*ul)Ez2+Q8`~_<-fLkG&=HU`P@8pfcA4ySovi$AOq6 zIP$i!UHhnl3}nLC9ZBgQ>-S%s#jOu{PMdqr67$aXhpTaduR_{#sBXJsC_ltdYd8K& zn_{a030;#}{7xUcP~5n>$Nr}kYgET<^1gNyrCc6;>r_Qw<8RcGpu(|7E99PeznXMi8I-AQo5^y%8UZzL5B$jkzwa2l>@oIS zf+ZV^vmw*fzz%um>Mof@Pe;p!vZ@M2SSL)~86v*fyJwxoi=N1}nq^hv>pYvKdq%dj zhc-L|r|(w-A(`+K+^H7ntI@#VfFsuXn=7+;yw`4)k}3Mb(xDHvos`9q)4#u zg7p-FHM%L)U)0IehqQ=c1PRaQL0_7DPiiKso_{h?(Lq1gqbB26g$xVu0*|h}97ric z>o*|HHOR(%0NjvWHl`PvA>Weu^CKOH;qYf;EbBnTx3c7qFE8Ahw++7}93lBcP>{CS zJf2XG{cEpNrb+ZFb^V>MV37$%QwPJjs)SifDMYN69OrCaQF|F5BeJhV7QP+B_ib0y z_hyS>%Io^kb`88yyz!B|d;T8?=;GLTskXW@Gs$GxGgcDKxzVo(ogM{Eu>jKN=^ zE-1#Ac!a-mb&(|I?{@71l?>cB>ah#$`}0#@wk?#3R?{KCibJiK55|iAt#-_uE&;ty zs4Rh0szok54{jAB`XNQo3gWluTPpx zZmTb7XPBp@?xO*T(aw~l`t>}|Kqwijf=U2ZySZ@W$ZXIY!77uPgg$j&QuSnNt8t5U zJc)Spj6zfu%peM1(kGkCM9kN&l#L&;k6sQ}kW4&fYgpA|myU6`al)u=!Q0*q&1SaH z|Hypd35T?g%q1$Uv5o62ixvfdI)yiwuy|JD!#wIO7Ugr-IqN38iq$KMKsO&OLB9aZH4lZDhW2asY)Bz^kiZ#2#nLEv-ViS zv)}V>8C@Usi%|27zZf*Q9-ClDg_wEj-}{42RHNM!M$by`KMN5=X9q1tyQrddRXJ1yxre0o5asIZZI=f0=9IVq>IZIIm2qj}(G^LKJ>(6=5x_5z@ z&^dez!kT(x|A(x1S`vm^f(6^QZToB6wr$(CZQHhO+qP}HXUCkFi}}wptXdJ7Rf(CB z+4_^SmeEHb9RlW^l7Vj;R~W=P06&(^8{d;7ObUrP;h@t)?y5Y#o5nydwRY7ApfD{X^drQBQefl9r6wUJOf~V%5%nhw6Y&rpjg#)2v=pPpv!sQn6q16CW_@P8=JvU zFR3a>@590Ca>T(p%MjSqmLY>476VwDF>mmSgx^OEm|3~Wo4k9KIJ?^(vOf`?0h!Fg z$H~9OfaQTd#J{>`syjMd;QR-&SGyJ zoCdDn7X;L*LF!&{j;7Fm3qHzad7UQ6Nx3PS{V+B#yR2Lhk*5vlXG;?ro8prAg5|=} zpFTF$m|Ko*$>9>N7dn2X8j3UU^7rC5WA7EE#19#<9WF&Qe4{LN1^%Q6)#~aI1Nh7! zdmWgDEpi-`IalC+_LuX-whIjh-v}EGMHYrMvf%A%>w}X-ll)rRWvBpaW<4iOSC-S|LsTpd+tteU{TC2&Ez8wW_oY2~=48(M&$#D1?G$`5Co8x6;D{H;&=JD|tA>E9k<- z>Pgyk?f1Z4!g)yE4S~1n0_fj?v3l3%2X7yJf(N4Slfa$9|FAJMS~ELEyMh4Fq$tTT z{z`0hYPHyfioO*gFWEuyAxs20J09m6U|q1(xr4&XD#_R3RRW@70m#9k{%(7E<%|XR zB`1}iUJVYLN1W2Uwm$^qUbApK)kQvM3Uc8uxiX#%F!`Gk$eODeq5YiKlQlQ8PWMhQ zCx$7@u&_TIyaIwGiC<&`H&)yLH%0=%z}(0FrA@xHo(*^}?{YRzWw0z%!_{j@vYHdP2qEZSTe79!_Hjwp&CK73LUR)mdk~ERq+DjZkeZNw3s!-tDiL*0A{EUL16O5f?jwIB;|7~aFD;G2oM zJ2kyFjng0&imB7ySJK;K#y?ldAtj+_$y+j~*m6vAxzgM5D3+K@7X*9ybhZC8gFcO} zJMDGU;J?MMolmRp!QQQJ5(K@GUdAj52Sx`ImA|E>=j|Yges2YFREFfz8iS(&X8NAF zV71wpX~8|2XwnBWhscF62V(R6PK3ugn){D{=p@iZzuHTL0Vt532n#(5kUg;S9cUCR1>w1txOCZftPv?p)&; zZ%vW!8^con0i9=e9l-;T6E#yt%jmp^tFGgyoPGHhVDfmIRcGHGDzGqTz&kxu?^g`l%_r%hn4HREeQjP@&Pp)V9R(MHRBn zd03h1Bw5%VpEZ%2r}(;dlN54ZOzw~?KY|Wy3+J$*pH@~t+e1^9=*7XPwR)iAs8mPw zbkzbY=fxHomMMbw4sjJScm{Yv_c>k_1o z2~zH)MtzkN8-dw6gddlHo^6u-WO#=OHkd<*0&FZ*l0I0vd_s|PL>Y7q2=Sc|Vu$}D z<`ukrCf%t5z4cqk2@+#C$Q2#Mf_l{6l{R>$wNEdDEwkMQG;0P_%%8lZ2MwWsH(Z@X zp3J-Mr2X2IQYUdJT!cK11cAvvJwVwp_ATC*4!YvwYox{|S2+dBd=l%}CbQxA1sJiK zm7<6P#19COXQ1pTE+*5luM5jwBx#+G*IJYy9arPf)_${dl}>DMW(lp}HmYOz;AwVx z2~Ke-Ut|Qcq{b*f3yYI~d$61)!Vos9TSEhew(<+(^Oa1V>F?+biV9mnQ6pAq^$sQb zV+x=~7ylZ_)e;$w)8bDkY^I_a9O`K?AIFiILd1D&3QiNHFB|5=0P=drC+Wq`U$FZg zTK0+Hqx#*p3WBPhEZ|uRb8QzB=%jf`{gG&=RcN9Ghf16sdv`^56uUZ~5q_*L!k3_C zOA&l4T!yOh;uQ0e+L)k|OleXiUQo@o%6%7_(VvaB3=cX&Uex*U5e^O*vXq}J7-j9^ z@akPCDf7J({9Uvo1F~9ZapujrCja9=l{u*Tki+pwIinFT-Q&b zOZAmoM)zbp5S=jy7$$iic(1-c@e15mE|P$U>_cl`@PmD9kq|Ls6!yT#QdBtjJ zjODl6fU+Ku%|-Nutjvc1*F5uU)v>ccw(^ zEs;Ncn(UZ$+2tG?Y1I<|wm+5cnEyv2t^>oTc^(KyqHs>7v2iQ2kcUt0Ry)aZtxHCO8EJK|6?Hi#II#2oDRUAdvMKu20~@u!I6 zx_}KFmRm0dtqCl)Ltz?IRth6*VGPpxp5eW7bp?G5;37pzeDJ(^@?3*4$pn~L8I`U>poJeo*by!qkE z3I;TKbIB_TrAU?< zAdA?3#@B!hmV4_@~ zz@-QG7EV)hao;8ErNRKW?wG83&X-$xsWZQmGi7Bv{|bqdV8zB~WVEL4zt}FPH}yD5 z`mXR&oW)-%4kVZ0zW?j;qZCz&nsFCc z2aX)u2JGQwfU|S&sshhAEF+d}C;6kz|3wr`f65=Ru z`{SdEgG914gQriPPKO86&(cd)AlHHYFVX>UH>VYxiepykvr9y_&a!L_ju^gmP?{A% zoVI{~oV5_1LgsyEzU2Da@G=0mWL|^~kb@6+2#)P%j}x7rSXu)$_#whdFMiX0A`M&& zfq3Ldf7+hxiHfs}-!68Xqc}ZUwG8KU|67DB{LuhIMQ?E%6`sJf5@qIV zpz^@tD2(8wnqeJn3rS^)ROSi_(koT#SyH@X{;-HM`|KZUSlb@aXtTOXyk$0^v_-O$ z7080!ELL}*!)lHG4M<ctzCBvp}97&gDb*B$-$52o!L(tCa^}X6v38kEI<)XMmfa? zsohBT27t_zUr@NN+Tt*|t#4t+8SSuY zG7Hl_6`OVU<}Xn+90voI{!zeYFXJaZaSkP#!$6%;Tg4!^#1ys*v$MH>kIFqwhoL0K z)lq-lwhqUFa2(iVdi1;`tGf2_{f1JB2Mgy>GEMc%v7z!SP@cpeoM!lcy<_t=dJX4p z#@{L@pq6%Frmqv#jR*0KY6VcM&)%q84L>#GS;oXpG%_g6VyjZeKQgLTQj%oGZO7eS z8V)~qSiY=1H(n56q)H(EU6L99`5Rd;vFl5)mE$VJ&~*gBN;reF#ck<(&~=n#%zHP{uLuk?Lo#=Wq|b`#S%O@TZet=n($ zij8$`x_;-QC|0oY|ni6msrLXG{& z`J_wSB9V2_B-QXuEFH}W5O5}}OmO55sLBhbW>zV9Q)RNxuhn`bL;k_6u1sdL;7k0= z0c%l-KR$;T)*vv#zf+v5e=sP9{OHL+N1O#gejkhP(K)YJO`IHTZ^QuMT%)Pl?fxjF z&y#}q!i&a~dZNd83%HaGRt|4V4So4su@Nn~KY{&J@sth?YN1rg!w5&J3{qB}udXR& zEiFQ&y%cpD$eLg33MnKa@?9`e1fg`|r>O9}CP8xuaYN{}N@rDj3sjqRdlGfGk^Ww} znz_#?Jo=Zx^QPGHZ7aG3mF=7GIx7<%z)8#zLGze~_e|wb5*bg5@2?j@-g)u3*v z+rl_47Z2|na1$c@pGaf-y;z^)B_y}($dPDm`OTC&KKKM1napkmAanPV&T%ms$#=F( zZ{Ws|k%Ac2_9Nz-^9=fML)q`+f6<#I5Vir1T&>;TL_+ZLEsFLhGy$m#o@wvtT1L%W zuH&o9q3n_prs@b!)N)n|$xs#j2KYBwW4N=hkOp#Ho5%)= z;r7shoNPFCFP2y~+06=wcu8idCwa{Z<`qxBukGCn{gq9zPxYs%_}i6Jh+%l$>v-!E^#mj*UA^YyJcmYRVuk z3MkhmNfUGSeUVD#W*g4*Ksn%05LK_~7SlC$91r>puyVSwcG)o5GBeeo?qR|`vS(KM zTo6x^1SH%KA|WlhzLB1Q)DDWvZK_} z9^tNHkrc!zJkAWOil}43vIGzhTV^-w3UO<{uGAsve!yJj{{^Raw~koaR+)6SIy{u1 zbDtNN_r16WlIQYci$w^bE$uDRXymKhy5CV(VEG=+g(!mJdJ0TZd)h14l|8HHa$)J# z4DbsSTWly;lZkbITi8mJRX42dnZ}X89VCO{deAD2lr?Glc>W7gGip-$-`h;?A(b~s zHAV+LOD{Ej%@Gnpl{B13N1Mh8%GL|Ux^%a0#XU{7&n-~!OW@url;k5gCpp=CFKaPn zpRQv>AJydEaQ+?c@i#4zy=n+x)N``zfA!qAlSr*Zvuso9?Y>iDi@^4v9!C^nO(TJ{ zqk*GI`qCro^ zNwo%j{w*=8Pkf3bbB(lCR_&TMfuna#yc0v@gsM`}xk`W)!$HM3qOy69#L0yWovO0C zIc1E%c!ue0mD}04_>FG8d4ki&8A?=g>azA=9#={Rh3#nE4O!_Id|KHP2M_<=oOD+m z^b@_G9|-d@(J)8X4S10J`RFqwZtjUEc~`N+Zs&TC+|4nmHyeQeNW4-1Gq3^e4MH4TB1`@5gNUAwVSs*U^@P(RR6YxGipgSm;XQ{ats1_Iu? zn_$S@PE?Li)&BtAstY{7--yfK2aIhX^9)7j@eT=zAfOpNS zz*15r)Gbqd9vPePjf2YUpYx3=4&aXLV@F2|r|85a(}hL6F4@{NUFnNapVejVfKfMb zG}@u?tMGxR*yAPU%MDXv4JLm=?x-CE=J7VV%Q0+uI?Z0|LJPio532_i4iJSPYwfLM z>6yS>=`kG}+h5`^kFvPWQ-rk>u6Ru;cB%`(rVA_XmS7VU)eEGY2>muBKE5-GA_SV4 zcRowsNr_V+v9fNU-DNNmvd#}7tlvGCXM1dgDxCNj8V&#jeUDd^quGp7thsxh=6YA$ zfGZf+3Q6n*)h8PtI3wJ5qi{gL;CdB@#mI~;-e|jkjIrtTzkKHDBl$N$WLn`fRAOg8 zX#O%WdovF_V=81i7u3kbVw$BwNqaNVEk(^pjhG5HLP zgPzDnUsx)nZ(*|;)GE5Cyey$2z~?Y>Vc7Za)bQvdQD_k|&#Y&|vZTu- zy{g}t))Xhks^Fe(q`CRXMw)$HH~I7qpL0?TVu2ci@q2;zLrR#;t*qD8-z-bfepM>j z!Y_6AUBbWFY&gSr;NNwQCdLQ)V7G91_?iAc>+nB^1`uXNv6o}+48p$Pu4Mlo3ZM2h z!PVN`+9Eo4oE9T)EOF1SuEWC!s}W>-GzMa(hG9s)T^Q~RT`#$mQ%MXHignkQm5MRQ zGl#0geaxsk32!+i=)x+nFo~+eaEIp1I_h7qUPr7Lbc}1Ccx?P90$eHyadt-NSKAt) zG|gtQH+lIe0M|YAtO9p$dX++i@9y<;?>W8v3Gw=|t{4yJffWgL+MXq^H;NPEKqPN9 z_n|0$EydxbI_mYbEpDHU`Mz4ejcVvWm#NVXBAAH1XlI8l>2NXo8erpLQ4%L3XUZv& zE8fWn@B5DyA2e>k*`k5@KzfY)%|3R%WHXA@UN1YVIb1CbK`T>l8}mLtN!a>2%$rQo zdyTYjJf*OdvUWWtWXsWQJd!zBX+F>_0E~6bMSd{h2|?TVUkX1yiaGuP0f~Z$rD9|D z86xbl!JLA}B?f`NLcw=R)Ru>**&!yN1)SzmAk8=#J(Kj=4AH{7C1Vr)(#%HAQ!DJY z4za3bHLmJZSIGhd4TS~JRRv7p#}gDZJkMZ6z(7BwhfcTJQ1hwZm6*kA#%3EvdS?Aq z>Y{}l^xu+l4+K3n-Ti6Tn0j3=`x$+lYUQo=&UnF30T546LmuTvS`d-TPc&?Z=*$DV zPxG-uhRrpfOh9n%=|a9^)z>qpxV(y@g4vpSgISisLj~FVocXXi7hkvK&;|KP5`9>T zxxq)UQ8(5Wl(SycvhOK!D;4?YaEu+FgXUe3=0FrZ4x-hm-iZMsKm?QlX75>f2W zOixOW2-gx;x9dc~4lrVUKF_i%^Y4UfJ$*+|e|1v9G(uz2TiA4^FX-4*b*jP+i}{gN zXe{?Ks~$4L>k!t+SO`~CkY5|lQW`l;wDTWaFbb5HNJGV#0Kn)5BH@uh%TPiB)@lVF zL>m)w^!i&<3^aJxZ1GdDfs7iWUFGL$gC~k^@T{#f1jkK{dJ+)-)f8D&nU!cmr*FH9 zw{U#@3^Qu!#UQ}g7UYg=AR%AI-mlgNmw7%w!|A9k_-A(dPHM})vOaAE7(8LbgxCl& zHiZ%T*Q}PO2=iz+WX`e~A?#M)@xW-w&<(lxn*&t;Rc_ZlOrwM#dSX>RuYrxgYn}J! zXd!Oxl2aVCJ3^_*^W&TQ{$p8xgqP*@3=+Yi_jhu^QrnLRLYa2(JIiHNnCBy3G5*K1 zq$MX;^tUL+ZS=DOh9I~TlZr$mNvNRd4640W(Rwu`Yy|+~uNiiPP zw)1+GBks~-L-W(JA6zmTatNfK#RQ~{?w1XW5w&|ELg}4JrC?>yix40ih6)+@u zMpkh%&D!8jTZ4n7MN4&f8JPPQOjSCFxg9Qu{j+!%^kqA}UF2%1<)kS+NGyvkMPkZl zN9S5UCz~+9V479hZ`8BGPD#WN1#73<{$pcDif6B8M`N$~ca2H#`$GRlqh@!IX;cso z`*KC6P9^x9&Skgk_+22q3PQhuZkKQc*mJ89HtuKrb1I&3**|QFg<^t-Ml~VapyfM9P zUV7YIw=zL5hP_Pyh=;P=(i^PHdq?L_XUYA*x=~ z=dzdjDutgwn{w9>H|7CNhNo&p`d9Y1pPro@E)B+*!wh$!T6_5lA+t!$-h;+>$#tf% z!!DmTV?SQz7X~n<52Mo`>0knG0b}qcuzU`uCAeagOOf$e`Z(c0SCfv?3bOA0o!G@N zq6qtUxb3dFspejp? zr$iA_oRR^Ro|(%Q3ecXlA=F1A%rXusy!)q(Q%e+pAKGQHr%Q8_2 z2%z-~Hh)a%3fqp4f+P6l4bq6SK@l~{wBeE;Uu zt(blvxv9eg*Ss2{`X75clJ<~$engf*2<5k?=y0YfXLwwAflXLp^fE$i#Q?T2kp$zS zE?hlyMpP!*EXj>AlL@Kf(8R;$cyKY3vwdf)ny%1lFx;#Fac6+0>i3uc0Py)(-uYzv zRb>3QcSrlEV7LfDXMv4VZ;|BlP{AK=zSV}`En7Qt|9;KXy6P(9d!+0W!dIuZvkPB{ z*i!k?ZP*5l2)#$U%8zxmnE>0y><2ueGF$m&^b*CJmdgHQtus40;R%6&xPB0=achqv zt+J#&^8QtR;&r&Qmhxx6bb*)U0nW4Z1T+7ohp6|BlTGfy@3_XR*kfBvK-JMTG;6|7 zzUE^YU-m6F7XkpE-||A^%$&jB>*$w)9tHvO{IlIQ(IqpSt;!(ZxRVCsS*qf3JG1IU z??yAM*QqmNtj->10U5%NxkH#PLM`$zNNB&AR|@drnr*)UZnwCF=_osPlI$rKD809h zpJddA`LfyBY<~a`pC6yIcWU?aRr;GWPjo@r6+&bDt1^4ErbWc;h<_mp1ZzCzL}hLV zmCxY8cZTxIeE&N)Ipd|a8_|d_RZuQUIo;D_^oUp%1WCKM*lp>~%#RkxHNSP|6qu08Yj6fgYp3pdomjUJug{fyg7=4_E5bRB^5aWGzUBqw@%=-~&3#uKc_l|nvI_@zmvj=Wl6K=C39&2JKQ`bQ~kQ6j> zqt$1m|B88H&O9~^XnC-nJcHrxM)B!Om^~Yd_H$aO2^>oK8oa95g&`%H(5#&@3etmJfr_tdtkKP8A`eRTj>NGGGd4Qtzh$?mW34#KEoM=ed)NX! z4GTxGwb_Y;O&$qlB#h*ajbRy!raJn=nU>gFKZ$)L5hAfJlgg$(>^S>ocb3Y9|CEzi zy*LY!Oc46Gi;=ldXUd0ieDl`Qac+5j2+S+j`cfaFYU!V*c-dBcKAd!Yk-ECkt%&KnG}hENvd{vQh}xKjLCi`;2a_#GQz#6 zv~Y^Y1?(bl7C}771EeUt3BaaEUxM9{6KPkY%f3PY4esAT0Y{tq%>K@R1(FQI>}=WI zv*tOxS2i`N2|Yn4^A*HpR@n(ElQP&4D$Aew%x{8m`+P3uEp4NM2-qXcY4+@O>!gX{mZ8~!#{;y1G>B=kfP-chwbb4`0u+D1W-vK&|$cZPShNl00Z z;tIO;6p3xMaN*(g=w`lUXXZ6G4Zgp<_0JkDgT~AU&biB51OKG7Z2j%FN4rgctMbis zD=@?5DDV7a2mpt{MmF z>^b48U;4nGg=8@E^*bnjSI!hQ%_#Sr9%-t- zR0$OA!kNv2ybnria|GB1VyKEoGjo4Vlq4?WO*XNL4>3k7BZy^ewo78|YF8IF5^>^U zdef(yXOEwoq7n^=o^5lS#a{&i(@IT1@rI!d1VGfsa_aNYjYW1cE3D;FogCmiK04?l z9r-~JZGkh9M>u1577)yBy{W1zHS3#VTYWH!v8iS+De|bpRy~!=c@;3g)X;xUx-BMN z!$7%*4eikwF)}zy8aGod+{@4Akj&E{*`)VlI`0F>o9tF)`afC^Khx;`D8+Ab&bYB_ z{SnQqpq8-Fb2>?{25rg!fpiUO!@V&_)}{;!Si*>@fM{3^vJi&o+ft(ShKA)`6(?{l zCeG6BS)nwik%B-(0>R&e;@2sE7*roQl94=@hm8}uf|yQWg&%~?5*O0WS?kCLd9^;! zi#$~Z-bK6cRD&CU;F5l1=%3l?FM=t?X#^19GIre~cGVL%Jp0-Jt7OyCDhJ1f7sxNrjTs3olN`qW5OvWSW-vTWSVnTb(gYls08}a3~pXMTJo4z!g z$;+wK-6kA{S{|eir{aIvCdkRt)1=e;tB9L4Sr7VOVSBdoV$TSp#D}u1*YxTjsE4Mb zYA=xio6v19Lg!0oDAt)^kQ@{M(NC>v4skOxNqrdfur74oMGF$MjcKm*y*UV6gP<5{ zf_xT-`TSL_fCM z7yYGbo?$h66NEj>_ho2W=RPr%vDF)Pphcz=qXZ;R5W}3g?~NnE5vQx=@rAsc_R>e2 zchBb!#LFQbsRrlyun=Uw{EYiOpUsuy3$ljoysr_WhAPXlWufCFSg64^-HoI1Xm}AL z6USf4hP^yegx#FWw&iw3!%GE~uDc@lo1A2LfhKIZ>${nnD^A5j$Lwj+MZxaocWl_t zeQ6EAn@HPTjuFTA@eTS3OpLI0WpEvx@t0+|`*J5!jI)y962Az4tlnauQb`(8`Buf=6J zNSR)%k0JDh45>=5&(Uv#=CE4uq7r>czb{3D9X;8K)EmtCdcb)@rs-4)g|;QXK>#k z_z)mqFxf2}cEQ~ODvomqU5-~Xz4S&tY0)(X1{KW>Owa|Vi|x!ajN4t1j$2%nKGy%4 z*<>ZnDUr-b_7HjSIhK^>>FqPZ+KJC;K$*f`e$n>u9iW4478 zmFV)C3usci3YbaI2`@5kk77JM7-meSj#J4SD8>gdGCXO=;poIYs$cv?Oq==O2Rzc;v_NStECjG4?M#tHZ zG&P`~TCLW}uG1mN$8y8ZL~pX<&SjVccKrkbSJsqmk{Zc@+3!F6V|C6CzPeTs8(Rai z2@aavSx+LHAK-4i`aO7oJbG4-rN<&&VrSiZg~2k{l5hw*3 zr!PDHZ9)#LH1IpsdPcgDv#YK%kYbfkM_lsgsmf=L7VSGhBL+=vgZ1Rw#wrh0E%F_I zsZMP%7r8$*;^i5L$$+pb-12|1hA3QXm6Kd40LG6Sz^g*%#LyTMl_f6VnxthMG&jxj z1MSI`r)(X|OWZQF35ot8*7;j%is#l3&1}n;2^1`GdbsFQy^lipRIfy5yW`xW;Hv*% z+5TaJ3qVM{iT4+G+DX2U)b{rO2~obB%*V_;b@&5QXjYx=6J~valVi(MjOT!HqIUyX zR;X%iBQhTbnIv;hRf`ktjqE)^g>C^E<_rUl@NMkMFL$=Q4Pa`I@CNJ>U42iK^FrUq zMe}GiQUFTxO>t;}y?Idj%#j=`Q{0r={rXS9sUskmKLa6o}o34c@e@^EaB?usaBNOm&=7C3^MDoqa)f#;3nEdLS1hZRYE{-;3vPA@Pp5={1jDaD#*2F0W! ztnJ%?Eih)-pYmU~5*{r-2B1ohqNZDVuAfIp@2(;YrC`YjJI&cFBL2hGpvr5E9p#%~ z$G7q1f%^TKKp1d3ce_P@RK^|Ynww;d!>)zu z%NHi*oE4l*e-bZcvsg#Daaj7pYLArkYult-uv07L{dQgulOH$^k>Pd=@c=ptjd ziU?}QLjg!U+!l%85em~GB{?DxA{p9Xzi=(E*(~-zau~Nn%{wXuMga|G{3rD5A4L_7 zN*lTYdJ_$!d2)8by%ef7_! z_w>CLv--58mhNg5cqm`6nk7S1HvE^VuF84r-4wzkQfyRS z0=0okZj1zkX1{Mbdd-v*p_r%V#f37J0bmP07?W7+to2oHD~iAj$So*_Zy8YfxqvqO zVMtsjT#PkA9gcq)NMNoX%NKpTRMg7H6Fj{)`=8HXF*920-C9H=F=C6!lJ_s*yJdDN zWFGCbLp8^9Xa-0?@z7yY?u6p9RT;AEk69tLG?w~RH)$@IIl~l z(mKE@@4d-E_1w`fT;d+kc8Hhs%&L^bfYFt!knU34gb>UWT+_Xc(3Gcu{< zhrY$kB`mk);YhN)Am@mdCX`LU4U)*orf;uwza2BDoWKl`2r16`(S6Bj_}j9!W{+#_ z3V~A!CQ1$r|GebJ8D0cb+oDr3$t}dC5U|=-=zhvU%jHUCA7F+h<*h@+;Kh=y|G)>g z;a}}I;&s_uQWbnZOYR$QGSJ|79S#*?KMVp=S)na%L z9a_Po|JLi4J6|Ydeq2;AjG*F0DPppjj=?PF0+w(NY-j&T0?Px_Vuq3-ZNDY-MB)2( zeMAn0+Q1m0ylEQ&Qr8Im>(;NBR1z{LoNY>S!pjGrbhq@fchvFVD*SDSP4&LW2 zsR+yGb**b3jYZUxBecKZM1)0wgP-^|@-$5iVt1x?sxB-&3tXo?oIfRR8*y|81 zG9P*=GQjP3vDB%yn;9h5y+ zpCpV`^1UZtaGYG8TlB|C{0nVj&Ag#HRC-0eHVE79^L~2jj@x-1CXV#nH?TI7E=h&2 zm*sLUVmF=&`9gP;Q$OtuY0j|vw+R&$2{7)CCTsjV$Ie;Ly?`EU2{IqZD3@*`4v!~z zF+9?{l`+w4g*jzP7H^zTcMNXx$6FicuRFeJo1dc=ZsR<1l|RHrifz9wXVoouCl5oT z`H9attlV+O%qDylgCaG;iq4~xLYdJuGV4S_J}-+OLVD1YJ;&bw=HrZN?k@73@HI0} zHic$#^tVMch$t+>UpWC}$m{n=(VB~^5txv&>bpq#WN9+V9-8Uf#^m~b`rpj1Ub1t^sJ1&!P%PAgsqa%@ zGAMG-^D(hO`2ZOV(V_A`7d$Ys&KvI&t)n?4W+x?AfT-^)_)Xr!hTG2`CtTa;_6NO8 zoO=1$%`=niM|9{oLwD2lVdz^jjFJFxb8qc5%5sZFNQ^jH2C;dn-Q~^eV%8ps!R-)2 z5DD(R_J!rJ1V=G{yT~M$p#4v z*}uwZ5{;V8YL7BS_gIsk`EJ9IO%^;}E?1(H>LZBulFHgUX0KWy)W!Ch5dWig6h{Po z`hL5|^^K!-Q_b94by`?FN^N^N+h}i7Mkr|G^oXP0RXS6@m=;&kxSV~Lc5q@{dVxkX zqVmk|J~S)ca2n*CKvg)r3`3D-`XJj8lx2+LDvAg_{kizn#i>)M&j!?y?;Q-|N}6nx zotX74*mtGF52r!V+(PUia0#;-adA}0r8F@`m$incgmHRlTZ>>nX2l@ z+mkA%!NlfZdsq)vZD~5jU|ivx79V9~qNtNDSIF+5#P(zukw_!l01m!JI)%iY(WL?G zd!$!N^88)&Mn(R$47tY$7c=)O5DysO##0O`(4{~D8`GThfE2AQsHLAvw1*<6K^MG+ zkN0SPv&-QzVz9XF38fQOb@Mm0<=R$bZVFC=)(iBxTcSd!wzi0cyX=fMo2jHi`tI;h zocrC!D7|Tn=Ouq4W%ZdxDJc z$Vpu#TM_JuYdFESCY3=Q>@gDWFmYt?88F|+^N^07HK_fI1Htn7%4Cs~q1e`5!7z{) zNJ>CDHv;3Q42`1+7<^W_XCIR=8lPVI!51O$xr`Ol zo`}VIA#4!zJj<>Nn6ce7&z-sf<<(C=|2b&GWlZu*pO?lfZZk7$o6!Y zbU^||{a+~IU1h`8qq>FtVtMZKL90$0DanbzRm#ikA5MAXO^z-NWym7o7rqX;qs8~*3yqWS^B&_D~jx~Qqm z1!P^{$A}v*2q6!5gcC+%JwEpcy5l19ZFuhQmm!6d4u77|DnQJ zynaFi?Emg3_IV)Jaq;)gHBVzI6&6o)j~SJ@h7FlsDhHQ@p)}<)w&Q%pz1OwBct%<% zbnrIe$H<3rnh-QFYd0@WdL$|SRn04Yw;WKajuKI7{sljy#tPbvwvRcRC(_b3Me+-e z7K4qlKppa%_iDZ7??L{pD5Bp^Hia)NmxyJ1KM^nL@bM~pHU-JLmoMPGC>x?+HQDP$ z!H(taC>tc4AR|}s>Ot=1Rd^EY>jHU~xA0BciH0=CWV-|-oGqZIn6;5j|D8)Dvk$IF za-WpN*hE?Bs5|%8dtc<6li2Zy22VM=tFYCgNs)Xs!!EYD4X{StkECbibDkTLoBb+6 zlik$D8wEnOoi{{#Mf3ao2>>73E`QPX=|7Dj0o`>GCz8`&C7KOMNwWNTgHnqJ1&oao zicAAt%E&5jXPIRuuvm&+0M=-*A58#tqH*x<=Jfvi^)o$!t|8@Z4%pBF_c=*0=(E?h zg*(mnEBGUyO+phWP{`F?1+W5!yn`geZ?pSuyNx?)Jac9+P|o_>3Knj#=u2&wPYXu| zb4B}sImj>t0%8tupWk~p3?WNotiSQIQF^muP(iV%GSg8FgKAY6Gqzdc$z?HrASNXQ zGmv)tn#GQe*p%S3B%wD?3!V8@9o`w!{5Glo6>%9ncWis4e@v+{9Icc3?GxOKZFzSC zW;>F4XDuuQ*E7?-w9;0!Q^v-_!^Rv>sBIM_D7-OmF)UFqgw*DT(I+1Pp))VLCPaTQ zNpEM#@8F5Spn87cc7CqRbuC?GD-i7Lh)Lgvcau%Obo!7oo$Hqa5E3>fInAs0!CcN&+j#G}tVELnj)pv3A#r!yf#IzVkaiWC-+YRKhjlEWg4eWQQhYJqmV58~f&b4Lpr)BK`fD#)l&rY?tUlV^^HJM=0>1JYsqa3KX+|I*m3F83^X>j?e~m|S9u_r zB{3o*Zl8ae3EdE8v7A`DHnmQv7)3?{tt?u}6`v}|A2B@}VkcY>X?|!wd4<*qB%NVZm3Ox4K-WSMHN9yn7AeZj5^LdW6%)nMOle+MgRB^tW894A zwFr>AVw;@iX{K-s7iD3NR?e?rOLbL!p>0$_%=sqZ%}WyS0L#VTLnK^{1r@Z-RU@o7 z&uSF*dEEF;CT4eGQPYHP&(o4zk^G~s+HJ@w!_4uLKJ+4v-+mJ?YaV~6Z7?vHe-7uZ zG%B>n(_PS6&iowxBg3^k6T>E*lvmk|G-cAd#aN{|TNxfcxHZ#p$3=Ib&MLfuKm4c= z+g*8#!j9sZm_oVSD0!gi-;$VMgnr-fu4i)~#6_4Q1E8|(T4_%eDm6*LZ|Of*Ka+zl zrsLPvV~9>i^)W1`jK|{oV#-mqxmoK*zG^rr)IvkVGUtkzOSEU`a@+L^^M-|O+0!&jOH=%Z$ueB1 z3%Pd(aV!)40u4gd5boD>Z3Arw;~b(x2uO`FvULv)xNoM;9aDUI$L8lg)I|t&51~vY z>=)zz4BZ#BDKvA!+?)6P$el2*962oMnkwv~@E&ESE+m)j|LS;zNEs5GP+DT;JG~P(DesgCBbP8s%LY$pT{c;qHXDP8*`|+a z9nN~kcugq*BGi6{XE_%g%)dZ^-0NSGLirnz-9ObQThvMl;0E>RBBGzDi?cyY1gt%= z&du6TJxu8)&!}>we7t-|C$DtHq~*lvObH3s0+Ev@NL+Ea>qrmwR1zsOs3Nh6n~oEo ztCBsWYS4gNVQViAUI$6xTS;?XC*mz1jC!9IIT88s!zQu#8K_XJ9~@Z5B$Iff=&_7M z86KOzRr-p`ev<23q}SSw%|+gLigUmMy&WIv9I<2XW>M;g8YOHETcAq92OefFUw?*5nX`*{!K*wP>q$4j>TPpvhFO8bLU^Jk$ z+m!#PBgEV6rq6&QvacjXu)vx(+{Ri+grw#OD>*bcnEgA#5E|1Y%F0w();>JK3t<$U ziTRmLn)QLWvPX+6cEHjRtwp|htW!$;Ze*o4!YnkD2Z(m=hnP7|XR+cbEpwlBWEO7# zJyp$Wva@bxSDS@ZuVRP+SsfDQo_gijjnQy1R0rh`vZ}}VAsng}@at&lIbW}TDYT7)t6U(8B{NT36D5vp7zWT2kd9!;#AH<{?SQqVYEc3eEkX75k#P-cAA`H zV_Wp~Z5M;=%N0hhJiVT9BaBP{2JA~6!=sf!T`+-k*-DUYL4L#Bgo;uGCZ@0Y}W z>x)EkBfI`3AtsdCWX_;;mR+zCU{C$6q1fX(H`sriZ4=0o@SBBR{uUudHvk7IGN;o< zp)GZI{>b35z!Q3kk8$`0ies@G0TYr##4R5Q}MEj!T*P6abH;_AW7kUMrlG|~tJ zrpzXIvc)AXwQVcymn%wz;Woo8dRg!AjNv7kSF-~j*5?@f#YGBUiO6G4F{V%#pgrm;EOgkx70yVhS& zMfYp5Rpys&w;ygawBio~csS{U!fak-n6s6EL+F}mE93r4$z=02iCScrV`((EGx8dwjl7N3 zC@$QSFo177GEe2gs5#t~>IUE|aB7>xv~xWr^5XA}pyGvP{n)0Ewmr&tJ<{NonaLJ{ zq(#A>Akko*D9t08h%oCo*g~W0YDJfcM!p6Sb`G|w8iFWuFD=K$%+yK97QDwUGK({) zlyFLpjib_tu^6M*#r|niTco5|ozt%q2XHzF*-m+^M4^oUjVw()7mTj(O9L6O zo7KI}SZV&fiB~o3Ytr}G49H`~bb7`(JGWb4+0`c6OMDGRJrruUo!OJ1wt@XJUQDnj zrz8R(t{x3#s%FPDh0h z4_fh*vj%VL!Mq|RO?Q?9y5g^RO3&N%(nk1kI6X}#knP7*WF-{j^JG`(wQ-GZg%=O9 z-ZX3vt{Wf#{ZsEo`VK)V3z1(iK`#@-QV7NCgd0*g0prVYVeqy9!#@L9cH5|tV!k{_ zA~S0DU7Kuz8*JZR^swzQ8n;C}=*s8@pg&=c&#+}Wdg}S3&g`^k{Ku*OTwTP}Gd^c4 zn3>C7B6$7Wt!7bJLNdBA8hdpkB7LO*&2;)*V;JyGFD$obpxmArdXSXZpeqzbq9U9m zWiRG+^E_aOv7IG!9!N}NccWxvH;Msmf)E*@Y1!|7)tWEyj{saOU*%cjKk*G+_p_(7 zR-ZwyR&a3aGsm`_PjN60O!YX~X;Ld0N<2-{oxlkI)ke0z00iGEiAcml60Yi*Sb9kg z)Gx+eOuWQ;0HLI{oTObz=mfb82(*-fWtB8<{tG~?eaHk>yah*zNQyr?ppefU2rHJC zNWOoyl1A}_F@NOG@nJ`O;J4q^Yr+;imF_UGtd2`R)KFBNz^ycIxJqA={UK@z577|% z#xqu|55yh~h`h)-vx-qaLj$bbdXhHFv-eqW^S|^Qw$?g}WeC-ZST8fm;rafwVVb76 z+Pz|(qL4~m{1I)AiCdr~XL2tmf$j-B7Q<2E{$j`9+p_o)9e8HPq zvd6GE)?(+;;y~}on>MNtnNJ&fT=TRA2xyf@%X-)Y3T>p?>5g(2+?@ntTDJJlIM8h! zbvP4T!VEE(Wo3yFnT4zd`v~nR-5iJ_Xk*YB6P~{SZy2***b*LjcCAfw6wOa*Tcv2? zx-KUtRW5Yqd5$@UGY`wQ5|nv~xRHxzqZPJ;S-Zv~$SN?FjTXO+0gh|}l*3zjmreh1`(sG)(-X_2(#!7snkO|So^aRNz*W}@$*Mv~`!COQ@9|r3SR97YPcZ?`LmnBjHlV3{0MM#`U2PnbpXNi z3(Y5}1?wqeem=rmV@lPJe)j?tUwyu+!XjALf%0WP*vre{KLFT z7y0Z>*H5GdVb9TNN)|CgrBt7*jSP(%)evym9g>-*DfaBQ2Dagh-X{8hf;Q9N23nB4 z`%IwVhk%ACO-9=kpe1pRSTG#*p%|M$=iigU%9D_Nz zJ4WAw_gNRyC;Dx(Ai`S7h@Wkp*>MS+kA~GX%B}jotBRp$83DGCZD;S-5voXmg`Y%E zBD!WZ=I=$Oc9ovffOb-m?iQIGH}W-m$LrEUogxH@kaSh^!V$%Kt zgE)&=8|~PEsXUm7jXQNJ0db0#CHI;3+b}{@gI+N}Gq_GWz#9E>0(7MR%F`IJeG1QK z;k&j`TzqzE#>0lQGSVtc<&B>;Ux13zbhzJ-`ez8GviIu-#p7UFpW#+0R04O~(iHrb&whNZ@2r=MtO=bmO$KvONgl#$q`^!R)XPiZ2ZV&k&a+TG zQwOVzQXA(UCyA4ON5Uh`kv*3bj03Y-n@dDvVc6;$L&@6$?8e1kXH#t(P>}zuL;1Je z9hLIX?lAy3YGNwk#r%X2PZUgTEX*j_Pe`2E@Xd*7<|UO3*Eju~?PEHz_xl%dU-Ez* zcSxH$qkNXry?#@fdv}~NibRi5H5Qrp%)DN7Hq*2~sY8i^%B&bq!FIP5@;dXg zG%%$CL`@V6XwnM?NF7+s`uT2pafvc-51?IbKx%;21#Fq2oW$df@Qv|cr0}V=Xn{xI zOK_cq)UVpAj~6ZntQecq_UbOa7-GU0#nUds*xrzE0jT__A6$~vPC5XSIB7H@h8771 zNjuJE7=h<9YpquK#lSm~9u14*w?n~Cl+NKFZKm~5WhQ+GoRF+-@6?pRtgHf1T zQAI0BH}sc3VqVNJm}yznUC3%IT1zd|oDG!2=d+cQ;l9O$&b54((Fh0cVpTghWa@mp zKV?(zeW2;nn)w%$TsTf#gZ;d<5g|5nMb5~9#f8QD^K34t7-DohG%hte*uN2)+o2nF zaRBI;?uUOUeoJtVl^UCDCUH!vn*tKLj-np619G5;SlxyDRNpa35wR3K^-O%7*{X)E zZbB{_t(b&vTRrOb^m`9b0P3AuiX9k~$WS7x15nkkaZ*Tuvx2e79IOopb^l%5lb+-(sFb0P|u!EZZk+-k+ zAR{<}SNp!ZVnx{?~tNTDIPi5x&CMAr9ACgI3#PX^eAOx6O0wxEny( zblPEVAE}Wtu$&|#@g!S&p&x2=SI588PPNLZKpCnWed5z^Khu6TWqCFF-2H&yFQbX{ zGJF}2lJCYoH^dHYY1!_ou9c=NCIMy%rbOIZ$r)>v?0$743}=AL&0h}AFlq=ZCI)@Y z>uu;j*2yXC!8QXxn6~EH%`eGl)l9ou&s(OXmT`hnnF3ns0ok`LpKz`Wqxv*kUsE3jR4#Q| zrNz#*nV;DC)F);)$h&1}LPOs^=5W;>#&J$t<+`R-*Xs{aH(^u1Mu&lB z+O*#uFTLM$7O(;3Eq{mbHwr&tODJL`V*S?hmsqoQ~stprhD# zv7DSlsazP9gEOn0FD2LN6bY&@FK;1ZzZ{;tCUuVhY9BTlPgav-xzqt$nfYyZPI?UG zRGMj0U^{ThJIU*`m{71mHE}+|K5^j}qPN%#Kc1ten8^lW7e@0H6;4VY1U=0&_xVb) zl|gKUeqKEh;^uMCE=TWD$}-yykfBs{kTW%}Ik?;EaW(frf8qWas3~PBVDe zyhtQZ0#*+d3S7w7+1XsnnT=yx2%U1)Ej=Flzr}Kyx+<)+Y-}v&=>*)MG}zc*_P{&TfJ=MJ|(SYaFdbPj6jn+r~&;_ zEccJtp23Px1aiTY!T_V07(%cRehY&ScZ{Z>h7s)_>OVWMWgt9?C!Og9|7|(8^nu-= zAeq+Ah}KWWkVTruYpVDB!e(4Px}y9TD?!6kP5#`6IN_PbFK@)i{z{I~;~boKP2GvC zw9&iAdL`mg1##vWh7mzMyh;jnHXhsrQt}kGNQ1wd055!P+2b8(u|Z|eo`-=K#+fvMN&%)OGp|RP-jue+>Up&W#*ff4X~9T%`(Lx)5Svr z7dz|SE)=-#A3NFsps66+ZCUTusvknVNJ#Q~YZlK)>`%nc-qyJ9S$nf2Cac266j>%w{QBEW=%^LTTUqkJ_0vqhaf&otYM9PJhvie%cFtixIC3|><&ENmR~cMoKt`Si|K_yn$ZU%KIwt* z8GKhG)AUv?T6GSi%5$=R1nju91bgqF=#*-<#Kj_ zh0B*`^!4Hwx(;Q}T+m7n2$g6-TZYJ~3RuMSSFGjLHlwpmyg?&Ri|4=6bHaZ_!;UPJ z-J4g!kesHMOC5{=Mg)df2J*fc0$J(5Lo2cuT~5WXGd#i(M*xRJ**gB*f#BF+eJ1&A z7~0>2eZeq_(=GuNQeNnxYWjZ^AVsUlz0?P05+tc)wvv9B5XJ)eGeQy#T4^1QPf?`w zegDX;--m~!+QOlcw%4JCB{0U09K?NU^P{!VGWm$%4@H5ILmWAopixu({A90}6H9ls zlq_DmCTY+?;+^FezC3R!NNDs!Xs{YI4QwfI6hCuG049CundWdW18d)Rs)6u`D&*&*7k%AbeivIw~0FW1{YJFlD(!M zryq7k|4_NhBV@bvm|vfK(n7f}{{CLG?$1UO;cHR;ElbnF;P}IIrF1x z&WxGUL5u~leTybgkl45?-MM2SaEwgX=8E<4g6`|C(~7Fm&FM4%x0Jsz`P-QpcyYIG z#?m5$9SV~b6?zz@?A_&sH$u8c2B&Qw%&hVTF6Llprx5AgwT{ZqQ$#Qme$OwklXJE^ ztmA+TvE60;nx}pZzAttFa@z$3JLqOGQkf!Aif3wa`9i&2jI{Wx-))xUrM}%@h-1GV zB3!Hri$%x)FmsaBrWFwR*r}b<{A8gbP!coAny5$QVPSerpVr4zZ>;8XIXg>h;k{DH z!R{ecpgFfk2n}?cOh*4Se@x8Bt&atL@-vky#%(o>(DrUX$?1nl|ACjL>YR!%I;O{C zBq&I;sL4(|j&f(y$iiy^rI?iX*bYSSvP*piHwBN(ZZda&=u~0QcZ3QG;B|=1E*?b+ zum^Eb-mr-);)^<~7z{9M@iX_#pwJ)KkJ_Ga7U&9uUYZrH>r=P5H^t9pQ?S`3hrIvk z4k~z640or|4x7u*-k1&4u6!F?~6@^e7?j33&7|E@AAd~nr?d4Jp84S>F?N8 z)MlJg8WK2+r+dTza-K#4$Ec|3q-Hfhf7i%x31mX8-8ryCQry2sM|(j@VX5M=B!8Gt zrMQx#??>rwmPWa9_AGuhGtr{5W%&|KX2Pzl4IKR#b2OuVX41eJqNDXA&7{>A{bYCo zTxww+yDDcZiGq;Hgeyo*ofGsTjGlYtW~8<5`mB9S#5sD*F3+c+6zTiqDaflQ-yT4;wiMn6 zOC4+vnY7#7Ito5tct#>88PKf65!|AOyLk`CB=kbU89&zs^AsQ!Tn2K;Mz|3$W0_4%un_)1z{c8^QF=70 zq&E4tYsv^LB3o1DW@))?8L{sa{V!wlMc1^KD36u1FU(WIiA*TOU&#vzIhZUmQ2NLS%l+I1u?p58^V40DQnNY-bin0z&=pNEZFb zwbRy;*e)O7)<^#0!_(M(Sgr}0aMVUB^0m2UTD?LXwCXzxCHLA#XD1Wj>Z9;U*S4p~ z`mjd$-tNMum?!ti}4;m(1 zPgPsuga+(+>vss`OpGIuh7Q!^`iWCKe#t@+M0k3x9OL4May$nG8BwfGTd&>`|6 za_xr{Su{LDsFMwB^SMow%<-(Ew}N0#hgX$9j-RV|dEwrBBWLtFC{%XF#cY8$@A+1@ zCSuH?EuycxfNq!CFaE^HOxic~-&QzqtVa!$W75Ke8v#OYZ4=?8C`{p1U09wr1RuO! z^6bjXF&BzH3zTW;+u36_O%CH@g>O#d>`In2H$TnkBHkfq7j_PstA$9?Y=sI%-1DML zkpRWnq1aE?SQ?PJ!HlKSKP-Kaq{lYw=|ZCS4UuxRiD?J&66c;6d!wN4H3C(6TC293 z!^4H98G7UMJD`)XRO7vx`DBQn)8 zi_C})T=WqSuDIN7?|50@`m%tUS$7D)lR6c`*gmoVOhB{0aaZ+M9rZ#XENSwpfuIr& zQoOS{Q83+oylP(7a^BMP(yVfjj#`5s)@+q^%LYXECV3J>?|;{z;cDbWVKY|VzHawo z!aXzI5}|xL=c2X$;TIaCnv?gy_NG*l3HOYB|V(tX!2Md z|5J4q=F#+L4x7i^W03~GOW^`@rWjA5_6ccInSZ2ef9&eN;WGEFk9&Ga^fljp|286*RWh0j@{~`>7^5qzmyDG~v(xQCTnwm}^pG$iTLPI&pLm zD>vH1Y}5A=N-C}qLH{Y}|Bwak*0m8qoZ;~uCVYXg>FiB*!mWZG41=U>8UgT(*g7SQ ze$}}1ukU%TSo$dRUT&FNu4GzA+zgCUccHb)2ETz{y4uE<)wsOA2N_0L9tOU;;iK6H zW!Sl`u<`q3VhOoZDV~&1H{4O25HO_+LvADl3EMY%=DWL-&Tj=OV9Zt2ybzmo-2tR# zXX8Zt&ac^542M%LVPB|&lE-BSAJQvLs8;9W`+Sxr7ZJG0k2$arfwHZWMHoT3GWQ~J zrhkBhS(3m7<5jP$q3m}quDmS31-Nze{6r-KpmwwLU@GKr<6XKoD1kd3;)tlnClWzCiMIk)Fqoz0e#*@XMGsfbj^R3E4Yfy+y+{nK(1xF2whJDRUj^b_Z>lIwO&pBl%I z-@>Ns0R9i^huIL-kdkUYnSqK3JP#HSk`Eqn3wN45bD{h8o>&RBa((u-d^ONScjrJw zuZC~6(>boZCiYX5p~m9Vd(R)Lom_m_`CN7$@_4oOA5>|_CXYJXwLry& zX!(-9^O8YyyLweVSPg91BlK3&f!axVuJHnsTfFDLtCY&HSl!KZzGDFbUt`s0_{Tw= zIrp*Eb4$pXAEDoN2zH*fRkaz1QcqY4SeNXm1QtX*35oZKGySy_2*iyVb2s3E>(d)I z-t5S)Xccrkj$0$6Nf6?bdSU(C8T}1P%tZFa8uPX=QVc-t^Z*J3?Lrr?zN*6Sh^feu zm3|hJd3v`^t`!&JUt%*uK@9p(Hb(GH`IZdW5YM9`^BwYOpESxz53lIr3^(-#N-1FaL~>6-%?mL=SvXW zUUIMwKd^p{V4AmtjOonm0XsanUb>B}sTAHe5Bz}wl65^n1YkIfx1E=ur^RL`JC)Kv z2&5Trm92{RVYj9elvOuqQ&^|L*tJbA8w^yo2R761!S^I_P!)1y8RKbh={+|UTvO2t zD$*G|?XG{pC~9@ta#>vIRetaZ;hmHs%?xF$Yy;n0Nj9rSzqF};%(hS3dz0{vKfJ4_hhp@kwvAx=FR_;`@sAbuxCrC7c5|~N zPu9-37#hb>htRvCr=#A`nyDD&SXn>Mz80*qW0B6gK~_z6FJmggu~|n_rObqq& z9!?eUK1x9{2ukz&5=AIjoB=6X+-^t>l}JXCoI(?(oq-8gf8+TyWZ6d01%y_C31qMlLyA}z;_vP7QkzXN(-*o=~f)naZd$p7G zmujYb1Z}BU05@x0Cuz+F=kQ=~s@S;`2}(7O#nGQsY!0c##Q!S$3Q=i(%BLq}fC)SF z=?gC>>d*0_qx#dC7*nh@@&h?)=G6CN@&<~Y@n)-;diagxyYG54D$BwF_dZ#^Udm}R zh5Hc2u22n`#TP@K;+QCQSBnEZAYCspDxD0hb#A~Y#vMI$u&~cDwazB>HcXkt2@qKn zxWE;F9E57AMaJTvdcY__pa~#KA|bb5e4k%b;J*{l=Xe^ z8BH@im<%u?4n+ev9Qp~Zh;BG+~zu%7ctTc#hue=#-{V{z$+s0_O< zWUBc>lM%S-hh%Ce`(o^Z2lpf2eOLh^AX32h$^h|1IvR24vI;lsm3$tDSJ;Er0scrJ zoITm3UY)p&WZ&@S{8!1UG<2{8`~OY>E#tN?&xGWd_{ga})1BZ^dhg92RfmO9Z~|^~ z<;1fIcXD)-cw<S`51Exyh zG1T)aPFPV|e&OpHE1Krco>jTulSatdhUIi`OJ9S;W~Aqq?3%rg3oaa|dMWGI2aP0C z@V+<*=IO=YXy~c)|DwDfG0y3iA;;kfLael%;cSkSx5pn%1^QhNN6Uu;iH#)Y7~Pe>gIs+h)pYcAQO(njum|ZOEd1F{1}OVJ7qHc{l}~++ zQM&1k%+{E(^e4h%qFnZnMhc;nouII&~AXg|IL<~5}o=WK41={o51(r6GqSh9ffFLEQB!M>6oDvL<|r;v&I z2jqwwSCp4(svq)gI|K_Im?ze26r{}}SoV};JxFQWD1TL>U-2ADh9 z1(|U-T%QU;i&3~K_>Qm!E)E5D8pfFo0_j?EBem640QyCP*3Xfvq^iMx$4(5Q6a&=m zY_0xPnxE|wu+=;endy;scwpHNB$ItN)F=ARCu`a2!Ac;UM{MXGQ{`23LRyyyuBqsR@!Cw?qN7-0Mc>P>O(2r7=hUaD|B~kfPOfp2SsYtxv zHiDnm_P`gXprs{VazxnEbD7{B_P-5;%4C_{tuXS&5*$kB1W9HwoKbc~L}Sk$#bz2g zN)x^TX)&8EfiFA~|ta;xbt1%5gb(K9jmgyZdKW}3V73L1M{D5{+~!{*gH`AkiS$HKUyRAgVwrgeIb)+!O!o%da4I&>kavg^Q{P~&1F2|N(!&l+jISH;N zJ|O7VdN&xO)Om)VMR=h`urwF+5fEXb=sdknBfv8TxbjPx?=Kb}0UWM1B@j{+;|1ks z@h2NN3lb+2og*Kbyi|PI(Ei9oeTKLR!gPF-#Gykuc;05F_Kev7V{o5fy(8ITI`D2H zv$F9ph?09bVWiUEOpj$28Q=6W6f$6gzwd^aobIQt{(t|jDURYMG? zveE8xh(`n6P(A=j+eJ;j+Ch~wFGt`||jF=Q%D9n9!cG)?iX*4;yPkqyv=j(N=TcctK4631?%hS_Vy1c|&0 zvJkm*r~hkQ(XPDt&BqlHuw@QzM2ruusMlc|-C^0Q9nfs{DxUeDaZg2ksP+WfSrWF#uBNrjTPb&;Hqy69Vt&-tcDE^=U~Ka$Hc>4{UhOG}T}52p zjfcz^Eu#35t|h+jZRSXRhe8XCEpEUof&;d+a@2L^5JDH}TFjlQM>|*)_HRKzR@pQL zOUu4gMPJGhZ6bBIIk>!$sx5US$sP|u0FUCTLnljOT=wXE>N!SlX3;H^-rqR_iwJ^F;fFo%_EA3`hfs=OQcE6q*k_ zv^r*$M~Tpag&mP5j_LYa*c3y513Qmrddua!(KUw`GnP(p_$@7loN6a;(B?K2s~*FV zr_ut<@48l9jGQo47#lQ1xxzKtny*rUXOkIqN_C1l4`4qAX)@n5WXhAya$vKbk7Yo* zjxWzX zUemw%@MNEsG1>ucM%&XN&r6L09-U?EXe|gv7$$l^h83xdh#VISZ{G{(EDJp97u5KC znR9c(!pzJDMx)DKQTgT^K_m}R=VGh+k{<<*<7$;>C$#bS8f;hB-Oeblt}%nm$9B=7 zBy;aS^W(Ut0Yj2_{1is^e}(UTcz1RM1}mc-O~B9blh-Xfs-R-|ZbgR16&6cvi~op$ z=v;P59$cC^H3Fu4M<}SYXjFook!2bbt-pzuU6~gA%G|uEFkI=qxhc`|J3Pmrn>c`l z(LBhmYdhUogAar$bX!YW7~T~k(?ob+&bE}ww8j>^c^>l?iK$c{Hh99BQ?DFiWI!0u zn{E>M>W%*cA@hz=1ubHJG`RA37zv2DdSVu43y5c7hKCqp_Kcggk=H4l=sK|Vcebe( zb6evMxx`W@gc3j$t@#{I#uF_71D!xbMhtFT&2}lKcJ_{6_8Wk>u2Cv6IZb9*veHHJ zIIVu8qp!oBz#gpEnJEuddzBHXixg!O9S@XO{RngP@;B$TE|0h;Tq{L5MnDYfdMw5Z zwJmj~DfA*A$jj8i1S?De;FWN0=HkVnPATvQv*sxIm({GxOcZ=1f9JEW5snQ)DI{x^-6Or|53^m>Nc@!|nRyjq?6$}{fC=_qkSxm#W>cmV z5h5k5s8ra|h$(DF8Wj&~UCx#s&pWudP9Obka7#7(?W_zj%#`kNbtKOvLd9Bx(`F_4e1Pgf)A3!K?_=bDk_Yz@Nw zwdOQ=*6kI+m7{JVo-s2qsTKNFueL88tqy>r=fD56y<-}5U<=4}j0Ul;;|ZDFtlH>4 z9SYZu#WvE~x)_1zDeZMLnH&k6W_$t8vMW_^z51ppJlTqe9p*E({#wvXI1H#aNxeeJ z=GcOx{=FEy(Uf(Xl*24GIkkj3{~GsEk?e5Pa3^WuJuLL}=E9a9TuWG2V`+H<`Wy7( zf{+z65eJGx&dIjd36iL!V1|}=>6oy32Tl8svrw=`EgWik)LdTLVcxFRzk%3R4CaD2 zCq8xdf?Wg5=11x*CpIOZ!j9Y8^2a3l%c8bxYnr4peU%G1p!oW=FjwN!u_PEoGKQhe zVLJa!|7@rPUR7fj1K@}Z+>(|$h6)gg<8lmK$gjmLJA8Anub~iz=oVp8V^(dy4l3bS z)7RL`PHI~l?BX3_z%3O>8n41`SNh8guRe)QAT_Tb$Fo4>0O8t(PX1(e=)jHH9jfep z;s+;}+9gQ?!lFiwmNQ(X zev!(YxR^Dl#|H+pSrNlFyBz6Cv$4ocxp~@h#H{Mr>BB}0etMypd4|(KTLh@ukTusI{AKjq@C!(0IfUllhU!Y$AHi1!Qf=+JQfjW!ayn>(ui177m@{X=8reqQ z;=zDFZ3gYO^$`|VBiF`e+tPApXCygVC&+~L-d)Ii8Z8E58V$L|ZoL$HY#3Y183knB z7ap4TAVd>Ntih0~M~+r~i9N$$$*+Z~a<=9(l*xq!EB!)=>oT_XRlu1jo~agQ-~|d# zn>$!u#ISnzD}Gv>Jo*56rZ6dtNiq=W%uo?e%73+wF zU3eKbth072ey$6YJDyYy8oi3aB#$}7SSk~m^ok{@^_>db1%NB8E2&G%r8eM#@U79* zvRaEPf|*?tjImXA0lj^z@G5Pu5r*Cu@ z!H<#c(_$nhp7HEA&>-CsmCbt-nk9E5zg$I^{u;@Oq3NQ5z~*n2yvlxw>2JTn?zeuez(o-)l$eaUL|^SKy>a(Pe4izZcWchL z>t?i7b|f?$|51n~77uDzD(oa0rQo`k%7O^(*h}0*R=)2okXFIcTWhrRBnVCAO5Wag zn;0Zv^+u^iE8&2aWF}*MX!HfAKk+s2O-F(!qN0Rz zqAyuJUYxc4o6u4uj}%Lk#yIwiU*-TZQSq8va~$kcq2 z4{CeMl3jV=q>wAU4;bn@L3oIA57C8m=uOpM!Yljasvf8_SgHCj%n8bI#T1f`FL={X*D}&Pn?qiHS6$`&n{y=CFGe$0F zeVzv#JP4ouBzs94%>^<<7Pn^cxRO_calQF{>NU`cUaPR%ZFq29%K$?Oy>RX$mB&!4#`rwZ8+7PM@gq?M z-0a)IM)nQ6(3^sT!M0_6u@mGWU|!;pBQQry^M_#e&C8?VRil=d%0I~K?R}!HthYy@ zWKxx=3-r|+b$6-<=ks}Q64r<}?a2YZvZ+0f)z440RQejh2^HH_1A1<4K6itdSbnht zLDNX3_!k2Qxy(&(%h5Q7Kj0Np7?PdFi8LSKZOL_u*cHRjZd9U3LKe;hnsyYD7oDZG z!qQg8Hfg9fnKmg_N1N{M+E_=94>348A3FN;AJRx8tvd|bvqdi+qu7CAnz0VQTgW_& zBP8W<`l6p+_x_FMx)_gzn&U}taAK+JYb&RJu85%UZOXDmo{NU0Z4ZhH6h7Z_{-$yT zlPw+4s+yTIK5LdKu7oDH)9-&2v%-8>Wdf~9E7LN zq>HsgI}MD5g7DEdwlDE%mmYQsMxfeXKH6!I&5c0667zGx##hsBrznhOpn&LOK^qrS zXB`*`E&(}vkf2`tR3MFg0I8_Vgq$_PZ@m7+vvS#pEqTI#1ZRV~nsf_FS2V3yjAvKlqm`p`l1$GRy+akdEVK=)Q471eJ_QJB9 zLWm+hA`WKGYsVz!J;prmeF>dEX~EswL(A#S{2?@muclb`?@6k$GFUm#Nf#BbI0=ZeZUJCph)RWcnm?SP&%BKf2Qaa|6`E}jyjA^e#UEL@DRWJ7ncya6FR zHSAgH=@|gfpZ0^YR(nSqgR8%)`_x=2Jc`^6>CHLr24w1j(APyHs`e<^avh6|7hjQo z@tRAQo}mugMUdZ5|H`LFIAr7$G=8Tw6f>O#U=e9NQsq5Qt(Q0XL6fE(fu--AKCE88F-kOkA2;FUPgzdv0PCR91ve*Ro$ znArgB%o%+6*I#^p-SDOKBR83Zht3JEy^0BaLYR=xlr=c1ewx%(+8~wEDWh|u4v9c! zACuFBK6M>+5Nmbl8AkV1@GQ6+g#ETx7y$TV+5m9cYncxp|BtJ8*cL_GmTiY^&0*WN zZQHhO+qP}nwr$%s?%9d=66+IsuJtGpwN70at3t`ghRqCE(=?&pk1zj)2Jv14eFrcI z4cZkwHK}1%-e9VfJUPi(F!Xp`;6w`AKb?#1*)*X>!!Sx)yHX*^sIIb6^8V$fFHZtL z3hu!N9J{(St`9)t-!wUzp$dxEHWe-bc?y4$qx%HSfCt5B*Zt#ruhO(_kU1KN8I7bf znc3!amu?4$?D#k6DknA-8gg5pej$=*+@*1T14r(69f=*Lz)z=}i&0u#zD?)@ZsDrL zq0A#Q_+8Cm#?{omV1J+8GUE|5V~S4}>zX}th(QML@VbMXFRA#lRgIUm$=Nq>?Z;SJ zR!j#{WnFaC*v=7-EwTf3M3EgxGb@S8OkUG8 zeum5pg9sgz?o=6uu-jUe8M3#%Oql-{zLI6n zGtTm(&;(U!gG)^8`y-O~)wM~)1L(U)=yFOjbk_@Iuvsa%_OjDdv10jNICp$SEU?>^ zOQR2SW7MSgME}+v!sa~=_>aB3Y)xA{FNK8h3gBc(yD9f3a#y6fJrP{0GEO5>xgu;6 zC#>qdk}H5TH4O_cFSbfoajYgGrU!?oEBnJdY^B4NYA6|1BS=+Q;D#krT-Pb0shHk=>lGSaT3S}M8TAmtVE;_6sfqz!GXx0 z_=1oW+)*Y(B{7wamxpc%l?HSk$iKJ87w3B}t|dzmsVuR_zxRjMzeg>Kp&7<@1SU<|8P$6 zAhwYo1Aym*eM-< zFPB^rapDmQhnE5DIpG|{QfSjmA@NM(1MEd;vw!Dtfh_1ND+-0Xyxd z*^qi!sYyj>n%uH8R`v0qc$r{u^)E^aVaYe>PcMX(Z(%y6tggla=KqQhOg<)^5f@$e zxB8T8^VaRzo)=Z{XtDuuzix&di3g>vW`3+y*mLsfToRt5|Ap2hJaN`LzZ1P@pPL^_ zuHP(+SJy?PwT47SIg9#a5!d1nlaA;&_L;68BbxyA381R91%2t0W zXD0K;hLqI~+3p!=bo6f?w4l|H<1wSxs;b1c)hW$#zhP8DR+s)73q-TWze3=yiwTVF z4=t<&!ulvJhbCU4xv1gIaisf|X=u=cAPdbE7|b7m(F&DDzHu2el+H{5uc%>p-zhhF zZITl7{(dkQiT{y>DQ26@R{#(gZ<8zu@aV?H1h`B_7_uw^I(iUC(#U}U2Z3K(w<;T6 zJVeKVJ{#ukHn*$I$vr1U1s}m)cbO6*p)Bj935Rd8^%yio`zI7wCma;7&C2ZiLah zCbfkpV=KU{#1n62K=KHpFdKkojtaCtrC=mW%|A%@>;wbu>0;O{)sIr}V-hlgZ<`Uv}VUjOYSUqAdo3Qo72)JT8n zM9?dB$4u)h4|_oSFNDm#l+=v;H8rGIOX_Y}ntWT#XkNxh@als0@wpar0viSSRKK8V zsv~44hGPym?H)hHpu0qErq$F>UWkP0I>eM131;L@`bZ;F3f;`W)O~|i0mAkf1&*4C zV31&|Jr$8TE2(>}MQ~ANV|c0GPqnz1O+C3JHEb&6mND)M_R+~Q{cdWimAI~g@jqd` zV9^EP-VqlIKYTV^d)nD;4-JgnMz>7pRSJYu?c{V(zDL7PL?`V1adO=MJqU=VQ(I|ZiZSuD8h`SIJJ31%n_?)Z zNndmz4N-1S&pe_eq*sAur!WtjxAqa`pEo`N4_|Pv03@i3Fsq38Br^cPgKI1aBD5x; zAPJcsq7ZbM7<$FHp@~x2k&|M)EBH8z~NJbaiEbzlv@CeW#PfJu+ z8iy$)`pZc~v zx@kN$gv*h+A~tNo^EYQN7F>Z#-DJw_V;(qp=#GO2%zhF#WQ1*SAk4V*lO zEWDZ^FMHOe={9hLWN9^083r0UF`qww*};*6@I8IuXMelQP<~m=-P=aLVaQ49*sy4LzVUvw2%GQUVBJtmaLxBN$0b$il(~6+ z4ry9rKpq#?Nyd0g5r___=+bLtG{3?aKX1CD*qlxNQ7Ahvt1IyH}}a-MZ^#G)d5~ zPB^GklrMR5HGbEAcCH zD*pEe1|RFxy0!V)kjZL5hn!P&m-M2C(=fUCfa?tJgF6-6Y{rkjgf$t$&xpFaiuoBOzeTE2|G;LDe z^~y~3Bl#CE#CC!IWIPNM@@;_Rt7gz?P5Vv#;qEurgReSj8aW*YP=ZtBWF4vRz9~BN z!XmGan9xDB;u%9|aY5{$A)*^onmK>*T1_d&I7cBeWj`nF=05NF931}HymdvMAD-C^ z_scO)1B=CtBHi;j!C!?L&1mg+-=Ql_cKT)~rWcD7kaBgh%ls=!5aj|gK_bYcP=*{= zv_@}Atl~Wmzjc`Br4S0{0|kUs0_9FQiU9<@n2(6I&m&39vSx!!Rj}b!`m_;Y%M`#B zVj80qG48Hj)1QbGSt-EHzhs_yga%(eLPn?KW>FKI?>%k&ioB3H457J;^{_bX`+tv# zzjAuXj?!2X?-DIU(3p%nR!sUk7f=R(2)v*oZ{CSSA`- z9MJGx80y)BE!&R7a&iNwHQg0wU2gi3gvu|fkukaOgCR9vqr*b5a~*8U)VSs0j(&wM0$;7qI_vb#(G-k9^O=i-omd1v}pis zcW1geu*(<%iE_&f8IiXqK5M(g?uGRQON0N}T(6 zx%718HU?`AxiZ6Cm1&Y{gl(4YgMUFrRil=y5Q zM(xCC@?bv|f!+*A8Ti2cK<8*x5hB3X7n>xbN6AM+_ z5&9Q(?6h~STw7_IW$3E`<#1Qw$DhukZIQ{rik!~<*O{)uSoMIxj~kEXlqge&SN-$Ydm; zz;@k4)xZe`wbxtR>tk)(dqNeO=jEig?F&k))&~E%xDhTk%F!IM6UTqo*e-_Pbn~dq zd6x1)&N{Rx{a>mNv!v8SiN#Jo8wTVN@0QA<;RVB8FB{39Grf0NN?)kD8u3hhk}9;{ zMN{PssNhpBKtNKO$m7XS&v7#gpg6@>x#2QG^~z#b64|AVR@_UzlM~9Pe|qkiUc}z>k=S>{VBYi5{Y@mDjB{hXPrv_7keZie=r1I|x@{)q z*8Ibik`gcJ$%Xb$>j3LAPnZKu`rrWNLAh;i5tGyOpeOhjO4E2^@YmImTmho_)WV27 zJ*T*R)CL^BhCR}OeUzL>t?JgRzAAQ4ETEq+NUErN-jUJTas}%RNYp@v%jp67_&Wd% z88h?Bwl&9@=4M4mpYN%9$9!_drR3p{BoI9#AcN~co)#|{NxY9hlD+kg3bLCYNmicp zMd%99(c;>n6at^&m5#XY0o=ap7)C7}UUy=2(k|{E-+`GwZOR$KDv=1p~EFD8MV^w zH0MN|Ig$chWhR2`=zk}j@w*}XE{6r@L@@gFvxuAxjVzdV9@rw3QoIYgcEx5eqLB6D zQBJ$%4b*>KV|*O>JgKWfAC4GlC8XfcbKm0e*g$ylgoKgFz6Rvo4!m0{6&ts6bd^D` z^j>gr0zxh@xh~mBLsU$9ZU0Tek!o(y1i*YO z7!4}oW%imLJZdnyw!j6}Sntvbgcu{Y>$3*+D6G1Q-|H0OZZXRz#u7$);H_LE`6!z# z0u;5Ayvyb%|FUL-{!V#!OM+yPoQT=OB=Rect!rt}nV2BkodAIEygJY^JQ^s)Suy^6 zsIWxDt<%MJ_!bMk;EcSz$3paH>Z5|K*jL$t=PVV2>q5^ggCL$i(L+T>FknbS-Uru% zcaPWsOF7Rl|Cavd?u^m9$?Zll2rh5Rq7`m?=9RGGPm}PyV!tOj|0{R@8a12mWh{PDp#D2UqyaD~ z4@Uc&L6)HBPtdMO1Osy87@QDdiGE49>+!o8;44WNWtCpPn$R+5Rhc0YCl#h$jHDk= zq8Xm2=4UZC6HxWUjvIW7_5l$$zy=7OAI2&F++`+KO5L?1F;$22DH+CjYr`WI`-NE% z`nu}QAgig1-OSvSS~2`qk58=EL>XUtAS;j+?)-QsmhHT%;dMa*5I14Z<*}okN~`0w%+IL}_U$({M^Xh3>0%Oc;tWS>pJ=QQZ}&-9atSqwNU_eKlLuIIpdiT#o+0^FmbU?j`9wJ zB%@}6T|%2+e6ZAeEt!VM*6~)vWudn-wgB(TPSIwy?!BTMMLn<7gyTUZq(#>^(i4y@ zE}(WDye`+pjdtb!vrs)x7i;@%4`fd)lHA62lNk7CWYZ`sJkwQW(x{zCemC)_%hvI? zk}^A@h4&z73k>jpv>`<5SE=1>@X(H$Gia|E2=) z%LKFLlCGa?z^g6~PJp@Hnn@N6d&Xq|fPJ|NDc%go594ybb;_|HcM2*}sq=uSVL=TU zt?R4&Fo>endd_fl+`DYWh6A&7o0H5Xzz)vpAB#9n$9ZiB7d#C2&&mm9R)s322Vw>yCi~#sIWmT<^p3&*D^t1jxVxP<@@U zNhDV;u1^d~o$dkNY~$pupx{;mV`WkYg@DYPykQJL&9e?IQ9wuHOWE_2DrO{jD1UEF30)r*q*bm z`D}eLVyJj0!NmX_Ub!n}-FzMQWjwj&D5?i*i|Sj(XheI*E-CI8obLL-V)#$=gRuzw zgGlRvufn36CnZ3c2^(Nz*x7neW}P|VZ#rJIh%J1icRDr=)3+mxQ+Hvt-7Q;L)9c_| zR53U_vErtF!B0onXWq56F<+3a&<)=@Fh7Ba+B(@+?IcJ@hR*WTA_9Xu<1t5^as8U0 zNa;G)5@WxQcdeo}>={jn2V6$4;&^7ZKJGTBmWA^PtoHs{7kKA~>ckX}|E|Fd%4i*J z(van{2N87gV2uX<#2~MSk7D+}qRtPD;Jt^wp+f6ZI8-hy!TB-;G50*lA`y#16HR}A z>pF5wbgqQxIJ5hs8=C+#B-Q6Bzr4&1uY`ZaUG*ba=%2K=fAp+V=TsRQw^cj_j$LT2 za**6^ZptO{P?7)2)}R|UEIKN>@%M`&b|cjBDRzfGQx6v)tzh<=#-<{BbRsQ}v&FeK zWsqB-Yuf6_S~s(YwKH;qyJbt8H2Zwp5VW75apYm+Q_2XM9V8ADMKYjJ*ICpi*LZr~ zPguoNfuiD+!=MonbgN0G^VWG#JaL#fV>0N%^Qkw9>B^+A8Mp(_Vs8us7rswH0Fc6l zI|YL2&f!FGcOCd;zwQ{ekF03J_fzie&_F%VZ#_>?WB<><2T+m|+_$Rb-@oY8?vCGM zaPR)%tOQdX^qoi()2U3#trKvzS)m4Xn9F&rkfHT+EuZnVs>70T{f+Bp6PUd=Gf}ze zIIcst)Dx`JWNizn9mY$kEwq@1Ic?5dzUhrxSEw<4aJ0IRe}77ZwD-E>S#Lnx_f(d| zL$o<5mH1X4HMC#a#>J{fTK1R!rf59Ho^?bAl}ISx{I!0aaAyy&Q+_t74bZCZjDU`z z)-i_QKUP$d^M(=2yi$+z7;-H6<$5c1LiqdL7$#z^+Q&Y zHYK0)GA{3ggQ@h-bhaDk13*#;z!cj~fngLWr4#SLU3iXn2nlGYr7kBM4bdoW+>UKe zU^n9~$CgxMP(ejb@Jl%a<)z2n;9Hs09C)g9f0mIC7ew-Vjh|b9XTMq5Dl5|isCiLm zlsxM|{w#Xa7MA%1<}xooWOS`N?+BB7Q_A(QGK-5~5M|m6)s4bn-zkD?QN=P(ejj4{ zAy)6~r!3REEqmViA?F=URi8n$>j}wTJ7S@QvQe559a?6je9GUQcu$p&@Hd{Qj{yjw zwzhmSV=-2&`<^PLyi>P0VLeE-*B5a1NiYHRK|m8uVy5Ak2?KOc;&;(-sZw5V0?}irMQTg-Ze=<#a%=$+Ur%U z&2{)r7X&4_m%wuw4_ros*+2^`A6I%;18!L!hRyNlB2k(xP9$+2Z=0H(vNbNis~tVs^b-7hcxw^PFp zA6>_qwwE+jvl`Mx2YRYR)$5gi5A+SWVjTjWlnA6j+9Ah#DrOt@1TM||yhdbuaeJQ< z@mnKA!RquAs(hS?{0>N=8ncQv6jjE3;PiZyafW#t7W(6si0$#>^2fbX8g>03*0Y87 ztd%JXC0~*z7shkx)wF9maz9rX*U;aiQq2k<5Fd29q2SD5LBfsasBV97bBH*vY{u>> z5vYTqDe^u=_e1OO2v910@}PKC3HD|KFS&pMZtL-rG14T74^dPnd|6h?`8%Xw1#~<1 z5Aco=SenZnG&)GVqcM6!%s1vlA9iQKOeky9khdeBj+Ou@U^Vs0j(&l9;E$dXOC zPpj})OJZ_aX_`!$xV0Vds30Aci$wwvNs!uvmlbz<920&REYEWtk%?bjv*8oi@2r;C z+{s0RAZ*o&Qdr7j_&?C23VVfeY%7H#HnrE9O(!}?vdyZ2**r@LxneW6!5Ygbu0$z2 zXkm6CLQ4b^jew2RKexm3Zzx05?F$zuj4@jx}YYHNKAp<0A0s?)`1d^6!M)y!PS>Wg<LGN9L|M7F1N%ahT{{5xT;J?N^~^?XGWCIx@93Wy@hxZ! z4Q5$C#f_`d-mo_}3soNNjq)pi>H0j2-+2d52r&GkCqvNpgv0CRgkWjln6(B-nK;Lh7(iqD4viy zh30W5TMNzI;o$RHibrc(`t;J#v;R1taBj#?2txXIT?S2M6%bO@-%VLkkI$a7@A0LJ zCpfG`uXa=Wc|}RQijL8SL?xQflzg57@5Ga%wAVYGI>^&b3{TflL4S6F1<8OaogFQu z1no8!p8q#=+Z3Y>1ur2?O4p0JLVx@CgN5*K2GPL~E@(hh{YV#4?uwL@FT0+w@93+pwjV7hl(nvvTR+`*L>cS;sGdIGHx$gxK9|&nChUeJE&P_)e#%ajuU2~ z!jggEK+{e4-nG*-6dfLsyPsn67orAwJ%4rd*(qdNT3o-s??_zG9F&E(O_4>TR3ZME z)kxK65}(`J_T*6wE&p2J0s%Q7RpZ%`fXne@sIvhX$|K2fa~&xzozS)oM%6|m*h zoVPm%JUbiD9YP`_r7B;|#tSZdmVTUSu-Et&PfPEqt!+a}*#_Z)dEu5PJg=^0k{Z3H zGz%K;J;gMO|J!8CGU8IAN0a8W(Q{UG;=-k$7km6lpb8if9M^tin$L9 z1O}0VjPKl6P_@vy_zd^U-j^KBR&S{Lgc=PN8K-o}GwnTH>!3MmbTTKztXj-JZB-wh zs=5`;zfX!QNr@Hvsa`Gc7C_$-5$tc2RYA4y8LkncACIpo7hazvZi-_g)Pc`LOpmk= zy1O=|C|m;`33`Dp|9OMkHm1F)tjQu`c?)xW23dwtf^gAvhUP&xd&n~)O!FY+2iZ8! zP4_zupA<-2neX&Z$i+4HSm!F6fN#6~RDe0(fLHXkSaRK2@vQL}Tr$}zG%mA&<7DvB z9mCJ7W(PuSqr<*hl2*`B#nE6=Q_aL#EoUSh8tMiK$OsA4jfjbYK2XvJaZPX;GzO2% z)$)RUzqbZysVY=#r+(UmmJQ1T+EdC;Tp)b5sCzxi89zEe z*F9X2{WeV5g(fH6gS&7EE@Nx@gJB%04mL`%!oU#P+gT5knLDpb6=CwKN}s8 z^k0E!2e&-cYxuXHF0>#v`&jo$9g2_j;*i-f(6I(y?31Zpjq)iy0^~?|UQE?j5syd0 z%{kJ|ks@MEoifUeo~piaY9kg|1BuwVWdCy(ah?ZZkiNemBBKEz)0sZ*fM=2HySbCK zj+zKC_yIKyq!{bTVBj_Ha~}`dgJa~HmB0zcmmHPr9Bg(XPI&S%EY}aE%yxXhjmL-z zWBgaKlbUELO@w0n7&R(MH%y5V__FfDoxn*2UgU-0RPljn#K6UE9D6Y*iYz;q(q1*9 zeq>9%lH-lh#3U+i$BVe-4A_lkG2IQtb9*d9nol1+VC#WV0B^2r{M9$kE?eXf$Z{Nf zZIwZ+Gt1%P>hG8$(u^M1ayxHbOu=+ydbPg46UmTA-8ODaT6F8bj=D-7Fp2%Hl6fsF zl{`goxJ`_&(8vB)ev&a;Q2A~hm&3kbW)8$3U`@5LcQaTmeF8-eB2WQB1Mx9TR}05K z8MoG&Pa4iFoBMZ_LH||AO&eHi~egSBa&zh zLt$F%xNURU`aG(3f(mXw6#ad*HnFNSTYP!0~HdL>A-Z+N1}w^GW1iSwL-F&Ox+9xZkh&HwH{wS?t^X8t{Wv5z&F@_o zC|GYVWcYxRArV6xc0N$sd#7HLtOtmR-oa7C9jQtg3*1uW$+u`%p!5s|W|OT?K(9*L zG*1;67h?Q6dftDbyF$!(EmjHCCk|5GHQ=h!GP*qkyOD66w}UYYxb@-f4^+FR65--x z$yxi=*(KC3j@Gg>{1bw)f-j%`Wm2Jy;u}ORwebMJ2g0nFg2|`m)lT4WZxoP zXr5m5jV2bWH{hiWy>44ZVh|OQ%VI;@hl0vM+bz&l&<>apDXTrsNyLcooB2s$q1&rz z5ZbsSS5jt6;F%7>!=QRUQFxLIX#er`M*nc8Z&?3(q=`sudhY_VbS>O3l)qSs_eKm5 z#PBDtkT7%~+L@U&4EtL{+W2AX$rI~Km>^KrcE;MqpC@sdBqg%>IO%yB^Xkxh6SJup zVHgjJWlD?dnyev&0b>yoX-1CzMR5;o42l&Z65;JfTmE6o3yM!R+}b31=_j^~M>yMm zzH7b*OOomsQ)F9^)bV^7Q8f72o*p@8!*h8*?&k0GDM@K)bRUXrz#ZipyRVoZf=JC9 z;jJVQ|AT}kH5-})u@Kt$&HObY!w^SOly)d~uzTj;njO_oAdu5v_liC)VDU-}TmEI* zo-hGWy=GJ=FuhQlsy7@GjHQ(eSD{f|L%@hjmuawe5NmX$lq~d0{~zZQzH9zCw=zD{U; zW;cdN_o_hyHK1&Eljm8qL}0W>R({kuOc1ner@~SK(fP35tY?&x{8F~$Q{n^I#U^90 zOLBV9-$Ml{PEU9cI>&qvixgFm0CLCB|JP?Ej_YWSZX<@vLSMz;IFVDjKfk)B(uw+- zjB(N?bFmt@>JuW9sh`S!g~K5)p1>=v=DHollMKu#vy`{&+YT}!Ww3^0g~5zdN{SEV z%j!_I0xQnefB^UzxAMiL7C2L23kUo8NSP%o^g8@%sP^Xh@fi%oGoebDf>4#FqZeQZ zY|1C3C~GN#ns}V>80H8MUf(p&=>z5&=A~Xr<0#OpEx`>8NE}I-v<*LkXOx&V7O4xL zVs9;v;(F{N*L4j8+yib92V$xEHqoss;2bvEPss&?D6j^X@APF zlQJA$EK8ETiZ9U07LHmwUOK3#7P+!;qZ|@nW6?&i@pIx85 ze z@X+fXn0sD6OAE=X%Md1*ZI3yLma{ij7n%Y$qpZs{25U;I|7ykI43Nz4w%I<6%S!?p z|B1y5k?iDAG}RktcPYWc`7wsPPze+%_Y!X}fT#3sL3y%6yrDuNkujl2$0{o&KQe7#_6eUQrQr5pIK=n}ySznhjOWOs4A?_32J?*WFsk}#}KzqI(J8Dd^V?s`Fo_Uz{F&HU!AZ3bAs+^odVp7DtX~bkY zsuAQ1qkdjpXSSjlYezgfyoFpWG^c9nbbR<=aKNdCsQkM3UBvuXwq@ppMFBKA^RRh5 zGHfjl1)cxBV0cixmkM_k#*iPj9nN^2K$tt89j7f7_Pb0x%YE!>5zomTn zh^dh|+~Uo3<lB_;E|Nl*cwypNUe5UQk8e1=;0imB-lXIOqP+910F zd|!T&;T+I2)HJ+*pK*4XJsc{gZNuyTPip$ADO zCESKm5jn|J+`v*0=rUdO{`PKDDdRvEdPQcnwOmXQ=m7Vh$WZ&jTIxhR5TQnEju_Q( zXFw3}3EYOL@FDlZ(sBO;5H4wlXkBgk5YJ=2CqO!tsJ=K5x{WN*fbFx>XlBOwGBYMN2#7n@ZlXs!W zZqc{GBR?60R}v4IqCWp>lmpotWJAO%M!j+higIhda?nuV4OCtHZ5-6ux!)d2Ni&n% z#snR+8>G^X5=w>^U3e8G;u{2!@~Q@ccp>S~3*CuSZz=@8wD@k3E=#zwLi_zpZBREd z7Jn-=Mh#=`3tXIu#X&uNyO7I!3$3nhQo`!aro^Eu3FAdJ`~`@ZyNpY%;K;KSF6y*v z62Yl4z)a$Z4Fk&iSaLWS zQD9T2#Jx*$v|1c{pxnpjw~@rn{0>pYmZ)LFD!zOzg0x@CsvTciLt^`TsoFtuW0CMe zd7zs{zT+k+*$67t@budR2fjqr&M?ssfU3Mjxdb?~wg3?jh>Q{lXoy)0p8)^pvUwlp z+}3WiNn4`02>%gAh5$enKBU8puOK{&N6%aFAEQpP`n>yWZayt5#v6jLPS~b+X zSRut^6_-bm=%<3>6jU4n!)x3W*v&fiAn;f+%2(<(=J)GLASQ$oCDTmj5JkrJ1?_;bq$`^5}FDZN$fqCCes|-o;Vgh4wm_bQ=?4 zhQZ*?>TyrJrJz=h}j0IWn3pgN$yD7r;9WitS0m&MI`kNd6!z@RCsXUR#w|17UWbO1?2?oCCnlAB@1Be7W zpTnf|&=?9ghl0u#6(HPE70BveRUuoxEnHsP^%fnEJF}q#sS)bBc`oTv@$sT#;{pTA zYas+VOM%HyRd})hYB3kcZcZZ0!GX-;dt#w>JVjV||vAV^$>2DL%h)TaXH| z{NHZy=(BgW^Q(PSh&+a^m>+iW=6>t0=^r&^zo~c)kqstv z6R+hH2z#uGg7f3l_pW@wHzw>hxPX6KTN6yIfvu!t`)2b}2m zh;>P>W=L0R%y2Dm%1o4fEXlUHHrdA=87NE1>m7D)+{YDqYLbBbO>Y?@sfP0mB+!(Y zotyU$r&i{~n#l2zf70;+FZwQMoV*y0SBzp!gWFJ$Z2{OqoRnZ>`~uqBPI2a8Wht!f=npM1G4+0{xb5 zu5N!eLQ}YlJ(L<9wvGHr-Aj_q%s;Uf2&6iLpfhoTp+qTJSoG}B4~W?vca9l;nz9-g6f_YH}pJX zUj8T$YC&HWddCM03Zpd{Wf-~yb&x5g937w3Y}Zb{QE@|EQje=#CA)~!l1WE{xuqvbU0RXx8n-RF|F|KBCOP6V*0{znBqYY0M1nijXK9Ap%PdtpE2qV>K919}dYE|Edb?^@gs-}vh1}KsPSViMXze@$ zA3E;I(7S6vaLwEhtL@>fC&YJnum-JrQSK6AR7c8o@krL6)`T-N%7plyBhphFuCqgh z8ptp=cz6}kJMNo63!{0qQ{F3*I}mS8D)QUhLDzS5yC$zp#`p76goMfK_s!6Q+K4%` z*sAdIy#{PFoE(93RG73p;41(9JNQVgK~+*W9;ko0S2u1X=4O#X+xU>gY9V1548Dm> z1PiLf4>1l{A@bt-^V%MF{9tcON2cGlm?g@*5YxPWsuJrgwl?o*JNE3W2kpVknv4%- zA1N0HI;5{CfYfX0HwqKFz79LlYDzAJYhtIL8bZL5Via0- zeoApPRh(+<9Y~}_jA{kF@-gY6nl8w`M_aaBVp6jA%PGdsW1^UsEFCg#UlufUEIxSp zE0Z|f0TI!Ou%K_5g)9c|{f-hUH989y@IYk`ETZF%#pRfCw5p#W@emjFJoekSLae^Oa z$D-TBaA(S&3$LE=@Qz+UCYxXXi@ZK3o-M#?K<8mwwE^d+vplk4^K|pgxhX^+UDUUf za^n)pG2$xNzaG+HRx4l*PmNw(1NefOjq18+^;cM;ND&Qo{JXGt(fwiG*nIXN-g8{b z3xBBlM{e>P{pZA5qBjezfdjX^FMAX&9_3l2CUDPUH)>I79v*5IR{T*pqydNjm;It5 zbZm)6Q|$`XCwH~fphEF>V=imY?mv1yUA+0WN_5$n!CLDx3NDK1H@~;`Td~VhxaM0v zhx605HfS%hej0zkY$PBL$z34*iHoic=&gyU0rL^*UBGQHRzbhBl;|piPc4@-si&2u z-DuQ|l!?;Okj~n0#)@S27KcOa%SNGW8K1MG57**Jlq#BbB~P?Qj1Od)sNBbdnD(e-?s9Ws3?H zqAZZ7cuq^iZd#z-Rwy0AHCfD~jF(Kh|EaF)FOd#9qfNH}DPS6gQ{KrfNiGkN6<<{W zE1;hFSh+%XN(#-O9?7JpoMrJuCXcz_bRv?vO15|p{IP{pVT~FEs=;% z42?6xGEgYUN%N|oMK!iokXG{dH4c{cP5(hcc@U;4VQuT;1>2=1;J{W!>cnNqXtD1k z^;HUQP|vhcNS_LigH*epG>2VSK(j1$=BC+J25c#M1V`Ki<7=bh3~o8cz@SW^G1pcu zrZu#!PWFzMcSFSZPOo!_b>#As%+Z)AGP=1FKy6rOHmE&XV)^K4+${natF*)tX17*> zNpCFij}t2hv3{ zZc+oc%b)!YU00D0bo<$Ze^SI=jK{`lxm`Q=bbGU78=Hf3ip@eXO4IL zW*W8=gQf59>tE_DajKbUwQ!D)KztE8`!Vh-CAwdhh4k@KG7R<2G38cj6SeB9jYs06 zcB!$r(8%rF`>yd(TaHdXf#@- zCs0gV6|(1Kf$zJ|5tJsdmS;JR2mJRKCPo9EvKBgaw`?Y?fUhP{pCRB08TXLb z#x_z~yr3;KASbYhHpg^cTlW%+doM5ctoqKIQ5Iinsxf1Akg^+3sl4r?6rUL8`-6pb zJDZ4uH6b8n#n=483ync^kpV9#oKQyHyq|_YEejoIyg07>^1w(eQo{y)!MMAv z#5TK3ebTWu>GilS&AB#B{{n05f#98EKButJ?9(iheRLcP)^sr4c#8zVmBJ$--d$Mr z7DzUHOs`98!ic71wN9lD7Xv6T9-CWWn*JrDPfy(+p@vtJnq%?*7iTb-&x9yTffmic zWWNaGW!WKWq;)F?Z%vR4CY@n3`DQWhbKxtJMX)0{T5Fj^?eVh`&u{$)?14<ltrM@WPRIv>f^&e^^>@JT@1oW{&T`MK}V8$V3!a8!LZpe1VARe zxQyB0S`k5kc=;{*kCwYV^H^PFJUC?yQ)>hvY%dYMKZ7TEz5V+>NPw2%&4wDhq6v|A zr5?f198;puT~?mEUR7t7?ckRnGumP-D{Yd6pzix&+yV2FX(I{RjZN>Sh;Oc5v!DA>p#NSI?a2~UGJu~rov zbME0D5h=@8-2w0@AE6d;;>Jc-iW@H~bkGkDRLd+hvMCsHw^Y9bq?dY?h+ZgXSUSRV z!%DwF6u4QAy^$=z9Vxj-LGW#cPrACNWK@7IMBtLAqK`$xEjW`-KsPN|#F=Zd7a@(& z)n_}dP1IN4^9(FmkX3T<`c5MXhXi!00wPfIoT^#Kux~g2O7g;?t5dD(WepO)G$P{OIC$}5da_g`_ zUAgp~L>xPhv}QB$w2W?{1!-ak&lIb;%+gkp9r-DlQaXZx5@+7)mBsP6~Fr zg@Mb2)vONK&rX`WQy-ZXvmnf*wIXf=yt-srilYxp{1g4BXMBE3EQ%c8nuy4a4R{nh z1DJx`hS z9Eahpo}D0(ocN093vyImtetY@=GL6fPtd$tzwl-rf>pdM(m3!tSDLvF#5wzCGv$_Z zqTKNM6tFHt?-N1Z!ifXX{36z4^C$6jsyD=#LHjKZx$#%bd>&1~r)5cGO-w$bcZ6Zf!WR18jb9bJNazBbnEae30alfHJ4L{lI;OH$ zqzb~FDF?Ld1FKtX9c45R%JB^-1+=98k|dZQQAW+yYnD2-xj#~}eWH$+%&4e>Z3^%r z3|{alKjNnS#ecsD6i{YLGYzogo^qOA@etIKlx7F*@LvrJe`^x>ZzKEF6TOA}sVU%t zL{_SS@A;Kt#-Z@uj#w0XmHDhn1D31Ch;NPsC!#w0UT@ z_sofk{<8&ANIHUqE8DA0Bw(dB{N{9!zlA2F+qPY*oQWCnyZFx4-jvF&iY&=M@qwMf zwD=|0_gc4@lWF6GZ>c5agnoL4u-H)rhrw)58{vcdE(rcmIpw9En#z)%5{Hup^e(mr zKm$Eg+zLki06HYMy>Jv*J~_8f4_S0IGOC25P-B>CLbXOSCtoFomD>n#7W_`kysjmw zLsO+@CHUBs+A1Teh}`}Nd^WT6!o`ETrmXEmad&-|S?z;qSNq)$q~M?H;6bhpnT>GE znP~(vSqbV`*E3-8H76X1BT{5}NiJn|nGo$)QwZ64UZ&fJslqOUlcJO`{$dyQVS4fm znmi?wP@z?~LVU#|@I`@e9n4gPEq<;v2+_a}Bm)fzZS;RxZIS$< z#^WQTc={Krq0K@NZm5j!`rb<(M9^ts5Hv9;Nc|mPPJyn`U7p_f%F7Z@S`PaPW&Qro zKhT|izLMQ%Zlb*Rz*>I)^P4`?>v4toX!Jzi?}YLVoMDO+g=Q|?EUC{# zar64a=&dKvyGCaWvWpzTM@^MGT0)BC*L1^}Xb?+lxR9xgJ=Lr#X)<33V;e8tl$OFh z(mW>qssp!G8aZ-|-GK$M0^qsUr>@sZWf$0|J=FMsOn&Gx{^EY9l>a0C@me!BXMF7; z!G4)ZAWtOcVz&<7d_?yDc4A=8a=TTyzz2Dr8R0|Z;(>Mwb=F9O2~bbUea}5;wwBZnxbiyAmYU=# z%1rs#uk3%Grt1USB3Bx1BQk9s+T9{E4mzy|nw?^3H9WfKt>{vdr{1?w)48eLLVwUw z)w(kxh+5fE#e#-HKxjAd1J^Ub%WO1}0g0T?HR8~KblokgJxbH|Hz(fy!o1qLMp7*g z*lv~d5IQ3HiXoZy3J9>D{OefZ4ucTsbJOw}TRd&4|~qBR0v zpf4QS&_W131xUp_d#HV)-g`2V zv#B|ek-=MbMhp~V_xT`wt($RI-5h}e8GMxp(t3x^(5JU3bBFJr>a=nRw3;K4BvB^f zr2W*IDW3VH|Jdvq61|38#_ey^IPHtKNZiv1{f!#R{MW#O?*C zi3`4LP|LqB@drH)B40ZcCl5S*f{meNa4smd0{Cl4y34XL&K$$V4psSbia~gd5XH>j zn_^7uMw6V%JiY-}Ji^2v^+i>GMopG|*d_l$UJ#-@M8KRKpB0(0=%-i>y_5ZX7NU0< zdZ+YD8^)Jm+W_8&K~rMKG?40_F*%T!pyLlXqNUJ_i4Bz484(y=+Au4kxC?NDtt0Th zIj)YSGyXcpnRXYL8J#jv4RCdLJx}`GvR4DVsZvNW93N@0XQ7%w23H=MNb@2Kz+iyd zweFY(C9%8wwMaZ&zSZbJ<|*aSYX(zeX~Cu;wZS|+nCrE6k#8C5=%|79(5OXUl%Br! zprQ~!T$^0nOjGMY;@}I`VGsR=&*uK_oe&*>dMHj5w4nD;(UFgvIfY#|Rs^q~ zM-30bV#^j^#)OS=3v*(dFhPx=sI!`y@SGvXHoJ80Vk+FDv=G0NdKQyEHQoP#3_?PF zPxLKrFbllK2bKB}D8-tAY?D9rF_8(yXF)%GG|?sTOzg+N7H`(4>m+{TH6>qnn%XAB z$3z6A8zA+s_Ddpc7dW~mLR^{VJP;g{!Jfi}{@5TmV2I;L4>*y~H3icq9)&_ILNDXZ zV;bA%J1v^qB0iZkisv4;13kh$Z++!`m{Po5kb3gYPZZvvclo?3>Xle*HZa#WtH%wZ zMT(k>$!$LNgl$#+;5K7U`-r1>K~`eo*q|2-!EPjVc7`E$2rCJxl%=hW0SioDK{z{% z-n(7exy%C?a2E@5@=vc)G?Xe(?5ayZOt6c6v$!F?b^8F8PEiF&-s?L36=R&n8fmS6 zbUS3g)8MX%#<)D^?xSacw=rtQ*X-%Yrv+B3Kq)V@2(-xpQV~bw0G7YYm&a(At|#QG zELR{CMsA@johW%JdO5PC5d5t8UlS1l&bFH~2V~ORbE}Hf)(b@3C&fWQUf} zvq1=#@O4n1Wa*zfa6q|wyh`>@O}jP!Rqp3gwaijSF<{=R=sh<-b%rj>(=f;JKv7>D zHh5N;aS+x-kN0;3z8}=6-mGjrxX?A3#FB-PoZ_|?v|4`>*r(#sFWXy89#mc);_a*D z4E8{+d>jES5<-VAt4$#u1Nn?C|8gY8A;%u(ex27h+U%t=rK}A-quHmqezudv*c8pR zF&Iuga*yU4pcgkn4-1ziQ1ny{8uBvR>2)1FM}cm1SK1v+4{FQiHI|Ioa69a|I1q3{ z_KZ&S3F$wy^^kJi2wZo{=3i6YMz!;otIXv2D1 z?-|}4#hVuSVm06ck@4cAIhK{c5(|_HD?=%l2RB)yj;E>=ch%U#&XcXQpA099djd?b zZA#yK;7(%}%WrM;A(NwP__Ve674(4Wj9(im9%u+C0-IJ?OHHCFi7TMlaZ zHO+9dIS~mL#RY_}iC_5ayZ&tEIGW`qe2z7Y9N`r7^-8#oN&bhd{yTtFuponUk zrh;wUT%29zH_jZz3y~_(FYv#T+~n;ZQziAQ+H0y%jF+w&P5ysp%yiFLwdd{axPQGC zL$P;`Xzx`I-2L-VP~C0v-l_|q_I4b%k^m4!z4miX#wgu|^+ftb3!E2hNB10tUZCwi z%3dB*c$8T!bqAnVeWoedJQFyy+3x_~WRI32dC9@-CMB0d5d`2A5Oudl@l0-8wYN{^ zlJ&@gX?kqwm)KVD;T_OtkL0;EDX7-uu&jI(q@Yt9fPoK5TmLykg+BrCS34anvSFqc z(iO2yrWx9oeHFhh+d3xDPHvvAGPjg87j~PC< zG0GI}X|4$9NqV0uG&NkH6rYeu;U0e5CvWh1omQ*q`OPX8MbInq2Wn5TFe8KdtW-%U zWmf%3sgP%%7PmcX^oS|qt8``&Pw72_UO54(I*LS4!teTIvh1yijCXb{F188rM?e(Z zg-Xl-QlQ`FA#jQQZ|!Ag4Nf+O50m!OqGYHF0^GDGA{r05{l@>psbxIr2I|_Ih|WBF zFc)eDBymug9JDD+pN*7cG%Ai^Y^k0F*z4fCM@CnUlUjJRq&+OQ%1TG6h2r60P{Xo4@551j^GXgSCd#0g=T$J? z9FKKFW%G|*_@9_{Gp?!T)ed58H1>IEI4ciRHu3(ap9X<=ly_jw!x<#KB>qApu@Aaip19K92`AhNcBbZCCM8_ZToQT^hkU;GfrtCP(MF z&1nU^K_>mVt|4`26QqNnwXdu+(n{#Y@vk~+TtD=V5(|eG1_Glg1W;38B!xzAF6Uh$ zPkdyW`pXDeq^rsSy+Nh+PEN8r^?_(zP21!=ju;ammjcgL0p5+EuB$D^^gr8p*j$Lq z2q6Ja^Yk)IF+pL-&iR&}MV?FCns3kL2)2D_y73E@cZCgz`fOOfAR2sx+KUxlEm3ix?c(it&C z2&|XFJd+=p_}6t!SjC{c(0z%2S8AL#N$_yD+ie}nkRC$8vaMkH&w})r_U~BTn(gU8 ztHT*p&9+|eCzCbf1V@*+tz)z32NLbP@U?um$EF9T?)ZQp;yMT=ynZWolsB05T6wgO zvQ?~ynO(}|eJl37jwkC5@A*+JD+C(R^TqRkNAPaYt;R-QO=h|4b?gWF4PG+B0KScT$M4&6)Q(`9irE919=s%pu3+fm2 zl1dlJ&U~hoF&fW&z+pAVB|W>L7-SEoZ9oHDshST#71!Fj(p#z$VXG8e`eol%y>8xq zJm*9XbqQyck)$Ow0y(8fg{44$A}JUEWKtVY(uB3SwE00c(caZ^cOS=2(`#|v|CRM` z6OT!@(Ik5U)Ov}m_u8TTw(Y4FfxdqW>QA0%6ybeuF1G>kZ}Aym9R4!o{erK)`>Oo` z`35rOM0BuOU5CQ;{@i!|MEH|DAVjnK=+35G3JR@*OdIL*wU|)MgidRQ9NDJ?i{e^v zPS1==hYU=DHPODLyVim0O2_;@d!zkMUD(Mco?r6;bqL>>A?McpdKd*L8Z^7j;1g<` zBkyD(28jrcuoa1kQt>(?S$DG)#;{@SCEk#!jDr8}Opnx&bOvDm_agrLo4$PMplBp- zJw}Afba+)at`~o+2E-l41%1ECl#tA?OsJ>yG!G5;2wIu89bBiL%{1E|AMdwHhB=3J z$>%%?i6tMY%RCPCh~OdptNK1@l;N~y+=hnjoF;&et-$R@OMKtME`OmZ-q05pbGkb{k46XMv-5upZuwv z?0KahDFYZ3K>Vo&`f1f2BJvcAnyKvt?wj;R zYKg_GmbPRuA*|r!1nY=pt~8|29#akcUcVdRDBCEp+%zm3KL3i2?HYZ0zLnVhCGuR(lka zo$V)O3cy=2He_PeaCT<=<{!>$==HN8J^jk}|0KALqJ62TC&Y|tnnYqoH#0RJb?c0X zOZLR1*)NU!V7w3YaRnHiFtE)_R}Tsg`{;DCbf}FS8ZYjR*AF)~Zp72|o7?gQi2~R9 z%DdWVEz>Ly)(|05WPg=JUIQ0qvKIU#4Xbt+fhzYQ<_@Y_-_*;S!TW|Jrq3D`)OV4rK!B3ip2?8Bsgd5 zf0|ljOP|ZTWHr5)XHh*B%3U(=l=ApPj)+4%>6kaQWzX^vNv7>xbHEMv{0aB`D2`b< zoLbWwgla$I^#Nt2)|j5VI93}P2A~W5^&oXinRUh{eY!g35S&8u$~{iv!t?+`h`2Px zAASfUA;9nm#A${bBhha%22m2!=uC?JtmDuNIxlEy&|9C=f!{3p?jb z@XiXEek{!S^D)kT)avK`Opkx0ZnX<$O6Urg*4zx4q?q}QVWmeOZMNyCvkHDoa#kVK zF}e$%E2S^W0@j>aS-`o@P(!0wS*Tc}X{rj{<6O83pc&Cz!l-^lP$kk+9BvppxD^M2 z{B{|)-w$$}DsQpKtt>D76epkya@@G(2qUVKg=T+c_XGd3)#+ohD`Y;#H7vCnpC+q6 z9%_U}(x=+0vZ|=B3hA`0!q{tWOl7;V;J5I8R4is%X6TXUJ$%=KjEP>>+~`?(B(`o% z-E-CA=#O$~Ey0-{D|{>9c#trV;8sjp0g!Cy0Devhm6trhEL31bxKG+Of7xqW0A3X< z&rr?+ICZAQ39%KoTueoaxl`w!z^cJ{0zsTY50)yBQK{@J=py&O-q;)_qt!PCFaW#(u9QC(jTi9LEw-HuxXyxK|=SISaQ zD83hcBw7s2ZRtz2vWgFoo+`gVAgw+%7DuhUwAsz_($t6w01Wv;0giomMZX5GNpK*^ z>ri+fC}qVS7V{^1cMj|P_;whzASlo7cfi5*O^*`QPbtcCyf+V}ksU@W^Htgrp&q3% z@*hM3&wx%KXo|PpNWhE`R+mE9*wS_YcBY5ESJo!|Jc739MHu1e{^x+;{|w>DTMHn> zbisITv6Z_CLLK?Kw>OqFZl8w=C}+zvZBqj_w@?D!p(7oT2S}d3RhJY5>Yi8w9)N(- zNOb0B!F9;hvQrRf@KYlT3TS$L$SlLRm9b9>)(v|oY_@w0ZvVp4tRct1j%fZIRc38n z<9KV$8TT9#2n>{76XcBfYhgHam{exqyFn27t2T@^1R{zl(TTpnZE}Ybrn8(EPoRvGJ`4|is z`4*-xYP7-D_W&PjgHC0so0%0j`uHK)LUJ8YP~jW0Fcnkamd%)kR zc>K^=xRCS{Cn8*g05tqZR$piMg*;p2yQYv#zF4Q#o@nP1h6flmB4&?Y;nEE{3n?Plleo<$>q)UH=C3UY~n0zM7KXLQOt| z?0ZuT@c}I_6l-z(2XpYc#`cNWlG$yN{-L_O`KG# z+}fJf;$v<^4|2>z;5wu`SX0j;C;$sG#pBx-%ex|P)hlvZp^~vcZHx9H-{y6?6w}T} zzD^$24&gMBq-{*($rWNn#PSqbiBW!r0IF$CCJe4bjxmgoA##_csLyk>h1#UVMvxbI5CD4TB_Wya?mI z_3ywd4HD(F4>EtFDfqGc=(#(m>>0w2{i}nJL!6wFQy7jR-}or0RQK~w?&H96FA#Gw zXmK`#ft)awvk%umCru(AMHWgutNx)_UWkGd=y*)x85FfYFoy7f%Zf%U3@8r5q~|AA zS_Nj+lxn1-5@4wu@)YgdQj4^U?1U+-{^&3ny*pHce>rhC{fL2!( zI#MS1)l0>}s_ln&;QbQ~=sd0>2a*Ae1ty0KA}no#V%l~`S2KuSXCjy!@{2#Lomo36 z?f?2JV)l~z4jJH44Ni_Q+r;6fpV_sX=OA#SCQKvarv^V@UF;lx>DM#WgerK4$33g} z@@3%iJ2kNgQLr7-ni8-1rYcGuN=@&1SkX*}%LZzEPLH{uUBSO_I&a9V7?>1+qAPc>@lUewCFW$4haZNRk?pY749@V5An*h}AmY;- zqr~Y>#(#tfyQ$d11#87E^2OA*I3FvyM72GfG(HiizzQi0VpPH8B%G2vJC}*SEa#kp z7~1ueYQOTHF77oA9AdlMb@gx9n;DZvvVXK)DUn4CniPETW(tP@X&vC3J^&DSh(d`p zxb2C&JlZ;sf4hZ?d*(BPsGi^$lpNvNR^f*EwdQUJ_JCV6hERr^T@nFKw^Dx0)b=5R zTyQc1j(Q`|w6NYn_bDE@)m}@DS#BYWizwSxK_?4y0#3RyYSRFz~oa7t&J~v^ zwr$(Sn|tpc@4b%biZAPA$H|kKQBjqB>dPogFv&)eF=*b}R{7mNy1GIu(}#i_kR+Cj zs}&LwO6^VMI-+c6vUk%6Hf}7_fw87u2ks;~%r6o5M1ccfnjY2w73%8YK>FI!%AzPU zSfs12Iv>pLH1CLRRwKmL&5@HOESR~;<2ajsWN#6LxgYv8C0Z3$hs{f5##Zs4@~!jO zFL0sd@g<+%B^?NQjIpw0drk4*_*kDOn7j3%#ARLYxpgZ4a@vebKF$rz=z^Q7)cPGL zv~v)Crxb{y{6bOx?U4t86Ayeu>h74uJ=kIsX zPL2?t!rMp4HS<}oP-M6!`lk#EuQP*`v6udk`bzo{zy${bl14Ejacb>fpOi-!c3A~U z00vkV0n#K1R6<%3fk9p<;TQO8UsFyHC_tQ%O@60+Us&Kfu%$x~=}F3>hPU$TK+PNl zJDryL`J&nkZCoNV$&I|g@eYVOX;QX<9LQb%+zC+_Mt6``SEMgbVE;j#Ikb5MT@vuT zc2le_O?ibjBk$747jXj$64(g|ldeX-G&JcFUC84fUS9;hq}hqKUG9#}eAx+*=Xl0- z5u$WzvftqU*W=J`VM4T9`H%oyjURI_aW%8bYsa z7Hrm{U2C=Zar#3oMsK?3teJjM1tl_oYk7d1rt&v9V(im>sE%aj1v5p&3k5s6uaazF zT>a?ckSspXC2t3hv~mEKk|1ZvTHE{JuiiYuv#<-JR|HNE~J3pSEo%4z3L(vDrK> zE<^Sf(sd(96z;ohFVL* z4vhsn1Kz6MA|GmBEQ~^`r02qrs?mGwX4g(oyk(#+UoPs~gLBNmJuv#4I_WW8gm*5* zfilvDW=Xjn^jgQD?FZzzw$a6u`;NlOGs2N&!SW zx(dY?VIEe3E|Fy}H15$NGzCQ)U-`?qR%H`%Y#0@rB$=QKePx&X;1`j-Y~rYr_yW%; zk13JWwD?a)v#y&y$tdV9>vkFU3mDsX*^2U%3a=LYd^=z*T^#LvC-t(-A}}v- z4)%s}EAR9?>$VaJD*ACwi8OE&V}oRx8Q#ymB5bqNH;LeSj}F}hI=BZLGcY@~EKVFPG`ym6y@Qu;sG z)Fb{feiWQL*KkBNyZ`*YRMpvvk1W7ktsA$@?k@h!@pW5oQxJ?h4^ zZ8||_Zh>_m)<%)XelF~>c~tPAdoTU~=bwP-qwlP&sBboWXJi68Z~kcfvW5SWvQhxi zfK6|pW@XNkjHuXr1+o}mtryrx95y&rLUQPT_)J2yP3OU&%n~ufozq`d1ACm9lEV;( z1anY@nRa=T6zfG;4VQJ(>zNUXHb$P(A9_bp+tt|Ujo~Z4nKf!{88Tn;%*2_d308;e zIFK-H=^AM~O}Ifb8uQWbATW_fv}a|Dtj!SBPZAZmik3&xQZfo|od+hR`|y`DtZlP2 z9nf19*L!BWc+}luWxoHZNTqD%!I5J z`WC4%o(f3@MM{L)^NC`~I-AhVrt8E0Z8g0DSeTK~Hph{Q_Lp{s;UyYIx+_gNFA!hA z-Ma^7s~9Y!G!*@L>yX7t!V>lPmSAPuer9q@N2P2%JgWPR9`%&_Xs3piPXgI7>?ulxP>jJn;WejsT&6TJtaX(l}W!jOYBGtQOlO=XRJ?w#B-$n&SYl-F2}9dyv}@&wE~*$QBCCHvmEceCi5x6xGpx1Uo)52?7-)mcK7T~ z#!I)Q=a`3_Ovkn1eL8v$Gg^v&Y6stKAMhrqvKu5D2OX=L9~)(T5;cDmr6io3;fwE~ zvGJFX_x`~ee|vtU({(FSP0gh4OSXoe2*rNk|J8nlq_d{!rM$+D4#Igp7<=Gi;rP~6 z3X!`leSq~n*~3X9s&_N!?>T6ee)&AcbdQ6H2GL?ZCFq4kMeSa2Uvv*B{kT@8j%ZpxlAyHFo_Z1qtnjF%y8 zcoL=@!k){*8zcCx(}XEkixY-+woimoq#?Psc?}{hwd~LCwS^f`ql}L27d;OPT$i(X z)I4~DfOQtb#jO$J&G+aedx9;wU+mZg`7=6(n^%453pB0d+Y1A|xm#q;a;hRFXsk-j zD{Hm{6P8@|$ON97u?a|afA9^!1Mxw+ZURZwf#g+Q2GW|@F(mVv=VpZw)g>4sB5N-; zT>;iZ2hoW&NXevk#BEu%5Cf=AdTGl#F#LLZO`{@K9rba;dUtU(iJ+yHJVI1bISPSX z+FV&yNSw^%F*+6WCS)97yyzFLd}?;NF3j^G!mnkM4VFhilY91E0ntRwS~)b$6M2(0Ht950`8FxRiqqJ`hUB95kc zbwCZrKGGFZP054sNxAGY*Lwpge+U=?1}#RcL_m42dss^@b(aRIuMBQyQZ^`K>rHHkLOBE8eznC;X<62C%*)03D@>+85QlU9h-l;0;Sh;#O|eL|1sgB zq1X${?(1+#%t34H5<#-Rgi8;vIEX&v=*~jO4b?Z~h#Z{J{QjFS^NAXUQl7Jype< zw7+b9TC=)AQxwQ5-DSni->|Jd)Lt|X;htL9{F%r^6K@HdIpT zz61w9JYB)Ti7Is(T`()OY}{O!27UgF_h>|Dn1BiS(Hx*hxiHXLX@VPGv;2NQ7Nkwh(l9`Fwne(%O90Ule2Kk!N10Vg z^ffV>e(1+q)c9<>rH7N2=b1RgcTrAs(I(d}tZN!blciGxsa;-DlTUNJ3M$Ch9QPqs zeE)l}q~w(1@@q9C$}3&7nRZO=-NVZwr0AxI<5YK%?!~-g-Uv5JKB8gNSq-F1ld->v zn%RQy_*4sI(3@SI%V*-vcH_Jg#8}m1{6V?zKFR{_u(PaeY$7QINfzD3BIHJhil{53 z!d|7yEEk%*_Y-ixn6GEkN?(>fhmg5$qKr_LrS^p=W~|~gXGt|`Un(NT);T387MF#) z3oE>5@zc#M^R}^e^WK{AiHs=6wtX^yi$5dc&$VwX1D2b7YB#dcRH2Ja>`skNxZqb* zo={wLW1;0qQ0*c#J+*rxQjTGaZHye99E|m?|ATA|EMOSvnK=mQ3I7ARxnTfG?smq6 z01;aoCm~};LkDv^CtC-Y|H?A@);}YvVj7BKBGgjmHd5vW#tu&AHpWTc+W+Y@Gco=A+)Up=(b$QQ0`LbQ01yNS z0fYe}08xM#KpY?ekOW8pqyaJjS%4fs0iXy_0w@Di0IC3WfIdLq+RoU)QQyW0pzr8p z>|pL_3D9=}7yu0P4J{q5^c~H9kORQLLEq5W%Gl&*J zhPGC=Ha|yeYkhzbz!>n~r2&lXo%O8%#%_jI`qlswfQhd8&({iIV(wxLFtK%Z0GI+y zf5P!&2EYtp=5A+ZYy&U{SO6>mRsbtwM@N7)z}no#*%4p^u=(*dz!qTpbF>54={p$P z{MU^CqW>B3vn+F4BY>UNkG?&?-r3mE$^6GA2Y@5M(b(Gje-=8Ly8-^UN+*DmnS-%0 zz{%AX;0$oKG5Ya}p{;{4zy;t6a09plJOCcX4z`s4i>iqEPdt9Ih5aX66kvFH|Gxxc zq5uCSkd(2FsgoH4AqPDN4B&qPBOx;f3)@fp{wFg1C#wI0KLZ?Wtc3sh{7hnQ_2Y)0 z0F6U@pFR1jEL5uZjy_YHeu& z`QqD3PWSXZ=nBrsslKubQu0MB18)b0lfJU5;rS6#qIYbi4+kdqNpiM_@M5d&7YE5d zy3x1Rw}nqQ2qafm-&7o++yJ=-@|6U=V_*s51XcoqXPx=;PXf@q?}m#FMw1B;v?w7` zu7T;IEb}>bnp@o877G(?EbgIxg6*QP3Gjc{Odnz zepkcX&in2sOEXIlxx^RD%kP6vTL{pK6Fz5lQ0Xth&lJVJsad!e*@o8odLBfQ{q6;+ zZ({>HM&lZA&U3l`vX25dJ$(a%qIb-?&tI$GQMlhCQ@$k2-Er@_BNGp{M#b-tYG1C$ zq*@h~-#jVb<*sEw=BE9=FdyAm!K@fd_}_e)-*^?k4fIT|5OQHFtLmS&IY9}5Kb_Tt zM*CJ@a+z`9vChC&%7$a3x%1Fut#7c-WS|9ZJ(Ru{2jf zvND0Jq`qB%zs$7^v^5K^bx`6KXZQHZCf6F z*C(?%xir{8nlb%cbQr!-U#1^*UE98?v%>2Ove4!F`wntWzkJbzg)TOLbslgltbjb0 ze5nrfj*KAe?Cak?WZP;Z3P@&_Ubn0J_=-N3*B172hJgI9_zhPU$+!%+2*(>HoQ^dr zHu9huCRGfe>{Xh3qmjqyLlj|gCizJ^$s|y)S3Dix*xBPUAv1|#RHxb0ucMxvYQ0HT zTl5Un&eC}d)utE`UHHiuB%*T_ATP>W`}NJaS>@}Ya4Pm4^di3VGsKxpTSl5^IDv2zD|J!i zW(SKDAcDL=k{7Sjd`raH&AH-+%#zhA^)~w=AnI1UubhPpq9u2)rz6GC%@>h|-SBpx z^UD3Ot$&(_tK)bkN~=v@uz%8;R`Gjp+0tqZ_7}JLVp#hoH(z72z6$Y31D z^fxA`1iS(E3f2tpq%pyj1zunSX?f15 zhPd+_@TdI=B}|Bk#ts$oywJ1iW92aHL)b^PqI3?wF|p-HpVGjtqh9TtSC99K*~zWWpAUYeQcLB_RXEJb>&ZFm zjX`w#in2l(OEh55f|h1+N_25uS*dcnvnmOj z2={wlw+c&HW%4(Z0}2<$cZVCGx>aFR-kcxS5{341M6iv`e5SJFLW(k#Gqrn-6kNt~ z9Hak=jsP#^?R%uOlnv&t*V!XIPfmrkA>!OGxat!cW$ThEOY9~W7X&Grbj$5@?U>6a zoO=xhqn!)KS6iaj%}O4bSEBlkVDC2cOKZ!zG0}iRh;i8s3xfzu(p5)^yI0CSTizG91#7KvJQ5VcjTKbbTGFr4t&K zSV!n#8uqFn29SN@1?BNzC_?a1qeviDd>d|nCC~QV^Inn?IWmf5+;6@Pu~Qw#2w0uR zZh+D)=XZd0Kg7~AcckcM77~|mhH;SwE)?L)@UMhWhni^FTcq==4 zua4F8yNx)7Tr+3}Ect2oQz4}UktTp?TRy{cA_4b$5h*ag1J-QQm>sBPor&{%6}|5Z zVy-EidVhsd$tJFfPD>jAl;FZxW4CF9o<!CIjb;F;drOthzA|LkW2kf^orS4D7^EnVv zY?j!loCP@)wgQSmHm&lUYb8g1D>w+Uku9nZ-6dDk=kHejd(qNyOD$C>LanGM0bq=BFn((?Qbk;X2ctx&Z`F8R!urz43m%tZ1^bAe6utFz^mR;Dz>ExmAI z3xToCdGIiScBH}!9ZDSnI3W--W3>(*$Ue4^RvyYcV?I)zyoc@=u8QD9X(#!v4(6X1 zJGD+tJfV+JOM_eSOpT%Lcw2{c-plg?Iw}3SW}FDaL0V-023oV62V(r7h`lI~?>C5O zp-jc3o^utf$=St$_>|5?XO`et$N5SBEot6?T!#3&bXT>4#384Zzl|vk#Hzp^x0m!g z4qpd&w{%gEF^6m*v!i|ZD^HjNaQR?>~g+!q1_LD7I0;OZn+$4wD{H9iR zl;Cf#4DTqL(HOAQy1?ZWHPPFK<*b{-`hI^L5(vS>M}+F3*j;uYFB}lv7h`6~o(6E0 zFx_;Dj?IUg4?46eQh~FL!kay+zE_bs)qBVOB}v6 zu5|dT<0C{aE)i?1?55uuuC6giCP*hF9BO% z3bG?>M=7-;Uq5iDI5Xtd{}W<|G7Fbex_4Px>hbCqaHX*BM?@mHR0EV@r5R&&8Y18F zOZMVfCiATWQ2^vDbFmthm}w*m``LP)T(%)+-t1O zlAn(qSTpFS$fH-3haAwLQg_|CtZ`|GJXY#jZXlpADwp2P+xj{5b)^2i+b@*)xt!*)RB@PEHx! zL^@^rb`Gcfd@>w&R4P{3YowjlVTu{j7IW>Vil0qd+pRx)=o2}dRM(AB) z$G5-6r<`%e^IV!(%a{zJhGg}^mR1B;4N6Ti30)iZA6{S#Gc*MIKCh|8asSM(PEzJl zvf{=#ekrTmXN@_vC`>1iS{+)bYr%Na=jV75*6!7`r}=o$=U3eEH*$%|Kmkk%@Pv7C z-j2jllejoe(M;@GhizY9Gf$0e@zwWvs#NpV!GR@wC>cpo_KeMiNy6=KPBGkZ4#ZNc zAE=b~a2GD2qep-qWN8&WD2TBQVCEYY0A@~LV%Q3_u4-RO=>d*{!F5o!WF)Z`DWXa8 z=JqmG$m;n?j~d3IM31-c(Y6l>H_<5Zf8bS-!q$HtcxDJ5yO9eSBODE@vlauuh;ixM zUj^b9`I&1#l)DUO%dmm~VrrH1+)38fs+4R8qcAOjh>2RK|`tS)b0n2HLOm_+4p# zT*AT0gv#rHuNU;lepuF&CxcF$%HF-(lnb@d(H$j(Iq{nY14YfmfG!<8``c|`eF*wd z@|8wyd1qLqR0I|0)ieCqjXkusMT5+2$UcA_;IxQwey0+cE`M4&5M=v|%-LorGV+(k zgl?20Le8G_-a^B<8{bq%LO7|Z#S<)j{4w{oyT5Lm9V|GAmJ zfP7glsm(?;dJ2N~z#FiLcy>OyL9n`TH7g}Q3(MvpoJmi|7hTP1WZ}WHV(i~W(L+yo zRRpDicnJyd+9{?RRlit3BG;18X}H`X6nM^Ua8>cdYTDA@h!7es;TKaCCI6WA;bhV; z{7m`a3Jd3fKR1dNE%VifDh|2r;&q=ep=S1WQ`cIu8=H7t9X%DHr35TE?F7VGCS#R4 zdo)=bb~;Sjd1a`7rgQ^aW_66=9$_do8b_7K^Vq#$_ui9f1p_-nzCJ!d+f%j<5zSdP zbbzciA%MMT2X6x}B^t*!^kL{K`7ETXsrQOU1%(zT7>G(w6MYpfMhzP_~=cxj1!HdG5#P#q_AA7WI^Ec2LL9^fHKQg_JaWa}Vzl zMXs&UA_2qRq_4Ybt+WxI0mvA=Xfd2MMGYFx#wb6M`P# z+L-#Ior|=coEW2MW!=FdAh5gQc;E7OhJU7q6a8+BsmcBFY#dV1Mup7gAigRDzP7(l z`c^l1*Mxd!>Q}(OZ79#OwN)G5UwBStBNOSy@SYk82 zfh=>=)9dVSA3J1#Z*VdmN?o#Ivpb?1|FqItb*=x?*%vnV>!h_a>dUO4lE> z>L6XO=7-;s5JzJlXAm%Hj1-7?Z?ok%Kmwj03Rm%^CpY!AWwOhZ5~;4Y%gEP1lSx_r z48#1gVMF`*#9^y+sVUd24a4tKguj~SJ)g35i5gfxwCCYTA^y;M7%@3b>1=$X$yR9+ za#6Fq!1JA zJ`Z^ui%ijdZo{a(YZ}H*2Mb|v&ra1?)yV|)0U+zias^BBsC>i~B%WHG#_8iN8XMu; zS%}dF0=<0#6ZD811EAm#alcI9OJ||-N7^joAZ=VY#|U7zP3BAf)3Fo5J?I)PcBzjdfQm1GC9nPS8M@U5bg$t-e$OMSB$@{gO`NpHd7a2@Vtvft4UrfyX_33W#CYxGv-ubae)E zWlxtuwbZmZAo_RWS$%eAe52pqx^k;1N9}rHCbhdWL;O4W$yF68 z%h0_fSv_guSE*OA{4>vuOyG`By!9XxbhjyEizKR{-o_G0Uz4{%YCHtS3`2`{hzDgv z#|%Lx$&$wyE~e&))$MXHK_1M@J$ij)H4V31(<|Z}Kq>4VR5A#B_(-r|kwS9($%$`! z%l9LG`QQD&;jebAHF-41=^~rCcj|FNcwZ3sJtyb!cavn+I#ae!@gTFm{wgEi z&(-1&oLEi0gTdglX8y}e=ED1~W zCQegQ!l^ba@2$d4y~tO8%^)>Fx=U(F1hG+4g!r6=y!ynIRYM_jRl?%x_2VgXJf8O) zdT2Hb5C$g^!dyKqF+RXKtKI1-r!FQ~Wbv2>?-iTPi`Kn`H}Em8IDmsWXE>?tv7<8+ zIGe?(nc4fi;3!vKg%CA`ZR=@9RIWs?BnI)B#!JDLxUfZFk-PTA|Iky(KtGX|5k0}J zBSB?UeTwXotY-n~Q0CYDw|yU-sS0U7-(7#@xKhN_->LvKTSMt*nb5hK9kd=BzfQ)3 z107&{_MnCDjzf5gv$zm>gItGSjZYXgqN(-iXm2$QY*|~DW*Z>G50R1iZppyzMF_B^ zG?J;1(INhDH*oSpnea8{U%thdm}&Zi;}!cTIp!)K*)}U53Kj9Y@cZErG_+OhNRxEr z?VB#qdpJQOrr4GdvSFJ!%%mA(duw#SX)bA1q`ej{-Mj|m`<4R3=|QaPZut|{qTAg9 z!9C>o(%bK{>Ax!`7h`I>q5_kL!wqYzu~t@nYs7^4bHS_pLf{Jt$M^+L{Mq`haVE(B zI)0m-VXSia`bnL4Gqrt=wCzE@PNc2B97hSePY-qX0O9B~2X7ROD*N?nBNMzKR>R6G zh{py}ieJ}yWP8>c|J2%vXrfeB;dDld@KbKHf{14f?KS_V^3wBOljW=m=4M;zC}WI- zk~m(TD(V{5)YLrE_MJ!YS8d+|wQnmeur-&G6IQG6O!l$dtF}fAE)wx=Rd0~BJbqqs zaW0|Yx&}9tzKyFqMbRng9;PKzKg`$kuIOCIs{svnVi+Ia{>uDP3DYnpKC-GInxJS& z<#^SP3oA~HmCS!(f9?m)>lC~bkh7wr>Z2ZK61bjBcYUHDrYwrSDwI*ECVv%&`SgPP z2%K?L%`N%do53tIA76j^n;j8_J99xA{PB#boLGgWEgEDtBiQ{=C5(*Z#1}f4d4gvOO`aa)=-Nn4##IV$ z#mTi3X}V$m29pUM>cL$vYF*{{uKz~}#sO`;rZQ|UMVqm*D;mpyhpq3x#Ml0mwPt=Qgf;H6SX^pe{4^cm zX^)EBLT8$qV(asXEdn>b@#xFHv$-@7Z-4@M-$p`e^nFyn^BQbA{Ox~;@2*hsw0um2 zQfYH^lZr8LDX;P<#!aa+6`!=;P3;+*Au&VBIu5v5RiDlm_cU zEV69Z?^)Jj>ko6qZ(Evvp#f=bpN7{uFND94gcKl?pNoBD5KT73I$gC7C9JTAuCi^RQI4Vrh zMT!Mcn z5F+EN7Yw(eO(t9f+2`x#R`&fH*hXb1JZ#5f9&my)t_3X#`Kl4q?zWZvhMnL@>CAf9RVu-Ks&9;p;9rVay7~apJGksf8&S3!EK{ zyBRh972!D4uq^T~1*0j4p4%lF_A{6$Ao|td2=Wy(R6-q|lQ8H!hM3p}$LKIb7~BGj zEnn8$i{p~9alwYzx1@N9PKd}0#LVaus)4JV%Nbp8UyH8WZqoH18Y=+gr13UqcDckf z5j0A)Ir0B#Y2{rBUGo&GQB~OHh?tzjjH^t_BtbwV(T-2AO+b>$xmV+hH2wAj#peYat8uUgYOXXYt+>1dGC*Q!vdW9(lq-LE`jr2Gh zQUU02*_&pc8l}y6eE~_9oe|?q;rnMVw+AQ6h)$5&Q>C#g_E^8`bCd%-S`RxVK|F#TW28~M4YLD`A zA%V@x+srU^&WfQ-bsBoT&y(ts%;WlOXCr+><%&qqt0z_ImRY-_0$%hH4=d;UFg;I&Mnw^4}k2x0}J!HF{Hd`$~&b+>pdj6NhK=SaU;4Ioo*w6&)VwWr4MvFgQpw$U>LCitd^W; z9$n*u&MY*_E5mzY_2t&{@pe1+A&|E1#Te37P&Krintyj0b&uQnt_g>JxcN{EkAI-JvwLRmgoM(8`lj6mZ;keObM>sE|QH_5C@@9p9{4`RdD6X zxr*;^*EDfm)PBSl(+rPV|L?PNfmTAFkl<~WDivoQSsf*3SAQpArGh@6DTusP^H!DK z_)Xevkv##6nx6PYyRR6Z_dm@A@##?qXX_0@Z~Y-jJE}8zl1Zm;vdoA3AK5h3Q`ftF zW)6R&Q^xvnRcJ@l7vQt8VaX$Z3AevPEaNq0Dtpft_c0TnJ*?y^_76PVLvzOlBw4bz zcv&pCDC}k^XlWlSOYA0P)GRgsbM8xr57rOIem+eXh=lw?o+iTiYsai&pNP_))Uniu z6ayQvvYbV7bC}83Donf|wp{$_D6-t#D%U%=oI$@Ap5BU$5 zkScpD)K3+nN++M^r$cez!)o}WJ8x;~1bAsrxI?txZkf%F^#^q2g#a3i@+-Lnd1J4x zeG>5rmQHL9wG7Pn5^o;y*;vAnX#WE=9COdF~JQu2ay1jE4lAorLUZIwS;BqyLp+^*-j^X&9~HZDmX^6Q^bZ z+`<3`>F}^j46lSOpgw7rFVKVV#ABgm$@AtMuV2I!Z#1Mkv$D{;K?Qlrl`Ww@L`7kt z$I7RG<0WC4da7XxzRBKq|BcIbC2(vp!5!R!6^1pQaXzA6r%grN)n=*KwU_2Q>)$!S zo!xHC9KQk1)7k8r@*R7QNo)bOE){*n!#}x*t8XnA30uYieEa2?Jt=xwGE0*B5(K932bI*I*feLvecuP@MgNFx_$L z0yeglk4f?ns>e3%meB%l@ko3UtxqC9%$fw94-v%+e~VrGmrr=*^ZMi|c<;S_>v})A zH;{t8m4cA!Umwu&?JOxt-XKTe`=>a(iYAxSfqAX7Lc5;TUz6&|MhJFcw0Lu$;{MD$ zz`b}d81&qwD^WsjcH*ixGwd?;TD%6nM*y8YnHX0y%BhUY^injerZlqvZWYEwh2?N0 z?H62c;KtN4JWy#ZU>y_XTm?raSZf4OHjw!GatLiqB}%pADP{injl6=C_Q?jf&^;j& z46ir&NHR-Qga{@()hplv%^cxi5EBE(!ha*i10FR7EO?*dv`+>B=5l0)N|*=>i% zyYAGyQ7)lIvEn;y;rVyIV)6yH6>?WC#%^cZT^sd<jnC8PO=%uA<;aS1p;Nq+L^ywSRSvck3iXQ?;+BWps?tJs9OB?()l^Qd z&hIYj3h`T@*S93vOv>0J{P#k2v~JHqUepcB>rHm_#gWuk7R5E)oN6pfl^E@ug>hZxya$gjR|0&tLa0SbEOd(J`mO=7!h! zOla{<#w(xg9)w{VwJeZ^3TJDu!^nIb7V+TVUsNEr;Y?PfU&6!ljJED*79fOFMYvn^ zHm4mt8pWd7QOXk~8y{C7Y(C%YkK*)`_z>5R33~5`&ZM{wD$SKXD?-n&{knsz+7PU* z7#73489=nA#6wx1W9)%vAq$F5j2ifPBP%FL!&%5qfl1LCl;He%Uow()rYz8n`Z1rK zYu7h*fhm65-*e3qEhBE0 zK0``*vpz-4;_o2_<=-rs$@n&1g{Q%7pX4lE|I z$)mLen77?XVQ|w=oFVB9?V{brlhY+u{-g{YndgvQ^C3O&>7JHojotq6cf)OJAVt}% z=_7h69(voKFzC-xp__0vj1chnn5J1h^)V%YnN@DV*+7 zd&53;mE?kQ5#g}eEJ6s&uK1-gSK2I_oHPxQAvIO=*KM?r4H|XbPG+tDj)he*PU-r6 zWe((7szdleVwQ48(CzZ$f(b!UWdO1Aq{jWRLRT?ZBBZ16MwAr>m~DaLbwrewmNnP{ zm9ZE!jm%3$xbxJ9NFVsi6z5XmG5z-4EFchnnf^o{VwgQkTaYm>B`T*=Y1>Dx^X3G( z1iYeOcPn=aTqKxJFUt3eQK5^Ut@j+Sn=LjyWx}@65###FVTd6{!W+A4siTG11MHx) zOAwm2HTC^(Zkm?JtV#L|Q1ov4p;l+v2nF}?o1q+_FE2?6jz zgDwTOOnh_tV*0PjE^jPX<&j3EA_| zA##K|U4dzTb2q-sv5%`-G`iH1`bZJdj;cwAp$mMn%$*Dv{RwQRayLglQK<35@{2Wv zGD!|PYnZC?HxrL|T>ET~4%-&@R1?c3P`V-LrdDrD&2bZZF%%w<68>5QD-_;UwX&aD zS@rVN@LRv)3I;R^n}8o^>W)(!er|k%S{tEqAc;)<11_k|xbh`~1j5;Z5sN3R&eqA& zAFdDGGuUshtkAnSK(E5C=Sb|>2C}?MhS*7lA0mg zxPG?AayG~d5EcYISZtKj2zbERZwp@QsnT2Sod1a#UE{x!X#FA1BvtIFQ_h2~ib_VC zGSi*-nyuimAuNR(k@Z6&@%WDYu&3|1x?Z%0r2B^#xj5Nd;@Y0j(R0uw#uV5T?=6-q ze8^@|Mx5+;mg!#GeMRQdJ>rg5G$GcET_8fFzF4RPr@Wf1AoBSp4ArKOqpjYE;6NcOCllM763Z6 zL9Z%LTts@6x?GW;Yb{J@qo}4Jis`FCAc5;I0MYRpS}Kl040g|dvLI%xHeg)V@OEcl zb)37Dy5RQfDR!1KgHm>O$KZRUo;chi{AWal&4ne-_zr%Kas5pHfp4zhh)HQ}i z;ISrA+SX-J_j!MZeDIk87_l+11kKe3DM0NF8LO1M53=36^-U8i254|>Ko=**h_sGEz5?$pdA!xN$YJ#Hl>tQWF?V*mTG)5-ht5H(5cUBBAjv(g&){hbyuv_3E znoi1SsN-N(Uc2&dCCxg|YVW7L8~~QgMs#ZIjmjvazk?$&^xXujNxt#1ZysqDQkM~n z{^Uuyo>2DxvMa>b4)cB;US_8idocG(T{NLHYKTn5*Erc7ozL!nv@#G~pO+?MUbN(TE}5a0j`Z4~D!ngf}|xPI!pfGA+0HcleABqOFaW zBEgI~OK4Z2aMq%JKNao*81+d#t+A>z%`@>d)FA8cWpFNQmZOvS%4a3nElerQN(M_%E*x*Yksoa6xW5de)qR){lOV*B1# z=|;NRZROiJ9>SzvT5w**eMR)0`rJBtW%>J*pO|RwuW-3~u~flG3}-*IG~-{$v?IGM zXEr9K!#HIFqTKQAUPG)hxR4fGA+ym(+a>kP?qIGP2UMe>GHQ+a{UWRpM_D{Ai?a1O zQ{IbbTczS&alVpf#~hDd=YsZk<#oXA=Hu}H0a!q%zg$@$spsY%eA@natWewlLyely z{dCFX;m$H$-WwApA9ig)NL+He7)Cz~Go&h4B1$PvMKXRUU1=be-W#065nvyvQ4I^w zfTP)wP71)hJPut6)f|5-$=3b*(YVH$PKSDWD516+0~akY^$T=E5bAf0`ODU6ZK)x5 z^=E_C*MVekE9y#9C#nr29DHj)=rJ4F>cd49U$J7v*ArIGEIoHyB_x6=MZWXDPHSrC zI#2g4lXHBKzW0W*)BG_M>BNvzYQ3+o;OWLxp@9M4XTl$@EVGHz=a_p5sSj-T@cgNz z5kh3k3LmEcoUlx!V{QI$;p4I%qD}moo$v|n>cT&Fq48Xy5{BDaA<>=6uLBo;Eqh2? zR5c*>uo4=lF7*Kh8C}qZW-NWUqg1@WUMUU?rtXH1%3dE<@u$QFf1}4R^sJx(n7^SS z9;$mnyK4<)T*Xs zzS&Ex`2V7#L8ws5o^3xx9}2R)O#w`(?GMUmPB(yfBvPF?pk3(`tJ29rQb3L|p z5IH}4m&zfZuw4bzo!*{>Z z@f|OZ7&4@;Xn4$y%hXG2%8w=X9{t|4M7=c@`+RVd@YEACO&Zk3M@4wr)}N}hLsb4s z`|rGd;h37$<&d0N8IdpAoXQvPDX~X0uu)~Z@=^_JBORo**BB#g;^Uzmzm4ebRuG*&narFBvMUS{o~bE*d4qkilFI4C8UFQ)OoLD(Y6F);Z!*RKjXO2 zjr*6Bo^cC&VWg=XadHd5G#IYhn)bBX`XoQ|{C}vC$?Oe@d!IMpN}R0~{&p~E1>w|` z@-=fME|JVSrq0+i6qe8(7oQiYl239tW6|mp`e$2F-Y2t#Zvxrqbt~h-`haKdYdq;j zha+%%t~LiwM*%VMfYy_6Q>EqsXNmpsEH#(@Z7y4%HU)+LDL@tR-}t`2)SVsUK?Hmk@t!O?Y2_p`FG>o zx6BUSXSh1jCfj6Ri_JaZyW)ygl9(=c_WQ#?pXF*d5u_x-_l6AYx}-U=zd%@mpiD5i z{8y*v+yrrZOgn+BkuWziQ_g#q)xbs}3+@V}s0QdVznzjIhbS(375h)~E@}A8P`E$y zM?f%{<9m9<+M}y);#)oG7S1+GKQIQV8?P*)A_;Bz_3ZbiuNsBH1^e&1hpYjJ&&k>*Yp*5QrRHFr?X-1qKd#;W>#oWubx zL!d;k6Y_Z4j0MX1vz;vv*^^kL)OKoO;W?Q-*EMH8G%vgPfuKGRa}sH*{Wt5{WYcalRDV*rbKPwZ=G(JOh#hEgVoVGh8rK!m{6PW==&^tc_S1Wq3LGDL@l)|rmQ6h#i^UsH8X3s5rvr6?f<0p; zg>gN|r|__TN@w?wju{_AiZbcHcErYzzMUjK8Zr5O6WmP327ix(dCJ|HrW01gL3@|N z4YQJSD$I-WSqPCDU)SbzIg#o~E?Ng$fd(Jv&Dr6M?5@*n%{q$jn&I8>9flDX_z%4a z8t7e}X0G1Ud$vSRU(2g?WaDx?K%RqYK46t?*opx@(f|{E?`^TKSY{iZ!jw=AS@?_{ zfDk^5`c;vr36*DGIj4muQypNac#6Y?Bc6s92>gd}3067?Ixi?=TCN%VndLVtQ=RhQ zUuqwI&8GzQnk?g71{tS z)3KIq$Ju_NKiaLt6>11Aw-RrK-U<;V=34Yk5R)^6NrLkps!PENa%#%R_Om3}=`U2) z0v!xOP?*iK@PTDbsUdevoE>$en5xfts2k$W=fa6E9CsTB#M44o z=C3Aa^(dVu+Lh70N2_QH#(Okas;yz)GdH7&(Q1zGgY>zB$GNuOQv|6mTk-!{JzUt~ z0*L-z%>lDHWpXjhn+&uDEgH5{?F-(lQgFu_YGX~?ui(TlGL0eB>i@k#>Y0M+(9{sl z=8d3e<7Zr0xL2V{1;28}HWQ_Yd5O$}K%U6_sVjm|5)Gl#m9Zjzdjjz@ijtNbtyP!c z8pPWmBp}6;p=3iSq!o>-b9BY=H8e$RX~v2Qj)lQIOJr)>X9qLc=!)H4ttxpU2{8&M z+U#}R@2vf$Z;s;3jM1_-9m;)Oi{{G|S9T^-zhDzJC$^-`HQ_zkRs&4WN040HjGN}7 z6D}P=CMnFP_amu~!YpiWYgBOK8Lnr5S64CdYmkO^GH=5Q#$rDH?KjM-x)c+U{xSg4 zVU;S2*2IB=?flv1wvxv`{*mL%aakR9aTsA{5s->*+4+gUX|^LB{<93edc=I5mK5Ru zji=s%gujX@Eo!C_m7bX&p-r7MDdZ1jxLS4^RN@pS0{0?VnaK|eb>8rZ&6Z~J-)}8D zY>%{B9bFsp35P;7Sh;i$G!|4UHVbdy3X&TMwwfqac`vSd*z!(+vw(8%M&g_ij<|I` zC%ej$r`C4`erZkW-=7EPh3e@Ce_eqrU6Y3^G{v1PMMdgqAiY;=rPdZd5S2pcJ$r9K zAOqrQF*XhRY3O-Mf9bvF4BclUlew-p?O_`5EOr>e__1hKO51>$=C>n~iVtAHMMd6u8{&{ekxX`wYXR>M_^ z$H1fSzL*PMPZ}GELBH2KO*V994tHuN0cxMDh_xgYGM#x?6)l~;a^QsRT|q!i?JHcA zo*XY)Q(mDo%EQlof$Oru?xq%Bmn$g|K}S>Ab``GpaDSDCQHi3P4gx5n0fN2{kqy=sK5Gj45N_Ln2WFrtUAW}w-i3L zfKQ(%23xF(lX<)(efEi>RV0WURvT$kTb=mdQR)$}(#QLz-zywa^*0|dj4;N9J2-HC zo*o)kntvfvA=e&k_tDUK#AytAl)w^3@?n!0kyk!`wSUA(=Go{eaH&Dv(Zs?9QBr@l z?S=9Wil_K7Y##H3FaH1vUQ5nK__-JXED2Rp7k>RX#|(ir(e%Bq<5>XE?5 zK;y{#{+G;EhW8cGHDoJWjf{?5eZyoP9U((!KOB!I{b1&jGD5*B3X)qreiy}jyX}H1 zYTz-9`*T_|uR&!aYXLq7eapkPfZ~H&(EmJYpqvb&l_!i%BblefFgK}0P9T8OzTp1B zcycl8^c36dwF8N1Es`;MrP0rKfey8`GCl~3f5^ZKxx1;y1;a(Em;`!4FkW&&!4tVKhnB9UFHWs`2aFm%&tm>=(0Hf4i$HE*_=m)hyqt>+tqxZPH*;#<+bd+Kt)Ru*hmx;g5>dEKlMlwC3`lv&3 z$IP8ymmzKB|NLx)74%kTtX|$yl^AiT6XpjG;?0f{<4KO5-|h}-K=^=WHV)i+WS3*l zyl}pb=1;L+$vX65g?|}3Fh2NPw}{A_k^L;>aqsN#QrQ8p+DuFYlsth**Ck6t*^if& zBk>_67!HWMef-Q_pHd-D?Z$T?m8Z2lTq?itW8Sw*%FakQNP(^F10@Wirq>sdZt9e< zACg;{$45{g{90;E+taV;4FA*X+fq;+@SIVMptL7G_!GBgPf4q!LACI4$N5>ZV#+f$ z#mp%ts{+w1fUVihNZtSXOWKs^ zZs?jw%w!nd@lE_0Hv6q~qwsQC;WXAX`a4M`w*YdFO_|{;jCXU?rL_p;EdurOu=n8P zMJHJUhvLAGH*kiTyMf?)#|vHOw^&MDnC4%sO5Es`bs9g;=wKzdI(VnZCq=ALiaY0* zAXD;%wzL5#S5&lRuHA66K6MHN1kZjJb~E_Uke_-3rzy|?gR4}naPh7^O{fkjHr*~e z=%w74K|gj|XH3Q~G6i(4ktNj-E`_KEv#+B*)-^|NyIQ)^uO~@9A*hSBAq!a@9l{~> zpdWMb+RLyRPzIxZsT6NdJwtiyqFh>BqjZ+kr{KO<2_(=g?@(2ngS#~X*gNkq*ELnp z79iYcRD167d7@;upccfTOI9=@i@MapVQFTU&mdOWc>#jh2AMyw zEJyUI)!dw(J*FHpSg?d@j>kt85r$FX-I;zBmbD$$|8Ul^=f0Kw(#pkm0gIt>Huaac ztPzsH7=D{?zRuY>>!Lo0%V$20uxB?zu|SjcfGFY6=G%1%9R=&021saS7&tS_H8rUz z5GeM#P73P~zc=BhXiw8x#cX^DicRi1D>H$9)!L(2qU+Gj!;vTF?1-&Hpq^JL601{( zfmTTFx`%zx;b-u_Su=Mx(PsQVT%6OAC|a;(%eHOXwr!icY}>YN+qP}nwq4b?Bl@Aw z{e$(85i4iLm;>6Td#d2fTYtpx6&E0$MX?;CuJ`N9NjJ=`6t;@f<73$)SR+b}xGz`G z3LU_#1sCYO*g^Nj%YGsfJ$?)NnmA3v@IAP z`nW=8<-G(EAFLyJg7w&q#F!*Oi$r+8eTskqKf zDa@ZW?yo7^)KBcnf!$$~GsJ<#PqiEQ;##wt6nC**Jq~LeCIzU(dF|$!+?N#jkrH1? zD%4h?yrH^*Phfz6^^NuNkBVAcN;K4v{Or--lhXM-(e#1`Fn>BI^(wS*SEZn2Qu(48 zU*c0|lbm-qb`hlt7H|Xpw1U+^Jx|HR0GbSc;zok=fmZl916}5ic|ogMz9I)eIrRf0^>fmbCFO*3 zKeCgHoK#xd$xp9@RsHGQMTe03s262%7U>>CG;^U44#G9Ge$^P!f+$zcpwEZEaWIai zdQ-yLMaysgCH{hFawgLv@yqhrs4;a1>{}@}^ZaXbJL#8=vJ8dYm@(cX5@u>%-nLu6 znFXO<)Jy}TZ7q%XE1*)JO|wIQa3H+Aap&UNVFQ6g2vnz`0ScqjooWR-X|YwOY|Dl@ z;lWc;Q+eSQKpCW+t4%a|rG=u7gqcu%-=Ele06P1E@%hTed%zA}Ui6YuAMt?yaAK?q z-eL=A;Q;ehHt|oVY1+u!Ti-rjRBuduN0q3@@3jJRT8;XP7`|TfXQ<&Q&o5*+2O`Os zZ)G(P=rL}`BH?xw>axEEQUWLBZac)UJU+-V-SGY#ZKTJ>O1{h#Xh7S83l#emk&m|} zDdu_y6Ka>$%=VmXkj6w;#=lMOq$?#rGA}@|yh4RgL>J`1NY!|#aE>w_QS|ojnyprsRzcfREiseiN1nHR z0r!g43c&Qt3e)K=OwH7@!$Lm_+)sJYgY)>A!Qj_Sd{O<<+(ys-5Fiz~l3 zG*!LS$2p8Li2`{V9wY&9U0il^ylj%#J6%puvmm8+FX(3r*j~`L3=fuobM;Msc^xLj z3VN6`z)qPtBqoe}C&Uk>A8I36Cbr6R+m}MskFVf3ZB0G0eP4T;HS-#H1dI>0{8_x< zT~mT<50Kf0jH*OsjVI*her;qqy{=|a9jAVb^XHM6DF|nWTW}lgkqO_oK#cQAHVQ+< zY5>ymsHp_5_S}HXDs%GMp0rttCk#NjR;P#o9aX*ch8Hf}i)t`R zky@+D7P0EXXD%c^e;b?UZ9O2b?vs~d4 zJ^~OscPfQ;s&Buav7)jwr_fo{bSvYQaoR~RUtNCO0Qc=?wF^P<^-Do=n*-sH;C>iV z3!4)>G`gvQAb*(YKvWx7=#~kd0EBPYu)(W+dy$d$ZYi7$V}c2*T;#r36zDJZ#C`aK z7=IfD)nLEs+IyE_f%|!luX|~%MyNF^=?WhRBz|H4tsYR!XH{y5SJ!2;$;Wf?u_D#&7u`R zBC`)Z3(j|Lj5WUpBsP_`>8tmO$|r{sa9@QUpR3MEOull6U5)-@8em%<4dP()8KyB*g{y(M=*o2A6aGt*WK5?O^hz2FbuVyA-+$z8r!2nP z2>Uihfa+|ET3`2h{2sZBDNX0nf(_At`%=)U1sF1tk>J`(`d(2J4~(qy#=Yn%Li0PX ziQB;z?KN&LsYLAXGjF18Xs~mNEQxa1{M|n3F~-PKuT!~>b{VlZR%p2az$6Yj1UrhM z22Wkba#z3DYMv}WxqJ*MVs;ZMcw%p~B0K>U2blYl{OIg3^ACRYqkt3Kf7bIapiw)T z0fqr5KWb26oaEH2nUMDXn?lGmTlB*%pg=7YGq^%scI?~BOl{2z-KL#SVMhv$kTgP+ zFk)n1=-Ip$5##Xi6QmoV-f52dt#SCpa+Tv7asI2}hhVdXrVE3EpU?D|(QB+V*z9v~ z>Tc;u)y?cXiqcfr*Jv0RRRb#E+IPU0BXA%!_zh6 zf`zvGD={EHzLTa5T+Kx44^2XdrLeG5SbTJRdl2*nk7tT464KO)QNK2??KUd z&}xUKYmV@UtQIl!5PEYwN%?3O6=B+lIqCTG{BBRHM8UBor{UcA;^5_QikLE%ek>Uc zX%2!!X!tD2n%`vH5Tz-V>N9X&4nKFSI{tC0aim!HI|Y5$t79V$*-mk zP*|GFmy>+no1NT^5J9y2p2DAg_96vrR1R?d;hoT~68S`c-&M~|%{hF~r%-trm}sN2 z&Lwj{hSK?zM0i2{P@gTqb?2QsL#0-b$ElR^`P^Sc{)AZbD&`}(Y4VkiZnkvQABva6MdrEwriNrAPi29@ZupC2TFdP}jLR)=DSZwBP0@MCgA~s0g82rumM@74;3bIBtZ=3p@r%;5(4hd zU>NFAF~XSTQOIoaJR#eAwd)3W2pH6;l@nDAcxY(F%N59$)>dyQIlYiAWM<7i z@t}hfyN%%Pg+Q%}@Nc2|y^$@-gXWEQ96HwO+dRFwNKNv@tREwg*UT`>wUQ11O&AyC z4k<+=(7Ve8DN*b!ZBO2;c|axgIX42wbT>qF5kv%$vo(Wgvl=lTH!fOjrH&d*DjS@# zCbt*pUIX`sgbpx-^2zM@7#xxJ+joc5Va)mpJKP5uvbrJjy^8Ufi0yh&K&(+mFkltK z3>G;?uRBliU%j}42@QKkW`$zf3oPV^!V=H*F}ZCnVmz|Z{i@w+BHvQ}=HAFFIrqSO z2g9o6LnbUXkbHPf%KAymzZml;j_+>Me#Y7bsmKI}F!R*jya=uKIIck&57(BA!_Uh8 zjUjznm-V2ylB4fOq{QTL2DR8a-!L|xQ)BO{_0xNREj2Im*Jh=T=Y07hRx;0Dnrqmw z=f^@na?K{*oxKw*R{rdQS4raSZ{2yCLOO>zLr0X2)rmuteD z<<7ynRvh#R#2Jp3Tf0b2tW?IhB+NVs(Zioy5*jK|n>fhk^P{NhJ%5O1!t?4GSL31G z?=y-bx^X-;p*jvWj(W7!xy{Q%@|_N*i5jQ9&;#u!!B)}JAw+m*%FFwwY0>N2(X0)^ zg+E90Gnx4pFY2XU3(ARS6x_TWN8C+pdW#skwa8pVg)=#yCG^23wSx|5u9nPeo>Cq? zjrwez%t+!Bb?;2qu1HN7qWW(Q2C^4r@w`yL5vHAFDmBB+nV3z;+QuBSVc$pw~IY-k|njdluVfhgrU36<; ze_a?wOvC%pC;dG6)&)NpF>2N*KO3l7guQa14MRZ4kVxJ!BK~Ma`xHS-rFFwvSh$L& zAmu1wc4Qhdx{_WA3Z%h`<5DPF?q50^K3sK302T{+4Ol7Fq=-*G13*=7PlV{~~sb3V|M_3pFkAL+|}!R?GPi&mn?I8%?Xs)FFe z2cjf;_`M!aZAPuc`^|Y(e<4?R9PYWf9h*03+YX3afJKwT0os^uu z(W6HjC*Mg8T8pl(!sC%eno;1B<@Xz$#rD4$j9YuI zNKM%3@HSOO|466QFd}vMNE=)00zlbf`w0xSN&{s?+0z!L*w{W$nRGbLGXNKyU@{+_ zERAI1-&hW76ElSF7mTU=;XUc7FFA;KXJW=rBTf#FY150haD#`B-5QyI_eBo9g80#o zr3w|eIlR$WF$ZU*Y-P7pkh#e2zK`+w>kPOsIRD_y&v9wgQ${78dh?{5kSf3?Yt#6#Ly}+LGH`vsb&#ADqf!4%w`6xIYu84u5j- zmlD8yYGg?s^1IsIBa$~&q<_9OZyZewRIed?>ZsHH;6A{<<=c!7Qq6PKCh!xKKJPyW zHWOC@tzR7-IL-9${IWFc7o|wn@^BJ*Y23A#vjyrYdd}}vBxJ}k*=nZ~Kj7l=b8xzQ z1BVA-Nkig5A1sVq6l?Bl_LVszo(o;`t7brweZ)-VY-&5?_G`pnn(XS|)%$CU zVR((9?;JvB;DxXvlASR4s-vm{7uD2WMWf_GVBXNeiQC~y6FvYlbgT9$Xm~;z#8{*Y z;mMuc5MW|kdajo1CEkN!$*5!c7a8N9Btl`-1hda-s6oItiJz|yoMx*`b%g8x7xd%H zag8EBB|mSiP!memz}9tP%DzISN9tqdB7q-0};4#+w!Qv7MzIoQVBsGNgK`z(gsug$#b3O zPJR+UJk;DP6o?cp&U&%mu|v&siy4&ZuN}m& z1lVJd%i54J(`l78gU161p>wpA>mIQZiT{)2uT~*t*ASg|KtO)|dSx(!GB~}EZRqIv z0!xcGvz>T48`)WxM`ba>kIA!atgfXBX2K$oH=6R#-ApuyCwAMc$@I>>?#H4Qyop&9 z4l_ciudxtz9RMFjLtMXPNvJT;r3Y0c)EK&6oge#>zPTE?TG-o5pTdIdSg%-Jp7rGe z^P7`73E)0eOi&1g%<|)HUsdt=0G>Qm62@^t4EyT^6q4n%fXGKZl%jLA3&R2iJ{N*h z9Pe3F$2PTL$E&OyRw+$@pn2FUF@XypRen1uK)pudkX+NidE%tRL z4To!Tou`W!cMbg4ZW+uVre3CzJec7&p@N#M^N791mnVvJ zQrUGo%s_Gnybh#dW5Di)_wb2xh z&+W516dQ#Wpf&^KPEKlRlp)~sPbRDfO-gg=+dMkp*FoSQr&)y`aV4KOvPAtqzO$>)WkjU+_hb2QOt?HxE01QQKTk5B!>uxuSq3CAf{>z)% z`1jXB;1?yLbm^|O1#gJVyjA{_?^OA2@*Sl@)Q}9u?%156oaD39O(A=Xd7x~`HFdNM zSoz3AwE@c%F&nNKSDQn?l-;cudl*lbu@ACOL~9_lE)MfD0>&QB1;|#QJADdyd?CZ1L{2C9=*iQ~Y_{1Q7aMwZ!>!7T7)w^^h&@3`E;`alh<^av zM^)(!Tr7UC7SFfsfD77sIrcQgSu$m)@CIU#rNwJQiE&D4rI>P$wg(V7^RdYDy5O48 z0BjE!2wpLZh{g2%)q?@4=maOQ_$wgxloEJc)gm)5NBVF#0Q709h?V8Erc1kHkhI>WD z)$0`uvKwl}1b^4oVhG1x-9#^_@2oi`5@vl2Muv7huvB5x6>fgUXV|=)VUIyl?B8w4 zd{MyYYjbpq`(a!GQsarsD|SoN3r>2}zlTyK{??H)r;7a)9Qnah_~~0SY}g(o>w-A*?!KoY8JKcL5GUOhRq|Cs9R=|ws`OL3kuj)nIvFDe~q(7aG zxar~~L?G{^TdV??B_56K_q4B>juqkS+Y89Hor{a#&mn*@xMIl}f7>l%59&*cL8~c= z;{4O{CingLgM}BqD!p5k%&dHzw|r*OMCRSi-<+ z7cm9=_}ObZmx*4+s|PYQL_pi1ivV)c_B_v?5_&9;!gn7&H?H)t0o#gaszk^-dmli- zSZ0S{`_C^G1VGx44`&0T(b%3Zmin-VjpkTIhk|-a8;o z^Tv3NWi+YsocszXC>)`es)h&rSj*k(?XF4l;J%Gp3)CVs8q;+PY32J2=mq9WU$5zra7P<9DCf2 z?s!M0O|P;M`JDfCnQ&H4TJRtMwN~@c+dcp$oGa?SE-5<5LStv2mJr?Y&hsgkn(OyY zPqZk&sM!zCAJs9k4sqM;t;NX_BL)c=Zy-U0zT8gAeu>4~Che>Yj{u~87x*zH#~qN5 zvonjugY~PGsPVN>0m;lx5{_QFg1%<*=~&DCN3U4BRk;Ldm`PJM8ueD2K%CUPJXp_F zfjUd}eJGeq6dYiF^b6~pPr8ZcpAY2ShBN?@1Xp{F6w}G8LXPYk`{$}R`+}&sx2k41 z!vQ$}f?Nlk?|dIAWX9>5NV}n~vCgYr$G}EONEj&kuW>x5Kw1~w`FG&W3tI=fEAN%= zhJ)BLHT;A>Bn5xXpm^dhDYB-MDLDA;RFVWTCEKAAVxOg#r@b>ff z1&V}y(pJ%{)IzSWyJbXJeUuNYVm3_NLn15!O*$Q-D8s8Kh<0hdE6zZOO=8@CTu<2W z)l|{#ny20nLMsn@8(mb9993*N2fM-WY(UhtTjw;mSFzcm&?4fPV3M1Fb;+#CcjqG2 zw2l>lM8h0s$psD@>>axI*m-tG+vb#?ELQPZ%a66ovefBawk_%k?}R6Wg1fe=qjZ@M zy1OBa?xg~GX-p0`k+)ae0n)xVReysQ%8_^|Ff$2&*VC`y&$8oC{DyMZ7Rmg~?iFpb z1ox?-V^D?1f9@u`R`LS-i86Lt);0i|m(X4vL9U*F?K65JbS=H@a&tRt*9#6TqwxXe z7vwQDvAtxbMamE~eC+z#kEyh*7JadU2Ku9%c3-ZDs*{&Bv+$40Y9t10OL~dj`<^p< zw%w)Il+_oEuz9)bLOF%_V5c?cZkg8H({5euvzGQyC)>+mZ`=HYBaU-^`CC3Z!E@UJ zMHvU+JBgF2kKyjNJ}MGqt~|a}2J682*eNmuFL9>!b`13E(tISLjz);xFi)QGwh|V4 zG=~QK8LQ;w#^dK0VgQjK4UmkN!6;kycrOdnbPz9%k3V>|m4fU|>9W>6oq|#%Mj41HYa1kOH<&Y1*%Hpy#dFOje=0=BJ9B^*G6pJ{sKX(&)1u#t(a zpg(Kn-Llc_U{>jx?8_ z-yMLq;0E{FU1^k9aHRlLwj@RGny&}-I@Sadwi&63I->GUa_oOqLb)nhae{nr=Hd6A zZs+*6N<&eDV>F3~tP_&51u*9oiJCb|3TCqg#6q{?t~g}gz73W#iPlLC*5@)8y_)QD(c8px{j zPdJbsI)F*w9t*P((7$j&irFqz!CjW1c@oXine5^$cfVC%MQzAz#G&OLKguh`e6#A` z(4gLg72h=aUw=y%vZ^M&>*d7q`K?ztA?Kt-Sbp$q? zpB-N3*ieHZ~A* z)HGqKW&W7Su$^k>RYn-Go-{MD|{ z<>l`Jw7I|ckkHmd*tG<;`l~5etuBDA2<7T@XnNz0$<_M@rUIhP(a-dT?f$>~zBZ=R zGpNoh1Iz8%-@Ms$J9@STPt$^pFE^8%wcre`9mcaBDGE8dz+v5mOJ9h1b=`L9u-=81 zAetiFHg>k?{2+l38=2iUM~*&L3JGPfO;`r2jw=y>#4y=RH!ex8(X~_H6&a}lXCo0o z?v{&*s!(!&9eDDs<&EYYd?9{&wKUg49&qAq@ow7-l%W)#45SR|n+X;-dwJVvZ&Og~ zJG#f`g{zt=AE%HpX_1F>DFMEZ&3r4`Thhf#3=uJF&y&|i!1h;RYV{Lc1;F+r20Q2c z2-U@vmq%@Xpm=w)#yRWTWZIxXD=_Mff+!qzr#dMYIvrSb8PFT|Wr;3Q@a%l}MyQpn z6~P)28Kb)l*-wQ>1=ra0YUnjFUU8{9Z%#L~u;Om7#xHsS?(?Fe-|9Ealh;=}q)kmD z9bq3CgokQToT_8P4YKl&#v)B7mebr0pDMYu6v*<(91mW`D7U6%NTxF=E|>xOZf_wJ4{%u$O!y7 zWe-XvCxn;J;Yj8!PP-u^5alR}4|MGTR=Qlr$LLU?p@WPa{({1`3J+j+2@kEh{}uoJ z;G36F!U-(E-s@-w*go(t1w)LyPQ7#AXSk7l0c`E1O2Z$K_fiOscS;~*)?tbU31#OQ zwSvHbk5bfpLidnQ=OB$eJLRr>NFvm+y#XtJY+B6Te8v0}s#V@@y&$j~y4JWpF5SF* zB?BJmY#X30pzVa6u%xR>l@hgH8jjCwxC8*yY)o~f9mvuMaA8P_G+efczVlz*BWU2h>63S0Co zdDmjT>h#1@!Pn+G<43@1lLciOO9YIK9nm&yMrAb(p60F>+LDaj@-)z}8PdY#;g0pn z1m)Xz>11npQEy+tNqs#Mq%q`>W$0BTK%&*Ab`|?~i8zu$!T3jys|7RBzVUF`6VgeG zVV7UISxK&(jn2bm62AR2g!tX18_SqUVeQ8zt_FPavMqQA@y*4<=KG#MD|?f+B|HrN%y0 zms*A(wyE2%ON&!#+MA)VpuM*#knro4Y8VIzv|{;y^W!hq`O$cnAaWd(;&%FS@{X=c zzAlA;;V0OJL7I3u zmQ&lSF_2;>x?9G7`unNEU}^9><>6YR$pGjE8L19mu_E#~?lJOCAF?@71P)eQFR1-FbdFd+r<7ASkb42?fcFtJZM2YM3*s{rM+T zjEWYHKv}34(6|6P8#KF5RRV#Xpz|^*`D-7W0#0dSACi^aVE?Qw!gS)eD-La#u`=cZ zw}ty06J7~-O|+N^wnnjuNdKT+u7|T@m6!5m{PxYM#ZLEt+TIXS8D9w^#DHs_x?npO z#i|~L%+U2>7eFi}yIY=1k$EISOzFPxEm(}92rLN^In;H3_xxg`BM8Q66d1s-MRS`< zz9T!y-4^9DASIkPdy$Aw6=`WgfinO%{Hv^i7zOA1SgB&&t++5{s*wX(JL)8%r)Df%#cD@!OE9tp9G7(fvMZuyJIy2p%< z{eu0Lm%75B&+?|8SvET|1;z9|)3UYCf?UBYrul^((sx3e18#tFI@wuJf|AR>I(12G z1WO&Z896t0r9XGMUWZjzC$D8!n6Z=G zgl0{>ye+dM`rSK;_Nf?b7>k58ni;U*V&dKw!(}(3Jn*TNHi9porBEGW=1tl0u*qfR zW7i%d_qYCE8`8nh1TiWKQRr@AWnW-hZKfB2PLFX8jXdK<@81pu7z8c@*c=m`1X-LA zMsu;%yE>YxzXy?C(Me+|8Mu!7tEU7e!=!H`+M-7gpX~C5kQIXzk>$Z#wE{=zUY;%M z`Wv}pac%D~8}BCNR=}2HS)3ybneIJ^Mo0zjYCJJ&0XUZ;IEdD_?i^`2sJ8&O9yuWF zrHoA~|Mg&*miDpQ^G|WMsm1Ja|I`B;4(Lg;un|?N5~+8|polz*GW$S(G$u;Dx%?Du z+G@-tY&BL*v9X(cr}maeqd&@l1EPyH0&62bFU4Wm61+Y-DXCdvj%`VEA||`DK%HTM zj(b*ACLjNzQm+8>79;T{m@uKH9&F2b-so>Ki4y9~uw5~c7q|bd6*J#9R@msiIuKRpD;{mq>dzNE{_s*p} z#!Jr?ehJZ&p^M>XY#X9WBIHamGlO~GGf$M$Qw+I|MLunJM$@2#G&oK{D1ow#)74Hl zd9*-|77nNIwFCNP_oS(Uv~8}Fa4;fZz3icvIi|f3n4Ej;#bkfVbJK_I!!_WyZPz*Z zf_g6DDjFAv3Ssj6r&r8F4^cq)d~sv9yWo6TDYN=7=-Fftpm7!Xk2e7R zD0__0)?v5o_rlMTK*VB1z77aXCBd3y8O$d!twQ;6bvKt3v?ceZx4UhI_2xcH{~!`r zmw&US4foC-u$fBT42#Pj`|$JW8I?4PM-bZ^t2|`zD$-W7>ij=?tPSST;5gl%avv&2 zEy(t0PONMTzyc`DdjE-}K4~wK%6a&$6Tb)G#M6<&f~_ON+hAzh7Z-|zAi=j1?l$~j z#(bx3?Bk00Kt)!IipZQmc+f0?Y}I&@w}65oXupK?C6M~@30BW+!dRjfV@d3FX}man zGT-2>abvZ61(!((V3IP5VsS8aRj~Oe^61Wp+UOzhGmvWB_ggsYBW>?D&F!<*b=C2< zuG^w>1HzY-kDa#=BW=K178AQG>WGhqV4<+8NDXG`KWm~C9=czxF)8aF38s;xGx{P| zZL3{j2^8%$yXfwE`OV8Kb-s^LVrj4E(y&Kl%_*7qc4q*m3iZh`{r%6v~zi({C}je9}8A z24V7Umqxrq@Z-jPd0Sw)EYZ?VsCd{g?#H1>0#^S#Fg>0HNts(l91Rcbn~k-oG|?ir zIcb7Cq#F5>pl4ZhR3hSW=2lf&GxDRw;H(DOFNq^R6!*^?JzsE+Zns33k8kNg1zvO$ z1ylBXxo=pndukei&s5SNaq&sPLZo|E9Cp>s@4fKD%T>+)dHR5Nl=Lp?-ZJ!2OJFsg zmgl)V?ZQ+6fAwn+d5+qI^WyMC@ zR4=e_#*Cx$2L9FSi$DWNil0_e9(rE0`>RSF1-&hLUuS?`o&2WLjAaz!E%*lI_53bf zn!j?1T}X+@_;Y>ad2oR2F1y%Wa#Y?P<7NY0?6jauAnk)m<2?N;D|e5pp$n_29)5BI z3Lu4zbC{|=dChlxFt2w(iIL%3?4P)(%J4AEOEe^vV_#YXcNuASNLhXwPIR@BT@b+7 z_P*wv8vv#fw5#vJWooNX)w_e}R<&<7QQAHDQ$mxo7|*7Z`~(8$9{vORF2dhBN@=w= z$_W>~UMBD}DrdwwWvW1y6K4%&6WMQT9}kNEj2D(pyO{i_P)L`yYKni`Be>?R`o4Vy zj}8nA#^=bk+Km!tY7~*IMtM#;K>$`jslU(Kee@b!h9C@oo*P7)4#Z$=B?1_~HN>Dy z;2Z6?*FaDL91Q@@;$rvD6nxztIiWKoIFv2_-HY zvD^B?rp5J&FZZG>TC?Xuw8M{S@=KOjaaAnC@S}I~+IfL9H_Hc9TfvvI$$@Ob$r;-d zaQ*nhX!1niALNnO5eVK#v=27_5Y!IC40~YOf5&-O1>+6XPI@A(A^9hh>j#XfAVQ>f z8>qn0{3Xwn40_xuoVyr!)Kz~-hi<*KupM<2klhYi#-)LkAtTkwEu9F5;rFDGmN+}6 z_!9wWXVvFVd9 z9>PBM0%aCutw+MB!k2{s9vgXGa)iK!ZF&fSVI{t1rm=K6d-E7LNa zxxmN`ehdboOjC=0_oXaS@VMu_siTu52^a(cv?$VJeBSO@PW)a<^zG#Y4gABDxfwmt z_U!PSICNaW-dcFNy`8hQreFrdBpJXfWPjGpdBp~$3|ZHB3&R4gt|GCD7C9f#Ez4}F zpEKX&DjQ&!RtftN$~DbHO1P_WV-hOpC9u8LfPiVp-gEy%Fpc4ex z(@%Y0AgWN>>aIUE?7)8`SzggUK%GeRvvMS(|Z6+$Ziibox99tdq zig$g2d@RBLCI#XPM%H*aYfN_2>RDVvL>(A5{MR@(w_1^av!!7f_XKpxgB@(<+Q}1T zV>F|B6*Nr>njQRDqWj7!)U=DjkTs|ht+6`5UDN1t4oT3CZu%_p*8F7nRHmb{Z(Vd? zt?}(J4o{X&knKaS3>yLJEvwptG*mI^aoor%SEJk;HU4Z@52DSlwW=S1D(-dcA z#wQQfPU6P!DCX_YBjOMtt^t!*!qj2!|9j7fM@W~=oAjn*vIdi@aZ2F7XTAXQDlm4r z+g#oy+Z0E}ulIalQ%YzE@_|TwGc+PXk8Z>&$FlM%`j$w&32Wc5+_ntRqekA~am5ET zN@*{9}$)F z*?DaMx8cN4h(@XH0e*X1%ckrV2sezZsfe#Dx7d}|jXveT9TUqoNPo&jDh`1`r}O$? zd>uvS+Kkl9c*XJ+WRN_U`(**Q-bM>Iv4iLW&B!9CJzlblLp6b$T;}UtDKX>W{)#7b ztqX^pOv%_&_iZ<47}nq39k93#f7?mN-?X%M6nuu>a=97*C^krY(8Qs>v=1&437Byq z$s+bk|F=}p`#7O9UCCX5lavwR`v62=iA@LDZGN+LCwDQNJ$tmo!0CH;*gA78{ww#c zALz@l62!d}&JSTJY+2WV`HV_q|JS46+jq5mf+5lo1UyXWKx{H1v zvNY9PTDTO8M1K>!CVI`7yb#>H3MMB3!mDZYQ0Q8-VK{l|jUqAYoEy`Dvb-e$Msg(#l%95>Xb;iU!Z3_J0<1mh~V zt?)ruT$B;Bi#=@l@A!2;h`pPkdZUR9$(pQhz}Hes5}XxX5;@m^#0er4Omiq5zXSe^ zjX|&YKUGQH8}LE}7n!?9pb|435p;`Fj?zQ6(x23su>a;JHZXO`hb((ApS5)>ql?Y3D`aZl=XSKRu4Sesiw0$>e zmrxIkwLq6a&r54ZW{C&%LJTABj|O}4Ki_<(f`|x}7yr`{ZAysqHerhb{$X1e(|F38!60*JH!!bb>o>03ba(>UkmgG4#_ zZlY5HoHlKH|8=+7d2V~i-_yp$oc4kI&w^sWDJI9>k0XnjK&Q6x&9C%uEAOCd=KcZUJ8MY*8 z=yytHX2IU*tCs+i=`{~er1)ZnP7T+ST3$ zH7CWmi)s;Q#&68RDPk-o3EjP%;`SyBmAb9{rVndywbQ473>Y|q?t%Z9xfznG)qX2Y zvB!CaT>WeV*ciq&3ND&79E|mD8oyi2vIdF<}pQ@i-dLS?cI=cv$WS$ry zwJQp;s@YaZHJD#4Z8LTylnGFW2w1n2N#N}wVMkr*_#r}USc{f~{WD`F0jvs+9ve+9)R<+%6 zVYY}m)5$h>+ejQ0GEUzbMM-HQuRaQ#5(Dd}&j@))XkmToQ=tG@L4FTf)=L6dAdo!l z3z*GEDOd|?J{Gv@2m=RR@3xMX6K0+nx1yG<6G``fAZVwZn390$9&)KKJS;3Z;n{Jf z`B86{N4Zo}hlZ#|103EXkkpm+K@z{9|I4Kz*t0S?-G*&0qo}2rLU(UsLkAFY9&BOJ z=2XfYLg#9pi`oe_ByPi;iC4M}Uz88iNC2V?7w2T?Fq*dFc^PIH1}qgs3E^*5D?Cpk zNhq<>D3O-5m0JT^83yxPPR!;5dj-|?XQ?07|U42~@>ZX5Qw_T+4! z&6-O8*Q{E&ZReNL+Bjo7IJk7l62H?^Y2^zOrja5?!bT3quS|GGq-l{)nX89ORIuT$R{{e#tH@u^th^)u4%=-jVn#Q=uB$ah_q?iOdNrN$GQ$1#tBb(ku`LJkyi7KE2qV0SBa6 zBH3?o({2xTUE?i%7@5kFaYdU#Ywt_S zRJWSjRu1}6&Fj+DvL>lwII06M<>e?PI%qx!$8foWI7-N+x@8Ro+K$K!M18Z7np{t; zo$P4^bpAHtV`~h0imL)+f@A8iEyqN&-)EX)HF)nD+ul7hw&DM+???Z&hin;?-&3(r z9}VdN6f4$UJ*gQ&=ToFX@K;z`1fTH`K28a+O=hSe&O908`F=KIFEWS1A4lz?b=C#% zNEl@jZhJ(jw=ScLMOnUB!dKTpe4Lqm(~B+{FYndO`s7j^!xu`8SVqeghx}vMs@{dE z3EnM!+DV;jKFR7_F$k%uU5!p`{vovyyJo%`12I?6-TN5?Pgff%dXiwgY0Wf1r=7Iw zYXh-dqpK4j3um)Stl0>oOlz1=dn+cT2l+{JMzqfOBg0Rd$ENY*7&Cye!`r2b<8;Xh z^%wwafee8k!$92$E1$9<+2LdaV4bkiO^c(^QgIF}=yHqJ>ofdiUmf_ijw-G$DvPAP z5mXjeRbwd=3n)lDJfyAxCBv&?8if{anaey9=DV(`Mv*Z52fAOfTcB1<)guvXiE@vw z4_CjCX&A}AwA=al8dG_RS-4@EPXchdfqI(DpMXSwgAfqK4D=JmXS`C#rc`kV-b?h#9;(Fvc7fvYguE|0c1G90zVdI;vNPLcX!U`#8 z15w!Cd-8NQ-o-R#05_+BH>Cjq0H`(uz}ko&aJ{4p-NE}V-AJKzzs zNu6BBQPlugW)2zu=>28A}6-5Yv4KhS9K2v85~kAc389x`emyRz<7B6^=5{k~R5H#4Wn(hbj3m~I7e zu|NdaK#a_b(2dHGrCs-kA~G45$gt_FuItsbPQzQZaEa~njl?jKgUH9+x?sin$B!#f z1a?v-=tbJbL}}vWXBm}w_Vz$>p+H3Q>xb^zNHWwgSIMpc-rWcq8kEikG)|;}y#dQ> z`@;;c0WOI%95@#F0sTAtgdWpJUGK$og=^j9CwukFgmAqf9QR5|^kRI7PjS%)@Zm~O zpGHmd)RGyH|#KeQcne>xw*OulO@9?p0Z zK|+HEg-%v(Z*0aP_h*adf)+8Lu$01{Z5$n@@bpXRa;s`nz2WS~z)5_zskR4Sqw7d} zzPL`rE!tRHAOqdCCY_)vIXAuUy+8IT@9ole1cVOJe4R6+D=imBq$#u{{qxg6oeVc= znvn$Oev{+?HMMc-oLuI#Xy{6-?$-~QI)V2n|7(HWj@s3NAen}TkskQt#P1?^0@g*e z$Q~{(O2cK}>vl&Y#W2Y{QmjE5?v**700hMEGOYP6fxu(mifUT&_rZ59_tTTMJuyN2 zbc*AKA|02zChUm)g4m~$7*&aA68)x6!T$kp9WYnb$i!Woj-Yfc@kq-vwvZ z_apd{;!Y&DY5)>IbJO*-V1}E&^w$RPSo63e`jdqSbG0R!)>L(8{z5=^x}&lEvBu}V zOdCm<UMw-#HX1ObL)Ef9sT$OH|6|&%X?yy=nnf)C z=n~VGG7l0w=bln`s2oz@F{*9WpY1K4wPLuQpvP8szyPA~yZ$W9CU8WgCU_ZxV^GHd z82N3-G_4kiHL6uyUTayKMSBn+BK}DVz2i_cjfCHWiWVIKR7`K}8RfR-nmK5Pfqa#7 z?hM$MUHK&DSWvQONEW65l0mt!2!|Ve!F(*YPhI=7$`IZqTJpYHyoJtOCHn@p+^Fke z|HW$&xXcb{P9XuL^dki41nmd^94}3^lQxEcJtbl(t0B+*d)8^X>_$ZhrFF+kv5V9T z_DVZfQE58IV`0|-2kPN)`&7%f18zHWwobjNlqsAqC#4u^0v$Rbsqv;&0iQ3YwWUH6 zdkGPQQu(GD9SnQv+tnG8(yWWi>T@jdwlGd0!ylnLhlOuD6J^*d+@>IC)y5j zJD@2Jf-8k32Q`3cQk&}+k#zfb(V7ZzlY)Q3@R~!1cU(_5bv-@JtZq;Q<&_S7f5QSP ztrU?9FE)Bo$K*J4!l<&SQXZLwR%{}~I=E!ymp1BaA61k~a40m4@sV7i>s?{GuS44h zZNRWY>g;x{|GH~NeZyw7`3q<5iZ=7&9yRRG60JKZPV0KV&@QHncR znH~=m>V#)hW=0FkD1;|TWq&1NEl%fWh3{XbLifIqr%{ez%26u-^rN84$j=FVKI)o0 zd8`j4_M}w>j76|j!(hjkHsrVw0a)661kc_yS3jL)C&@Yy;LGHQGpmK+H0PFuNYbZq?u+hDfxk1-C-*ovo*xr!%D`-*DtCU&f=Fo*ce zG{q~qraWJs0U%&tY1xz42n`IN26FRUGUHMcB~A1Jpn7fEzEyp zEo|JRNszcMyOl3^+bxg5x9!GDRAEE*Y5NCqcIontFzqaaCk#1vOcD`i=(>M_UNb&K z2UfZ@P`y1g){Xi2LnVl=Ik~&=trcVe^ZslNmn^yAK||TfLx;& zlfFQeF?+6G=KQ^c>D8d|F=V6H3P{y_KG3N(NNOhF|{v z6Pme-+vDK+a3`RL0+97p3Io(VkV|ERS!J~ShlL1t(Z^IWSh}mGS-^a>?xpAvHh>Fj zr;26M|1j&bR<&j{$s2(5fWVYNNLP0B<8+a>EB~PzxdAg6PO!VGjzFMrTa4ogj@fzw zK#iFo5u~0~J&9MxMgU(_-B!t0#K3|dz{078U2=18{5U+#S+Z}X7nz|<>rfEenqNl4 zk2srKfH5!U{EM*0=~9J8lO`4?$0@1CwC_PB01S3r; zKUYW6{KxO`iT~B1zXRqGC8gr|Zp*E^fb|bbiFaDE78e-#Uco&0*{b44A_20)9s*dv z;voYD)LeUfLo;1h9(lcS9SiS+wC#um_z>elYF3T)*nV@4VYR9RHCRd4HYcAu2)bNY zxlJD2d}4}zTF;OBtmR+1T%vX5`xe0bR!s3wzAfea=jGLXAMUx~(jYvLuAn}d5ejLR zggPFTU@d6$%_mm*`iC5C@m`g%;_PCA?<^wExI$xLl)q=?ZsMi$9-_IU?O1`APvYQY zR^Q*KmCSw^AyHSy3~Pxb!-lanJ$O?riip@!?Gz(RhO`Co4-E{~XST*jYmkao%nHRO=yU$A8RlUn5cbfrAJ@0E<4@bujc>idy`e@>Jtg3v(muJxRiT_R%qo&KbHCI} zM_y42MG?|6M$}W=#yWUDO^skh!B%4|3+}eyV^DjE-{q9b|7?bgy{m`|XP}5q3OlqM z4^lCJH4hs@qjk(5v!|OI2u-GgXb=|R7|$i#fi$1k+acrxrWP^&%;kY{mTeJS+Gy-` zh*ep|%bt~_e)*+U4r04aI%=^ttOgwc80>kH91k`tY3eN#`sji$bjKi33#C&K zvdXR02k6dns+I{AT5dIz&hCT(Y#Hdv6e5v@y%Wwx$HBf615DcA5_8oyOzM)D#f)QU z^@^p+lJ?|N!+OX$c&7q;mO1MoR982|@R zBtHv5_OuP{=ZBJm`Cb*5iSU+oFkEu?3uCDo3HhHgW^&(b7DJun-^$X%PtoZq>$YO- zDHD>XGoeD)=~d;l71UOjp!738XQMn*!AOPOGw+)t+0{pkm{>~-Qk@OZZc4wkGSx04 zH+T4j<@rW|M6rY>S?SO%Z74(^S1{HzMi5|Hx2bynK!6q&n47{lrJBLW)#-{ zWX+heIC7wYrZv!fKf>wp--lo0=kavoP)ZPFbvRq+HJl4|Uh<)|n@vS^q}$cnDZfZp z+j3C$<|$CNjW{)OUlhrdDUVD8Y_8O(_P4U{?KzKJJdI~yn#5^t4P5cm)L!O{KJ%P~ zV}Ze%fq8jW4HORV9TWZAda}H0*v4$oV)G#d_!zq>NsrH-$uS0U$;V_c$I^Vs$Daev zj%A9(uoCT_dTBc!^jT{_P+V7Af}(MOnVPpMJ+vur1H*m+mtOeSP|`#KF3s~TN2C`O zT-DmbB$^(^y=@PKc4L{mIP%~}g*I@-T0BC9wakqeY<`q15*(~+xcF~P5pi933SGeU z5zbQRw%-!3Xkq3X#u@ ztfiAYi=B49P=esQy4G6q1Q5jw2Rb|(jbhVhlKjr-)4jM7aoShi$>bXi7(Nr;f9d=@ zQ#OKm8X|G0R(s1;2Q@6MC}Qva({rkyTMvY*wcmy=YtYn|g$)}v03{h{gUPO4f+BFs zu2uQqg2w8wKK&Wg$tfC}o9ze$w;FUN)+~0i$-gR=a@Q`FOq(nUNe^NYf~x}2yKT`| zyfxbe#R5(rqWzO8MW`uEYJ-OtWuPWA5d_8)RD;Sz4z%j-cdmvamo!xr)k;sn>UGcS z_~RibmheOmUblSV(V72|1H=oR4l9}HrN!cYnBtg}GrM#ma2Zc`3g zh_G3BZ8-^)A>>g+7+A#b`s{lYH}=QzCojVccMVC$Jj#49$Z^yWOLIx0t4$NYV&0Rc z7B~S+pBN~OPheewgZuwll`6BiB+ONnzh31rF3V~H_&~19*hO#Sy z8Gx%d*q}8^L8;+FU*7}u7c{3n2cQ&3ED4Ab*AsA5VWkz9Oq58j93i+jys=$h%V%mq zPJl9FAy}XH2AaxB`z}<>uDeItZ;CX;KAuR!#}KJzQ=_-ZGC4@S{lL-F86bk0X=nyxMHdK3P(Ke;C zY13pA;7GPBfBHIfHnlb!oSMN-Dmbe*3_Bfu2)i-|t&!4R?swqYq2MYzh2m=tA1pw4hFn%<4+&%3>ba;}xofLz-!Qd3+ z6VUifVqN>+LRT+BYjD#KqQW?K*9k8!H%4|{+7KOVyDFPO)L7reQE_wk(9nkXJ9B#$X27y_UMb`aMObW`K_j` z{sFU-tZa}It-%cFka(bLzqbBJItLU(8`xaFDC*fph2>}a+AB$*rIZ;aC_8uP4jsr_ z_iT?4I|7?$rrl7S=!xItxsC`*600W=X9*o;4PQ}1#F1M#)zR|~KL9Ck%8rAF)2jgw zdFi{YvN+K{Kn(%2`xqyf#8>77?P&9fRZXjPGSV_|TI#46p38@It?oSzTz9r6M+Sz! z1{l@MG%sIX%=fSn?I4%%lRyV}fpM~~qhHU8h;vvXp;ZY-aB@W9FVd$U+jGlpBa{dV zOexyBC->r~TL_e_*Mqj02_bmZ-42FmyJ8w)Wsf#DJ3AzDf|fkpMn?z(!XyFFjpG}S z;YcA1Js7TF@yCin8q}%M_1?|2ri+>=mo-$jt~xzTolP}g>AerwD?q_--h99rIAcc{ z0kMF#Z@Pr5a5JSd*$OC+KMwtPQVyvgbJU{+8#1r-Bh1@OzbCo0R7v++OyISe!%) zF%h9R*pHHfiiy)ji{cYYb~0}R@BYQs+83(?jsY|`RhY&wH-bv^R<$*xHO=G=?LPG0 zW^Yn=V7$A6Y|zsCEW7;;-py_z$|?g242~e7LaFQ4gEHP&$p(K`l}RR%kl)NSZe5e` z2r)h~Jxw4uFUJrYX%A(JnMFVhLVH2Dq#0nAuElp$J#3M{E=OW#jXJLb^i3OMtSf5a zF^k;LXR}I4IC4uz3ATM`&cYL}Olp7#(0aI5fur;D0eybSu zmNdF31$!hn37GaIT$>UpMhfT zrSHskV@ugK|6jX{B4L8dTzR}0m{g-Q5;3*N^d%eRBfMM;ugxhkn60{9*iE2koey{O zv1HItSec@A%1eG1NR33`TW!`Cn8c(f~id9KR!U+Gd z-~u$YD5f*j2i8Kf7Y%vq8Q7Q>TW_myIpu79MwyVBfc-DR4ZRhJ60PW^L?~Q(l!0+V_Adq2q<65<>lUQ>Cpth zz-cw&N?LSLdAaeZ)p!|_-CAOn-jCvhY4Q%%*#G_-w^&d?sEctLEAiLvfDMRr2k-CM z1|1I4?XmBR2s=2+m>+{1WuDm`c^ZySc&bYP18@PtGk(f6KNi7c&g3K|3@K1DNQJ|> zbN{;xm@4;e7Fv@W*YMm<%E+@Sx-iUq9 z>67t9whm?$cslffa}|OjFL0`QvwU$9w4LHL;#oALF+L_o*e39z-IRx(q6Mdd@YFoIe{6$=-tZ{MD<7O}tNDQ=9d!Odv4bjN( z;?>n_JIaV)?tOho1kQeU>a1lA4Oz^WWKQumU_}-hZEyZ*MmVYE0I(QiqGp{OAH*TF z`BV%%a&Y?h`R9ubCDZwNt3ojwL`tBavkiHDqk7aH_@V4zKTh%p1O<}`bm7^q?#`)& zxyF?~xoF(jW)1}smrhsnZ$`gRYDFulm(%ReqDxm_8W^Ea`Pvb8l-q1=gmawGvEd;U z=f^?yvbs!p1LsyiI?ZAcnEsH}kr<}Zx?xm>+f!t%LWxH9r$@Vm$56>h+Bi=E`?15y zWxQ~Pf$4<9f;Z-!Y~(oet+TJ80h6xS`es_7TdWCQV;#4utm7<+)TV!&QO(k&5Sh(Y z5{~7-cq=gl>@G$6Sq|$9UJ<-gaiqE}BLQbh?%02E{_lZGMd`d?=NOjbsNrFbcP3L! zuR)yM9HCjVhP9<|Mq3@SqUm>cr^rGxux{`@ zGc$Cf$5Zc3+mQPzr3*YwY%qN(aJyx4wqhPIfHzcd+1%A0ym5p4PE6p;MBX*UlE9

256s09c=g{K09CnPFU|l=%$a=-7#r5u zhOsZMT+TnjE8@ui-Y*Fi*9aF#V7tv_8*qi#DOe-Rs}H6?`>AH6G6zm zKh;5p+R3W41Jb3IgBR`g94Tv@rOIjvA&^8Auky-${ysZadSu_xCr!lYy>%n~MOcvA zMYO38imM@!skM)m)+HbRBln1Egbw_3Sbl!-vOq&96rFAeEwRO<(2f-rsUv1Ee`BEe z4e_x{nqmAV_la`eszh9&)&fu>V3vp)k9OR;>c(+SSX*z~T&VgP;1sA-9`SeAPnXd& zaL%}otzEbP3o@izHYfz}y8PktznS=3w)pF%Vtyp}&ET6X$Y8WVhhu zrwL)%L5q}QM4{)3CnFWNwCCG#1H+j{4nAk*5%TI89VILkSLJ|jkI=M*=Cc|sK!2Q| ziJyF2|3Gm_DFCp81#;Fs2EW&LS26BmmMr+@nm)M${ z1JD2>mFN#o!?{3dNaL67yqQZeM|8C}GN1+5@VW(xB{(AB!m~(4wp6f%-;w&+8;M#K zHIM2~OpL1Jw^N00+r@L`=~a=yRm%5-h2ul`LKgd+D3-h7ZyTcWa zdrePB%2ba^LVU0e1g`6IHja(~UQ?o!EJz|&vTR&uYmGi*>alp(eA)p2EB94&?Dl723n5? zdgjf>J-eorxz|Dt=oGZAnLHlj5oaYTKdq6})XKYvn{Aqs4LGoD5}rHwdduaNUiEZC z0?;|!$N16s;xE_=@vAhp(MZSwCauheznKZByRhq9FcWgt=3tCi3pla2^_rLH6Epc6#9E7rC65Uigb8 z%-1jkmcDwzKWP~q-BEgW{4%xtj-@Khc#!m-JPcryFh^Nz+Fq%^>5ky_GU9o^>Bgv9 zEkZCAFBo9Q??p9W@<@IwyWGNbb;*3Z5uAG1!2UBZ0PHS6N%tDfkAGHWE|dpXXjH)`HA$xGXjbrD5bnfqO}3bV-94_xZC@cuJb6G#TL|`KrF*S}RkcSOQXc<9 zy%n_6!$S|xl*8s#`|H0c*>I%GtM!Y4p)l_2GBz_3sjZ=T69|&EAp6|Z#!ZQku>y}h z|E5VF_AtiUi8x!SiWT3Q3~e{laGnKXkS=Q{Q0#l0#$bHR3QhF8tbKXDS(kOAhG{VU zepkLS_Js#6#2QZ~-#NPYmE|%!Z~99wY)?TFARz^6+pDN=9L`4f7I9dXxxh*HP-ZZ# zMS-_4*23IDYk;^rZ&q*dh!2d_pHPd*K%1;kPr|^?AM0h@hSKzEyPZ>b9%_-{yntkH z%I(!m$@(MF-=&-|*wx13Bx3H;=HA@tAer+&S3cdL!tIzB2h8}B7OXZ!)E2%>1jImq z)Cm>ChX5}MXQ-C?5MhU;MRKWZlrxvLZN!8HFPt@i&f9U>p9n5gK!Igz1McA{@YB)N z%PgrUB*uByG6%ulqu7~t`VOQu-EVFJ^!t3A+9t%ZAV6_S*Wok`;itUG=R^#2S8a9) zVnKCs9NKJHqKj3d1G55jOk_`#xm_)HlF~oNN!1!nbo^Un2o0}tGZ|P=R5}>o%O=^4 z3ZC11MF}jx^EzPZCKTUWg$<-;#N+cSfzys~gF{4@;xC7&=CCn@#u^VY4NAKkq^%O+ zQwsMn%~`4V?!!HSk5$%Y(7O&V>{ZaHP}{~|@U|?@Bb7mDGY1$|p)*gSA-x0>v1P%= zvbOO5A6&EyUD|<5eFR|uW8($DxSyt}vI;Q@8Wd*YZM&>Crot*RG37t+sT8w+82P#- z1QTRV$OQ8D9}=`sTI7Dk=dOH@GQ>RU`5|1>{7;p8M5Y(6*Q|1TUS+%NO~FH-{Pu*} zqY|(#+21Y*QnmA*E*k_>rywS~nhp0D1TQR0SvDZ9B^mv8i;=H({|S@XpE7T-{3?VXa zznZ8e{(0H{x9vk}>8gNFFI{x{H*ghmF1Df>wj8#0DB5|OHYux<86Y?wdJ)4M@A~ik z&j6r^5nRggwuw(m{Kk#Tba9qgyE~=RX=w;tnF#?;;(!I4O}(8{z>FDi)?o8 z`qWz$JkA2W7tpN6W&^Y3(`b3J4AqDYVCAZaVay_dK>HRo{6S1wRqQLHU8p6}9l~LL zB!0Xsyf*GQWX)IaZRdgiO~5D?|%Ex?Fzsyo9K@B}j0E zq;I{m=YgpM!XJTd+cW5uO7}rpEkkMx3YPUpQkY{5wFozf@3{*w@8 zbdHZekfea9cb0_5*-j{M^w?5QJlca0}| zZ;%OxI2EqHb;di5j^qy=^AQ1e3LN+^n@~@a-wSPneU9U4^cL#f#WT#2p3Z3fBQ-@IS6-(n3bbJaf%y|fkvQwG2R!9Is7j6*K zyCpC`?i=rni4;o!$yjL=^3b-4VDLA;Jk5%wtyL47q|(nCS#Mz%>)*Rd6ydZQm}+0- zq>$RtUQ|+MMUnfR-~Lzl^0CC>W*?i4dZZ zZ!mUK$%;rAcw-b~XLw(jV&ol{sS$=&_CcPUTC$AWRDYSU zY21ExYQbB@$lg@RL62*HcN5Ylvl`Yy`hwPf_uzpunhM7d8VixVs{8ISxzk3Jok6%q z6AV*pnku*w+Dqh`v(`u)ouj_!ez_WT6W+)+GT>fK#f^=rIznk!8AJHZ1;hC)SxLk%um{ zd~sArwNU~$`TV5sbw_E4Kvz-P&9*93%RO!}+u0U7KIhSI?VDrvsFxZ*{xQKFJ6^__ z-5wC%0Ro{>_!1dg6MtwxFWwwI2cN-3Ac%jUS-et3`7aSYDw%_F)Ai?;^B<^3(i5|s ze{s^sC2Pm!pYBqE6l1mNj7TqRxN1342M6YEU3;FRtIsOmO{AJ6PKSVR>w9GD-R_pdUTtBDT7nD3Wr)kSV{<=apT_ie}aCrym(3q@lUpY4D z4E%-I=;8e#g-EbYN35Y#0|1a~Hgg+ct_XN$XhIZUPrNPcU28_4;@Nc?o#Hv0wRo#e`qdoTFX*6?68AnbqE1)pU&0MpdAh`zLl84oKS^L_In&S)c3~r#sJ?A}iUtIs2g^DR-fCYY2?*V0b5c-Whz5_b z1+(-_?CMZUoq>5USATCr5 zH#Ul7C1?+q6-NY!e2(^Ei)T#?G&Dl|g-B!e zA!FN_rpe201RB1_OW&os@v`;Q&7=&CmX9<#Np$0P zqAyEb!d@9FxzRPFX50?J>?zX;e^xf#?>`5wqAgUzq6JexzYnaJ(=UQK$ zmWcjB^Rywv2yI>iW0{yty6TJWS~XjZG9~q5dt;Px>ygG}M^dojKka4ND5yK5IpEwp z%h|9{_-sk~S)<1p5ad%`yNQ~YH{@)=9aa;J^*N2vt`;)a0EkG)70$LQ&t)miPi}HUNfHYa@I;^#m(zy#il?z}P_llfQTel#;fhuT z#~42bygVyIgrj!^&i1PN=JbpzRvE@gNQGzS!+?I#YUC0sUUHtz9 zaSE2zN1Fa`Xduj_)g(+;Qh1*mmie6Gb2vfqsC3>JQQ|DF!7$Qnrra#!~i(e*K zpXyiJG-z|L$O4^t<#J~4*b_Q_-P9K|XD3<~6cGe15KWIE-CqiHEfMt+Vm?IAq4L)E zi1H*eBtX5kV3kMgiD~4SLSBzkvZgM$h~x;7Hraha*h9Ws*~j`lG~JUAoVwYjLcLQ+ zBstpq0y5+kR~8cH%9M5l1vbo0!d1D6ep}U5fQ$wRpcDY%?#12{m`a7;#_k>p`Rhs4 zi$f5pWa(wTqqP=rD~=XNiwLe>tPJ*^dg4y|Di+gcCuI;7uyq7d#&&u)fEhT46`|Z) zH~!gyyV-Fs#2`HHq}_9LWzU*8{Mfd0V%xTD+qTV)*|C$3Z5th@W7}4T9lZI@ojdo= zUH4rxvwr!jp6rv_XIEBMea=%)st!0erI-@O8N8ybA(R8xTq3x+F1quA4Y})uQ&rK{uO?Wl zjGrU-##hPXo?gKg9vzzx1*K5 z&a!*OtaRVxb94RKzR=uDpP?cX+Vy_22;{7D^HOHK6pBn)4O){HxK-BPzhCvvbNMu8 z?rnXcH9Wf*XlW1g{mSQAdix{<`%{hsTB9A3G)4or*po86-iYpPFwq_1g`oNV=TIch zJwrsc)31lF66`ct{0x{Naoqbn6V`?dvHOwa;JhtGN)|`#f>V~m8Ws=T{>)S9QtvS3 zZZV<=<6j_FJMpVo8)PZ+BSK3_LR}p4(a5A-Ip5ZR7sPiQZSFDr5<`UpepCwh(lET@ z%2=TlO<=cARMDQ!M$!ye%tYPKgA-iKIL-gJ*lz6$%H8 zM<#p=ai*8=92%O8Rt%U z_gt~*d66#_r7Ne!BCLx*hE(FsHzQ3Iuf&eGEZWc%BZ57n)|4NkG0tj<4KC_?)&b`M@tcwW6 zSQ{#LX;)7Zzs9{$-G}s=F8K9J=94bz_uBdm;ix#CGVQ*C>{MN8{Lh%5x=V_n)4vDB zdgDII=Yh6{>Rn{z?ltU1<*q|pYFj{2XrJT;c=LNH-@N=GC0^KEuq%?@fd5PqEV~Xv zRz0=Nui%JnT&(CAphb3n){ESYe$TL;kZN@6xdo9wE}rOr>0AUzUdW`Pui$2PVQDe2 z5TlIR(}K`soz?k97ems?2-yPFsC@52W;b%1m-9K0`#KvY0wWVM*fllvgb`Vc7V{wZK*6SOD2aaN>d%@F5=8p;48Ac4Ogu^!{y_c4nj)3gA-$ZDU;8J$U zHz@9X!D-|Lqy;3GX%vSw-PK(;`TZ=5X7P+;sS@}zaAfz|S|)0` zWjK1S4u~ZHS5-&^E?>_r{wfybs-rusCH*3ECml4_xKS92O`OqZXJDTSLZzx=Y_1|Z z@W}PswxT^HngfGAs2+#8w}$M*tYLClzs2;;$#o%*$Zy@xnZ=FtX5kNC?#k9Eo{1O$LQF`&#p)l1~=UHq5SbCL5?BzAbAD=y%l7w&q7F?G{N#p62N z^XZZy<(5M4vak8%(!7>^tw=w*UId83mEh=fT2cg<@!>m)3VgQ3CrmAQCZu^!2i_}r zLK5&39Yt0`o=d(6WGIE(CryyCIFKZEJ- za>$Bb+Gg4RNm`PG7np!Z7ki;|t7oib^Hr~mQLj_DK{DO%9$T=b%afBqpR+*VABA#i&Og@d~VrpfJyhzlRG( zihmghaFFA#19m)VJ##WHEV@9MuIsHgs9xfrR#xJw+Lrh2d>z>E777enzHT1C@_{{% zri&5=mUMUhiNtD(L0W4mD!rUT#AMP7-*!FJf%kI|W|Au91F1`aW2otk^3c#})~83j z60)0DQaKu=+@f)G1Z>c{_<9{@YrSci zAH0b|<;5kTb`8?dTZ4yb;FTyc$0geW;%F;PLPqUIg%wH4$V;TQY24(HC{s!M;qbNO zu>+dbNfbX=H^jmFCQ0q{V4;75A@mCjmiWEDrZZ@RFI=cx5sCAR&=zt+39>6rRLQQQ z=V60pQy;?Q0qjK_BQS~F5+uq*OGJgIkC5JyXEmjf{=niV=AdiDlUjIFk~;x8P*CrO z;OmsJe^EE-o$`L4-TH;*@50P&RV2E82r)8LE44eKO{)?UI&6`JPEh82A4fZd*xIk! z6^J&pb8|XyWPF@4#c&9!%yyeh;bOS0`B9>jZh`u?t@A(x${Kdnj9bn^0VjTuJZon| z#1g$r?qnpcBS@%xvq`FkV4Rfs9gW398nGXOnkQhGJ}@Xg*Wcf1zs)@@HSG4s>bD!i zvik)pzX2+@q|pt~N*1mqf*9L?HS;yu1$%NVDC~zqI9r8vzkwIkPixT`g-N@&xEH

e#_Iu8h=Z<+}!A2h}W*O74GDfn(T}7?Ll~jk`hI; zj@xHSi&jEHGXH1xuEDtyMAOYnRJLd9oIV8{;jV>^>Aus1UmWs9ekko(8BqW~P*@e= zlIa1n+^e&x%yiWxK7yll^qTHX1*XI|B;J}%1Xl%QTtYco&pQXY(fh|kb8FQqCV7y3 zTsM%q0=faWtUF67eeSH(KO7hH*dqq|_If$ZEIyh)v7!2z1u&`(e#p!CL!zyRO0}&p z9H6h??aUeC36i6@wA9f8nH-$o@DKs46YGdD5_T!P*p*E1Wr0}$HIGcX5P4&ymC#-u zlVD?2Y@xaiWgC?G`SgTJies6)4)hQ5JNPgS9YA7Ew@0i~>o8JoS(xZH7d0Qk$=fya zFXQOjo9oeytsYG(9r#ZAEiZ(Aa7MQG0Ir|-QYVv?rD4$De7;XN$`C3BP8oG z*X!Zluwx^)7Hc4Zs>x7z!#Zk>6uz5`?~vba;a5a|Y0TuMk&t#rMGZsEz>UH@MwZNo$nY7VGV3M+1rwYbxdKw?{jYr11A3QH1$aAdm%f3~j_Rr+ z%}gKl3hlAw8WdouE9Wa%CF{IVM-U3eFsrqAF^a=%a(|L@%)2V^Mb}Zxtf57%8Gh^?KFGXeE z9W;LyoRZPljqdx85t!Jntt@$XZp6QAUKb1P=v*|66(< zh(jWsYGweS*rdX~KBzf&@Vm>A(d@{ZCcN-P*L{TUBa-_D9(3PkXo0<1FHSFQk}bE+ zSce=_3<|bqPUMV$2B zpyMBCmynftPsOtnv#%vnTQqE8x;{(Nm%<-(Fli0#Fz0^JkuN2Bk|LUJDrG%JQ@v>Z zagMrHiNlaH`!I#nO#LDyegK-Hw<&+7E0%ku%_@Q74!73rQT_HcfV1-@?<1*K3*a4n zQiM}{-XPL(Lwd^x6$P4;AH+CnZazNhB98VqaHJ5?*^&=llVX9>bWe^Lj`%2_2~WtfL}TFWJVZ`~ZQ+t%HZz z!rqbUD|t0OXj_DaUVx;9*#+(z{|$YKbbait&Wt zX^TDEav`u!kCR;m_ZsIj_VjG_oE?lbi&%#Oa$ha*4(`F9tkH&xj>yY4lyv$$>y>+6 zM9vu&Kls|Yee}II`?R2g(em5}OJiO_RrtfPt2&rl#i)r&ueVLLBUMtAwS@->R?Uas z{IAneIfn%fL4&4T@1`CB3Yo<70HWYdUSW~|1u~yX3d1@WcJItQq;XmgaG5AV5 z_X=`^U=Gx}Q4CXMdGADif{f`lNqqo%KgVq(mhw(W#tXkxLu|@J>`CBIk+V)q_peL_ z?6kRWxYAi9d_ArD*;3|0KmpvBub2tq6s0`A1^xK5sqK}SI593jFsgUKv2l_nrOJUd zU_iqp?6|W(0$z%gQ+h$j_tqpcQvGCnXTdx8Od+jXP;wMK-+?xYi$>f$91MsWLfm!U z;%~}qZH=fLX`Gw#)=R|Q?dL$>h9rJE1C1nSRE>U}cw}N~E6lk|&$bsQwer}o8%ouJ zEVaoXRW631!5eC2!krTJBGEhz;_{ekCC2K>xlY9`Ftem@fAk0Ordu}V*fUCxUpVV- zzFXwSU<4I3D7_WrD@))MQ?#!~k3cjzGiLAn;MlKRWhW7kUht++gf!f9n_1W7Be4Sa zy589A7y5YfV{7&ud6(&YV!aK%_$!?pqpn%iQ2YCNVE9K08b)hvtZbb+zC7u5mw6<- zv?o5!^@S6*6? zjsX9<5!OH=;yGo9I3iSz#9M>U(6^97it5F8Tm-e?jFyuZ#P1_p$xp_S2HzNu-i$E4 zx>bL{wS&}lk^4|Ci7=*KbRq+%?aN6T{fkL$vxFRGEW4Tl8`h%}ld0`k-y&TN|4B`&< zuA*ixCeBult`5#H{}Ia@+5L4zLPk+Rh(^}RUe?Ok%-Pk--b_{M>jkz(7A^qRzr9je z*x~Cy7&>+qRsbCf6ElFFiGvBi$;F}v!yx2hVrK6OVCUk1VGuELlr*!lu>1d=$Ki)`jK)qvb8c1vbV4`1JE%s!!W40n%SuXIM`trH2?FbSed!LIBNhPT z-JlBdXfoX}s3YJ#Ltjatb7K{YtNdOjyLIE0`LJNw1EP#|A z*Ut!B63!@=T$m7^1Y>AP(Fe^1f`?98zE{5rA{C(v1pvJYfFLZcl9tJEJ@_mCVXOIXjRay z@UqoGAZFf~-aX1KWjqz@00l&JGNM5I6U-sRz1no-C$EKN%;iAW)Jj~)I?g)Wo6wDZ zX+)1YFZTjRVoi>W!EjB{%nC{ z57417(goO$PvTzD(3dohONR?gorDTid8=JcGLU>zRUjfN<-(*iNKz!S0_jWGvG9$w z!kcA_S zB{_40apa|i04K$o-$7DHjU}aFcI3YySz9+!ff=G$>!xSFBDSeC5{qhci_$TFn*cv$ z6fBp<3A8NRvc-g>pn_5?PRgP}hUzfNGW5WzJ5<3;WE4GVtdLQL4(?!5>6B>Btv91| z69$_Fpm_gjZ5y)rS%S)gBVPHUZdJu&P_4V@%aQ%mqjvm|8xk3oe3OhI=lEyW;>uL6>^^95+y5BV%IMnVv#Kv9PPDwrIbG7HP)bb8x zuU=FA?30JdOvA}zF=Y4gCzWJ0+6sN%UA${jw#_wl+huI$ zx_ZCdjXk^-v<}F2t!i~u)C~eELKvIaFMVG!m(tPA-Q($jtx zoGQs_>DdjrfA+sceH%;@srnY|mMl`{A$53LFSf2q53E0t)X-Y!#JeAP+sARe6w7=j zN6Rq&t@h=|`c+nAFAGr(r;dZtP<4wHm4&aO&3K9l^`<$gSRsm?>+k^gm^`w-%UT*0m%uh1WCP&rzd48^*gn!)pd9HAwXj z^IbHC=jlI>PfmWS{fvr+nBL$JU@;sh$1ydfaD!t@W+EubxkPlyF20g`hYc;w^*^nQ z?$zLObUmf;(Rh=!a9D3EaZj2rrpM#suk!Ygv$^tIUVh$E_I4UBAj5S-EnWqOlt?^W zM5t*w2z~Zb!@m6Ko)z#NZi5PI62$yCM_R;XFVh8P(&5gS=>fzHtfSiAi-;2X6xDbB z@mWh=u)n81itk<`2DA7+d9ZhJkCOk{5Vf-!_+k%z2NAdp;8czL5;y``_(30&M!& z-D+>Yb+>V0J0isGJpH$}YDw@z5YW^zPZlO`L;Li5YKudTAS<<5XYbtBJY@|&wO?z_4vFAv#1r45-b^{@4Gu{t69v{xKCABL>zB^T znshpF?^}G@{H|T)Y+H-y?(3a?V$3kD&oH0)L#?1VT`a$rI2&w&_98wUx!(%GnpuT} zHLZ|eMR<8XNS)X9fNSOSvo1YbGqmcr^K;g-g+Mo6$dS8@8~9M%PCSr+&&Is-M1wBP zBMkrM?ZR|o%Fg{|OZ!|VB0xdLbo`{oT=$n{K!&Fz093g;JA z{);G#Uo-nZh+^>tudf;XU;OYF7XHN#tpD_o|K$f3_AeLx-49%>EPoIFJ0CbW{x%ja%z=}zQTomc|pjD-`g^%Na_%X#+>FJd?tHYD^TV&vVG;vCK$`8F$QkG(W z>&-SdtVaSZIDi0vlyy=V?2Tc9@CQebJCd4(D}wzHgp!pD{vLI?Ct>{?twy?pFQ{?= zUN#dbMG_3}h)4^@mr{LmrD1Fw3sM!=nJw2unjDWz9JEcHkD3BpyXhwNCRLrS_07Nk?s5}N>0?KU>Vl-GWLE0NZ zF<$^uEk5MnV~_qFm;#nGU1e+xAO75Ik&}57DLAozT~H(4;6=|GmrD? zT+n;(DCBr`FihOwNE@oI{_)F*+`CC0XFb9SeMU2+Rt&^-`r@LMkBDoRv)nXdlnssC zn8)K|sefbJay?(oxm)KMPwZ~KmiNyq&s$u4p@)J@|1KZ%nU=S{B5;nyr*J!WdT!s6 z!s22ahcP((Q|PN`6TgI8dx!0KLOySd)SDk&N8aY{YGqFbFP{C1IP$Lr#_wZuyz z+Zy&Q0(Ms`-@U$(a3(zTJ$f5LmPWtYhmARzevG?}qsM#Gt2QXtw+a7(6mV$ibiL7*Bs%=QUl%Bgh1bP@U8NGgAGuM%nV=V%rcqt#_Hl9t zZgB{Cj>v955yN?PnLhk5zt*(Cfp9g(qhoWa!Mw4KYk=ZfcB8yD0zNP*3F&Nc{k}wp z>>{z0H`^hAls&A#byIP%{Zi4^^S+=d^=!GfJH4`rA5Bv2vC@#b>`8dqGtsdc6h2%N z<^L$AWc!#AH~SO3cW!+mcX2Q5Y3ogZpzr`Z((`-_r<`Bsh` zT{IPs`Z3nrkSTqXm)e70V+&7dgW8LcnAG7`Z*~VjN8jR7J!8vnn!geQHex0k{>5jz zvDKEZGa#3%iDJsJ*u0?oao+?!tATCf{ml4DaqOl&rXr|xZLan6(2M9k@;$>RO`=!; zK1B_cBU9Dryk%VW8Z&0{DJl13ZE#w8w1B6(^*49Vw)Ohjn@bcZ&ZFS+)5EO$CSztQ z+o$?zjo2Oj+4x54&Ukf2Qt54N%#YsWPNqFW{=?_I_!pb17P&; zWUuAozCGLDTYu>=wp_oCEO(p#*n(=`Y<|q!@>`bM^J zw*fQV9i!7Dzd3y;SJNFGM)*w)20BGTiZItfJZYBg-~*Z*igXWok!Y$*Fp3`yz?NPIQ^?uf7EKNR6+Z^gpM$n-CY_=^nxq6qeX zdbocmg7crV5UlK9UH|RcKQn@vg^BZj&j?sfRWDoxu}t>L^|N)k4>GaILp+uvVVLB} zq|P!^Towy+`B<094D41Sc4^Ekby2#MP%%uZ?+sLo;bQ7W$#U9R?3H9Mw&jml<<-|d zk6u03Tr=%m*MI)>USGfW_I@(y?3{|YA?^1^u*8*@A;tEC&KZ)Gm=gn)2q6tmPGYK! zCAR8Et>T0#7IKc@#`7RYD2j1E3!_8dOAPhlBZArjY26#rBenoDhV&Es+#R9}?Lz`- zBO>aDA}UVj+AT-~qfROJ?9(*`-pT~pbIwq`>u&}@5G{j42R0BT9dzWPk0mu?rP(P# zng7V$={Ds*GlX76gTf`LIur^6P>0CX09PU1(Wn!-cNH9i8TSBjOzm1Ws6}B zXHSc$NQ;Ovm4ye9&^LoG%*e>y2SkLCWQ%{q)EpLp5ff)c|A=?kGKWL_$?6~n9TnMZ zI&`MkK^RWG5E1wZA=*KC?W-&bo?gdhI~5942qYOQDNabYi;Ep)8KT{ag!YQ09(Tm6mQRZs;pBw(^SVRYu;huZauD`c|%XD!w;j<<_09P{hqvmi* z)WFFi`+eCQFzD1`2eY8MBbwM?r~!huWaImaFTd;m}>ED z9nn4D?M6Rl?S8Rw@OuSsk42jNEve8iOoP=Cy`BQ8WW8rjbK-mdTLQnFiHzZUgM;GX zlorE^jr}yZESKw!V&sxr@%x+nZ-_kR1}t`L{Ar3vKzq!;vV&tOFfY5^ToO%>OE#kL zm9`GuN9tKA4i_pK(GgWpYjd(MzH|Lr!bm?&N?WRm$o+YD%QTR@maD&Y#J7J~VqN?I zxX0195@kqlzZvLnx6f`h`x|#`+c@i8^-&l_bx7P@%&S5 zx##sMS3s>ZE+$(n-haV!xgfN6p=q=^ZC>A8)alJQO-wZ^e3c;C=Cem*UsYB_(_f(Hr}O6 zDK$&&D2z$fD;kr3Wc4-Nf?GVvU^LIfdakJr-16Q+qw;}w}V>*Bm? zO260C=P{Efe^aAG50t=$D$caNcg>ZEoHuHBl~nWijTriSQL|y|=B(s28f^`pD*jlKd_73Y>7T$)R8vpxg8`MnQDrrhQ&M&pb%uiDD=9jv( zncq;ef}QS-7Di+WWHOFG!3Xtj8_G>@;VpR0w35FJ+gMjp>2whIAi23@Er(@3yYjA<`3w#BMbt`?nPu)H~o$+h*o?$ISI1L zRZoqzWWVN*B!OlB7l6qaUbyp^@>aw^^*a~Cv!{FqN?dKmLwEGfbhlgROl#EkgRwiV zvjR(cyFYsMSy0Wg+LG|g=$q*hoceLfs88y=yQ{mKQ^a0V4}OOqU-($n6lN3wdZ>YF z*%O3+u4v=tmam~VnAh9o_vY(DlR=jc<)Y;wb89q}!VaR&gHY7#SgsTsyR?O#9~-SxY| zuBLv2S$>u}dcHfy*bCS=ecq?mRf-Ju(gj>F&E+I+`Ow!YD)jMl(4C~4rM^!$hCW4G zV!GsnS)lQqD+l|lKYnBAGRiL4b+9H#e@)&(!F@`?rZ0@r8Vsqx4%g5tHwPZKdrRWk zf-UUD=%Uy3G~1uu(sIE=1B}nly3Jk_OVLLjkVX>n;~d@jgR<1v z{4qDvyo7tsCP`e*n9jDdt*|iL_0%=H zEiN=Wsk8L^VE6V*k5BK5`Ak)_|7Y{kb+5lo)-)WA=sBm@=!E&x`^n3{&l zkjXIJ-1;me$=P&4hUGy7iY&^6oy3U(1Ud2hpq8jIV}K|K?+sKRa9uHcw8dZp1TEBF z%#NclED>WU5C|zP7?CNf3WaU~xuO=O73k#9k>LUuW4wh}DM1%mUyx#Gq47>ggb0&v z+{6M}Og$KsB=mkfbdTgwHB6%N55XbFK@q=SM(GGnWh{N@1)2HUsewprzmkskL*cMN z`Wc5H%nL}%>x`J2seY^>iBOptLXEMOwzV0eQ1H^i^-Ge;`7B|RAu)-`PvNz9#bOae zip6Itqb0+!ktk86_h8}F2ybKyeAQ!JHY$WC^uZhr(58bXI0lMFie#*z@LPj3qlGrx zBa=r)s_(!6(8vCgrdS!Fc9Sw%5KxjL5z}k{oUhfaAx1*JF-j2i=Vi?R(=r7X3B2uRLa(lGM}};+ z?TN%()b4$zceAtk()>7KlA)AT2>5e{b?cbPfKa^QuM_e_o39ZBkF{8;xOk^EoCwc^ z*^MKVp{v^9=%fEg6%ZGvYxDJmgiip{4=P7=8JXyXn6M4&tAio{qSiQ~V_C!IA(mK* zoe`q&b{K}tjM+cpfWo3;fERM-oA!3KK}ujms-JCT>;fOfoa>_iWoIJNMbz;t%HIoP z0ZI|+kNMD;>*V&7vb5*(oRg71JhnIkY}O)2P0dUSaj(mto@BV=yOG??W3_TsgTF)Q z8Z(~Tr;YG`q}MAxg?<=!tB!)WuNQe#%J=4|B;lstC~mY=k^f#z{At8Ns~uAbYA?q= z8lZj#KK?QTCyk&`tEYcZ;2FanW3$!1+{{=m@=;+ifEYcko>NgaDnY~U=V==N# z|6QV{`M1uHz=chWz@(-+Lvz5o?-Sbl@1HJ7f@7j;4wK`#cKzh7d@3zNJ!7_f8(hVe zeBxwyzR6ORqfQtfDjN5gtrXg$aVJAtv)Lo>jOn7NHpFpVWwYndi)gaun}=TotCSVzKGe! zk{^dg7c15)=c&PrapPW_pF{C=^^(^%c|K~lb-2!WMx^^Xg0MRC)kq{|u3`C%+uMws zWyZ1pa8PVfgP-65=W83qX@TOU0iO#3zs=&(%V{>=<;$`#zV}T($m!BQKQ$H+dStv6 zuK4*CLvyoTJEsbMts3uIJsoc>MYCANox5i_NIO+J5l_eZ@FzZRT|bM(*5}8JXJ2vX zyZ7p@CM4)k$??0fK1EEY@C+1Z)*rPe!asyNeeEr^gZ~jMQVn|l+YYDW=X(+k!KSNs zPr+T^@ZO3i_BDL-{>qd~^YWv}g(?HNmzx0^%4=Q+dA`}#-bjN{kKfy`OjZ_bZY-pdy3hi19^P}T4GE7p}C-d>=!;knFV*El1 zDi+r5Y{#f_KXPNLV0C-CrfW+d55U_S)%2X>ZNcPTGJ!pM`=5ppUB2JkP8&yyk9+*2 zE^0j!$R0(@5HuTM6%qY!Ed%2Ae$Bf=f1Lf_bKPr?Ss$9(GWY4@=3vj#s#$w$_8zro zFgx9nuFt^+P<^3aLI`3z^*<^U@hG|SOS^r4;8AHW|7ZewmujWE@=x0}Sn)2w`v4}Js!PNhXy+(Ap|3B({+5T^JNNIDi?0cTjvH5JhX*q)jztUJzegz(PwER zG>=c<_1NUdMA+;E@X!JC_iL}~e-bFty`XCQ*L)|lcG9S4aZ zuxo2vjZh5##d~*~j!wqTYAn--VRZELFiRp@4{juvbxp(W;|Vc4?M2TU_xEH##Tt_D zg*nCX(N1*@U&Xpbre!aCs;=^k3}53GZQG8i(*5dBXxQxYYo6&fVyBv(ga=lm-3#4D z;+*>B(h>Y@j^~}F=4|X*6BG>wIcRp6vKJ*}l z(}ImhWd|(NgG>jk6NoLFqv(tY)l_x40$~BsklzmrMu}_C6jdFCtY`T}bt{M+K!O*0 z=3TaUT+G{_{6D*&{#-xBm)C#em_Q&BR-y_@ru|x53S?Fdv3X(KX)sE+|H57(wd;Zm z$AicsPD~#ei4!CnH3`+XqL?3sACw>)k(21)wd*RoE4L%bab?NA^vpBm0pS&&AGtv^nDLGTv1{w7OaKB9+H_b@tY82DB`WA@{=c-R zTZ08_CT$o3?S9P`nOc)r?m zIRGXun8{!we$rBco6o9lL#U&(>)wPl3o*G*g;*8XPw5%Fa`j@I%;1b1%p1p|zP6;H zjlf2}ozKWNRgAcD<4>M9mns47h0+W@p{h?6g6jgVn{YZz<&uE|_cmoVZX8*XVPnN1 zP?AFPDPrLY9p0y`XhNAT5HF82%Vf1?;ALan`JX6vokQg@}boRtF2S zpvIPMa8V?AY)7FJ&|rfpffJZO8QOHw#UkIk+I{&Wz5%;o%%&G4gLB$u1Ioz&!ZK$- zZqujUw|xmvj!m2+-@p-Gq27}(oU66vQV5f9)Vzn(4bdFXVucQWXVHajaC_+)-K{Ra zxEqKyc38t^niIxsmA5Be5c{9l*{n8ymRFtMtQ?jXTWa-TvzOjVYY89kD3CXW#0*26 zCV*eu>r@seFnfo~}^E7FtseeE) z8>yH3>-7@hcwoV&!on}Pg@IeidCKbbKXaN8)j)} zG6pUB0t4f?ykTI($<6N_DSlM_u(egvf5>--gC6%+9 zp*9S1*LTqSduYC}Zfb6Izo~+1yP5aQuA6kCM(a4Q-9uUE6LnsUZ#&Tslz zJc1{yA7vb510|#f;ZJM%IPX49X<$;f)bMCO+GT5$!@H2I3$c_}lvVNgO@t-y<1_zR zTMK4MBV6|*aUSIDX>BE{@4obMi&~Bea%01(^xp!%$R?t&I10Yw6LUL;VBy>TmTmc4 z!KUtp;1fTjg>>d<;gF)q2mXfo6TRmehWQQE24|~R`aNeO^`QoehxKsWu2Wb7Hn|I3 zLG+R=-1Sd_-I0?O{R6_83Tm#b`ueL`$^pyfv~mW^+egV;yRwUyihHy1apL4fx5>2L zgJzPz7BA21U2z7k0c?~hQTqnVZrbnB=TzSPj7&YUVdzNYi}wmX^{c%e z873}02R6u~Px5x0CvWqq#-pb>gMhK|VV-Gfjq1${rM&OljLX`uwJ`m^>wPg+EtBU) zWGl>7H6E)tLNy+2)@fk!9AvEM4B+F+N)`-xFLz|ltuxO_&AT-McBk^^sSG5aj}uW& zQAosu!i5xS<4-QagBMStIxtEuK?2%j7K1Xq7Z(IN)mmRBxU66c=Sx3$_|kTBIoEX@ zHy^%*)03daGmUMUw2;zlx<)xkwFD=r_)Gc0!;eMoo4=U|Nqgx7%5S>7fJ_M|wv=;G zP1m(ryguT!P;he#^Pe9>=dLcXwW{=v+-B;$sSE;iG9C?o!-t9K_qYJ^-b_T{&*2_n13u;#Noed-T?DP z@jHjai7g(xm!ok_bbt>we-PRRBflMex%zNDPOh(Z$j!bv`}!+tcR+IFnC^~j|Kb4TpF1^%KpXnlw!#V7JsG;Iqs_iY;rgUqg z;^NU*85wI~()+@lAy?vdu#XSCH*GfWocox4(^)cE*<9yfoa$;mB%DkPibER-rOU=;p;PbLO2Dj;-al0sK*6LSov0r?&cKFgA(%u~{ zZ1HQVCJX)fciV#dR;+)EMW?gDhHkVJRfAt6gvh-wyZptvE~j00q76vt*>rOa@JN=P zoxw7Xi$!zymeHPgzbw{rvVIj>{ZlH9mz( zRa{*Ew(5(Sll}jqD$egVxN(%?63=w#XVIKx*!NS$=D&4=3SYGuXM?@M^X5;eC5>*U1<$)r1;Zj1a!d(3=|pH1B;E0Sg%RH|_{27Jf6xd#+A^Ik5I!&H#V4pXiVLPIy|5%O zP^=%8`xhW$BuUf;h(?lBm^1^}6CCt@O2@g4)-nhzSd%z^@aX;>?&0BBhVfVhivTr5 z(AQ5-i2(y@FlPT8mdKaD+P|7>GVG-ADEJ`_VFq^>jJP0Aggk~3V~7#V|8*Mbf+4W% zC?HW3=?r!x_!$WJ8$~kQ4bTCippa|J#~X%xzyB{`l>9yP~dw&5VFUh`beNP=?0> zd7t=5@JanbzQMh}E-ibI@_UyDj9Mppreyd6rZY30g98<510kFMK*sf&fwF}_Mh0n4 zZWwI6ghNr3oOs}jKu!>7#2JzxqhO#3p`fGBpwXg`IB#kC7in~5P|2WyJH`fupn7L^ zR*&5G=8NDxTXS)P-%gS8_v6TnPYWTR1$<`kVfT)DKMk85*cV>~_~^Bt75tZ4(Vm}a zWrcp4BJLQH5R=gI+k$FlfQY`e#_G)Z8s+VL%73PwgV3EUFdaH}eHO*-58y#XBc~|b z2c42bO&s4_8s?JWfidA3^5=B#Oo**u8wu(XVg=!G@_K%30_RgfV1c59{g&I3as_Nb z4ebMiF^9*Hd>$&|#M5_p1A%w8!G|*TAe#sM;)2660_H3P7TkBX>Zhz4-Qpxhh5`qk z)e8;Au*b-c7vl7tMd?%MLj)Cl!eetFKmq=R31CE4V9ZdUH9jDl++ztRp$$qs0KcI@ zcLh$PNoqHgN*pRqhmM|x3=RfxpGi@Cvv>WiI5ulQ5iP3VHSOE~N7^|?SH5W3K9!1XCl%YaZQHhO+qUggY^P$| zPQ|uf&h75ow{M@@ug`n?%m2g97)i$1W9+%+n!mYtayUxJoW-2$73q~>3x~uTna3XD zM(x-0b7no98GnLK@jO;7oyyzTTD?nOtm-~n=Z@OTR#Qrqjl2YBZ8@|^-CT#UR>VJ{ za$kxR%9x?f8!M^k1XKu|8RIClYYj?+oS&X}C$n-}UDCM`b+ZuSPffa#T(}&`56(^y zKaLhf$qx=ms&tq>DJ~%4(1#LhveT2VSu6xvA8;>kmU0(#6a=+;y1!D>b z(_$ENAnbLOZE%y(dr}r~Sm`#_(nxO8awPkecbQ*Y$yb`PE$r!L$_Yvd{6>E`U(nkP zL>0Q0*JnZvU-W5nC(ds`+%fr7Bzh!m|8)qZ!k{h`wTFlFK)z_kt=#RzIE5T48dS6I zhGH##*3up3b|dTj92U!EG;|_DYs`6kf_c!lzvmQ$V2mo<*0xTgs>5|V{8@`JGb0z| zP<|>PHIDO~CeX`e5lQl&Cx+;>PUM(=GAY?~D)GL`@wpg@$zQo5 ztlU4J?-M?%EU58Z=DftIUJ){=c{!d1@b5H+Eo1xqTq1fID`rFiIeUEMkz}DzvWL>v z?z=wS>a;8}UOc47o-o0LVKC8$6iXUh45M;vt$jI`g|$sOT_#u9aRr-nzB|b6bqk6) zKQ{@{MEZ$i3SOknBM2O2ie)#R0j_TMCj8P)+IirNK4WoCG-%VDj5H_>i_pDRJFChB z+EO|jr(w5=f= zDa3qigNseM3)`7f7eI?^fQpxe@5M{2gXB{Sg7ke0j(h!ipEp?Ooaxf7j zzSXTfTm7`uW_%ww#?TVI73gxJv7c9|OeUV0=&oqfB8Al@>n zOsS!u%&ODs#n1m`l!{8rzpC{1BrIHv3;{77*=j?{s|h_abRqAKkaN!~Q2cP@95af1 z$WR`p1wE1zhsXw=Bf^=@!r_Mg-nHUJE9jBWV*PQaVrnHrQJc#9)Oxn~ypDlwP*hlo z(;1d$rNZq@AFeZQ#>raY3B6pc!zqz}_2spFA{|z;7`dfoqtL$}^W}%UvXI642vp2q z5!V}+2eqMR&HbLEr&{XII2O8dYY5L=Z*G9puc5 zqP)lmX2mer`-PB$-HZx2b~jUON^)HT`>CEeqYzMU?+##+<~@45MNi_SnTFSdM?*B{ z)QDIwvh($DXh8)ytU#AJwkVFHqmPI)MmaPQAa=7ky;6|3=U2WkbeO^Ow850BFrDMM z`+~+tK`S#g%;)1D#=Shqr1X;$OqZlKu1hH_vK#2OXFahd?Kb>zR7$(JDnu%Bwm&^q zN$XN-m0xY6gfs|Ztx^09hqj_POBY9BVxX%!^JgUw2n*^A{p6gV#N!*9lOHUlW!kvi z`7H>b(A7~bj;@QL6pa?s!L@nzeW1|A!z65ScR^{SAIZ9oak%}V-E1i|3wjdN46aVL z!EDNvQypyqku9KBLytrr= zHrw!uG$i$plpslTXvY6=NWK+NR-agI!;|5cC~{^y6^T!`B0MzHqpBlj^wGwA-6JTo040y6?(%{E;pO4QIQW!@*KmU+=Uh2o!u@#_cQYxI8V$ zWz5zBWX4r^kteJQ_eKmAKP7BR)(`b$?lo8DL59p|g8S~&)7xwn z@ayMstPC_YU))ufLsJE6TcwdbE9}NqfYVm^IcaXv4!&KCRIhO6r2R~i8e4>(5cKMf zsl>Rote>D;p+&4iwzx?r2{u^zc+OZdM5F6yCK2&|KM(c5D5rUB$dQ{CU6`n1_1F~} zGVKM~qq9iSJfJ&_Y+Gk`%hLleZc!eur`pXuSLUElGP&|A9-t`#F2itJI&k0wbQu^X zgfhI)QQ7mhO6W0T;D|7O>H=5GtOZTA_%hXmd|3fmnm8VsF|9J@fnk zQ)u=R;!%S1aW#u`s+2k2d+@&&H-SDNwYdblR5>dNp)}%WAtRHoT7A=!1j{I%IPGU> zc3xFJY=;(ku*8xG_mKjpRGiw&0G^n=kSuj>Nj_aTT;i!nfYB}>MgRPXIa!M`tQ^eT z*l{ifHR5e)-M2K&cI44)GS;e6@(C?aS?BntlgM9zP?UvaVS?|)?y`KOis zKTxt?@BHZ$!tlqi@~>i}Obm>Ce=POCo-i8f_wNX{JT2;-x>9O^> z`TFtrZpD>Dlj|l*M|T#L2LzqZpyjJs$-jU_r#ti2d}oCn2?yaiE>Q;)WQXjZM_pit z0}}x@yF-L8s)|Ml{Gm!|3m6*!8F9J`@C_y5m@&NHmJ3Kk59_ISMjtIjq0%jt9!F$9 zE)cRdZrPs>kyn#CLzuheq364bFg^ktlmxz0of?7Sh)m*=;D-1?5YmE%w9ombiutN& za4i_p^KW!lMM8e6yy2o?xWNZt;?J4bfby!$`ZY-KtO%fsw8xUfK&dYlXQ!a{vGPz# z13tm85&3#OVA{v1SRLcmiMOirbBGb&F^F^dD8YCoi4j>j?D%$5%=!dGZ!B<$!S(7| zdf@fh?Aa!U~M_akCu-syQ#u7r%xd~@No_k*MDF|#_Ov@4so$KpTG z{6uwi5qtM(iT1z0G?CtmQ%rW$9RLMfg^bQe#UA>Fal9Ryk zZ0~`y?$(5PMC8K@z4?UrL_r6Hyf$19)Ruk@6QE^(_ZYY#5`+-k^&3StDBx4v6vd)E zAP6M1S4|NaW3Yl&*ULfER2s8 zfwfH|Fw#|gQ8JK_11A=eWz)68@&o%Nbd5wzW`h#)oe>Uq3LlHb^Cv(+v_4QP5b1&- zKJFBo5DgAW2r!yC(vGY9?H&9m>I#uL7ReZ_L=+{L`50V03)HV(gwalA$=&pyU5p2_ zYX~tbn5G+zCh5jlo3$!V9D^yZirdy(S?~PwUUwNrtGBjpPr&SZFHtvzB0qeZ=vgiG zO&W4q!EQDT<{dW*=Z@dPlr%0Sa45|}&n7&PwAxE2^0_DEulK$>MoQG;c?ud5uy)%`RvABSET2^aQ(cZw1S;jNJTX`|7Qp_WCy3#Gp74 z5~4n}Q<-pqvvKTIW{GIE)>#DiQcQts-Ct5TiGg=AKI}++C&uPxS4aGK9E3&@U`Syc zMd|MHI7O@aZBXZ!x%foV%~F z)!6q#E1}|)2^613TIwx$Ln)t$zI2j2?e*iyZ@<2ZG|uJc?49%G_wMg43(6;0mR2${ zzalM^U8txFkpctuq4rIC+vXr=FV;12*BZHNJWcqg-B==|9J5DT$}2leKBFy4pxxBo zt*qeH#-e|;VAtEhh~Vbxmsx$5Z=x_-nR-Qy>iK#>m*vt!j8oF!kXO_^r6ND^xt_SI zwpqvZ*v5qQJ_=b6PI!T6v6JFj3Jq_kMb_?PY=p3^x(r;b_tNhV?_$ z3d=hWgPw>o&XAT!5k3R^I;!ktTOB5Gdwbn|5i`?(GQpzoe!sp_Xh_7RVK>~Hv$ln% zGX1Wd#Blk8ngww)eW9b{w)eGJ#{qI?QsTzfY3&(Wqv7j3d1sBLGvj-(06}%Tl|}us zyp_DxGiNviFjVOpO-iv*3I@#lK+|t+{4wOybrynOeF*eaDmt073*22s{?u1y7S=C; z-HAw-kkK0nF{0iHJZVaGdrsz0{ZF7a(in0&UCx4IB`f3(%@Ba}rX2ukFK_Hxtzs4L z!WPc*+qV?I9eYPcQ=BQUf!z>P&=`?@j5}^|8-8kL8z6XCByT|C_1Jr6|ESbH3AV9e zzqj-JMYGE`+*rl0<}6gal5iw8pE@zfrHnI{VXusB#ki~2Ybv3oR#?W9R|odCB9P)< z(d4|ow=2>m5U+7Y0FPdg&1u@)GcmDwKC#i6ErQG!(j?`5dZF#k45X>SHQ~uVWjd-0 zVv(&QwHojHZLz}b`9$~tX<|S6tmD1`R>4Hg#;%G0gcO_uNTYIb-eE30{ngv9y>X4R zocD3gQzmU}Z&TBIw|b~hI)tk+i0m0YA*s&gZ2Vb^O(n5Ub8KvW(+HY_NaB%ggC(pn z!v^;84(#|5l3H7*?B4mwT5oA<_v8{7IZbA@%e9~EGx>Pq=qF7g`X!mkM94c3REJ#J&P; zeq_ESW;Q+2MwWsM56kj$;y3DEc&Ipzb`0gBpw)q*Y!n;;Z0=dLF}Q)M(8LC$Jwnb( za|jx3n9k@1l~R9FOkK`N!D^gg?dWG)Wojt0X=00^JV+~=_dZa1TX3TuGId^CZ6uE zc*b9d&nbp9Ns(DXRpFfUJO5fynwkY|qy&=yLt?6ZRUloxaV3U@l*J-g!f)?{ji3bm zlyFNVdk771r$kZ+A(8W+M2Q>81!HVM^}&klM=Mhfll9q7&s|@9&!xxb<$FqN*mTHb z(zYJhk6)tf4O`H|#Cz}hr=iIQ`p*eM?Ps`O4Z*-I^*BIbe&OI^ z0w55KtEl zPrNN5jR_I?#su`677~OOh_9zN`@8;ho0VK=(T!) zkWObHQlz{eukZPRpu~gUpkl7_nH>|?exFe>>Nf%zNVxA1k_-C^!5M;vm4UwTSkQp^ ztEIof{vph6zl7O*AI~g9LQVWwNQrK*7I73gV)_krL_-g@0KTH zSC^B7&{Jiqp#{HYr+bGs2^C*^?`H37x_*pDNbPVE(=6xPi+BIN0p{n5t`YFtDXp>6 z(qTRd{SJ_HF7@w?4}w+JX72|*8L*qZm(oYv;bBt`_S&Q7kL|4Q`Am<($A%?HRZAUV zRtuM77RA^k{xF<4uhfGFJ!w6lMKVld7Rz0qH*ip zF9kH1ySZoFD-Fz#_EeK>ukOLs2hmw}YSe*!ZoptxE|GN9s-$7M8JV0rtTg!Yqm_-+ zdov$R;`eAae+`eBDTn`W>06>}KR za-GskxcsW5bY_k=Xdx$2(Ih>WTvbY9>1C>_DIy}Bc$c)_3zn)s_w{ zv$SXVmOhDX&?o*(yY;8FhH}weNMu9hyq%FtAS5KQs)pGJ@X-s`8cw>$qP?tC7my`wCg__Sm!c!x z7@DyT0T&1xYbmVMoq=xmpemltXz4}vOH;Z{^)eN;ujnrP*+z|dr@Sfc)v%Fx-Okvc zNUw~Hfj`J(8@6TpxmCh;&WME<|N5nbw0rmPO}yDjz?w-N)ceFj9#IHH4)*oiOj~KU zh4Kr<2l4H}e&@)o>lqU#L!2D>=A=g&bk$zI;idZVWa?yUa)R$f? z8m$MtKs=|+hC=G^C-(`Y7FI>L&ME6d^+rUVgOBXBE5nz_Pd6eW1mLG zMpq25^o<0m&~UGa_ckc+d77~C5v8rM2#hb7j0Q_Xh1uojcE`%db}8lF_vaa5Xi3TG z2S@qxiinI{=2_dthGpDZk5$3*2ZWs_jidDda2ih40?_f8SzmGCa3T{_!?s0@>@SiWJK& zec)r(6w_?_(xAhliK^V5tAbeafFu*J;@pMeAmwtl!;|kZeuUq4D}UAJS?xCH&^zwS z(S!=5)qP5BOYP`%^GnK6g#~Tg?fHBM^CUmnq}bc$G|3E907xUD$!NlYJX=EGb=q1e zy+BTkya8{ciRdP} zUf>!hs$_F3>GIMm;%OmkUdku$p{s+t+g%q-<~NmFf#oq1nMSxK1c&O~QD);;AIU!s?KU=p2F-_Mqwm`Bus;B$_og;uAxs{V9q1 ztOT0y;|xpglV@?d0_MLk?TcH_Er;y-f55b77IWKoDOWgkmXkvu?BKFZ0pC1gJc{IWVPT3h1cXwp{^^ixCyskHh#~cLerMMAi3O z{hJ(4$`NXK?-fXo-0;vRSFg*6rcf7FC0VUk`V|r^7SK+pq9t@~038CF5%U!^aKgme z&6D>P5}1FeFz+uNQYc0|IAR4`Vgc80pfP>?{?val5NVtHd52MZ;q`oAJ#EN%344T9`L`io z@k;xe&){_XGtE4(6^2FleNo|M2>E?k-Mrpc1EJ$51X}a9wx!1b(BRgW*jtuYe^1@L zF_{|;LVnW|^bHV&^9>cmr!Ai49e6b3+^9Y5#Ki}}i!=2Fj3Z?vFd!hOC04*C2cM2) zk@|itxeuwc+l&B18Ul)I+D2n3VB(&U);U?I>eTy4l;z4F2>cz}CLca7h%5I~&0|wA zl+o=oVBVXw{N2YKOXEq#op?FCWxb5-w`v4KVJf{VgSqJ&6e^Epf3ko3h4O(#712Y5$@4I7(u8m&wOXxbwo!q`sB4_8r`jf zpNEZ&B=sFRVh}(MP3;g97RH4FTviJdD3(US-ImM#ir@kY^?~_jIRuGa%MSbE^20-f zNoGPxKI6t;qn2DZ+_r~P!so=urN{peHW@m^UDocg1sj+DZMs({Y0!)^l-xbl{KkgH z;#!c)$Hv8~HjQw~i)pK6Mw|MO$(D*|*4>OmecKUAvTjbkHp5^iD1omf=kxF_A7?+7 zwtXjApQVw}Ltxx%@q2{&=PwZtK$(mm=-uY}5o{_AJuJAD7SG{$hT`U2qRE|C7IrY6npGCcquveWrqu2qHnSu( zHwWAvKpwDWOb6Oj+B;HM*e+vMuMb^KMz`N~F2LZu-X`pV$|*73a|F8*`;Bu5=Y~(x zYXd$~jzmP`J#HT-lS`#1R6Y}(Xn(dqBWJTKwB{bnfBzNWS%tPx)G^WDuQj^Vcu}Sm zIdKgX7ZMklNp+NbXv588zey$6HUcjkE2c zmmrR*Iu(!0YumSi+xoVAu|0(}5m5iW)f+|>2yYs)O?dQBnZ05(_8IMkkbNj`1T3A0 z6tViJ_r3~(s=X!|oUCD?_ObWO=Ck4@;Y;k-k@<%yibUXeVb&e0daZNwnT7C$B$?(i z{>g&;Ns6GU3I^w7+A`LyvjgpWvxOZSLXX7~A9o9-O=1v4vh?!;f=&7e>5zoIq~8_e z(bzZnE>+6xE%-hkJ22u45GqAzk8CV3W2AZrXzs8KcRX@u(Xyd-kOtB}KyWQ!j?!Ok}k}^pO zK0=0EV8AR`S^&z4-*6HT5*qys{VM#{sI!f1AC&KX7%Zcp(aJwb6_srs_aRx6y{h?b z@Z%RC_gmUkM{(1u-}(n*)mY$^esMeBLSx)_{d35SsDq`E({kt1b^17J)wR_^9gDkJ z`s}nPNfu5@P8m%L9~SFv$znH!`$bDg79ypYwDkJcegbf1Y>7f^l0{MsOEw}CV{BrJ zdcjX&MZls%E(-%+Q``Pk0V0rMjDtXI0Sv@f`lLZ>>4}Bjcv~OJH@wTn^|8S?j&#h; zS|6WJKmF`=_>YYFp#8Xe2T0~hS65G&w^7afoi>3@4Wk$DI4L>GfIaI*O*fE{wCTvp zR)w9`hxPsZrK;`>b8hpMXF35ImWb)wGF!{#_vozhAyBx?<@B;t%0#|Edq#K z8`;)7@m6s*El%qG-?WV#8>r1yDRka9>022YVs^LaX~GjSj5I}->V)k^d5o8$L$_== z@LhZv=-^g#U$G^dLoV;&H7k~}cNIt`sSK)pmv*tsbMVW{3iYP}V)0I|xY}A z1Prr)5;UtuAq}+<1O>`{PuwQ{Z$Cy2#wKAJM#T9m&b--PWRC|jgQj8#tBnL7xs)tE zUGc*Vy>AXX;tN+Vs?8Zl4IR9KT)Q)CjW|b79n$g7%kE@*Nd_y&ULV+b)}2mLcKdSd z4pTH));WVt%_m{lrP>|N3(gN7;#hn%P1)GXQBfL1c=*@7?n?O_gc@W*Vve#2T0y5Xkp4ro5O==L}%T!w#xscV)$1{cg!V;zs@H zppR>kfPqHxKnHy?cEFP}Y(9ZCjp1g$f%lTd6>5R$U-scM!A}rs2r(^iLWBZRDEgjoe zarWO{U;ps`r3^Yt5%P~VM{4ROjHDM~ncfeK<8O>3lEVSGgCKCB!h&uD!2SC&Xy6Qb z^zi)5zNHjh)A_YXsy~2*bcM|MIG+H*pLk^}P;7fuR0M+_6g?>wM|~mrsBv)NPi0Xv1bikB`8@$hS)(WoYuc{nI@G z4z{w10ikJF+t6uvsc}iTqX6UkoucBL_aLbu~ofKckJXo3^gzwY8P@aEXt6j$!`@@PLC-qgT)Cr6bE*jI0D%a@zryJr0>uz00KyS@#P> zkjKdM^)7_@I++Y0g1;L+fN-7a3gCcC2Q+`|+mm)W?&3`%7X)K)ffI`>V1=89#js2d zNRY&u2jZCrMoKEKr;8Wa^~{e)oA28iNvn5d{tYJu*Nhn0^u7U{7B$NV1$MNf$<-YY z6+CP35X?f+Nm52m@|CZQt}4U|dGacl_M3j?+5};f;q41z#?)Q17*E)dqvlhS*|I1wDUV@y zpy?)Dh%VmFmDRb$#b`BRcjq>7jX|oG5?~fq?d?Yk8A|Y-&qOW=3gMnwDYu{Ks&w`G zad-L)14Jt*G#fmgw#QCR0`j|v(c7{&kQE%8(3!+1Aw?-xuO>b-rRp!`2g2V<47Xe8 z71_i-`x<_lNIdmfRM0aMcXCcA&t2OcaV2bCo{xR6Oee_p=21(07ej$>wGb0OCo(X; zJC2ds1A-l$B~hI}Oq%fUB4jAaPs@e<>~uew=s&-a4DTFS4UYVM*1=Gpy`k@6?jQ#y zIx=({v6w`??r{3TztD6aQZb9Lq}aAf?7-!SXfayB{%BQ2(|9+0YGwsJb;}m-#&9vk z%usB;5L_DPfWFarhi2 z4E^UA&iwWDMndUS08BPzeNv7dxe2IO;YXdii<5$0mAMO_w%!G(NzH3(k{UbGkd9Sm zwr05|N*9yr$5Io^ZKYs9oOR1wY`t&gv1L4CUJAtSb&`E7-7wa@8NXVZbONz!dFqg9efkX$ zCNeYy(TbbS!0_-If}+`E;5;ONTB0&3u~(meM$Pt+9d!nibz)#wQEM(?8m^Hta;dA< z6D~7P+-7FqTQC`ETSoVgmK%E^ajKoNk?vU9d?(hExPLOTb>CoU=X!N6#75(@8iRCV zY#Fhuj=DBH>Z9RjVsbF-PP2+0&?NwNhB-9`$!>|iz8V7(ZE$J$W9`t95in!cipGkL zs|oy>>9k_OWe8RIqr!ykof4W&Kf=+L_~V__bM|N@LS@-KS0=+tmMz zGksvMKb&_=R&THRY--wFhJbmC-E=5wROR@_EL%-#{(2GZctbd&ky8qF#^!Y_UttcF zv+8&z8)dSaW3Ru(3to?ira;S~BT$4|K5dRXd0}pWI|@@mV!c|!(qfAhE}g*L+D-fV zP!^Rt!a%gRVrl^&kLKM*$MM;>U17#;j1Hd)l`eaz>xIdcsJYL_?}V-4k}{s67$1pE6hQ|UvJxx zYCCXI!r^<)+pgN+`KIAR)f$G=rh|@yU_J8zK>OZ7jW`N$k@JG^tun^Yq!xn7ssga~ ze00_NMl3aKg9bvtRp$)DP3xO|-;xB#pSuTN4ycAq1qXbCL)iwYf0N~onSvfP71ZkC z8zBDR>V+NA9Q?!L#QhzyO@<8whVRQr2~z7v2cK%lyp0JV$!s%$YP&;*0OW_nJ0?R2 zK}#6-hsCKSh!+ythabd0g0!|Ms z0IOs+Trw^e+G}qJWEvkWE<&iD*wYp^kGg9pR4sfm*i}#~Somi)HsCVtQAB4l83Hbz zFRCaI9~b}$&(?=kAIQjILC5r^qew9iR4f{GHp*dkMTy79Ars3{2*3_5ukSD%fFCXx z+VpSV{a=ij>vdlaCtN}7h@&q=T$y9|w;&L--wJpb=n->kcR|PFf?W_G-AlT;Slj@7 zIvD-Zj%}^SI~G#b70g!#QX*YodcD5METZ4kmcO!uDN~q%!wFkH%Z)kV<{vo{(ZC;b z{0WtVoSXA#4da>sCZLg#_ClfGbq!!-&3IU>C+Ur2}DVn>nt^ zc(a`GHs#gIg8jyXgB}LaQAs2-)N_H&4bU0wA$=v$Qzng=5|*XrEtdUO%-aJs7_jV} zK!${i1z0-<79y!d7kFeU&hs*jX6%lkse4SYP;rEhp@gXV-W zx0KQ6J>7!<36wfq7Bm1Py@mzEfsF>^r}hMT?wLH3T@~apx_OjA1xb9TL(@`Z%gidh z+!Vs+vumEe=JP^S|G6%?wv5o?*pG~Ve0V+^Dw311U}timJS73(geyGWp}}(CZc3Dv z-TtZTl*ar7o$b2sqg5hMYKA3KTWDkkYK7^9=0@%q+RB`!iNb&ywbH zq4cg-iLLRdqMRCENiQ1l5j_jj7L=da*^!%*llh|I`Mve*qBct{ddPYI*M$&-P{o9G zqBthe&Sv`5an+~l3K~4K=rm9JUX*6D6v0k%u9H;2Xkfk>qRGVaJI4|DO3v+awk7&C z=E&*{sZG?Hv~ad%KL+<^ezu9bT-}% z-#xd-g&ImCPaBMC9Qv!5!G#D;(;-g!(vbXr7uzX@j8>bso{Z*MiO0@i+L;LL_nb-48?ne={eUJ}^0H~Un=KF*Ai zXWGtXF+*I0zwpSnfcJxD+{!%itMEzOFM%l$bT(Kn=Eahin21`zfu_6HL$~M7-aAd! zKzM>GIC)iW)`8%(k0`F-<|m$t6pYd8@f#Dyo$efVN$GBi7n8|%ve8i{trijr+k+n+ z!COCPUC2byZK54i4PRDz?|-snBr3nW0oXNLyXmgUr$E!$X?u0X$Afa+ChSSB7BpY5 zXe!mPY^oM2SJ%s?Gyyv@WWHVvyG|fj#XsVVkYFBPsH$$Dmss4IkJVsgyp$OQ5;{s> z6?@?`9qie;hz+(QxU=`3iM%2sOqHU8GznjCf`eL9D;cQ2OQasga@#CzCIl^vC8ww_ zXQnfmwo+Rj(M@5pgk_2#&m2~%+|uuzhkGG1y=&xTqgQa;ytuj)@4_r?EmBxVxc8oW zRH^OWUtF9i)*)dGlXcy?nStj8o46GcZY$jZCN%&zQygUHK%-U+4r4Qs1xa|DRI3_b zQLh=Du+o>m{CZ#VK{rtLzWJ_QX@qI8*XOONQr zpIE;v8Gb}uzQo-N^yY;}Z^xZ7Vk?jPaf(~%>JXggJ9)CC*-z^o=Qu33X8BBe7+%uS zNEQ#e8J?Fltudn4VRWf+wv(jcUaOEl4GN~7mAxq53W)pyA0+Lr=6-cEb_$g1Y{n0s zs>OJRR*2Zzkr>it1TxLPvTtLEjCVd*^ z3>-*$?AWl#lFF1OG|9dX^~xWtAsU_=Y+BUl=9*_aA4MBar_)p<%o(LOKgnQsM9sq z8}!rF)bR2sHXZ$dJ*q7e42WcJWaYjqU+IzN9xgLRy|iR7+2z<)syIZWwlKsPg1a)g z5;IStGFkf^7yaO(xWQGC;UQDaB96AWVuXbBdE0&bLUH>CK{2)>MaY35f?AH}nSs?I~TLOnucfHnq&mNNsaO zXj?&6#`TGJjeQv8S2|Y|2K6yIecDFfv1JTrQi8*Kyc~DFdV^?7O5$8U+(<(fP&&@7 z#qigtA8P&il8#xug74Aq(UQK}i-y5Zvzf|>K z84p(<5frXasZ+Tk2bKaC6jf;;;AfbcagF#S=h z|0moLBkf<|j{azwLJ^8Z`ev7Bp4Sab9x7%GNC<=qC4nohW>~e25HCiLU`(5aD*;d5 z;x`D9pJ)$}&+Dhc3)F}N9EqRdkEuIDt_&mF%TFGj`$UYZ?sa*W`6w+-{8cpN^8E4o zZqPM87BULIiwB1K3yfSc;LMLzFq$ltzbChsc5ruC7SY$&=w8 zdiZt0zY6S)>#a)n13D3G4R;U}0X*UTfclGCSi=KnlmT7%MPEJq9>bqW`2`8d;OLmH z_OTSviuoz&L0jxKrC36czf+uiN)cJZ~e9eTd zExP=Fs}%)f6UsV`9EJNPMjg)W<(h}qg&5&x5iTpq$`&aLFa6j*jSUfa^!9HB_WFSU z%upb6DEa_~puG6N2yJaaHj1qD=z$B?+{BSl;J^C)LTQo+>Po@zd`Ri+y@3G1(g4Gv zo;|j`A^;hD;gI2Qf#3_!4z!%mz~E;R-+^;t^Wt#9^7-JPaPN=KyC?SXgII~9+(93= zL-2ejH7@s#FHM*xo~`~U76qb%%k6_g>wyFM#({!4(4|8>9Ygp7NPsY~SNA*dxb9D@ zb4#_J$zbq$G(#MZTcp{Dm@afQ_oaZ4Fk66rg@IwjEMk^UPsm1fs@_*FE?Yok+#YB&QK5RF?jL_NJn$)e74Vg9k#QiATxKLmF5^U5;@pbKNRW9`*wYG#+ z1)q}>|2+=a5gX#0uDsLgft#?#)@OG&2aQ?&^;z$#z2 z5r=B#(+!g>swes#mEH}fsQ8b|AAt)szZtE;I@p(TOS?xg=WSo1Cyl8s?JKUpe0;St zHtIexmu?cRk88z`wvTwoWEK}u@)~DwYS>-1{4hZAS)82TAI|GjvNeQdkhUVCY3@`z zv#;BA4*bO_CX>jsl+ZBCiXDM#gRlg(<^;4~bN~2p1 zS!W3@f%;j9$GKR_MQs!-s;!bf;ri|FY1BD#_*EsUccP>H;+TF8s6gh5s$>Z#}9%x-6I_*59UdaMlG^tZ*vE9E*n7_#<#PS@$lf=n)(isrjL27*wuzU z5e79G1FP$kS&Q!&8&b6#1Nm7VY3fgdDY%~#eUq5Mw@|puOR>6`dfy9ZO2FE6s2(1L6W5S)*s7+M^L|i+g@=yFDe*>m#s88CPj0#Fsyq0apLVA9w8AIbiB$Sx zU@WX)c;hiElRL1qUOg?+7vFNjS&L44d*|l`Ur9)kgD~J5GS)QfgHKE-wRj3@@o*f8>wst3{ zV zN`4Ea4MVK8no#`9?GrVtAS1|aT;;XJ(_6= zn7QoitUlcL`R@-w(D&_tIU=A)r)X55M!?=v_Y@}M97Z%9sU)0d`lqqoD!Gg!(aZA} zY9&c#wR{>V=6P}J4TX*629mKEthKlh!6Mc{i6m~(uEZnAuukPZP@`mW;1KfD3+LC! ztFmL9Yjj$j0T@=Js5p)Dkj2!Pry)NyXAXdK+6*1FUWIp$grmm3N52$PHL9y6F=E}g z4LQAQLJRnq2#sY<8a^jbxga6qDtLc=g5fpYJ#3<@NE_tTr_(1s>;J7ohsHJzN`s zMe$w1wa{KQM>x`sG&We_5$pvTZlpebzvJgLWqj-&73R1xqmZh&;&(Yq7{eC0P1g&j zWLOkLoHh=de?kM7{D>x^aZb7SaJFU7hP9~M$THkpX;p;Ya3A^^Uz_deUitvd&s}Vl zeb++Z1bA$@8#5q$Rekpof#P&QVTiMJvd00K;W0Hilf~M2a73rj-0>8NZp8AI3Syid zlstl@^i%GaXbPlF6S+fwACyWyM@`OYhR?{$U=7^CdVw+y0)BgAiPJ|*YeazXOW=T> z)+FcqV5bk;8)h9qx9y+m*uTPKiHR%7C@cND&29MCbnJiK{QqxM?Ek#?7i9TooBO{r zSuFp8$@<3}FT;OUq66_#<{*G1NB~!Kzb(-pu>93F01q0f!d+Ee4=xtG1ek*^E-eruv2Tke zN|L8-lphfeDIbvTcgon@R3t>uINEf&ZFv6GoG(~@T%{ww>%a z*|BZgw!S>w@992$-lyK`Q{S(-=8v^%Rjs+|8uz#cD1=54q)GGh==s@*+m`bMEUEDU zL?AJR+ZMrk^}j)DC{LIBCwVh4Y#O~V1SPh$2swOVd)_cB$GP6!f4b!jQURz#NA&8X z06SoNp!@=>sp|;H5pZDzB);2>f`dT}{P_N)jBd*bfh5pLghqDbfPv742nv2;KhNg# zN#P5DfLsR*{HI-BK#kd?<^Y*JA3zg>84MT*=78nqKp0LTG;cO{%8tw%0Ot6S>t{w( zMoP3}cBqEBJ`_S9fKn*rKWdi*x~2AZMB=xA7{nkFMnFvv<{~Xe8H|D9#$X5=_z}h| zVNUu)d057uwfX^3^@&X)G1?0D_6I|3bCoIxp6iQ|Meu%abDDs#$|BkJp5)-2fw)PygkXcMcJK zW3KI^|N5?7;^YKhOg-ScE(+~ILX{*F2^c;{0Ht=~hww8}N;R}$Q-au20148j$IO3s z2cTSvG#Nas?+&-cXZwQ}WX#yJJIyXNNfvf%40L-ANNZRL6A9IAF^-0+Cjf#9TwI2^ zy~oZQ+K2xz!OQ|mfPfEAREfd;4O#^m{I!694ur_@;W>pVa20HwIKpewsG}MAUI^Rx zqW6p*uRU` za4q3Ea5a^wkD>J&;6hSo5YoWDdy+|81{s6EOCT3D?+qD_j-tr&> z-keRjhS$;cN5BJpLW8yQRzO|$z3c2Hp-K@p?grfp$L8M@pS-*Rgq%yLxii`Idks3Dq49Gzyqf+c~!34Xfqp z2x+6g;!I>ysGA6`xVzgoGjnC$M%~D;Fr&r9cTS~JyzZ963^p}US#cXlPs8|9*d z`19@3xoiXH`}bgMw^W@tlwvGGdO-8gXmnLAQ>SqjVy*|%1WFbd6Y|1(wiVfV0R zeeqVX#%*0Qz~vV8OZH+Wtcu;Tz_(V9!KU3gmdlxV zo%X_ia1s@yc)QVE&N?)V461D^4wCEWBi9TI$k}DYyH-}ZeY0L2)l44`xGqBKKxb^; z+~lvCwJA~PVM>mbHkG)mT;|vBoj$p5Bvdaf>sxuc8u$5XW%CT5=6V$;gd^JK^j zS!&T~9Q^#8*ZI)!D{i@bg|ckQ?9O9{q~9ciIoRdPd#y~{>sRDdMqYWT51#dEO1zq3 zHpN&HLjFL&*@FpI#a&eTbrzOOIcY>Vlh!dAjS8f&j(f{FVFR)YTnLG-n2iFjYjJgV zRmiUlU5Cfc)9Uo4s|Q1k1l2z&#e+C!@R}7m(H{w7yxSKO`KCc+r_^Rrtr#AENZ!)) zCjkZ~KDXx%+li8zc$l>>!pGf<7WD^r$`rjP;jQqH?I1=P{E_roImU$N_Oe$n-TPOJv_0YB$ zs7Oa1^IyUmc>%!F>=6DI_5C~UEiow(A(j7=n#A`1OYh0_ZJGLqxPj)c{M5gdH~c@? zOEyO4e@RLD4~X|KY~|m(w^;uN>SOqOwvvJ6-{|cA&cs(ovqq2yj$*!84fh70_9ZTZ zA|`IFk01m=4p~iayA@yjN(!W!Zl6z!mp+!Ky14AJO?I3C4 z$n>2gw?!aMe59_08R?8;Ly19MB3Zar!C`~VV`1CCTJepLjm88JP~e#Nv+Ub2FhP6i z{{YSF`Nys>Vx*%GN{3b>%rFG%r6y=)(&quwCJ|!f<(e&W<~s=S#Y3A$+HShQzz-0T zNg;+qie?~E8pGJaz{(R=N9XVrM%=EDi9qO0H168zQTYY}5KAG9PbV&8&~gs|9J< z&hK=Lxoea7g@#^8AXSQ1uV0EaWk7!gAe!Yzvp!HNC}<>syXU=P|MU@7bt(inJ(o!2 z`i#B9UVn+jyailWgW1`EQo6eXV5ZHOY~ES*MBNgz8Fqn@ zC--FunbddS5l^f^h&6?`%d2CAAbl@qAd~WimY0G_{Voz6J9xK)5<1NoG4K<^hz&u6 z{P7L@_=oJiVV{wN0O)Xl%uHwqFkmo}V4D?MA>_CCl~!)_;J;v>#H>gxy%1lU4?H^c zT4$Bp)4`Ll%bkGvhVl`XX(p7kLgTs10ndYm{)*STtG8?MWBQ*6u{2wXEP0;_>eHFw zEvZHsOzNz3AoZT=8^s@Iu(+#Qc;Xe*t5KGoKe}1QFKF&SRI@x_ z>58W+H644kA0e#M*PGdTi`eTVZ-4u&`VE*;$?CQzN9aV@eJvlZ?o>3PrKnbX7_;T49>J{G&m-n^45+J}YD&ei(4 zH|$ZV%sk?3sn=JZ8lFBpzb!eZyt=3@9H!Vr$rz62$)12!&=rEH{-O%2S>f{?}K!sCo9p=F+7~8Z)T1!W5nQTP`+~c+S5w{cV1X*#t&9n9{Z`cP}2yJfn@z!Z0 zl}jW2i00DJ33-}y9sIg2Zrr)X89rU+dI_0s-HDNST-};6qvL8Z#csPQs&sojm5_J| zQ+K@bM7I ziOS{rXK-!iC44wCwC*aaXa`%l=LYBb`}@j>*7=Tc-B65u$7)s>o+*uEmv@l$cWf5o z!-f7D7(-8YPr5IWx%`PEm4}Xz;op{hR4=qW zw$`3vWm~93P4g~h{Q@O{jsf+BwPA}+hoztcT zmpn_*E{BON%`!1%O0J3Deya~==T7UsIM?5fm+*m{lXD-7LBDGlO@}$o5okPWH>)ZW zOq1R-N{v3l6BjeG+CUp;=@U*1LlaByH3u?(GBwoQCSEa2)Hqn$ z-fVXD#I|(4ti6p6CmnALUz$-b2;77WSJ;RhZ}BzS;0ZraEmgt2`P9msGz4X+c4(Te z8|JMw$9?unjNBP4?Z@PlJs9;TaXsav{kKTeQ?9}fYY7zBlxYRxaJP7L`hz4u zrH@_IHPToDT#InEdER%&Yx~pWUNXFPU5bRL3OU1}1d<@8AfjI2TMcjN>qJRjvD5(gXc}G>y#BbdXrWE5vLiv{b5pG+ZMe&Td z*Jy*`#MD<3tIzH!jMwSZ=1|F;*=|4-_UgO%l9tU7G}w^ircMgQOO+y7iEf0wy4|961W z_sW@xf+|5^MG^|BTO&eBtysNspLUy& zAtWG>)X50M6F-sxRjs(U0fy73c5kfNeFuyjg55Eyi?+!lfzjEC5e89}9Lc0m{fNTx z{o$z#ll6!}5MqXkVM15?m)T4eg|Ft&_fhLpyUb2qaj!-KDOZaE9jDB zWeiE_Ffb^vhdi&?Vu@D7PECRpy%&S0Lk|U7us}qB!+#WPV3?UQm@GWdLT_ewiWn*1 zyBCEXaQU0NGi(6BhT66>M-Xfe5)FjHl@icU^B>JGP)dawCXryljvCg#4Z$i(t_%V6 zv)n!|YCOjA)wb|uhKf~@*L>c$rh~#0z`w$PxS?>!v|nUlj=FR=DS}q_T(BlT;h|8?=!gZ zrTJ5Tuwp0vX1CIe5CW>kI=xCztmf~DHvV280+D10;2(@dBv4m)Z`t;K< z2nzWF2C@CQs-DKcvVh&``C{4>PJ0n9-VqSU4b(@3X!v^R-VrGUM{TmF>z@(@D~ z0bER&kbZ^Jehn#$l-g?io!K|fp)~zQ^d(v4Q#?3Hl;rf|TOS zfC$gYIn0)d2!nJmZ{`B*#Vj^`x;ZE$>l`_E&6YSvT2tqDq7%aqP5uk;bb)Hkg&$k@ zW$!kpH;?&AxkAf44_brw;YC5!<)nocR@$?0NB)T>2WQn`BU@i8-i?j->mf` z;D@>vymqztEB^TCI*qkX_3T7@%FAwS6f`0OyVoz&i>J5DQ2l0on=Er#>trZ?(-Rzw zps0$P!Ls*x;c#dB--=r_j!Kdu=3G) zl;MfYX;@K^aFs`k*3YuN#1&=TtBkgLwbjmPSP|CC%V0H!kBs_>isFYVDpk#HV_m^; zSj@Ix4Rj_bo7A|&S}RvyYt~mAs4AD7Yt9tVvdc%x&I;*N_-t3-qClAb+@k2T^eyXqgiznT0x1!ZLK9v zm}-%A+N^#$H^N4>T6ec?x+$jFsE>^42@YRW74J9zhSd0UOIFT(xXJhYz{@BLT>kAP zmH&}h0H?N<9Zq2~Mu)x+nQhufL4*9{tVv$2x|!y{6w2G#V(PM^m__6WDTobSTf3aS zKE~d8l@suc=?Y!y`sN@77!0?AL$|fET=0DdZ%Av1U7+b{ zp?K;scp}DG(5BEt+Qlp*aoaE(!%SN`El}8b8xsr^QLB5lf{YdUh|Z{N5+_y}t#JzS z@pq={`>*I)?G{cIR`gTdxHPtc22-D4@P5{~1zEBC%gJcxy0yKW*1DluFIdF8`WJ*9 z516sH2kqXfd59P@V0J8f2_)IYLgpA7B`A@Oy2s+{Sto%3SaZn5?F zU-JMLCDRSfO@>R>)ZW(+?Uovi9*(PB{jkmS|rZh!Ej+JnCKpA zP@mhAq-+>jIH!bN1|!?zPYAdi4K*JZ2*+ah&evz^`uE`rPC##H+*wQF?3Wa~9rNk@ zmqc_{2~NFM7VWqq9lHYR<%V_!r+%+=CRQbKzipCTE;+jGy;|Lu#;ez|=PP-d6d?C9`^0>|kbi&R>4mG7!LV7LidM+;HDl}>(7iofvEIEN2 z6+L%fWzMsIl{{Cx!CotKo0mf?=C>m>)?-7!3!<=}jUrHJb$l9vw#c2@~gq2x*#);Nz&X0*%Pz^Q?F|v+h2!?>eiu z9zO4Qro4Ecjy~6Oz#W!XWrTD1hLEL?nUkReP@@6WdjIH=<`zSN3*tYbpd~$5fCjT8 zeWamq!rnnM-;?dCtu-M=H%;`;n)`YKKu!Z8q+<{R1@Hlgu>(Dz$6R(x=efn(3sLHc z4!*o0_96)W)(zzi5;D>E)t&u0I_g{YAWjcLPcj?&xi$*|fCqHG%#`<*5c)G8%MO+p z$~Rt}nimGRB@SSE>(oS@a+}JoSGB^5F7$U7R{F|o}8K9N_3Rx zPYeV;0MN|Y6jp@ci=saudMhP%G{E-Htu3GGwMR%NES7yT$sReGXP34W+*uP89R1gIaO8gzOORFsDk&~?>6vSj)@4k_k$FK?WdHZ9^D(h zmOFWXPYNS(Q+cj1fcvfQNDfmZzM@ZNxQ~-(AH7VvAgtRjgv`*NvY>o*LO>)vPd)YwV8WwJ!_UpDfoq=|Zjz3F|o#K1c2lnKwKTYe(=uZk4R`7BxDE9zu?pnxG? z&<$jYTwZ2Eq{!3H$b_>HUyOQEcZJC0%t*fTe1PmeK3WiNKc6oofFXnd60M8$d@(w_ zSf!FgOs!)8ya6li^gJAUe)1CmVr=3aod~Y$xY40y3#|J25L);U@wz^A6A)`b`+`n4 zOE-k}QY-(F-NtL?0)GE!Nx44qu<`h;c+9r~7bFHl=I#yfa+1BkxB_RGQjvTh@mCuB zxqu}HH>L^5c)CqYd6Y_d+*Xt-TNn6ildUQeo9N8t*1j1UJvoAjRk@E{oM{-`TCVE1 zrrQ^&eyn=ObEZXGG>OTSsm^hQuv>teM*i}`x_N&rX+uyy$=GDeJ!65$vYy*7P0PsbO?mX1+nmy>^G{lzU1pzy_0dm{ zg+5%{R~-xpGoi=9bbobto;{Mx2o?qwoTg#CeGBMLtVzy;zQ7;13A(v%k|VWoV~}dU zE@o#eZRd+rLJGG`GB`bZmgIwN_?Ah<#VvGW`(MjNqd`H-LWN#bAlYa@h}aFoIxGM$ zyR;QNt7X>bsHR{xc+j4=pZ~ylCSuiBa4ZRac2XnKk4AZ@`2AWx8T>h4L3Y1CIiB>V z*dwjwz_OAv1cfST(c%fbhiDu%p7z-x)6Ra=bop7d!B?rWLq)Gh%WF;)$%@+ZxnMei z^m4PpNxt(1-R{Mo!j+|J{><6bN{BP*oMKXUa5bf?3Z=EqnD7LWTbQ*V2D;qnbvq2M z#*&Hkpt!rnM~}Kg&7u2d#M&zfzQA9G-NTETk0Fg*o@Rw(X1A_!o{jy9GgN?02Ko#W z@$#PaTC;D8yZVb^^ry2mh`=4{m44sB-Dvsl=DD}q(3^$^m6NZgq|m6wNk5)Q-4ey* zAZq8~lJm0wIppZ42Of$iKIe4i&|S4 zTig>2k2V|{vn_5_r84p=bm8`E#0eqwPFsaH-n=62vl}3k_exvw)<0j!*9w01&PcW; z2yU>hx4hiGSi-)IxR?!AS zdhz3}Gx<4xW-qT4pbz6hZ$<5PoJ+5hsUcD()OYdcFs2*x;*v}_gc0|wmXk1gB?M}# z+D9BYcwcoiG0v2bks>~m?y*&(T$ihkedG@5nD^Tnl0XIuKz|i_pep z43UUR-L-kD3HQNhO+mKxi9Er$6MD0TU_6GHc(eY&8BRsBA2t^S{7U*8x`c22xo@~r zr5avH=+^<=1Vm@0O2V!dtxb>fa;P#)($qA&!Q-<|{G$(+_T!#H%3-IUyDDkG9-pV3 zct3@W;YMnTjbqxb=_X0v#CfpktQ8% z^|uA7FGlHjY0Sx;s_S*PB)pI%Tac9TK0*mk2jK|NsqRk??+W;L;>7#xU-AT{n*hb*Avp7P?z@u1akh^($>cxraemU$eB{apomTgA8F_^`fkto-q%-#ily%7vC&`<|-g&hKEBbWt* zM3cC?ZCcO67AyF_W-g*9uEkY6NN|63Y&ZLqv5GYq6Tasf-||NVn4t*9^)0aSk6%Gm zw6Wkg2l>$N#aPJZrI1)l!aKF}>8TSy>)3g3P<_(Zf-Kq>k%Wo5w1VVY#BF|D1obPu z&kZ~-uwQzw9Ov!B-=5%h(;)e9Ik;)gz;l$+d8%8NhA?(e1;xae`Esnw{Ej$>bnk3I!Fj4xq7xb= zcrR`p32yhlbfj&zUoxVA;x%wn9{bu@kl!->;*H_7xZzT}s1m(Y`2ae-!;}IQd`FsO z;nO;De%B6trfp5bD0nOnFu| zngq92emnVQYSKr)r(=6kC6F>nd2?5`aFoBvE=1fl74AieFs>Nht8yT(qg9XldYOk1 zjjM9o-ngxgb1m)$pi;VTBhx@vDo^C>V5@MzQoVLtj&gAHQ@ygdBE(06XY43U-JM=z zEH=Jndt-rNUUmDqygz>)VdP2Y{@~^fclA{{KqG%;#^H!HM0<6Gi9&MSr*Z(&0J@cB zJYvUXW{4)^#a=`u?1<4{!XUuo$t(w}wdp)v*$&6(H8YOa*uzFB;tEv)dh>%8V4g!_ z&rNF_^7Opox*FdcSM0q~y3S&MBP&22xkIo8-I|a=8{FUy49|RPk3zwUNhQ(6)l%93 z`wp4eKibq#adTD7X-7u(Ha`4pDmkXJyuPo@t=i5^CK=prLts&fUe6ZO!0nfudx+1%6Nt3!P6#%$V$T+Yz`~ zR>k=h9)GxORl_a5&x%G2Lqv1RR?gH{HBc!yF8;fDw4^=gF4kr1Q#wXleM$pQ@S(ml}B<^r~&%U@+N+GXRs@Z&nn&;*K|Jr^XTCf zXywM+yKb23BIOMn@?DjjN>nov*0Ol7jnGY$?_+a%LEH%bsx@s!3r*&6UcfL#-M0fk z%qBZ)wfOFJwM|M$)0x&Z^@P+tE=tIhTKdNn1DxyGMjk(wmOD62RyNE5^fvg@%Hvcu zSHBX@z72tK>e*HD)Kk-6=R-XR$l>YD71SRDK1eCtZ zsNIa+9RGGlL&Jhk!^rVnSj@;lPyf9QVP@8bqT_coG`4ZVXZasC!SAE_KThd1tPJ0x zoxeS(Gtkrjlh}s&uNy%#eFsHjCwy``0|$LWOJgT1V-qI>bJKs^I+&Z9{m1?H5#H9u z$=J<__Fs?f|95X0```Ho+5cO3&4|y$$nl*8_kZtlm^c`j{JmRI-z7X8FjdLFWn5oa{<`;rsd$oI^z*6^}Pj; zM zavD2A)K@hB^a%eqf-~P{2w%@hS(!VY{N@&gvX8AYjF_Avd%1b=4dX!m41VzTR302) zM{G7o53mqE1GdFh(K)a^elDDw-)47r)eZ<(JVYy>5`pMw?A1}t+LY*HXDx=(woiXe z&kTO9i6L-91HIyFfw4~NHJN2*e_G~FHBQhUxAOIw)d;#uaJ;}xYC|4 zx<1Hv9vZ$)ta|~l+%K}N%dgMDcmPoX?kEO`d0m9rEo^a+PODfDS-hSf(YN3}Lpbz0 z__#rTd|B0e_Meh~l;#Oyee522#HKPZrnm5>U$cN1biU~If^Yu(B47wDAejf-cH`oT z1$JOIE=@*5D1^h0Nel%L<0`Kz4(~;ZRshff*uk}Haw}ndM(4Rwqk2-LhrS?`@XVzTg8}z z%G#DbRjxJeWzS$m`1?1O*7%O};ED7Bsq)|zSUQdI`x4zf%?F_kPj|v={f}}M@gFoQ zCIXBKK5A;)gT1V?=rD?htBnJCmofxHgdXq*BR`^c@@{cIxtE%BY=n@}uUhNd zcL&eifo-j%IpgqRx$0z)`%*701NX(kYSOnj4LCF&%cS~Avj{AbAnA!@$on6cWkH)I zKlHgW&Z7zGn_vCjczq04-$2oX7O90`&~uCeB{QWIjEoqfqy_rwYsCAdkUAww2MKJX zFj{@AMw7u00(;e$IcBJ-a`rq@GQ@!0?{eUkRQV@kl}{h5(mm!(@MM)JvJ-O{I(|sm z!)6%1Y~K$aY=etYB#nP+81?cK?vLK;@s8cz6yLv*dt_iM>x$qTr^Q6MP=Tw4P!`x2#C_JB^`3u#tlChJX`ItBb+A^NJGHuAt*x{9N zm#d2_PpmX#fYp6wvp*)i^ep9Om$EyFIVb+A_E7(B^5$)e2aP>qeTcyp55i-^`d(|^ zpcfJ9K%YTA2TNcC5^e{a1Pdmd9Gf1W=3=B*X6tAO@!)vRfF1!+6=JFSKJe0naX@SMfq*s{`(63?VK zGa9EctG$bSoij zm+OfWbmysRxmCAXvpx*R=$$WpW)y+7LUM<-&|1LJ$Mlz~ z6O@gfD{^O$A{n-VQ_1vkUNN8= zoHyM%VAx%F(421%L46vz;8Ohop4N&NbyWN6v@D`>qY?JQxFl#}F6?9pi|HYB5p`i| zSJYim6`{XEC_bky;t!6Jd0rt*G{>HPzG4I4Q_7xc5t+Co4q!AdW~R-w_DFPw;IJ*X zHMf+90M*7e%oWoUr?$d3Z%J*c7*s*B2cCOIg9HfOZ9G*6A}4tS{ryQ0qA$67 zOV6ddKcM^!mC+#yv3=H>5$_7u{W`XDgKB^Ye+DcxXaD4`*)B(kPx$-c|CSvQl9l!R zp?Ub8+_YgvV#^S5rpf@HBgVEtskzu(DA$p_y%xT6hYDYqgNAfq z2zv1GNJe$`C_~@JkN(EdROuw;`a1agbM;4TIgUyQnY8s&n!435EzhfhG3@Mz-TGYy za7Q7Z0hj7)&AW%?gAkXEg|qcWEd|@tYAX}7QpBU~U&LEj%RENzSMz$U!$39@iZF%vP5Mc*?h-Up2x{^ zzF9>7d6rvPlH$U>7>En0W4jA@f!R!D>qYwVetQpgVyn)Le2i*N_?`!4~DS7f1@mYlGjw@*VP7!-??`^;Hb^&qVzf1tE{}KYjG2V|ewV{f!bX?pwgrJ+2^zmScaWj1_$8-{cyws$dFR1hF zSbTGh2(g@!6oxe1U&3}}lh!3y?wc&wUs!c^>Oxe#Rt}bjlMd2l@-YA$ceI2o@^?6Q zY~p{8!|9S$jmEv~Gy}pa9*C9AuDLgWJ&qcWF!tTXG=o+u#ns=S$Y1+20!z@NyJ^C@ z9BRnS0!3LqnKO8dzOY4&20fR#dEthdto)eU4+$Am5i#1CntXD2PYsVc&2m zSPWvanQ{o=QbzJ3Q;sy<+@f9SMpHK9*gl#IClaTZ%5(__mK5Kv#ec1vzPxM4LxOgN z%r;;a>f(0KtNBga1t~67Sf2lMJGW~n0{;|n5o)8oknW?AfiyEyB?1n~C4ccu*u^?r z_T^TTM5oKrFruURjdG5wpa*kWpqhPrEXf87Cf1dvrmnbJ*@TUZ)yX2qV(E>CqvTpc$a)}l_+JZ zg>oYLzU%NWF-K<`YuIE5$({5-^4e`e&jQyyY-^_PG@7pY4-;soP6Xsodik!rfIX>w zuhge5-lZx^-cIU|g}tEPT*W6fyGSB62V-TXC_=F3mcW##X&VWS^?YWjO1_zG_S>ak zn=`o}RhSxu7$P^2GYVy7pb_a!(2tzRTuZ}g@jLsZu@@4{ha-*Kq94pMP>FBVvs`aovT2=sPcG_pMG%cEr@^E)MH4!Km%+aIX9 zgi0v1%EDZqCiD^f@Z7(qqpqPXb;SG=2-V4u)l{GjTUqeOT87D)jx*E6XO-uAEe&M8 zQ)YIk()hdK5k2_TBw1?x(0?`Pu?{zj;mlxdpE6CP_!#D=sQ=HMRl~(P^tGZCHLjiv zO(^a}0ip;oO9D)w$*v&;eKd`q=uwMUur{lnVG0H>8oC^67Bqt4tl1|kD-jpN7di17 zS|;n$ZdxbuC3VNOGF0Wie@skXl2KL_dRY3Av;6PMzet`IL^{f!V$} za>xAsoItt&>>0{R+l6kOlwc)cnou=E-WH2bf)23riD6)q>T~*Wj+r;riRMrSx9Gl~ zh!v($JTkU|T4A4KxFXj$MM^MbMwHfB2VZGv##_Z@Ow2u(rs06F6!=3}**Jg5cDCSQ zY^NWZQ57@@(R;H9qiYdmjfK=}F$P9(u}SPu@!_sj&-qFn5T`~L)n|VW(!4U?^VjKb zo)@ZH04=Lv6Nwie4CGKT?kEf%Qxu1mB3*qkueji1ZJRWbDxUo)+$spqlJk7pAD(_{zKOd4rpdS5(M2{? z7^s+q%AsQU@G}~yb^VZ*nZ0BJnf{p3Kb+d=Ux7kCIFrg&WA%(0NjpV#I!?)_mUm9S zs6F|9@$Jx3$=rKTf7*H{r;Ge8q4Dqd#pUEA6-9-=2@Pv=eYL-5G`>lPZ%%`m37>(U zi4mWjjp4r;jqfIE4gFaDp#J=g(u_> zO;NZTjrZ$y7;t5zGPK8K;S8`mVYLi)rnmKvBO=P5r3o0#G_T0vN|rPeCuS3_7z$Eq zG;)*Itg<$tuQZ%wazEv49o@Wnb#F~QVPQcu%W=@-2Da{D@EfPjSp()JR`~k{aby{o z9TN)T0}U{!hVoef28bKhnn`hH!QuN0HShEH5Ls)wLvawNIZdZg_ZVra(Njoq`pPo^ z`XfMw%bO)!Io9c6(^nR|t0A%$1Q9WEsDof62ulN~BMmZ?LG_5yyUP+J-R8-GV8}i^ zq`?H`D=d6rydx+f2>=-40u_W$uTZA=7M7+4h!;ZS$|{zw<0uo>0+9S6z{iLmjWgdw z4?s*q89)G}6(wT=R07N5k-UTCANcuKyiPJ636D&!L48{lo++^?GcYbt%}N%2o{<~V z6~6<6KcX*pfWA?>o;NW9Om-G9=9Lmuqcj&hdi7KA35|@oO)5r+ycAGsvI;=_2tH~M z90qYcNF0oBd?yuPK5l@0J*I*d-&XUe*u;fG<7a4${WYo;4|404NKb3#>~+dnf*@ljBs zEHRBvkSQ|XS4}O%1p=J8|48R`tDGvN9f$UXoUJkDq1kr2_*dNB+eP^JCs{kXWc09d z_j5%{B;Z&pO~GDGu}=ecR!B0w5OnMTl0?L`Lo!*&Vmi8yu*`U+5uUq`>lIWI<63f|Nsv z>fYA~lCd45 zvQ?SEdW$&h=WWqx_l_;%nQkJ`TdP1ePj5fFh_IXnC^A>g87xnglKoiDFBn62_L^k??uwQvElTBkADP#$9L zTM3*EWA)kU3AWzt?pVEwjQFBQ$^M;o_pi4|Zm83fXxmn~)Kk=z!|6pH6OTckrI_eo z8|h>d_t;n$pZ#{jY+G5iYi069 zkAF6qO;tUZbGYddzb?1?3Qqy*cH}BYXiVjWwcSrM8U>?`A93N>&`$2F$4ZvpQk9v~ zV`y!gXBP29bYn!%n;aA~z7|VAXkESLX9uQaK^3q?96bjw*Jl&q+K9QSqi))cXkW{$}kN*xB$IzyJ97Y#jf@*)ubL&yWAk_GA648}T2s{rAhi9dB&R z|1{qIwl@~{#ifALeKKQpJ~djN{VZn zLgqk(VhMx}v6Kn|$HFJl5S>qaKp+A@;>Vo@%<>eoLgo%9vlaNliMV`#!hD?hPAB_2 z)>oZxT@O`vQ!7jjN8{NanrGK`r#~PmdZ*#+oSC7>h$&&>LG8NKc&YJ8Ve+ul)z`{n~NrViI z03rHjK%qo|L}=wA!87AUK`(Yf_}SaHjr@2!ebk|WuwFS6xqQK}L5DIu`T@Xsw^ezZ znFldH+bP7bh@r0Ax9xE22?=G666fe7FwTf0{r7}yvV0U_K^6Ji+xz9&sf)-VdjE&Ea0KtU-G1gCFSU|%2@jU^lV(E|9G4Ib_-X;#YcwnLgUOzOep`Am3 z35ySdH4f8TzR1sQWz;b*pg|zQBmo5&cXt8QG^BuH(GtM?Ki5R?!k?MIj<-CTb_GrpdBz61p~5XHK`MD@VF zoD~6hLEr@4+Pc+&B**W; zy+}xWzU02_uD77uT}NAJh$4CRN16cebXo{@JnV_x;b4*ggmUokFsta7C!oTggg!&U zQ}!Wuhuf{)d3O+mcEs;XRv((AUe$NL2HWJs>nFVWBfL9XL+`fO@6dy}+>*$wa94~+u3SkqX zX7&iwG8+vadQb5y{#X%D_57{j?>o_II_rT7Z_5hnJJcI&*OCIA863#N6E39J=9$!U zM$*t_3H=><+w>b*1-5E9bl35ZXG_VC2IQ$sb0PuyHB;5Q$5od8*_si1>J?bG9k2&) z#fg$LQ?Mo|!$f)_t%0bALW-Eo`qa$;9f~ zRHMjl;#DUY%kEnVUTyo_d3Y*0#!FF*8CXActucde$2=MhfvM?KW`XNA;I;<8gN ziVIC%DW7@l4^${!dmF9zq&iyXcRQ5|z$A5}B>PVn%9fP9<^1~CD_@sBdeL*b6vsH_ z)T|^B&;^?-bZ0(j?S0wu@zeKG%%DPAKi8p;wl2%hm1}YIA8F7?1D#)-S%H+T%HOTN z6Pk&7d{egr*7gDV-9!qcd_x?8>374->$^AE+=zUAm**fmw}!$7rqN*cR3#&ajo_2l z8YZo>!>09>u-xxhtuc0<%Lp!KZ#I5Z6jYpzjT4_^vY+Kv*1UhQ6e=O?Ym8DzJ#n~h z<;?Rc)_zf~C8N|`KwR`CC7w8aUMdbX>{s7*u{9H_T z*L?<^VVSoYLb5O3ap>kJ8&`So`cMe(`^i2 zr(#)jh)JWt=RArNy}V@QY3ef;`hK&#U~M?FtCbW(Fpxql&LP;pY1frqz57XQ_Hg{o zFza1(|P|uC`KmJ)M_P{4-~V^QOa$omJ>w<65`S zoMA+WFL~g% z61YZOiUa0usLMZk5id)DF_%0#lc)TG-5xpPNtlv&KNSljjyY+Z8n;jni(A#F_>w3> z{#1Wz-;IvbF!LEgG-N!w0D*A6j~3kV;awO`@er5pNUI#Btn%Y!J%$0Q4S1`jn_lg~avA-OB3`D}oSx*tF>xVQw1U8hC@Z!iBq^Fm* zj`1C*-R;>-QK#60A-|d1nOUc0>H;>*$dW9NyeMADQ0v;HVK4AL8gerppX@^xDN=rw zH%rYmod4lav?2xx+FXIh(=}5;RXsIiHM>naO+WPhLOIe>&0CN^NOs`9Lrtn|=2&XB zko)$!;>DeJU%Fxh$r&S}oi>!sqzROmh7tI!n{!G6Ue$OmFX0AUsp*bkOl?-#s2y>ZHJ?2#JW}A&#iv*HwNvcM3>Fpt5O4V_p{|ihl``MdWOiugADmWj>EG4=P*{Q zql_hLl8#>>M6WL>u=S}E|wzGGrTctouC%|&} zk~)>h%ud32m!f|7oc&(O7yD&3w;qz$QJB6kpbS~krTP4O!|Ep71UX922OONa2?$1J zCe*5XMg1+`W&|dEVa-svCF_tkPaD}FvumQ*fK8?&kzw5Mxr<2Y; z>2&V&8A}@r*Q44J|JXvO-I>k_Ey}toGQY1)0d?|`wC}qW)K^wqAv;O~(4kGnd)nuf z@6&6G1tu-@h&%maF%jI*3p#str)bmYvt$KxDIcC2P6{V;>N~m3>>hTdoTP8grRGx= zdZ!<-%hZrjmQC?~;8&?|r*->;9{p&WmJtO+#CjSJ!G|!Rpf6~y(}>PTz2X({NLE`X zQ&jdY%bKAZIGV~PA??dM_VX!p6Iipy2*3Rb$-h{m_AcG*Gy#to_lI8inQC-K;SG=W z8vL$46~jPjluun-N(=nT!yb#-3uRoo?GWbSP*Qlc%}-cjcg0+%FB_?~1@N_WHYH_6 zWFM7X&dh({@ydAh=~5~Bo|O3utjLE8;tKBbH#{G|t!p#U6rq^(jWH^|e9sd3yy1}U z%v*!u3#LHx7sJmai9r~npI56RA14MmB(&K1f-V(4VU!(6;=36%XRXdf@_agu4Hx9K zu2+W~8F8^EyJ1-(?PcbfNq@$98Q!Tq5b=P+)Hlj(aO1?NE68Lp+@x8>jUKjpYaK`x zv67tMnpJ%$Zc2^+isQa8h3B0*?{N6k!9KD6_qZ67$}*bH{w7}UtMS0Sk0~~#1PV_z za>rLp?hDyybUWHvH}Rp5FU`l4D@ULB1z8vQa04e zhXX%4MPT2+oOh+Qmz-tTsaF=WI8?*Ehc5YX-HAUl6_t2_;vSbCX-6r$cS^eK1I|`j zL=O0PF?3C7Is6_?v(N4JzCp;cBiBWlN1GFsX6YlvBoA?&6+%{dSz#i5bn9qnGOP(*YI+) z##CZdTfjOYb{X)0Ik8_65Jg7*kR|NS_V@#ZRH{o=wh)C*uIJ4NGp5Sg*HMbHJ)t-@ zd=wcPGVr8+DrR4lr(ufNN6}9xG2DiHhCV1v5hzfQIJa8Z(V0A=Nz9wMI}K-J9-2RH zRTQy(aCE;Nd#-jHA6oHrmo2|swb;Qweg850bVKG&Ua#rJ214kx#)il&nYtwJYc!PM z18kqM+s1_*n)vi60fOdIA&#nYxF&8SFbr=o7uY13KR^hPux=Tunrxu5^;b1sD+=b*jvg1oLLvIGo#cd2q`r?oi{ z+m(6(Pe8JKyQ&CY{im**#wZZfjgPMk-l>fdjOT0Zs-RqP&#r3_jy$6>>%`De20g&h zZ6ez48}POzj*kAomW~IBG+dWjVcZ$=WfBQOcMvIm6q%zE^o6(YMUJt7W18!knxsFq zd@Fl4u|@E%oMm`ZrZs{7yf$M^j(Vupk*-68b_!7myJMVWpp*0{F14)sfsmqv+a_vo z#5tK4n-vk!o-HImyl?eYCZWuhp^El>L;FL+KHhmg_?uK{hV8;z!j^GEO)M0_HoToq zp4iJzAcBMKE;%tUhAPTkEzbMgH?1bQm?G=8U1O44dmF7k=0yOsy$yo za(eJt*x1uACPOM;$_PC=4#YEDUwqun{4lnQ>4|>SpLeEmFRHX<7jj{}tQj9)=o%49 zZ(1jb-+&vV;KVBvZHks2qn3W*qiH29kjzG$*8XIx9^^nr24lMeT_}VDp0z!_`dG+`%&eVEaDLsi3!gfArZq<)mV$!^VKvD=BF&8VeAM57H$ z2HE=)KhTZ;Eb{lQh@G#bT((*fZmmInM;ENKu zUQAf6xk#i?J>b!dX$;HJ^>^TMFRcYfI5D)T>g5t+_9!|&WJNB{c;kYQs&l$wK3ayA zI+qmPAWt23XO!HlVwGjDqSGi+ek@_d?t|(>`Bl#6#A@D52OK!wc(b{so$n;x9;F_W z*SHQ$(g{Oy*_Qg38TFTUwPq#dC@%d+@ERNGTTw&kw&JTqD;!IwB!sRHW$ZWn6>oNa z#4X%EQb2!PfaSN>T;5qhEZ4}(*&6SJ{z;~*`}VEzO%%pJySq;;4-;R;;BA!Z#&B(} zyPj_F3fM2(5;)?GqerNlI#9TkB5pyd8a0Mx8+)m9+1)9a!%m~b)-`$zJoqRUmFjJ8qMID$ZmvRK7Zkq2oCuKW<<}81lrC1Z z*r>|XAB@6yxTbjPqTMAKcIn^^I^A3f@o1DZ2%gS|T77cHrG{ChK#SOXfFP|2ar~}T zc;h7s>1t!xZ@tj}WSJQiHAM+E@vmO!zbIg4=OVwy!_H35%FV_>&dtXCSGJFf8A#~; z<%NDd{KE^q$HMWiN|>+z@MpH~=K^MZ8yh=_%eS1Lfup6Ru>;81(%1?pmIm4A+ZkJ5 zS2llp_O+-P1Y8Z2@!2~X*aKI7EpPstpZe=6HOxPz2)}I-DPnC1F*36T15U0Pu2nb?r z403RWfE-NijEzAi5Jx+ZiJ6lz$llBaWN+*QyvF#to*QIs23%+ev4mIyr>)GsJ+m~n zw+DUu`M`F@`oM>hbFzc<9YBvjLLgz#V~_|)6eI=`2T6b=K~f-TkPJu`BnOfw=Vk>d zf|NkYpeG;|kSa(Gq)yJm3Nir7$-mwjIS&W$^BMtP)(~Q6OwPjv(gzuU3_(U9;1)q( zkSWLvWDc?bS%R!U)*uMT24oAe1KERsMgcj2oIx%iSCHG+dUT*UO&rKsSUJ8OeQic< zWC4Nejtns{M`mSa{;~4>-!>2%&$srl2infk__|5{_D(-8Nc3;tiIoTBpzH8gJCn0< zes9w27P>Ch2kBc~_cVQLqi>)2z5o5DQ3RxXfYzxNT4!rvJI zr13|W_=@3w+e5znUSAvKe}1!QGr?P&k=>w)Tz zzt%4Mx3B*f6i?31@iV8Bb8>(lk#lnWLA&H!tRQi6E>4g%ITtrbmYkdUC))kWspLF7 zKa(m@V#D<#t&+2_u>VS|KYtb0fBsci|Ll!c`VOY#fBZDSGHsloZ^Q53-ulP2JpS#k z^bJkqY|KByh@6f4FCzUPN6Y_JhyW9;{ z!?%PnIS1GG1(V5v`YtoeYmsohx}bycV`D%E8D9^^_6~r0utIj3@KBb4%roDvTUK?! z5I=ZWyq|fX802hBnV6+?^HfSQ_A*`B>uKyjai;@_;cM zxr!9xj#bQ-C*u@soNe3QyCtJ4Ic7Y)Y+b{B^aZ{JK08-rX{Mff~hnx3CcCONn=&pOrWIpEnd`ASc@2wA|hqlfU~7z^!gJ;>a111kd-PVg1yuICJ= zHhIrq-^G3TsrK%hf>Ppm>EtFg+j^5cc5Nc^K#)6k>Rq1Xb}bb9DzQKxNAVMHuA6h1 z;kRXNSzL)JDc(LFdweUB)jMzu-NxUe%b%)C^b^IM5d2Q+OzDo+F%Av_^3_kS$s7?3 z*|el2%T`(4Xi2L+k42TJ@*hWJoJw-s6>ZMWZH&L=pieyN(6PJUmtV!(=K2idqlNd%K$+kC_k>Z*$_{W+-vLG<2vhK$LpxN3s^jR7^#p z1mYdBm9$N}hmD>6Kt*)i4HvS~mD6ia_U<@rLGZKM6_!Ao|51X;;mracH~3sUF0+|N z0viWs?JDWYFr5L1!Tox(ojY%{vkKX@O=|ZCE%Ni?bBE;k7j`3s1~kpjZ;~-7&;1&n zu>7>a%Qp@Y1!g58gOnT%99(UT$wAjAfg%ebeS72UzmS6@pNKqutj;KH2B>WZK=#T2 zWF;d3bY9@E*YSp(nT-R)j+~X5?Rx5_;&rdKvv;_zAtYx7A{1$0$o+c239O2#YG&kM zY7bn?avdcB*D6DvSOe>+-!25632#CWcLUN4%)3H%2Z!^))8d{bcf1 zPrB%6NqLsVGfINi8Sjm2bV1)(@`QNi8s%&amQeLrBPB#X8JMQ>z*Th!j5w~Wc)2c{ zY;I9!(&bzWEb=yJFR0d~`s79K;_IFUB1{ozz1jVTH(9K$IP<-+MnqF|_88xN!9bT@ zYbk&+Syw|X#dSooio|)b5U= zv$X}Wt9N=+;JrDQMwYq9hIO%@C(sV=6yw`Sj*Y1GCpHrir=Jz7Gi8!m8yS?e2Fpm- zO|`ZXwB;1b%O}28Bl;4reVz)+=JPs4LQG-zw-tQD%|SZo`N;H4=|X;VnR650?Pkcf ztOa=W%RnU?|8|-xvTprl;{jV1Vi1PM8A3vJD$~Uv+4hO9(13->#m(n?O3#0V4;N6< z^LL^0Kfy;%NlZ#n`8p~rIbz(eRFl9ifH{xBGY}- z&x;{0eM@($Zzt4~9=bb(F}g4HJ~3p@pn2zAinhxGrj{al^@-DMdBf0HPoC46&@zU; zCk<^+*yrWAdM>#6==Vh|Hc@I)^V-=;;$B9dDC8xy7z#Q>#wjAIp-N{|*J~SzTy2i~ z1uQLBy4o&x%yA^@-ccXsp2)8C!Gi*xDm}>&SrkT8;f)?E z^Ihp2SB%h?GHAfQ_Z;}VtW7~A_-OcOY<#{|34xT=RpwU{a+uG^f;oYOlPvVcJ}E@Q zc6eK;4Oz^qbq^zrT6~TwhVOmPb+flh_WXrAkzSYM;#;X?slZP>Ix}}Gvy@vnpI-EsS-wrWFx+%#3Nsk(qLv}oi z1K3V3TtxOYAz5mNFN?|I9mADQ!}c*jUA7q*r7T~*Wd_5I6mXD#WGUG6Lz`d^&6Pd@?*i!remxtU2|PK#&KJzo8A)k&Z#rX} zFTIR9$!B}H^up2PeJuQXP)@94`%u>dv^vtnQXf1y@S+(FcwW4B$C?JbQW?SKpwUS%Q?M8`1zZW0>g|UBr1#@ov%+K*mms&U~YB!!-6swF@Q(t^1G;WGdWK|rp?Z6Q3w(j#z*ME zdP77@L&1rB4xc_hYwK9J5Qh{EF3P!|HTRnZ+gFoKLB&>Bb^1jF&)lZ#tJFL!UU=QO z!GG%f>k!St`Ky2RKMm1}QnKo*iU7q}3zO5Sh7_>TrG&yV;2opLyV$u|FVQIBXKW=scS#(lT3W{Cw&P9CQ#npvGUWLX#nr%1#q9fi*GUUYbMAQiJVkYB??A=+B>f086u$ zMVNJ`E-!MOv9)H@lR3M9zih^w#zfA#gsfUMceOo%-=Tb!5K37nXfiJ0v~c>A{T*FK zrB2`k@swm?!||8SSL4}khglw;{6wjy#5N>PG!rhhRI(U119w#v3)^z(N0N&V1?{C& zHZXvd`kYgDo9m*K?KTS(zt~hefEY-e9>Y=^Q`&lqI+5H?r5FfX343)LGx%w|J@>{d zv{#A#Xs6ZOYTkHa!$l?bGaO=Vva}SDcLy5@Tu~K2C)%#qyun{?WU&crR1RbIC4=uU zFT7o}6gBHXY!bM&zuNrIk0{>!CvK>?(K@F1)h4TLz*nKvhsB-fw8uU>T)P4en$cO|X$uJds|??|HT= zxD3NbccoWP&AF~jgsW9Ka)#06P>ULX`+RJ{$J^ZpsKYz9(L%%Pm^qA+99a>PJ zne{|*nXqk^jbSaxg89Y+=jK(7)SCh6<7)d(`-zim$_M??j#U;cZuGUYiViU}zX31T z?0nN|sF*%|$%Ipp~p7eZh!hP{}n9D24+J1TAEcAlL&BZip%jsxgZyY*ve4IBbx3(37xcu;ADk@O~1#NZPLj1F7!$@yW5iLyH4p`{Zd`Th}T+h&BWRnineP zXM7%RB;|a;J2JLttR|a!8hfTpo|i(!NVu1sQq;okskoFr@&Mb(P*)DzY8$L#AW^VI z8`?6~H!nrOihbK zPiZ@PZGw@=gG3WJy{8HBD;yM;8yV&ha1Z0TaqS)34-vS*md{bP?md$##A=wI!5y(t<#q(#*F$i&nRiQXYVfz(7M`h$3|8Wyphy-TFunWy%0v5gQ+7N$EL zOg{Hin~0o66T21+?0k&E=mmO1noH~j-vz_+!iDs<^*(Wk`&s+7U~t2~fPz<8wXX$( z=d@t0nul4s*Ns|@v!>s04(E>=|DRc6iYk&q>e4?62BF_524Dg0zXc@M`}zH#7yt_T zGookx9=-feis73{@RMTrF{l3Dkxt-(=r!p$px-P-EU2Mbw_x$L?tJmw2s}<8WZe`q zf%W_zPs!6buav^$WV+jSWBg;vg2U^oPa-rh8lJlQTM3dpP4paDt7(v}tlGD|n7qW~ z=VMoL=7rjxu6b-jp~LHVhgQkecnxnm&T?D{{k|xX3kFZGjzD>VD5bXnZJ`0XTOqXQ zGW2Bh57HUt@A#Q@*g9jj&Ybg$yVl<&3LW=x}6{obtKWH>H!W_n!rer+Z?xoORZ>ZJ9^YSDNRVo{QJA7=jTiw0A zxTaL*mVC`R32x_)dQz9aT(i!>AFOlN=-ly|b?j|D*c<9~zp{?RpR5DcIUvYgb1wZW>2S0E=SHHqsG^F}-$+O9 zcdYZ>8vH9xVg1*v!~D(j_)+ToHct5#&iuqWKUz6|vd({Gjf5tAvqmteWYAmxutrLv zWYW4#qcx3$-Elh+K%ZOAp$>J&eBo*Q)QFnHp>7ws$fl&1XM5Na)_m2>o<+l|T%naY zj{1kkbA)_+Lx%1(@AXd?wU(=)!>2FLSc5ksHHQq#i;jgGYWEi}`ja6^HKms+%GI%+ zClXD>hbJ5LK4j3;jShRksr!9U8=jQrHt)Gz=9-8k1 zCEBiq4$HOBkpYB`nyH>35;SBL@f_K11omL_p}=|1NaGV}nw8itwpoYfYq~k>JSBGs|d( zD@1Mqz0C*%V*2d z88KTq{G52NR;`nO6fiv8!C!rlIAa17)X8NaI<$*(raq6rOn zLf6jM6F3cK;4!pj;CZPl+50&*g6$wGg6$BvN=LG{H8#;dWgqFGnk=>p1C7`9gU>G$ za6I;)`hY*eB{?CshnT&jj$~&Fmp;RsZN0dd8i|0&BtQlMySXROdQA;-`N~=(4qkko z5fC2T4Y+?caJ+sw*S2Plb$%mf?`-jRr1N7o?Vl+fl}9R);z~a$o!_PYfEn9=Q#$NG zK=r56xjy()=rI2pUHz7FzUiT#DCfsAlRqhk^`BcKfE%0e@Y))w@DpEs?uOT`YOJo& zC>}mhW}cQ?`O()g!04sVF2z+n)TCWP^RS=PlD{2dGUNXF%Tmv>U%%5rug@-TLH+xE zm)C$7OIDfvc`1u@vTFcszYg$X3mcMW^ZEwI1m3Gpt2iG{_xC~gPpwTcVtcjKz38I1 za>#TT#?r0HrYm=Z1)r`sTgOA2_Nr?M=6C$Dc2EP_Y_gKO`-;1_Nr)+@ZFsSstXkq}4v7{5t)lj9ubs&3 z=D>2mlHcBZC#ni#`N_N&U*8~`s~ZuMfJ{=t*__1mWrES{o()eDI{ID|`iRAF zRo(33e%&l-lE%5J3aBo$k1m_CnsXzagx6WXN|VdVj}9-tOegQjVE#=m2d{IJ4CBfM zJFetBqAQ%$_iBiYFHNu%nw06O=`*xmc~G!6(wlA;gBD5Y(D3YZ#hX5umdG~IH_{_x zOCyN-+~erm;Z_^g8=6vlSxkY|J@#zi*#L8kVO&i$eOg}LQHK-2IObm&2lfZX!R#<7 z`j?EO^9SRw$#mDfB^r^(T*@$b40bUIs`CYB-Y~t4^E^$8T^c zicARxrhC-LOfutH_>Anl!lh(S3CXenD|WAks(mb>BZx&%mv!cbQoZjvV8wR#v9-5$ zjtjCcM!;`oGIe8CEz%g8_A<7Apf4gAe7a|i$%p9Lg8u*@6+KAP8P*QUh+Llx@MMKS z%}cT_U(o0H#UZ#Ae8I4*4o2vKU+=cjMHwMb0)4e(3D5HW3an(GeWjbRYq|*p=tk$? z(oOvLxT-WNvA8lSu?h6ejdhdkeC-BAU%=tKRBvnFDLXk+HcD+&gy8ifxkYg=`}MhC zF?-|{6-`h0c~g$7>I-7Rrng+(IYc}@D??5CfvTNdr!zWPon#jW^{J6W;0nPdT^)(+ zUGMv6{WTkBnC-*av?oY4bLSSn(hUpek7md}qZ@e{1z};CYr6Tf+~9XsEKn5vH@ac@ zk#1P7H@*CmZ&<%`(+`2w*BZyayE(rWEA#wV%KZo5aPa&GeA5*&$$h(ao$|sw@Pn~kR z0vgAQ6r{8cOe)`GsIJNDII=rvIq!t_I*;ZpV*tBsSIBv)91j~_a3Ac~JoF@9nOP)J@_meT8E}XWtlgS=W$9h_HTSED+pebsGvCEzU z-dnR4%Fhct!wXEixdfA-wkL18-GRW$(zlQ>RD6;69uQb*d2B%el@mYFWNH+XyFRI| zaxhCOTxRO&#@}~&!oAU9TCNyaG&k>>tkXGMW4i0Qc0PmwTD!#K@Jr6_T6Ngz&vpRF zq<6dJZP;%1=0INCcAKMxrzgK_c}BTD-R9WozS-oN8E@^0Y389uLA(jcX)3gjgX&(* zMRX04*0gs+rtC+@GFDSgscV^o?GuC|LC=K7jI4o3j4aY<*5X5n&B|;yp$^uI(u<-& zrbSF|j*36N#jWvo(xKA3CLKuO1lgnn?5*^HEHwS&8>pIY>c)*obA-5uH*J}g)}q!q zY}&_Qm!}eL;%U)&cGjW2`|`kUC}bHkd%pT+A&j!Xblhdn5@ z)aZg?DJEYKzQO3?ATbJHndFE=@KDzon+r(YOZMrt!f{;c*DC2HJ}x#&LOLwz^>$Ow zPE~zrU$J8V&_h{-Ju=g^l4)mR;H+Q~HA&^G(4pdD z1YtVHi;-cACy#6{^k;03(j@;)e@P^2z1Sdi?VA0FN50*^z4 zAdvF$$>cvxvMCE)#E|VNRb1@9C0eI1JN+R?I2#pR^(mhYDzR z`1u}v{m3@oW2~RN<8SZzgSr8hmIp}fx(J_-50FmA*5K=!P++6q|2FZ1FZ3pWQePlL ze7eFsZFoin2}u0F-3}AJx;X0ztEia}cE6F_vEROpR#8;XZ#9)+e%yWt$#mfqcHfd( z$eMLdvUiLw{{rl9v)dH+Q8{*ePL}V`s){B3z3k|CbxsFSLap`3g(}wA{3|-MeMPQq z1~oA)NRQlcz4g|5-D*cQi{@rX$4g%H_CXKb^Eifnyf8h>Z(N4B> zel$~yp3YN{AiT~LYj9*q=U41Sqs!I1QCuXg%LST0D^0s+X1`UP{`?_D(y*lRlHO>E zhv!&QP@G4xA!K9I0_>eu+@bTaf>pSZQKrE{C#W>ajwVK=*iKsMf(?(=&?`|Bb19nH&rmb`oWny{IJXeU#pdz-N2M zg_VjNV38QwM_-dZ5__1R6N@3m*+A0g&O1Eemw0ULdw1W&9~rXn7Lx_)3o(S+eB8y3 zi@rOg3_py~co?3J%TsnrV6QOS#}i@#hkg9^@@W${T(5d4q8797W!Sv_EnNk1j$z`s z_n-V?>E~ykms1|mGzE*Zxd&BYAUU+d*t6-KMOPvA*nZ$y0rQzr-5)(py*Gk={DvpF z_6-KoG2J6C%q_VW@00hhUYPXM4eu0Y$E!(o)Z)nN?za!@$TfI7VFaj2ZQ4KEyXwlvE6YKi!#MZIg&#E%(_=Mher*mwWgBEf+$32%*)hO%R8O{8T z7bx)VL!0SP%=+~+=joAPrO}!WNA6AMIiqHq8lEbfhNQEi)j^lbORAx`y)ha0*$c1W zkEO$cB{&7A8|_M52assj^ztL0C$ljvF#d@zUcXl?4eZk%txQ)_(!@vW)+*O#>%{Tk zLL|EvPnIkf$(s+IzRiSde$;v865kHCJA4r5fv?HsbP-v7A=XpBJol7uiv;jqnPPJt zc^f{0pEmGtb3hy37xskqiDfT2SdB@rm2Ejpv0G0a$lX^nty2!H)@jZ#iS&u11DdvP0QS5I9y%-^d3N6`c*;DNMzy(FouEPZp2l0tD zW#~nXDej_%z7&BMZM%nq&j=KW;NWxMb6gjR1O}e3<(^g$(A;Psw3@hmf9sjPR9_by zH>FlnT0K=rn+}P69jq+A=I1DPrO!d@t$kIM2o+jlA=RJjS{bTzZm1?wo5a8RYJ`w? zONanQNcSywv_5Ift5o+V^;)_X!$4S4q*J)+Gy;SroO0?|XIMS>)k;;_A1KqMgG2ib zTkv0-*td^Giv+Q-)fm>oW=W&D_5yk#B@?I(DF$joS_L<0u9nc%jo=OWeAGMftBi0A zn; z;IY8NMC}#dd4(p$cIu_jPuxkC7~tIYAr&{sttT-zCelxqkocX;b1jU+CBBf$+U!cy zq!I4yi*ZknJ0yNo)hoh~cU_Zss$^@Q=`bH(%KS<-tp5eoh>A(c%RTy8BmB+);rJ!h z!w#%R_b1h`Tvwv~$u%s$Iv`(X!2BGMd?S{>am{b)IXOB0xkj*3ma$j>ibJ5PrWig) zVWJTYQnx+;TS``BB1skb7dW8#TUq*LUU?ph+GaQ&n_2-i)TfNGA8NdGgQX9Q6m!UUNY0~hj@Jy=+w ziS{=aWuhy<4y@c=j6@ZQCnW1xYei9GFmNOk>Q7=9hSSUWh$O;lFNj4wX4pGM)C9Dd%N7-P1Ip7A)+Up0S$&-2ZmXt^@l(@^1V6h~QS$Hxxu15N z$Q~2RvxfmYH*Wdgx`RI%*b^aAn37oten>|Bl;yeWb8%fl!7w&_BIbv6{Yi~47Q$|S z5poPveoH`mV{q~j?clRFxOXgC#%|mxF>ppOD8mzb%q;=)#wGujI0LNDLevd-SzCk~ zNm8%HZ_*Db2|OeJAU+`>JetCO?`jL0cb-U>K@0bpQdCMSBI)EE7UR1YNg71mE~1?N zG~Bx^Ei4u9oX|BR?)BI1Y~st$CJcYH^^NToaNGMd-l49;357p@njH8{w_6}*yQj|k zNGqh4`NTj>*Pz5T>n>a`kc#BoBxYN3vFNoXXxs4{OX@(lCX% zh!DaPKcJsqmR!jcvKSQKB%^4QX*;^|9SQJ6-P&D`GRu80`TnfZLPO_lW=hYEY(-~Y zbR@W*pF(?*B2d81J?j{KMr!UHaYhYT9u1fU_5-=a#ElNZ!CkCPc!SXwF$d3J6Z5C zcs7bzgK_Yg1WF?g-K41EVIAupMbX!obG%IApll;N3p}(dc*0Mhxetcyk^GCW5qIM^AN(d zPkvadL4#UenXStyGCIy<_E%{XOr|KW|Cv$UD++`X& zDQOUPZC4s*U6V6v0^G#$lV|xFUbE<&yG-6I&Ej3jd}`NLLt5kd_ORrnYCEYdZDZ{; zt>+-kF+E{&?SyH@w{T`vf)9Jr&SGLU{DY=a%ChLJ+H9nqhk1`6^3fd(va{no2mBu5 zl`s0%eM%NF_s7UK9cV|6;U2wxFYF@&&GakY>@M9&)*7XG!zweNE#JA4UufOBwzNGK zZ}MIP6A|BmPnX?_Uwd}L%Of?0-1V48_N;`XqgO(y*e$!wmQbLeOALJYfZffsM}lt( zP^!~Y$6z$FW=Bq8K1YlQ=b4Mm6Vxac-B3Ty7< zC=!V!ELqDSB-(Lb_BryOq1+8XdUZn?^)Z}_o=f*m;|}#Rj+>YdQJ*Q%J1Gjj8N;~u zkOk)Up&U(?!mh4t>|6-|b0fUW*XGu1;*jUdrFe{SZ#K3KIgP*mB zne0RroBDbh>4B$;QPX(Fs>&Xsuk$>%$L*nr7cP5+|I8Go?gatxst_C|jW>og2a+=t zt#2fmB?~j*fLf<{jl0ZuEj4ja^)%rP1A-awmGl^o9!BvYK@tC&O-czsK zg)s;j_YHTj1mcj|lS)0&FCzLx{3%q4RXI&O;p^u$u+0_tP<@`?6_`ZUR+-ve$8+68 zua}vk(Vg|+$GEADbktl-_CR2FWTl8VXWPwaJf*JN8jpTPCwd?6R_in9Z$Qk<@?(DJ zpMm(Xg8HM!!rws5Zu~nC|6(<>|2Qd!-SZI;r4qy6#7- z{5y)dfROZ`dOudmUDoqoV@MN>@Q9mDC!4n@2;4T@Z)QgMfO*Sq&T*wX&PEMyeh zD3jhVEKN&Ed)jJgt7F|nh5e$pw^>ZLZoIewwLB?WuoAqzRk*g^)#)?{vLKqAN)C}* zb6i;uP8#w!)#7*FJRqN6E)>uqbXW2KX-o=FUc|l$srIV$GVz-p(@wjvbT$iBn(TS{ zc6M@=K6e{lQti;^$<`QzH^^$1Kc_8y8!EI?$NeozP#8Xh4pS%c zCcYxMaCQpp5fT1*XUQ;eW3_7Xc*ZVg39@IC=!+4%*ObtJ8cZ?)?0nT=6bVk~I(=I9 zA@wPwTrqe$Fthvf=#kOzIh0dSWSb0}2Yc+%WaKzIwp&}U`EC<^MDy%Y@?NmIYlTHU zABq9#_$FjRtIU&vEc_1BV;YxYas{Mf@kjY26l%Bbaqmc&QoOkJcCGQmG?Q(uE@_yfJ8kLBfS4h37|hiQ1tj$oCdQ5^2+sq`!NhXdLpk zU&==shyQL_(XM=HfT((~tLa@h!|2K+pK&X{!`V%8qMG{_&mSQs+CC$|@D9<)x`nQA zeFg&Em#CV3W46AIOB;-0x;*>KA5uzHLNs_h>`oRBI_H#j%EP=~ysmn<^uiT+QJw9I z@N_i4MszyDo}R@o;63a}cY3(kpi+xcDJZxel>>oLIQV(HO)r8y=K=c;d%T)1*9K=m z%DuwZeT=E~s4u5*x9;0H-|)P!0t*)9*?YA!94~KGO-=_uKHsdkex(I9r{CHPSpAt8wF=||FssJNHwZ-|s2wl0J<%odtOimRae zroAonbd9@ko9r9R<%vIC>x|sag0vU1+aE&v1IC#kA9u|+b_}GAb62gdm}aZ9rV<_r zyw$ERJ=_tWPr3&(G^QQyOY2UwfZlsVdb*>3+1uAK6Y^Y8Fyzqq?dH_Wvvkt?8E5L` z{?X3)4*FiwqoctdF_)3cu8*-R6nk)z4h(GbMDJ&v$(9#XYf9|Bg7s;LdZLY9N#}g8 zh#eDdTM*i$<$N^siaI>d*=-zSIy-Mqfk~(4qeD4=mtW1q%Cx8DWZ)x`Pgs)$`Q83Z zW(Xj^yzs!3$#YDPrxl|2r%U^yqh*ZGj^yLF^!h}plPjbBM>O><9gnREY(DI=n+bn% zyQ2-8@=jbOerLiNPCqdHZ3JWu|6d&rP|HX7w^QIgKX5ef&VF$v5Oh>DfI}8 z#oz{SQ7H7n2^n~|N{O}J@(<@+3d1)ugnuD?E6@n*_KXe4+yB|BC=1LWc68QrDn;dZ zq3{w)N93}Ug1CoJf+2zg6Xu@V5w;Vk6v#=8D)d3}k5b2!A1SkwedLqlK**=Kg<>eQm61RI4*17zAK!#dMR-9{sz+$97e>~c{?7;|J zKODmXc3d6?^GF!Ku!}EW&21WA7Q;%EB||R95y+d_o%$8g^e>)DsN}{n$iW6W&s8nj z$Aah8eAF@t3{`kW6VsOxp&tiSdp*9a(?E zo*u6|HhhfVdaK%$&Ny>0)+1b?+O{pcJvE(Em|Qd=-KW7-t*+8RxBI~1P)BaQek>=+ zEE|z>TiW9_QQbRF+An8Q@gP7qA8(&+uRSI1A%@Ren9|7_$=7-ZjJHDhDM&BmchPV- zH$zF=E7;_k-5s=JpM7E%aTcLTFRib-v)(qF!_i|?N*%(y;!Ut55CJvMbf*rIp-GJ#8Dvd_b7V245rT!RxV5Kf)cv_F^I zcDBqaD6vgehg^fOhtW=VRtWA~$@9`T6ChJMNpYaX3A=DtK7t7nl#*9!fmCRTsuVPkSRM zjDQ0F&iXiF8(gDUs{rN6t1wJIRB{?o0v5LGKYRNaFk`OJsL;QOyYVhE3g$#SHFnQc zUi!vIah#hxFt6oo+uMQb+z7Ibm}4G+B2hEou;0m_;L^)W!H71c!Q&&Z1}I_YGZKq* zTFILV`;$n`WO^TB65>GVQx%%T+6Zx;D!0M;)m^=wb$Bff7aUT-S4>Epuj#$p4w&AS<_;gRiE5JSu0kzXwJwl6$yQr|4gpv~pb0WD`t zly18_x{YXZ`zbrR8-MGEF@(nW!e!S!y}3_5oF{oC*R3+zs0%`mSOwkPJ!!f(%6r_1E2}G@10&vg&t_E=#v$)=EFHsCws) z=lh=-d%mXk14Dg1y-BN{etif*tx44-O$`hUT%}KT=q+`u5~Js@w|BtsHLmc#Hu|n> zYW2>T*Ve3ByMY!a3+iq6gN5C2g?Ae_2&+5q?K~0w7|t68%l4&PGkrt7k1M-TuC3)Wt%76vyB8Sx9wQGPwS=TOZ;=SW1ZyB30q2;`ntMt=i>|{#)z!Z?&hY%xztiQ`e%tFMHMh7ECU5cNyk72(MPs+R&daLS{brS)9dg#} zZ7?lx$)nZ5cF+H~H!OR_17D+f(c3H8&YRZGTl*=|fBT4O%fl18_Zqd=IpgN}oA)n% zXk0fht$ca;%yZ_U`O@htiaPwgQ9oyg^n3WKxBL5TsCZEKeCe&U+x-iF)Li;vICb5@ zx7_|K${p%FaHu->BpXXxcMM9c+(pIc;>X{+DE?RFE-KhD0p|)%KLO{W+$=A0MH?{h z^ivLnQ~zP*VVwK9(b1>@>1iK7h)vo!8I5aiDvy5Z_qThCE2G=b>D}G9th_jO<N$=l&~YT?MpRc>egN{)+q*!6mR`Qy{4Z+rC^vwX|e75)Q*!)$s+ z=WIVPb7K8(FNOyN*z_<7o%HteqfO>-_Br<1(b710&el<< zS9_m3e*3Qx$H_iwS-i2?m6W4{E<~(ztDltY{J<+a{gp+pyd^L0<|qH1`N7|zrFZsc z{aeSrekpq%{?abC|I45-T;Fe8{x81+tuJ`nsUc&~f%?gh|+G%a{_<5%?*EXyo z>0I)uVRg5Au!W8o@Rx1!M&G@gl7}ocoadLeqnUl}GhLOt=Y>>%d;R3vTK5_?T^cvU zd!668=h5r^&e^YzIk0Z;j50-99zF9r2tJxEY$$96dpWi&PY*u%E|3^cf z55Hb)uat<&mrrdv_TH-Prbk_jwrnaBl^VuJRtsp~{X{kAPM+qr2iK+U{;(l=VvWq@ z{Z|+GP23#UMlr6!=zI0IO|q>v4VgD&SIcKf4LuL^wzwQyD|V@>R?EyN&vC`Eb8fxr zE9q}z3|HHyG|Jf#ai)$UZ0`CKeb1gPo!z>|DWgZjp7oqM_t8PwnB#- zFoXQY-a$E6@TqrD*lGX6I{xz+#H(-3C)Qp3{K<&-{Y`4DX#M13$2P_{MhEy8HM-w! z`_(oP=e%wYuiCMu$3eG{LBj^!Obkyg&KY^T)!m14j$A(79MZ^lyZs7#b@1-~S8vMp zfBCXw=+4*|Z%G>YfJ67^r^hDbLK@k|YfNE3i^O;bw=EtO&S~AA7T8sI#jo1A)oy0k z=G+^1-uzvsq`!^VlCKh5lRw_M`uy{Aug_$gimsbG<)#>R4p}?XUD@nlrt^yXUB9~= z3|t)7erjaz8&mt&L|hgsLq7pm0ny>i{=kmulmvmRJn9zM!@{(?NWfmI$g_B=K(xBl{&-5b5v zt#+MO+i8GRnx%OS*JD*rKi$zNWqY4nOFc$x_gnvYS5q^E{?UPpTXbFP_RGdd+PTe5 zgMTImHtpfpU72e;$us3uY!{zm%g7T&cP?+8b>@t(d`od@cH=3TRb=|_BIZ3_lwp__ ztz0=UV|LqD(I;xJX;yW#;=(D>oK=~YQ!9+Vb{MqdQndk(9iojL549WI|A>|07*$Y2 zpnUPmWvv@Z5~?ITjs5b(GWJkGm8TaoNx^emj9Q7pwod+8cA-q|O)IY-C*PJ@j zy(Dwmt%>3HPTegI2$>yocwBzbm#*)Z1)P-S{pkJlpnsOrfuQ~IeNXlbDRf#8_PpZs z&(qynbv$Zc@Fr>c%aaoGns2@Z_FVhMcYgcf;p2AKDc^Z@-`mW!(@k4lZL>ohaBGZf zdi#6sifLh=XBG{#8EuiSZ&WL1Z9q;&j-ou@b8iQO$6*7Ho}HYT++<|OoS$Bd!#Djm*lpRk!K~|%s*P*SaNK0j-a_d=e^+(SCY}NF z|8&}W<9_|fzQcX4F1>NsHDJ+)*e%2F@9sAsvrVLEV{VlnPvol$^TW?%S=MUR@YNKT z*-JA1u2b9V%XR0bJMXsM_||8Pm9J55&vB+oZ|5q`=XY06YBXh-UbhBEyk?sehS?Rh zn6}jscc0yg}w%Dq-_umdZV>7g=Mg)>`% ztvO4T4HML-J#c&Czu#-owV(~ppld2IzUI8Tab-h%rv(wY##@yap zW|5y_dg^s^hX9l8+I`>+$+GV^!j9K$X1LVdG~sBE?sao-nb(p0 z?mIf9SJ9n{jgvnGhNxP9Yph!L-lFmTqaMlYn*A7Mniw0AUzqT!;+fyDSK&1W-dnk) zN2{EJTkc)Vn!V_~)zDkg+Bc2!HqP|95R+N5C)56|)eG~x3sT!Isa`X>U9~xV{i;Q+ zNB^zX*B<_~thKUTe}l$V_e^zxKNd>E0eAYeH*>3RxTIl+eN*k1#vH4c7*_uur|rp0 z3;$?-z;D*8#nrk`vrx|LH!8`b!;)D0E|K%2wnxp6vW@nMwvD!}b}_W+^hrtQV^l`d zy51^_>98PmN934hHhq#zI`2DF&GC=D=5qJ#Cu^nsQR9F~Vn2tAp?5m_dq2#!vrhSx z;yZPE?!}V#vrh#cFWPD~q31V;)<@Pp*Z(lTW4~p3r`JY#ztK;4*;&7<>7GaL8*WNn zY|z@RL7xVqL*1(#J$Y?Q-P!#3GX`0&U(W+`Yo%T9xb3lJWAGu}N z?2f1v;XHa_PSN0<{WC|cc(`08d7h!XWpq`(v**H|&wSQLd1rOHICom%%{9GVj#Ayb z{vha`i$SRVW9vBEln&*iPPI!j>L9-JC9z;+)FtIIS=gVYcQS^w8MQx*|cQN+rC# zR3u^t_Ud&G_dNXjbzXS})E3TwF1Bbp-mvNFx%b;I-FbI(K+`#ECik9K7lp?1=!P%6 zPw(CL?$Em{!H{A;em(Z5_wdI%V}d5WIXo_4_~rK%X7AojA2Y^kPh32N#z!~14EhvO z^mfZ%FT#@V<{sK&I^az4o6moXmc8*E9Ox48t%Gf=&|iT+54l9`JH0sb&6I$f!MO(; z-g#d<7mkUlIwbzM;@G0(>hdAEGY9<>I@Gb=;2F-h#$>~utWZo#EwxGUl05E;_T;PU zojq zh4T3n&toe8VYXwockJrcsZG&y*goA9?TW;M7IjURZvzd_saZI4AByrwc(CS7XK-*ZFKfN@Xm zU-7@t*7->{L)260wU!;9v|HGAoN2R$BMlZDY|ydl1c_zb_Q}Scot;b?`_KQ-_DD6K zwkD%LtgdY|;Nqr<?X-5koZ6+-t!S{%@TJSlr$0Y&CcMcenX%M(QcFM2tvi-|J(W0h`_z%o`aDa% zvhd2Yz#fyce0%l$QTn58*`|>5dD(S+vKp8Tx^}USC~EcBHeYH;Qb(b75onvmP5N#d($4Arc$*aH8Rye*W-Qp83bI|Wn+vcwM9$vR* zyMG=wRF2$r$*d=A=QcOj9&=l7_p~6iFf-0KBk%C>;;sjBQ@8Y8wSCrcJDacTx4h0j zZF%CfBtW+1V2d${2Lr>R%B!p4f^itJxu!(GJ_}!U)o_S;1NB5{!qjnd#nayg@&vV_@cIf;#+<0e?phw&53^x}=BxL#& z^-8@S<^A(vPD;?D!H<4r_nVWu@2yMYZuU(Rb9SWE+|j=7=o!A|g~zY{aD)=9#MM7T z)2{DNNwGVAVDh=({w)$OOtBa~;iPfmfrz5?)lMZ*PEcRuXB!c{Yg3i#-s$t&KIyW( zw9D5jm#g_zS*+*Wd-Ah`xKW#C-H6*si?@DZE+iz*6^jnq7 zX@A(|F3+9l7dPLkZnJIv?y84{U3>KRsME9Jxn3Qg<}XfppEq&ccIHV+^($7^erYWs z@=oax+|bWs?4g*7&ISDqckiBP_W975;`KKU7|UAksZGGE2?hMFgPIc;gWzAPv$+f+qP)zyWQDNAA8qwF)tkaWN^mL^E)^7pWmtQ z$NhMt;EqoQHoQ8^%B>`_@zTFKRUdS{dzV=oJWtyf$9&w~tIMIx!3RQTtawl-eovZ1 z(?hbovLBYs?gxyBn=ilE-=X&DcV1UKR(X66*|~q;``1Ux4ip_Wu^jZQC@0|kL*rpT zU-oK{GpNDV(Knv-N*U_0fVL1tY+L?!TkU{>{p^P`M?eZ%{EP2=h5fS8K36O)dY?3)khUX(Fj z8khRVG0SLqluU3xF0?>JNCh}|xtsjT>Jl=B9ubggeDlWD0Y1{U~p{w@xk#84{ zXtuz*o@hy(1|kE)w&VKLFE|<5IhSdp2ti53|;G0TWsK3Z>;0Badra@3%ZR@h&(uc(S}CvCoI}vP+YG?yMfi_UMgz0 zVAcJhM^`m%-epEy;o=7UE3?31o_rAU z^V+^KaNSt+>^fm%J3R08^xgayts)lew?1NZW815~d4|ng`{(y{_jn_#l2U8Xun$Lq z?)2+iW_&Bw?a$i#p3k{^!okR}zrw`jr(>Iwtu1T|jAH!sJ(B`6e#FUUba0tFXOnT< zzzs_;i6Y%|rCY*hZ8WdHRo35PeDxchf>LI_%}wd|Qopl9{U;+Hwkw9x{DmfGTL&+G zx2mzvv(J80t~Bg_yU-}a(!9NBx8bF$P|?_r0dQ(c`d zt=#;)cSP8?%z=A{UT<^jb7^MA9IKMTr@0qzXM{YvcQahw{}}9bDDZ9W_Fki_e=5#CyQN#i#EST#WjW!cPHC+} z%8DYgR!%HAJ?Qw+>Gu*&4DfCKS{s1zb3)m42e;J zvUg8jnq>A}8yi3D>=!#lwDsSMGOk^MyBT(R-kN#3cG|YG*A-K~oX#znu)J|?S%i_I z?$y^@){XA_xqRPebUXKrL2oYPCEO1GRk+>$wcp91TOthY>>AIE+v5KDa7K9c*8Fdy zFHa8`;bk-9XHx#L@P|f+dyYacUhWy$FZ|WdlfJtqlus)>r0=dMFu&(;a(QF8YIDzm zk=s{qUme`WaM69Zojc_Gc5nTx=9c$eucdYNJCc>wIjyr(!-0BNYI*#*wceCtd(-xw z++AawbH`1|HFoOl^yzordgctD+eZ(S2l` z=3e$6c&<-caFTh>^5h#aGaDq9lra{C zHtCITE?zr1`G!NvwQPr!OKT<<hE-OU!61&Y%< zMyIzt{pZ&Bv^njXeqF2zY1c_FwM_Y8%7BQL3B~@g7aW{AskUrYD$3I$T9%YgT?N;? zoV!%^%h3Is^Ou^_7My4z^c9l-;ll0yu0!nm^)+{ZFFytb2f@dWd}jMgE&2parUi1$ zVI>PcaHjFz-@pl5ge2f-^B4FDAfCZ=10;V>+&PZ;ydJw>hb;J ztk_Y#Ji_veb}m~sd-5QgUM=6Bc|UjN**PZ$*M+;L%66Xe%)58oF5*nB=egU%Y(jo! zeDAgI)8UE_8yEC=^Xb8_&8;$vX2!exXFn1Mcf8ndnmwQDM|^DhEn5`ZYjIrEvo9`= zhj)}!+$n?Wt?s_)6jJc+w*R?^&#pVBAM@Ow6?8Fs_2s;YFYo>^KWcjH<+oIKkynf1 zIV-pHDpDMbmtQ=vs_`hRyF2_htT8sKE#FZsfTSl?&#!!YZLs^9jY{)FYq!R(y)oqy2z#KUmFuG+Vq?x`SR*haPhW$hm;R5+UFXLIMQL|_+@1-M=l>N z0Pg@!Lp(jkVk-ELkQfUoxR+Rpgo+F+647DG~_akl-d_&-KuoTG4)akQa33494Ls9NcE@~g4%axFf5DOYp zTnQV#Gmu0E-xB)QiQpmZ^2F6?qWSIHMXsy4Mp=~M*ZV+fpGQe+&PQ*a;(abWFVE0? zh4RuL8xK5sv9d?m$CICjxYgMx|vp?cO?f>^mgykoWhQRqD+4EPi|` zAz**2FJohamL1$z-lWsx*f-N|TkqexOsvc)JXh`QlGkvrcvzFth_~6_Lk5i4F?-Cn zCJD1GO;$F_A7Ps^#{2XsQBd1i>)pDI9XI{4=g0P26fOQ)@?g{Zp)CTU20UG&m)hIV z%e}&SXY#328@7ecd_Vg{VCKG$kQyqVw#+N&{kl(=Z_~;PYK<-Vv8nE@pN|)~O6w{|-t~L+(5`xkch-}GyF8Z-8+oXQ_4nLS zmsURWUwvi!+AFmco%cO|=&}2Hfppr!b;dSrZPA7O@U=SM;I`spxh-<8Ve<3&%af3E(t!?T7{ zFFiJxn$i7rgOUwPh7^hpWt_0|pH?UuG;egH_Oo7@`7F0^+idIOayiU(gwu=VqJ)Rm zkIgLi<+pkB@_wV;RUi2#7xd7-)Zy95i%xH%J;&xL3nLbN-&FF_$iaU0(;I`ekboRN8nA?_PmSM#zzv*7RfSL6KS8hd@Y zHLiuJGOMTKdsC0bR{e!5N`enL)H~S!uNB3);u`&f!St{?ER_2~f z`nKo#@jJ=>XB^~5inb2@)UWX6*=?e?Q{C(n+#U}}GLC!q>V0DQuA4Jvyt)zWe!W@$ zcZZ6y{&;yyI;45|9+B6lsMwUm=e3W3su<9&anDZ;(8`ErInZb(}#Say&aTwCnM$X zTS;2=XZPR(irx0t-TxRC?AXu!>pXUwkrTTqJ2}Af#W34|)SLSr+-NY;JS%7N`U#Vk zjsG~#(z;R9v(?SbWJ!0=pES7VIHk?3KTVA5w&`kC+Aq6Vn@EEN@qG*=m)GdqE*W50 z?`*y5V@^?q!cI6*SHL*7Wh*sjCXoXTB4isn*BzP*e|tmKQ(NuNE72 z(5lX)9&)2GX;a3xZdzeDXP@f!=6Ma?$BhY#`Tl%L*$3CaoNn*q`sK~4i2dSxrIlre zyw;vxclZ9&tHSN-uj=+ee|NoI{GpL(4DA2aW3{`;Ydz8&Y+tsg6^*n23@IH+gEtViqeN{bYQ z%Nq8o@IN!~VE&!_lB=%@udFP7@g(Z=%=b3=UV{dWxxC7MvT4Q0NB6#!gul8OzwmQK z_F1oP5nsRGM|d^q)V7r;!akjozx-uf@iV8e?4NU6%6-}u{J0aJzu$4BT_FB1JuOhW`UsdziR5)sCl$;tf=XF$IY}pduq-EI1(e!Mep z^mCxk483dKFRQIHoL6;5dT--x3-U}{_f_fq+_k0K?kXlbl)E;-|992jyTda{w(;Q6 zDzBPX35^u%S^Fo|x#qX!YL(SDhgNG}Wo+ctZa*G8YJbnM>bQ9iYPAhro^5|{TOIGQ zRT|gcd%pXkA;S-OH#l$9_vmarS@+;sg_A<`{ihARne%3TV3on`j@NE#x29@rqoqR) zrd6*ped&4^qk4br^*m{Qf1O{lt>2KfGwPpgS*ogUJ;|+kdC1v)r?O60%t7grB{P|CS{FWlc}<}*C*Je_TSQ%(<6hkMqSLh z-!VRPp>@ktgMx-9{v6%0rc3P1c^wZ#N8K?_c~(3>;JNIqi+|{bf}CSE{SLp}8<6pR z`RF=R-FK}>KiPWE_*yBG?(aI`l9rwkSNq*!)r5vOHjAGmKOgZ0O83un-2BP>db1{H z>ScGiHCca7)xnxk!;41NF3QjG_ z%saI@d*3Ei+Tl$q+neH%Kk9!t=r=lcbn()6wFA;p+n$}EZ@Jzpz^2^n-o43oK{rlq zcy&|0{MqHCm7f=`9cTLHW^#$N!PSTEAAj`AZZXfiUX#*kxhWg{Yc&z&eVTsm>BQoi z=jIx$d{%Gpmz`GEzOG%AP_s!z-8FmDYf^j$Tm(|N9RJk2nY^zREkBf#Hh1kGtM z`)8%oKn26U(JSXVGhwbwEW#dwTfHx)RU(1I`PWVZJ~ovLcbLF^LQz$V+pK7BvtdXz zy&s0plm7Nw>XUP6csKp%R`-pQew4pnGh?H1kM?Hqt@rg`T9|iyV{z9*4^y|4LG}K_ zv#HZ}Z`qwc6J9*GoOI(xy8L3@N#-8T2^DK+y?!`tQq8IHfk&K&)UCVnjQ{m#yN@(@ zJIQTq{@X&+>fe@>E6OLyf4n|i{@|yZY1FB|9H!*IDR`wE)2en<^q@`KR>!BjeVY*Yoh*g3V_K^?YOU+2O(V!2N*@+m);?>|(M1RLg#=e%@F+sm6liIpIkO&cS}E zcO5gv^%)_bE#LL(65J^ly>#x15bCn)tv&m=m#@l8Us~o~J>2#2 zAzyQ8+0tR_116MzK6EVaQ0Vc;j@SPl(dhESqt0LR|7vYl66JAd=(|C0tw-7P*8gB= zUB7n~@3iGDdmEfLF{#(CYSNkXHC3-wxwK~LybBgfgVNJnuWj$#e{)y3b!e10shWxY z0A)=*)x4_bkMuTPu`70MKT(y=cXvr$8dRy59Mp8c{suKxUyL%2pOl{Vq2ALWOGZ^S zn37g?s#~{Qk42p=cRiinxaz#5)se3oI@X!iG;2-d7o#EP7J9#lD4UaW(q+xI`{V!l zwlCN-DZNv#PQ5HUo_k`Pe#>2NW{=H3K5of)p74C_l!GTF%RUY)FB+5_d$PIA|Ip2l zJAX%hFItjxGEY=^K4-FTQmFUSs`5$K4Sjp4F1sE4qeFL}xY91U>(;&-wz=2K4P)oc z4Lp2lZ?(k!eLSv7p6pV_9qSUlYxU$6_p`H~HEMd-`f0dH{FrMAid{8FkB>Yme-mBM zypeM8q%VV)6*Sj>I%S34p39Lx3bt8Z95=yrneET6;$?~3(xrxB6AUkB=d`uEa5CKC zW7!HXlXIK)MDM8?uNZ#o>eJ3vUN2|VDmH)E=zjf>alM8=JlUh&((q%o6EbVRKl$Nj z)ha=YJt*rJC#%)l>AzdQ1DyNYIShjJ8yre|B}d8RoGO>E0xExhFJJVJ-%we2<_XJ} z)Esg4d;|^DOfq}EO8Fo5{Nd>Hl;}eA`*yoB(w_aC7ua;&jsB- zR;>LsNAk-ibx_<(r*HC^75&ba?2F4^km-B)+4;-orixDfcyV=Ki|;|nKmLd`xU@a! zMnPorJ$|QOEjjK!!OAOt<+4qs&Hib-?`g`U!WYruaYOuSY&OkLco5(E`^Gj8i=P%B z{xB`}>P)xN4iA4e_2@ODV$$4SaYsHBew^0xTR_VZnxFZgx>&J?=j89CWhmrP5M=`#O8?HeKxJ z|1{`(qHRWchl0q`SnDRkcRah0WcASOM9=7*^`_t1v47rFgFhDS*s}Mele9r%oB1oA zU$67@+VW+V^Mg}tLmfYK-FDGY+^^;CrWf6l7f06U{A_TW^39?LHdn@vNwzw+PyboV zO}_p5#O*n=z}WU^mUXJ$kkNhZcARvdZW+5+Y2jx-14MQ_f4w_U#wm0|g##JPb%r7t{} zybRvn^QFRf%|^wEr^DLMd1v?{bJD%#r&`W#J2bjl$cdkmfoiWa3v(NI@ z-EN$HweVSw9X%{A)j9j%MV~zH)OX%%5^YB8Qrv&!eL8DyT1A57j}yPT6vT)o?m6}) zEFsux-_8B!&#Zs+QorcNw6yK3UVjSNak!pk2hVM$IbOldu1;z2kA;(><-3$a-%Oi) z3{_rS_VZPZb3f0`OE3-jVmj-b3GMwt@CTJn;@^3);UnA}Mhw87j2gWNPL4(FJ8?ux z_Vw$+V`6Y+B&4ZyWgf<{BMz;$Jfv?a*kFGw`CcxjIHIp=O@*f{;<{^^d z{Jxn;f&HVIh+MA&AKWDW7859BCML;0uUeI(iYfPt{L4|r_yay}W@2&`y_pz}wBglA z_~Jbl4gQPg$V@^$>%|^b^1qKNkzfdDCXo`ECFDreOhWb+GbxmvAugokdmQXhWq3N& zd&Pg6VJXhcx|zxFU1RWH@`_&?4*!1|RS92OMKh=(JFuBbO7y5w5&gnDutdQkYkcm-8CL}N$U*CW zJ1_(188e2)cx3o5&M2Effdw7T{h+^dm$DGj~f+4pVvuh#54UCd4 zh}m95)~sy-cxTUq|MbZdkZmH1tYu{jedE-smFu(#Gt5N9jM&}bUw%(4(;ZV# z1>LDXX2Q%ZzdOcaTqeu{u9=HWE4MHa*TIs`iD$&T;=2WaZ4I3>l90|RoFh7qbL?fv zL`aw!rFYJh=2$VE6FFF%b3F#(oVnl<%`(~Qgq$aISs@o^;O0!Qvd#`JGoTP<2fSpL3==q62n!97jqf zg6uMQBFKLF+pxi%u`N+uEzL{>v%-i2`~5CIF-t}Tj0@wMCFi3AjHa18j6u`*!$y@} zK|Llm8v=A#CXRpL&JNr!%Q!=I!8S8D+@2WgB%&~%eXE=&jMI7j{&uqJt2Al-GS%P2 zu?X13R9?5gb*aw5P`hP&TEQKi_$okdw@PO3wFOK{=7ZWTW14st1cmEd@PKVaeHpN= z8Hpi&TZ(#eNl$!#im6-%32sM5hrg>{sc@dnsjpmP6vfN~u{pA7lRTA~`bv7W$;nw} z!aZ!pk|=(wQ~hc!GePPBvBAlSjaM25{(&dSZw(TJ^LtLXJ+U>&yy3^{7E!s~%71GR ze+0U6g4EsO84)swRLbiKV`DVcBpmt8AaAPGumg9jRw$Wi0=Su(X1G^Rw1hR$I4a46AO-J0tqa2-5AATfW$RDC zEd}XR0v#UC;daYjfdY`jefJF8Z6(CvAskM(YK(wYNdj)xBv8;zCAi^X8+Es&C&F!| z-C`VKD2>Rk)-O*Tzmp1 zKnAX}eb6|IA=7=PP45EnIY|<99xyQ|XnJ7K^a++C_?5}3uz$7g0x3B>yczpvcv?){ zGUsP8`dRq21b!yLxfeK2{{a8#Jbu_+OSbI<-2Nu$o8RZ7F>(H8SWXQSlh2`>qe3y)1Dn1uz3CoxaEpH%D50J1==C=a% zKz5Vy9^A2DUV+3cBrXZ&6-d~NuqEa`1ibS2kn;s*BVe_|<8}gSg0wT0Kd@qvOzpI| ztzfZ(<7ZqYhlJG29LR8)6Co|i$qvlpTZCp^PK-sfxX7BhLy7p}vU7`6aYaapa^@g` z*BerzoWNoJKuC#l^+w0#0Vz?g-ZZ!*q(nKnQJ&u+nsqse4K)gkc;&IE;0ug2pw*y7 zNQrW_!{PFWl!(4Lfj1=%2}V{@+lY}86>3k!ZG)7kV6ygHzQt(P6=V@;78f`bG~+od z8W!O)ft09F;|4AXDN(_k((wjDN>q?{S@}F5B`QfOgHJ+ARFdtRPeQYiV0J#QbTMGUog?knHhI3k%yw0DRNLMk{#hSfJsr| zOXPUV0XrvavQRXN$oEaqi0hg#0@G%?Xtl$~WEtegmQjps+FA|1ITU2l)-;zYMiy;N zau7T@kwIHirv}-xwf0R%;FH9Bm&B=Mpy^VK)&_G|0GBnG0VPQ?@qS09%)Ft=qaaHb zk=l121$iS8&158KqM1WEP5MMUauxAa7IV9xug|sH3nVJM?4SiGK@-gcc$x%7Tyg~!xFB7a33^Zx?9J^7J0Q4iSjaN=KVqhyf-|}l zX-!P>6};Y%*2E+u!=s?(Atogfn#ANwDV6fosS7AckI z(!{hdLW-3}1O32&l0Zz2Qo6G!M)P;{^Xr+mnLJw|NXr-xZnYa|JGo~PdOTjwB z)n+`?lwqBbE4Fwn<9Q}wo+ddFm)wB_g6hIWGORQjqLU$|NoashhLk2@ieI?nBc(}b zrVhg>X=qc9CR#$0BpStp#++fG5!VUfpj+FfB1c;L9e}g94mr}Ax_XQ|3euW{sj=cx zkk%yXNT1Ui(wc;}t;*3vOGx#OCP5LG+=2LUDqcfc1;tuZr`0&DVXZL*Yur(=)@WD} zI#bd@UIo?~&1@BTqP3f?9J=K&0F8M1M5$73Vk)rKXyLO0YmFSf@d&}5qluOh->pfXh)aGWo}jd>5?gBuq%|p1PRQ*GX-!HhKDnbn6D2Ls zRwAuQX=bZLT9Y#6qMT8bXriUs0X*W7--susu6&XbX-!H?94N8YNJSxU6s$EG6i{NV zF;%Zz&al?h$!PXOEAd2=Y15=n#3i>oKIp?cnKr{!Vy)4FYal3@VpYxH3^Ei^NBqnoYzr$4Z!SXjsM6g`}_)V}+2lq)mQc zn{NQnlqbIi(8OT|bIJmU93s{+E9l`6v5r{)l0(EgW_fB35$l+hJ!KQ|kOX*WkssyQ z`113;H|JI{>e5$OVi{Ob0Gksm0xL{q)35|A?8v5Ji(usxCBSBvC~ zf9E#j>0Lvrsj`id_#jfm$(u-^Ap@1OU_PfIGEh0|kcUG=)+A@ewHzW+t(;V$2**U4 zkdpvHqx6_{A0iT%0N|Ue~V&#+KVlB!?T=S(DC|?6)V~>V)&q~X%X;}5lTWb8Vu;y7|1iKwp zJS%2q)3Dyv6*8R3R^fFhr{*HrJqXl}8uAvsE?{S^B1T5eUU(C!vc&39S6=X##OhI( z%(#bHyq-Vbkzj(eN{jhv$lfXPV?D9P^psrz>%;Nvq%@OKi!k1D#4H z3AmQCGInel_CzGa;2McYOpJte6vS?a1!pBq*fcCS$!lvA9COSSTnsbD)3`232TWqY z;of$26#|%wxt2$^N%2S}7%IfR5v3N6Ngc6d@)6-AZpNcLoQzB+D<{LI;mM>$i_j;Y zOcE?=T;rHyuHdL4PvaU65ZR1i?a+cx5edEJwD1yW*koDR!^%G8%%tG8%5!`WTO#O2 zi}gehvSAwDDYOU<9CHOn4S9lVI8&@-QbCxcrCNXy>}+VE9MG`lsGG5ZXpR=hi7?;> z!7J!P%6I>T)14gjP(gGHsA;A@_$|N?ENN@!Wc0xO3vI^#s z2R@I;!W1-+2<_1NR}he>QE<#Lzf*o194}9;Yn&iN1udi!0S!fJ3ReA1rQ|?FMyp`e zI&g@{Y8A9d1$B!iTS1Fd5E0Kd^(2xr0N>tmORnBI_lnRWbTk}RAT1g}M65wtG=hj& zg|uh{5wQ+g>2(h8$cZbMOBA>|Bp_O$e*2wMsm196*cP_riLWa`2YizHNE&8GM66*N zXh%e>VH#>jM66*dYzHFNFzbMUEf{X7Jx*uX=8MnY+3`N2!}u{Lv@jjUz=lDK(t(EU zf)=C$4Vwk)q>wEgwhC4`37dwEg1nBban-AkFX9W%-`VjdsZDSU(3Lc=D@MDGl2tB4R6|A$vr`W<;R9M)Bb>;9D>Od{o1E`wWSUt25 z3ust9v=9quSUs%Lt4h{T+zcBSEg}+=I9EZ7dJqjSc$H#d(1jnkQ z9W{zcB(I>wU_is#p`E1x4NoQ&DUe8BLB$F(GMNM|Xf$@5%-{-+8uB!*Dq=S-1~eqNk`{vj4GFHKCF;c_T36DN@jxSe;(%78;Fx2s;KFDf2ijUSPNH=s z?H~;pL8h*xoudH_nYxk|^8pP{ChZgrXvox+tSY=p*Qdayt|U-equ|159Xb`5x~_~I zv_Yn>q+xS0Nhv64_#0?gJ2dFXQ?3ih;?5H7cnd?f* z!C=^;X~8(qh!QCEFhIi=O$)_=hAo;Fi31HeZzU}>1{yX%5*cd|9606+&JWhGZ`HQU z0TRHAK(q`KhA=9cZ^HmaMe}SJzNlz^O+vyrB@H424O;<$$eIMkoO0yF?RbjT1>2wv zwkjIr1{yX38sr8VHUb*t1{yX3R)OMg*9A0e1hnHSpkX7RR>ZM;0FL>B3*4G6&?bQZ z4OtxRj0%c*1C5Ezt0Uk*HRq!ZF8O!BInw#^I|v zI_kt=FsuPulngYi0owT&(C{*(1+)?pWGQJOE70&{(vGBnhOJL~a7H-h3XU4`1lN^+ zgTb(NXu%oKuy$y{8PKqHXu%oK@MO}0Goazgq#aiQ4NoTZ&4@}{!yNMk=lL{pud!C2 zhFt~RT3Y!sR^<>RGGo8*z@}mC&>}1eiOiI=syLwG$)p`u0S!;4_R1)D3Kl0l5RT@@{J4@A6-XsK$TVRp0^!lCZrF|O)S zOP=()a&OQNmXC_vqw5>yNX1u8ugAj<_j)x z?>ZqI36WK_0}=_)u)nv zoj?v6VcVsZg&|(B?b41*5D|F<73&rHN)?jif{GT}LPN67urKGCF3AO`v>z>@p@C_x z?omsw@OU9>^>-w@prW0q!WdX|S_}s?EII8w6=(>zuI{~ z<_eA)@&wlj=tzDtf;T^=6u%Mlwj z<4LUx&0(ZUMIRWaQlSS%sSNJmx*3d7sSp7pR23~>hryW+mxj6IiORd_MU1y7ZT?J3 z(jqEa%mg&NZfS>IK*JuHTr$KHn4~dOwD1So;gv)?V3LvyflB-9D}-aN+^8W>$GWf^ z42FfHof82K3r9OA0vdKaw6|A)Muejr76T1$4zw5zXn1qb9;3liz%gHNfyQ;gHXMzp zXmw3E7Gb`y!5s%jA}U&57RMnfTKW`6A=G^mqi+@2B{lgkVW}f(#nZ7apoZfQ6>ZA} z2n<n&H zBRx>6*D=me(Kc|5GN{`(J{VEaHgCMUGF!K1QGrX2R#7Xi3F8VvZK7gup`zgc3@uc& ztSAN+Dq2ny!wMBGBZ@(Vik70pJE}^16%Xc;BPwde6IBPuB2`-yj7SQwnA_br6AC3N zNZk~0f+%RQQnnyOLait}5F&w#RgwIg2E7Ujwn!_UusVPhY6Dvg`%*Zy4I>ilFw8C} zkQX)>6=lyttzdsqQMN2Z0{^0->{y5dp@)i;kZ2MZ9s*w3>Lu-XBI`g^s0~`SlnoF_ zXxb@25>b#IDODMWg!D+MwMQh>AteooNND1?o+GEUHG z(=a*9u%@71sA2 zZpV{a7tVqWi3N&npG}j6=Y>AYRAIXN7B@J%@4W&1&X@Co8;IDy(5xXX3!&AU9 zUvR$5#sQ8t`z8ryYf6y;@Q>dVv8J4^A{y2yrP>tHuuf@+3}{%VG)M+CtOKp3!l-wF z*wBurZ(Xzuuf^93}{%VH0%X5tWz5J0vgsS4SkV3zBP$jG^-mi%u_cX zi{Q{yySDMY+SZiwW)NF~RZ2ro(6CBr;0$P31q7XGmK$-*mzy6l z;jGrZ25A#6m!|T8)Crpum4@^Q-%qB}kV3&BQ)x(}aAh@(hSv-!W6)&Zgkg?- z3tnawV;rH)yrBtFDf1~tzH0FDq*P3RCE!&-DVShtT&*du_W}v83QBbYknpM?#SNN8 zM$Ga=<|9#zkF<-7R~e;F9k{@&j8aAcRh-zoDd(v;XrL9;K|vsCBUCYv@QNT+!kXm; zPTAt(X50-6S72%p7pl)N6O^}W5eX}wl9)s^+>Ua%jA)p93bsWwyq+oG7SZr})_TN> zp5jT3+wsKKfy+=Ycs*0#GSD#llvo5vn0rbr0wl~lB^Ch^9*Yu-013Metto4Gh<}`p z+wnx!kp+V$*b`Bb)SIZDyIi@Wv ziNrll6IciOf{`$Pl$uo_;aR5yRY1biM2V?@gr|uTQUM7s1WH5&B)kx`22}76@X8Zd zup8^ZT};&te4j`->ws|Z_C(3Ts!L=^}MWB979{~ECLNHh616`=vXrp425Xe%Tp>u5e>U}3hDtGwmGfm<){NN zB%a)S2Zp_)cCiWEq#!KB23}>9=mOCYkL2|Lo~s8MQmL4dJcf2y+myf>NLbkH1I#O=7s#*SaR)OZb2VrS?LtC|uz0|{%I5;+42E1D8G0}1Py5;sc-gk?UDsaaya znuUcmERFsXAAQ(_xnf+$P4-f`AdNr|R$eppG_zHt4Jk`hVd+^|yXDJw9-^IoVC zPq8`>7b%{BPrjhkDAy{1gbkLGbO#ci0!lqH6s4dgKnjg`9TLzgrUW2Tg44uWYc_?2 zKDZfAU>(^nXhNi-Xpg`?Qf|Owo#3?JUtpbFd0jVjh?d6h&#-byXleZZ7Au#8mWEjC zyM%;Sw!?y7_}ddUDlL{QB_~2+%25K4@LW*d6_k?04l$)_8A!Mlr6dMO*e)m)%RoZT zN=%@=hNVk*l6Ici0lER*bM-nEbfJFEcqGKSDxuC3kW?!LzbZiz%O4%wl3MFZwNm$G$ zTUgYHC#w#ag##5OB}Bk+g_3eiE+aXc-{0(Jc^x3(iKB!SGRALH0636vD+0hZ$cp*o zh>BWqWyObJT3nTk*##(tDL^7T2=xjita1wemNCAM0-k_`JER;+010=fwIqb_$`Kef z;|Z+ez!65mCP~3gK*C;(f}Mbby%+^M0SRv_6zn8pJUS)ZkTJebYqpl~$`Kef;|Z)I zrv)S7S*IjqfrMwB5>Ch%FH4CSfJ8bJW=ViVIuv>dAmMo@7+#Y_V_rD|qh>sTb>J%) z39FG35daCPQ9?OxkP+W3p`0klh?kX6lKe8_#UvCghe#+8m1w=UfiTOF7`NkztOH@8 zvCu{!q2y~34e3ilNn8RAlPGu-NJy0u3f=?~Ql*4)IR=o>+)K!7S(>y=xaA4WKV!rG zSDWV|uPI0<&=$BrOHx9q>IV`Ef+UnnIDmwLAPMCT4!jtYlmmIZ6zE_1Raam@w_tN@ zVTEu5Zz)=2#mkEJDzltyJQ7NJ8AwF!!UP_Wux=^%6i8UN6nqLKtXopCtwFZ}tbtqc ztXT)Rf+l#CQh>0WY?%@Y+65Apmy*Z^5|)<&Pl1HxrNC1;*%~F}EJKsLm{*Q=Q8S*v zI=~f-L|7NPO&}50g_|&t2tTH*u@@f{Xw#uHcv z%#suQAfe>NfrMG7)F}Z8vrZ{f0upAOlH&#vRwE_H4J2&sT3=^^hhX#MXc#r)39JKV z$r=1W$%_Mt2uxYt478vCX*r3wB$U!0Ic%V4r=kF9AmOpJ0%^i4M_|;9C$J8f1tVcy zQGhg%u&yXT8c0}I6d(;GtSbtT#&fHrs2@WCtX8du446xfpu%_%v#P~WDVR-sTb)YK+aa2;u%?S$PjieOZ z3?w3z5QhMXNF~G}KtdXpQr>g~64o$@STw9%!YfB$;rm;-rc#?plhYC@CH?^>(B3Ph z6mBSpkCjrYGY|G(44*v@D{bpo{+1Pc@=JPXWgqW#fii!SQyeP2120g>g~} zwuB+@{8Qo{AmQnv#63VFMock%vYSaMrBKic&z08b0UqMNPtMAm_|pb4ION?{d{ z@XS-{s(^&&iSp6_b^}UEtul53N(xxPEzX$e<*4)nsL8uVR18_usU!SYJxXSO0pTz@JvupC!*o0pk$&E4X;xQ zBt({DVkmURrB;5~;D#sCTLIh3;q74c~@N<}=7&l6p)mA61F8uFaRX1d=5=dBJA-cqlPAn{M zz+O(QwYmZ31IA;CDopU;EmX6h*k6i;5Q}`YRVoA(K!72o!YV`{fPhkA`j32-Rw~@o z5CJw+DcQ;C>lO3I77(}Ltyb;03WmWP3vy9Fz#I#pF%V!~QFcurfN4pECBZ-dzb+MS zaXY9C!4MG8YzfnIf_Sg0!?fT2+8 z9e@CaA|caDUyASu@W&OA|6V8_QJaWpf`u*uYz}lqskHzC=t?5In*#{Y6{Q3N2%sy8 z@Fhzi0Q(Ycx6#5QJOTM{c9WUYDj=vzB1ERpHK{O%n3n*T!u)>yVh4RuPe^gkToBLaGwhg8%`kN(f|ufK(-{!oe<6EZh>|cQm~O z_iB_7*yAiiXv33GdoBq^LAnw`Xdob639Co2cM}VPPh3187Dk@<6*#dl?8ILK5NnG$ z32z+nc%QW(i(Z@lV9v$Dtr!D;i4e8n2!&E#fWs4s5U=4=Dv2-^h>xfw+VX(-dj~Ah z1gBHPZD|$_pG`@G89-ceNGT@3-(CB^#?EcWvg1h4_x%)oGZ@k~)pgn@LnfdRN3fxh zN04YkfHW5^v8ZXA(2k4u5?tFABrm-ZsmuPAol0+LrD;O^Z218h_hSy zp*HqvD_{}) %lmxNEyp7s>-;!*L_TIKZ+n@JV+uQiOcSdrjaNI9B z$NOSs8QNxcn%v9!OXscJJ1MR|Nw<^u(cfabch*N+$@k6`Xgl-X`x+ePd@(ef-&N=; z!JIEUb*RDO??i?90p@&gnkYZOoDWuA_yOj8aP}xaz?=_OUHAd!e0WK9p~#jwyUuos ztx7!4oYa6hccR;E#ot?zZWI3AdUR*z+*^(Aw48hUZ96CDe$jjPnR6N1#GJ~cEbGN#e`NG_@Nl*r6(Ht`wG+Kx=JkF%YiUz6cbtj z;fG>EDwnMFHFY4>FvtwwR*`?_0>Mu>MC}>T%pYnOIBHZuz z?4)J1d+fo%-S$}RM8Ls|YhQW~sPAx3bL%R>oG<%ds8Kt>PqXnuajn%2ekiVW^pPKm zYkf}gLvgJSN`9#2d&!GNk*(Qqfio7p9uel6wvxwA*8NTd(p_f`KpVs_PYvo8RKh#=To#TgED+g%XL%I{0?|h4g zMG@cMfy?MN6Abs#V$MCk13Pi!!AgB+Z9F(vxKk`1tciDi#e>s&JGtU1K>x$rKR*p87{y8Vr4k$Sewc_0Qk!T*1Qw)r&qyI!klHpQLf#0oxgEB_0x+62 zZa7nRsZOWMNZC$XqV^%VJJQ-gy(U1FI_;w^GNDh5J-3)fsIBO`|Z%n761~Shx}a-Msr>q z79J^`E+fSU6hz(gL@W(L!lw@lEeON7jL^w~K*GyV!WIM)@{-#cJ6|AZ$irzRp}8@> zKn&>i)@SzeBON~#i_z}o{VtWD;w=}&=1w3Z@8PTwyDr6W?}lE#0ML;)CFbFl>*e-t z!v*DZxxHH?rHEUurDeDji{b7ayi32eqEAl61!8cw_ajwrfr^-`RXF-6Vm_H5OQ|B} z!wBy!P*G#&$XR}*?{&cGxoPcfmv0}6n1>DR7~J|8!P?xRhUkONA;Q4-o&2{u+(QxbIF7KTlOpD6ICvMRh%Y1Gm^V;-Kl#$7BQbb60$%=%=N1RYY&We%c_j^ zZe&t+B}RI;>;VmwK9_N7n0v?9$HzZ?diVYN|IjMwaipS7C<8tYIX}S+`Zx}}35E-f z!~ZkEaKdqTen3{}p4*y8&84MUn{lw!Lx3X+kowaaQajzf5YYb}PVF~PMX*Kd$)I<0N_ zB=D#5wYi?YqA}sM!!9;frV@;6o>eL%y#_B#tM=>qrHQ#6#(y5E9@owo{dt(9SCp|o z?f5Io$WOzQd`0Q*xWsqny>tD&OqXdosRcCaJU<)Q=rk1CYnyPV@H6|McY7}fi8VKmpNU`uRIvgYe&r&1QiY3S6~E^E_{c+(YaQm?W8 zE83*)yr6j)wbO>xeJu-#PA_m-jb@rko^ibwpPx!odes@8x~!PhahUm6w6@c@dvQgZ z(reDb6)h4COZtiyH`>N{`n>{)*QpS7i&fdPdY>v+EbcT+@hjSt)&z^v<4nGmElLlY z{fZWe#xo#KXvM`&i-En%U^SZSR1^_wxEt+{kh6 zV=8-o^QX$E;^~n&bVZBOBS+aaN%-RvE{w#8_!TZPgwl|2jmS{a(2hokL^ z7NZYW@e^9$Fm113k$-qLu4t1#*ZRUp&x?a%cTvs^<~kEf$4p*4>n}zA@yNz?Advq! zJknRR$)7xPDe~)7xfJ&x$``vmXW9zojhw~b zv-Vu+VIy!fAchi(TV+Eos?P2@RR3e}nFP6bT%Q?wU(Q#as-8NR_e6syFb)YI&qt^A< z`~qEWpAMPpFJv^7vqCjG*J7FaW`ft6OOEqr)5xmMc9wlWYo)GjELjXgO`LHizccsF z^5212{a1Jf^!UpCHTe&mZE#i4WHKk9Q0BPLD)RH=Pt% z#-4m!v#IG~$j9}*5#Jjh@?t%nK=wHEX&BY# zDxcytpa3SB}Bz?rm%at9-X+8X*)+O~l2eGCDFv-E3LvI{Ip(F72SithufS+1*fI z?uPnuH`JHqyKSgbcSGU0TNI9Gmcw8EW6O|m7lSC)OG*s=o{Rnu_p*DMtVJI?pLy@@~ip;oW%$EoTTRNmNjlnN$ zmxUKY*prt-lert3%-zsr?$&q%+jK0>OV>)iXwz}#hJL~^hEN1eDhxg5Zs;+0LysBx zaSUO|%0=&Zh8z4mVn0?EW7rdwLyNf^TFl+hVn#+DLTYfNbL*y+@GD^b5YKiD-FVVr z=rHTWKp1i8FylTK$l%CD<#>h;e&nW~n20fyD9kYo1!mmJLL!e@ucDp4W41T#LPX@fxh|GVk0l?4^tmjN7fWz8>D=_A1CK zBiGxhr0OhrgZm3Xhj<(&8r1EcScM(=I4+;k_?YleS;l2j4zhJ!){C6`1IX(%^$D=( zzb2Ff7`n>1@=0&&qKuchK~_#&Z&~j5zvQHM`VnVE^t>Yx$IVQ>e6k+YO4|ZC+o6vvS!A5TOLkWOG3Y-Oi1q#IdA3VWldqV>C{K1r@ZAp` zS;hSQaCY1e zW#N8N7Uo%Bdn?88>Aw_0YJrjzA1;&op>m9DM+UL#gd?RHq}O1#?{oPRCJ&dLzio$Q z_e0qjS4q+M#%8jzF*U!ae)|rz7L)2|Ea%WM#?4Q99P=DH#`;$DJkM~TJsE~Oev1~) z+5J#27KcLd^H49wMMaP?#23|za+RdtV#hG-lR={xqGM1Vdso){bI$++E!DK$8HxI@+pi?IKqQOy0$TkJZ9Fd&v2t4Yhnr7|~mZQ$8SEca5? z)VdFLuEx#-+$GC$p>?$Q)#JxcABm+cPMB9;e);P0{WtX^&}yc+j>1=O{`p7T_3sy`1=XuJ|NZU1)qk(|XO}9!`u>~8H~-_~<0$^- zf4+PC_s0*v{_yzifOg5zI*#uCi3;WPv1Sh{`BF;$1lHp^G|Qz z|M|1W_n*J{)#InP-!PEM80{mT?tgfE|FcdqCSKUPb32n-;W6WG^s_&3g`EF?`oqo5 z%^z+a`2ROIzpsD(z5aPu|9n&be5!x`wf-5U{>%IyxAh-~`lnm?q5kSB|7kAO^&boA zhW}iDHP%J{e;WRms?x1@3xBHr?8-mZUmxn9ZvSKb^``#$uKxMH{^{=eubvgwZ+`ya@$IMYKWx_LpPt6jqw31Pn+I}Tvu=H}Ts?=T*S|eA(>-_5G0406jfvgd zT>ok^_5$}m*Z=JG9yR|@Rq6sw-DapwfgbZ;t5j3|x=j67kD~v%Qmz+lwBO^u4*0tK zP1kE{qx`qkQ!h$a8gO@U<--C0tV%c2^gms%iPimF*T4U>f8DI@GoAhXX$(#Co_90q zOB4N7Rl2TLkM&BEo@mdgNjb*f<$FlITL;{ggXUei|LL}R=%f5y^&QLKtln5JXaDDQ zyN{Z^{JrSC{9V5P=}tze|61+uji(9HMgLMo`aegd*f{^Y3iK+C0?$x?ce{N4=GPy- z|K`U(J%0G?SMPrL_2cip_~Dyx`9H78rTEFs>(6)>jpyHPKmYvIvIV)X@zvW;kFP)b z>ObR`zrEqg6<6{2zyI;({_k&Y{+@CO^S@Q(>kn^#_~G%J*KdCD_PdXdoB?0|5HQkkQ@ z&Pty!{=`oqn%=iRXD&y3N#`10UrC$G(Oz4Rf%W@+Ge&!-;HzrykaVHFenxYy3)U&2 zGj@06fJIB1uxjt2+@cf4pS;(y<*UNZLHirroE-w1>Q;OAxsR%DSx!^AYVT5Z%Z#yV zr}86AShp8r=4Ym{UAMwIhhnPBsvSC2a>A;;j-5?d*Uh~}du@gz@JA4$Srrce#Jzpni*Us$1=KdijJ^ zd+mu1tlz+yG1@zX%&zthWpU5tXs;jB2<%vP(~Keh&LKCdy?!QiE=PNvJ|CFY2yt~& zv4*K!w^x4U3FA-1n%3iRsmRD&j^|xD%{ExI*WTH=+|3QgoBH6W*zQ$ki$8gbReN}% zH+|6bv2&uLkA5+7#;U#OquS$gu-a>%=UkUQvVu4LUAtMpp1=8P}* zLbq3M^lsZb)1t8cQ2ku)!0{HeulDfYy6#SU{Vdkp9+xgTF*kLqy_<><&E;-x&_P0W zg7u}@xg710gS4qjdxuNKJLYm#w^F|XJB2L9R7YHG$5&W?*JrLvseW`huu}yfW{iHB z$QGln^fjeR>?!*0}>OfUwP*^KW7>^60Dl8pOVgSowOH|H4u)}NY> za%|1$19xwpGxXbU)68}0_Yixg=60!I;arZo{rXvAsdo}myREd3xm?l3W4WBt&cmJ| zEoNJ{Y@7-#&Fw)0!l;QII0OQNdZ}~OSaLnU`lW@rkHT`VVqwePFRQzfTIRZ79Rmvt zri^kAM1_M^)W!J_WbCC!2D|8=b!hhp!Z&@Onx(x}G|0ULh8nk>8>t{2MV;Hj);;Gr%_L-#FczJS)IDau zg;iqE)JMs`ejIngZc5`%`x3kM5^|SvFm{8=N!DT8-=u6Wdp~6k?RECZwqN

Qds(_ku7#3{~vwyi$U9RsHe#4n&&2e6XQFl zJqU*5TXea2Es=_`f8pmFuciIZlE^#g9YDn zo+HCNkF>=rTG8+MP2$z@Vmy|>0 zGf#Vq(DkwI@@)G(-=&P8ZfDmU46HvC9(DW6R*9vIpl&}h73Gd8BPb^y z6xiAG;7QluE6QCmPFz^{X;_a7R83l4ZY!sJJHAU_E)7g}JnhNfSzemlGhosW3QL_8 ztfKun7RAab$HAp?r^-Z+G51SLft@2RS#-Ii&R49 z9~{FO1A>P*LgNeoJEksBSo(9oPF@cJYg%7APPxXnvL)BRGB!a}7axMw63Hg4-#yr_ z8|SpWjXx|VB@K>HU=`xo^^`w7_SPkBW+K>LzoQ2P>0`x2{1`x325`x2}!j85|?yP_X;oiJ#H13F~{YMtlH zCmwPi5r<7bKkfC4%yS<^^9Xcq#)2()t9&@>_GftKx?ufkz>FQZrJs8h2d(s7B2V(^ zgW+)3SQJNOe3=t-Q*qPOSqY3OMvrBBO1kj!sA5H6(lNpMBOCL4!IYB#)^9>aIoWS0 zm}rXI`GWN`;M=iM%D;hI(U*$OusF? z88gwrv{!Ms-K4DxrdSpj!f87eFt&&=A`HU%!OP89NaajBh2XDpXTW6tf?+0RAH-ea zoS~dzxL~F|KHs#7VW1uU!#oN)Q?5S?vz;3*_>g~;>jzq++$H7sks~Gf08Bm}u)b8Z zZO{1|lslSF*@Ie3!Y*1%(s(pq)G*hTKL;jIybO%2om@9$MDRG_tsCO-I)T`vHibv&`&p63cj=bE!5U|QeDlGL44tTsW zTbhCq{S+oyLOJ=(SU2f8m6cn!-8TEE99?-%laHSM2C4wwnD#V%#2H_@ z@+s{F)=lwMHYJO`T_dVuP$$M25NmmYtAvq9o3f77Y5B*=rY7hgeSoD*1d{KXt>y7y z|E7FF!pe>!rK7)pH}fPI3$h&xr*Hbv(E~6CW6VfwBBxQeK5UfbNJ2|n?aVuRX%8|n z((|%C?qrTO^NDj@_Vg%E6%ADSgObc%`#0drSS^-e&9$O<6H|F!?sYP>t0GB2}2; z*f0=Lj4X$6(tI&?b8j7xVY$ACyOU{!L8JLrc3JjI{9I#3G^H#-OVnN^OI7wDSsocn z;35wm#q75f7-7mo;b!E$&VACVq^ne_nrKCsDf=ZEJL9V`v+fbl?=jYrL?Kc-a?E%g zWq)u>Bz<@o8kg|bq12s;I0g+!!N@ZYNhkjrU7RyFnZP26pwS*GgY-!d*-_<6%evem zNWQ}IQ#=$*`BH@?|Dj*?;})~bDP1}DCEAd347trDzfWOlcSFAZ_SB{iBv{HJB)fbl ze1A*&F4r8CE6!Dlew}X92Oq&mI-~00VcV_;s$PFtX;T-MN6G_q!rSDvx?-1S0M|78 z8;hIvxVo8q1xLahF&6a1JXcHq^FG4=BAJ5*D7k^gmgfQ)$I=hTl96BKK&(9X)`6oe z#>}lE#k)xulYRxJm^E0xc{9@rOnGTwN7+4Os%1Qda%AmnX^MiB_d3dW>sRD9{oc{RR0fxdtY`3hr#3p+wN6 z--AhS;yzQ_t6VDL&x+qvt7lEJeDU@1LuV-%dWreqb*C=OM43@q$ z%5ghQ?I~tRxxCMLQ?5g=Ibr+U`@Dl8{gk&hB(K2Ie?TAosNZ(JnCzkz0lnl?4#GUU zX;1k`rPk?eQlFwk0&)lAtdKb;Fk%bqRFn9yl1U z7;I$(7h9B{gR{=Dr-~`X+$blX8<_M?FulW4Ske?s`=hY5_iJ}#{1S{;C30@0R>Znd zj-aN>$^NCBa%;gz090KjA}sxc+zG)Iw52^5TX4IUV8nH^T=`nETqVS9$3k5iR9&`K z@E`L~e5SBykB89+m3wZS0-7(oD>0lX+p*9dez@(J3q#3NUBxR-luR23j0~8li*29# z7s;u-CF=G!h-dqQas+|0J-$zsW9B%|a|@p;O=Vp~$#&gPRF+44r+!&C0)N|m4yOAv z$SNGc+wp-N?RTV)JX7emzt}SMTVqlDx3JW+!8m|5Hv)RXPHA^jS24)KcKWak;}MtC zX-@U9i^jso7Bm+85nEa@U+y_*ExEyJ@v*Oxm}xd(4CSVcb!LeY<{FZ%h;6#Xhk9Sj$K@&0_*LZC!ziBhe#yyW|4tS@d5?aR8Xs(y9njJndj!8njqmz^n0cjBn4`@dj% zKMV}TMD58hN;xhNM!6DAxgKER4YCi?_r>LIy~_!PBUpX(2S7Ib$6FCP8}TrTH%Lbk zZ-9w6N}MK5x!oafpb4_v?#9%OmReFXu7)&CVxp`I%js? zg`k|?0x8UENpL55l6+ z+b%5ib}-!BITm;*d6LYn(3{X0;Gx_fbqy`|2VT9jE2yg++`_~|^)`n3Kxt4Pb+G0< z>X0&~vzEx6&RS0M^q=CEKS&2g(xuOca`_G}v_gIMSh(@0@o}k3n0zQGow_HCt6p(- zEYlrY`MyS3u<4U2EOQ*dN;ZS;3^+ za;qq8h|+-jv!WZhi{;|I#U9ieAx=dD{3W6RDGAzJxYj+7oxR1AcH(;iT;h8|7~(Zl zO!3-LcTq^eK8XpP~|!&O^Lcl=O_PJIzO29>I1Rz+Dll@DCG-J4wgYko3z|v1hIr+j1Q?3iIex&b}kfw513rim|SbqzBBb)Go$i@bf zEP?-YhT@5oo`W@$v03`HUd##LHR2*}$^#S~@i=*D<{`avOuiFASM8Y{dk}Y+c?cJ> zc!*2|@iSqolyy7^AU_RRks0429K{3k$s715#m^P^Q#twhX-~P`g{2=DOnEY3q;jhd z66ZD;eh?JnEltbMmG_1fpytNaInkNR(xP)+Jl>3t_uV)avOUxY z?HN>+oj%BNPGs zgL}&DE-dpw!1^m%TN+>^ny>WcD0Oj6FAYKkn;eOj$Y4u=lWu@%f|zz^OAf=$wV;8uzDNUW6?WQ2zFLI)&tW; zJ|40s<>SHqA|3+M`9ao~{7r-sbbf%v`GFBnSSaNmX*@9&=()2mdCAPQf+;m$ax{~7 zNf;Fm;k}n#L5NxB7MSdcitVKQV&MkF%2 zUk(BFp`5I`VzSe(W7fQqAURZT%jNjU4b{1idFg%b_c3{dML9r)$!AolGdVXd=gQXy zCSM;O9{G{D#4BH4UF=Ps#4ROXA4?=16HGcL8k}@YFzJ|hP;`Fqj-2)&n9dJ0ANc^l zBqLxU$%uLiGx-YBUNQp9PiFRGkBjS#*)QQ=oeNkRI(sUwS@S3`$3nb2`@kDvKES`BeN>kuvOQwfDPwul&V3NG z7X9#1s1IV+?!&nYylH1%BWCTfI8O%epLuO3K3z|)Xus{mr-?R7FX1f^@d2cgUIHe) zgzUc^KCnLr?}lU;dC1aLz{D?D_OchqLzb=rCS3(G%jdytl_P>FDY;A5h|X0~0wp`S z@~zw>Zcr))4yG75X$l^TbNo^6?a$!}V#V6Pt@S3*+eRBm#fzhKglh>FYJBGXj*5SZdPP+mS6TnduAVDigXdS}WeFv(qJ zCb`S44#{0G*;_>NWpA;~Wp9DWFAwj=9xU5gbSV#ao`YyyWOHuUh{%)dGU{4}F_QEZ zP>%3>wnrEu_<(Zy9!p`V%VSh1XAz9od$SKrgOGoe)4iv{QU?apJN{s@CBbA%7MABU zm~6?yl3&1NpM%LhFD&_mHIm&}SjuNG`AZ5*SqGNyW7hjL%B@AYS1vY*#Ja~vUBw*W zHRU^k@xocIC8Uq@mvVYTys)${!MMSy_P9PG3>UsIE@T@sPvXc7c|fE{@9Pz2p2SJ3 zv0!d#ECg9J7E}T4Ra7pIMe!rXqWDo^DeJ)WJ&eNA{|u)4TVT2;Tv*y_V1B2Fl(Dqc zxY(li3cz$frLeSdz?8=WraYd)(#8Q(tQ<`5S{0Ty4j6|@@(`h3t#5s>SLGBxr#;2b z!4yAdUn+iHSn8c1il3K-ow@)~PQ_;^Cmn?LQZ=-*!@WZC@s3MN}>yn70nligm@SGH*7@uRX$gFw06d~Ll^8?k7b80q-nWd zE^g<1>vE|v(WO#sa&DC-lXdwTOZtMKp8V7dSnqa&>D`aQ(p~`5cW=N5QK_J^8Rx@z`_Sweg*<&F%MM7jO*f-SB@)V#u1WramlDXTzDEENu;^H^*l||xt=CX zI)h2)$2+9+tv)N5vINX@=GLgkqMTVm4%YbzLzvFoW6`?tjW5v!lUQ_N$SD)KfttBd zTtrbG57^F{lZ58>EIT=l&{DK+kc~}P~s*%2M#;km5upM5jWSr!+N_G)O zE~7Bz@emeL9uJuEcnXuRg-;x29uMV|$3wV>7jttg{uUi|6>lWWq&Hx}l*Bp-nIv2onF7T-eoeT92c*+Pc`P_ISD&ucFR={Qr`k|JH4@yPjH-{!nJ&uXu27)#A>JgH-d?Iyt_PT8XWb7_zohylUvWP` zva?c1Q+9$$wiBw%Tv+CzT-d@g*AxtP%QZqBN;!_Wm%oJj0g|0yl2=4NB|F($lAWZa zN={bjGtU5?&GY(_3no70qM`T-->TLQ zbHJqMaFm&ccJyb|XY)|KxSnfX5w66r*+qNI6wwcxT{OT?Egtf_e)SbL^AIfQv2Y1h z2u5kw;W3Kd}yfiQt zF8k%6R=<9qnrGz9YurH)uYsA@>avmg)i=57i;0rEbq68$44BSUvR@>N>kfkWo;wI0 z3u>3fM<#_Z-Q_0REbnr|lZ0n-57r$7jm7Wz))$`@FXNP!4Z+tO%)8EY;Zx$ubpcbZ z3z%|U3X{%HxJ)`fD!O!jFzI!q3uNq_KJ-2VnDSr1^gcsj()GxYldeZTzxWSKIvi$& z&R=r(#eZPpKhn{~e`KJE|G>n5gcikrVB$Y={H51n_UKFo%e)(&Pt-f$@S5HgFHA99 z!kp@tCrw0WG-c^mgs7yOVLZ#1fuSe;3QRsXcBjy?;iR7r&5tndckPLG69Gbf<3W-o%5stK~lQ?ZSHfUgr@j8Tmuqp8TxE zl-sk6a=5v~&-K{uhELHUuFsw$hmei-%1xbo zP|pPBJixSPIBIoPppJ(RzUHCtJCg*EZ=+Q??>An83mv`I1F4wvAo!%Y5dcv+LJpcQ z&ci6jbE@)Rft{0|`5>!&(qQtHB20M+ayw>{ZuD)+O6AP;07Hw5y7hEmjv3uHVntk1 z!il`)H8APB*gghy06v!P4JUFTrtvYcn@64w`5W zyFmg7&!K@*BgH!}XBmAVHiJye&m~Pw-1^ z)#Pz7Hd4%ube}kDX^#+n&Vy$wLJq+!dY1%@l=AEY#`hV;L7ij9&l-LoWGrr^91Cx9 zXl{I7JbYTzMfcgtAuvpKwa1pu_2qVo=F4*mxzBkl1A!GZB?J_HR`v!#^;}DQ3X#82 zZ#JYJ2Bvph!O(~DJV#uGPD44aGbIfO*|=Y1Vzx&Y;=dz4@woniM-mqR)91F(!eRXH5mIge6q zg`uzsOaB4w;poqG!xj(UCgli?r5xfo*Iq#SrLIEVjM>m0jwy{9caFvkNsW2$<1!EZ zls>qFpt-?9>bJi9m9&DfQs$IB<8pb2l76u(#4p^*%>7G*)U-$6P`~Ktxd+SE$UeAH z6FxlNQb6qHe9QjGdDQ1(a<5i8P4e1>7@zvBM{0w997ozSd}>DeMy2B98Xt?9+9SM`w8w~u7!b5V#Z+BhcFy%6gH$>L*01M_vp#tjk9pXu^o#phG%crF z(iB&V+9RJv>wDZ;U*6-^`m#T?ZtM@yN^jLM=F0BQ@gc-CW{wn%nf;+Y>LVW69{WRm zus_ruS73q$hq|H|eSk^6faN=P_|@eD1>=f#@Bvu9yHMrwK3HM-9WgM%LK+_lt+CH5 z8j$M&mT~85FJs_fiaiyUZ)+Bo_xB59w{F*i0J!uVFgB9P<$GGRha}P(5yMa)^@vrr zr@SEALs3+}@~=^jJ1{OM{ho69eFN$e?$LVSUsHS7Y9TkMo4!ceLxItJQ3is?DVJ|~ zS6wz-(goqJx;(2E`v}P-dml`89?C)9>*ax3Vi-AJJO!FBZvODSR^5Dq7!1`X$4m-K zo~xA0cgm}7z7GP%y*7=H#9{S;Zsv0Gck&=_`rGM4-!(4`1t!)5Z$_Rom|OXN7x+9W&j8AK&9Uv%h9F5H->{+&LLwR;PedjE;r;VGxZ0=jam_XN zKA$Vn-p72?-mmxhbI;Tp`x;*bKyp3U(&`tn5$6YwcS7l`ORQ4si)rd|I&0CCGe*D) zVdG@ox;Bwx#>|UYR@Jp^=T%OfZ#;jR_DrQ)xIHeEq+H_;hva14xky^oXDKufoHA|? z0TVRE`;uojUw6Tqt8$rN2MzEjYAoaxXe@YsL{mH$xt8SaN6r|1VE3eq;AvOaCDB9e zVRq-a#Vt+AgL)QLbV0>bdpI*RH&R`4FCf-3c0x)_-mhhDTys^w#FRvf`PRdP-f~ zjy`a|h{x-CkIUt~tZFa6BL=3t&BF4{slw!E0LwRKs$9M&17<%p7~b5R8=E!xxvn22 zoynlroVa*dd-=z^qFzieOi%M)*+Gxy_-;Zan- ziqX?UzLCuO*29fimrwMGuZYEn2Iw2ED}O9~@Y0?7kiVF6`A!1k(|c)!S>NSJC!LLO zpZSz+uKmIH^EBUj87#-lM}f7zq-hBwoqwXsrw?!6efRj`)lYx=`ps|O{olveb+_)- zo8Nr@{ipg9%Dn!~t2h7c{kPxOf5OcDpI^QH{ZBCjk3YLR{KL;GT=@^bxV`-2&yThx9Jb@@4=wJ%@)?IQp3`pYk0ef;$H!>7M|c>MMi)WbSIzWTer`^SI&#jF1ZMuYaL literal 0 HcmV?d00001 diff --git a/wp/wp.tex b/wp/wp.tex index 481091cd70..13a7e7492e 100644 --- a/wp/wp.tex +++ b/wp/wp.tex @@ -1,15 +1,14 @@ \documentclass[acmlarge, screen, nonacm]{acmart} \usepackage[utf8]{inputenc} +\usepackage{CJKutf8} \usepackage{graphicx} \usepackage{pgf} \usepackage{multicol} \usepackage{setspace} -\usepackage{charter} \usepackage{listings} \usepackage{hyperref} \usepackage{float} \usepackage{placeins} -\usepackage{graphicx} \graphicspath{ {./images/} } \usepackage{tikz} \usepackage{verbatim} @@ -29,6 +28,32 @@ \definecolor{ForestGreen}{rgb}{0.1334,0.545,0.1334} \definecolor{NavyBlue}{rgb}{0,0.502,0} \definecolor{BurntOrange}{rgb}{0.8,0.3334,0.1334} +\definecolor{selectColor}{rgb}{0.686,1,0.592} + +\newcommand\YAMLcolonstyle{\color{black}\mdseries} +\newcommand\YAMLkeystyle{\color{BurntOrange}\bfseries} +\newcommand\YAMLvaluestyle{\color{black}\mdseries} + +\lstdefinelanguage{yaml} +{ + keywords={true,false,null,y,n}, + keywordstyle=\color{darkgray}\bfseries, + basicstyle=\YAMLkeystyle, + sensitive=false, + comment=[l]{\#}, + morecomment=[s]{/*}{*/}, + commentstyle=\color{ForestGreen}\ttfamily, + stringstyle=\YAMLvaluestyle\ttfamily, + moredelim=[l][\color{orange}]{\&}, + moredelim=[l][\color{magenta}]{*}, + moredelim=**[il][\YAMLcolonstyle{:}\YAMLvaluestyle]{:}, + morestring=[b]', + morestring=[b]", + literate = {---}{{\ProcessThreeDashes}}3 + {>}{{\textcolor{red}\textgreater}}1 + {|}{{\textcolor{red}\textbar}}1 + {\ -\ }{{\mdseries\ -\ }}3, +} \lstdefinestyle{mystyle}{ backgroundcolor=\color{backcolour}, @@ -55,12 +80,12 @@ emph={delegate, filter, first, firstOrNull, forEach, lazy, map, mapNotNull, println, return@}, emphstyle={\color{OrangeRed}}, identifierstyle=\color{black}, - keywords={abstract, actual, as, as?, break, by, class, companion, continue, data, do, dynamic, else, enum, expect, false, final, for, fun, get, if, import, in, interface, internal, is, null, object, override, package, private, public, return, set, super, suspend, this, throw, true, try, typealias, val, var, vararg, when, where, while}, + keywords={abstract, actual, as, as?, break, by, class, companion, continue, data, do, dynamic, else, enum, expect, false, final, for, fun, get, if, import, in, interface, internal, is, object, override, package, private, public, return, set, super, suspend, throw, true, try, typealias, val, var, vararg, when, where, while}, keywordstyle={\color{NavyBlue}\bfseries}, morecomment=[s]{/*}{*/}, morestring=[b]", morestring=[s]{"""*}{*"""}, - ndkeywords={@Deprecated, @JvmField, @JvmName, @JvmOverloads, @JvmStatic, @JvmSynthetic, Array, Byte, Double, Float, Int, Integer, Iterable, Long, Runnable, Short, String}, + ndkeywords={@Deprecated, @JvmField, @JvmName, @JvmOverloads, @JvmStatic, @JvmSynthetic, Array, Byte, Double, Float, this, null, Int, Integer, Iterable, Long, Runnable, Short, String, Boolean}, ndkeywordstyle={\color{BurntOrange}\bfseries}, sensitive=true, stringstyle={\color{ForestGreen}\ttfamily}, @@ -68,6 +93,7 @@ \lstset{style=mystyle} \settopmatter{printacmref=false} +\settopmatter{printfolios=true} \setcopyright{none} \makeatletter \let\@authorsaddresses\@empty @@ -81,9 +107,10 @@ \pagestyle{plain} \begin{document} +\begin{CJK*}{UTF8}{gbsn} \title[]{ - \includegraphics[width = 230pt, height = 200pt]{wp/pictures/logo.png}\\ + \includegraphics[width = 150pt, height = 150]{pictures/logo.png}\\ DiKTat - Kotlin linter } @@ -136,11 +163,11 @@ \section{Comparative analysis} \label{sec:compare} \input{sections/compare} -\section{How does it work} +\section{How does diktat work} \label{sec:work} \input{sections/work} -\section{Killer-Feature} +\section{Killer-Features} \label{sec:feature} \input{sections/feature} @@ -148,10 +175,6 @@ \section{How to use diKTat} \label{sec:download} \input{sections/download} -\section{Examples} -\label{sec:examples} -\input{sections/examples} - \section{Conclusion \& Future Work} \label{sec:conclusion} \input{sections/conclusion} @@ -166,4 +189,5 @@ \section{Appendix} \label{sec:appendix} \input{sections/appendix} +\end{CJK*} \end{document} From 0b7cf0a23a15a4d9c21124ddb6798b42ff4f36db Mon Sep 17 00:00:00 2001 From: Denis Kumar Date: Fri, 15 Jan 2021 14:35:38 +0300 Subject: [PATCH 08/11] New rule for complex expression (#680) * New rule for complex expression ### What's done: Created new rule, added tests and documentation --- diktat-analysis.yml | 3 + .../src/main/kotlin/generated/WarningNames.kt | 2 + .../cqfn/diktat/ruleset/constants/Warnings.kt | 1 + .../ruleset/rules/AnnotationNewLineRule.kt | 7 ++- .../diktat/ruleset/rules/NullableTypeRule.kt | 5 +- .../diktat/ruleset/rules/SmartCastRule.kt | 5 +- .../ruleset/rules/files/NewlinesRule.kt | 58 +++++++++++++------ .../main/resources/diktat-analysis-huawei.yml | 3 + .../src/main/resources/diktat-analysis.yml | 3 + .../chapter3/files/NewlinesRuleWarnTest.kt | 53 +++++++++++++++++ info/available-rules.md | 1 + info/guide/guide-chapter-3.md | 16 +++++ 12 files changed, 136 insertions(+), 21 deletions(-) diff --git a/diktat-analysis.yml b/diktat-analysis.yml index 9ffbf8021f..0bfeaabaae 100644 --- a/diktat-analysis.yml +++ b/diktat-analysis.yml @@ -224,6 +224,9 @@ maxParametersInOneLine: 2 # 3 by default. # maxCallsInOneLine: 3 +# Inspection that checks if a long dot qualified expression is used in condition or as an argument +- name: COMPLEX_EXPRESSION + enabled: true # Checks that there are not too many consecutive spaces in line - name: TOO_MANY_CONSECUTIVE_SPACES enabled: true diff --git a/diktat-rules/src/main/kotlin/generated/WarningNames.kt b/diktat-rules/src/main/kotlin/generated/WarningNames.kt index 61bc1fad94..277a04125d 100644 --- a/diktat-rules/src/main/kotlin/generated/WarningNames.kt +++ b/diktat-rules/src/main/kotlin/generated/WarningNames.kt @@ -143,6 +143,8 @@ public object WarningNames { public const val WRONG_NEWLINES: String = "WRONG_NEWLINES" + public const val COMPLEX_EXPRESSION: String = "COMPLEX_EXPRESSION" + public const val STRING_CONCATENATION: String = "STRING_CONCATENATION" public const val TOO_MANY_BLANK_LINES: String = "TOO_MANY_BLANK_LINES" diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt index 981b21b565..3fb16abd45 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt @@ -96,6 +96,7 @@ enum class Warnings( LONG_LINE(true, "3.5.1", "this line is longer than allowed"), REDUNDANT_SEMICOLON(true, "3.6.2", "there should be no redundant semicolon at the end of lines"), WRONG_NEWLINES(true, "3.6.2", "incorrect line breaking"), + COMPLEX_EXPRESSION(false, "3.6.3", "complex dot qualified expression should be replaced with variable"), // FixMe: autofixing will be added for this rule STRING_CONCATENATION(false, "3.15.1", "strings should not be concatenated using plus operator - use string templates instead if the statement fits one line"), diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/AnnotationNewLineRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/AnnotationNewLineRule.kt index b337dd9520..eccc3ab41c 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/AnnotationNewLineRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/AnnotationNewLineRule.kt @@ -68,7 +68,12 @@ class AnnotationNewLineRule(private val configRules: List) : Rule(" if (node == node.treeParent.getFirstChildWithType(node.elementType)) { // Current node is ANNOTATION_ENTRY. treeParent(ModifierList) -> treeParent(PRIMARY_CONSTRUCTOR) // Checks if there is a white space before grandparent node - if (node.treeParent.treeParent.treePrev.isWhiteSpace()) { + val hasSpaceBeforeGrandparent = node + .treeParent + .treeParent + .treePrev + .isWhiteSpace() + if (hasSpaceBeforeGrandparent) { (node.treeParent.treeParent.treePrev as LeafPsiElement).replaceWithText("\n") } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/NullableTypeRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/NullableTypeRule.kt index 6565093846..1317fdd8e5 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/NullableTypeRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/NullableTypeRule.kt @@ -80,7 +80,10 @@ class NullableTypeRule(private val configRules: List) : Rule("nulla @Suppress("UnsafeCallOnNullableType") private fun findFixableParam(node: ASTNode): FixedParam? { - val reference = node.findChildByType(TYPE_REFERENCE)!!.findChildByType(NULLABLE_TYPE)!!.findChildByType(USER_TYPE)?.findChildByType(REFERENCE_EXPRESSION) + val reference = node.findChildByType(TYPE_REFERENCE)!! + .findChildByType(NULLABLE_TYPE)!! + .findChildByType(USER_TYPE) + ?.findChildByType(REFERENCE_EXPRESSION) ?: return null return when (reference.text) { "Boolean" -> FixedParam(BOOLEAN_CONSTANT, TRUE_KEYWORD, "true") diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/SmartCastRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/SmartCastRule.kt index ad4a3fd533..60497b7e81 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/SmartCastRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/SmartCastRule.kt @@ -91,13 +91,14 @@ class SmartCastRule(private val configRules: List) : Rule("smart-ca @Suppress("NestedBlockDepth", "TYPE_ALIAS") private fun handleGroups(groups: Map>) { groups.keys.forEach { - if (it.node.treeParent.text.contains(" is ")) { + val parentText = it.node.treeParent.text + if (parentText.contains(" is ")) { groups.getValue(it).forEach { asCall -> if (asCall.node.hasParent(THEN)) { raiseWarning(asCall.node) } } - } else if (it.node.treeParent.text.contains(" !is ")) { + } else if (parentText.contains(" !is ")) { groups.getValue(it).forEach { asCall -> if (asCall.node.hasParent(ELSE)) { raiseWarning(asCall.node) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/files/NewlinesRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/files/NewlinesRule.kt index d08f1f742b..f32760c2ae 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/files/NewlinesRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/files/NewlinesRule.kt @@ -5,6 +5,7 @@ import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.common.config.rules.getRuleConfig import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.ListOfList +import org.cqfn.diktat.ruleset.constants.Warnings.COMPLEX_EXPRESSION import org.cqfn.diktat.ruleset.constants.Warnings.REDUNDANT_SEMICOLON import org.cqfn.diktat.ruleset.constants.Warnings.WRONG_NEWLINES import org.cqfn.diktat.ruleset.utils.* @@ -18,10 +19,10 @@ import com.pinterest.ktlint.core.ast.ElementType.BLOCK_COMMENT import com.pinterest.ktlint.core.ast.ElementType.CALLABLE_REFERENCE_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.CALL_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.CLASS -import com.pinterest.ktlint.core.ast.ElementType.CLASS_BODY import com.pinterest.ktlint.core.ast.ElementType.COLON import com.pinterest.ktlint.core.ast.ElementType.COLONCOLON import com.pinterest.ktlint.core.ast.ElementType.COMMA +import com.pinterest.ktlint.core.ast.ElementType.CONDITION import com.pinterest.ktlint.core.ast.ElementType.DIV import com.pinterest.ktlint.core.ast.ElementType.DIVEQ import com.pinterest.ktlint.core.ast.ElementType.DOT @@ -51,7 +52,6 @@ import com.pinterest.ktlint.core.ast.ElementType.PLUS import com.pinterest.ktlint.core.ast.ElementType.PLUSEQ import com.pinterest.ktlint.core.ast.ElementType.POSTFIX_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.PRIMARY_CONSTRUCTOR -import com.pinterest.ktlint.core.ast.ElementType.RBRACE import com.pinterest.ktlint.core.ast.ElementType.RETURN import com.pinterest.ktlint.core.ast.ElementType.RETURN_KEYWORD import com.pinterest.ktlint.core.ast.ElementType.SAFE_ACCESS @@ -59,11 +59,12 @@ import com.pinterest.ktlint.core.ast.ElementType.SAFE_ACCESS_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.SECONDARY_CONSTRUCTOR import com.pinterest.ktlint.core.ast.ElementType.SEMICOLON import com.pinterest.ktlint.core.ast.ElementType.SUPER_TYPE_LIST +import com.pinterest.ktlint.core.ast.ElementType.VALUE_ARGUMENT import com.pinterest.ktlint.core.ast.ElementType.VALUE_ARGUMENT_LIST import com.pinterest.ktlint.core.ast.ElementType.VALUE_PARAMETER import com.pinterest.ktlint.core.ast.ElementType.VALUE_PARAMETER_LIST +import com.pinterest.ktlint.core.ast.ElementType.WHEN import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE -import com.pinterest.ktlint.core.ast.isWhiteSpace import com.pinterest.ktlint.core.ast.isWhiteSpaceWithNewline import com.pinterest.ktlint.core.ast.nextCodeSibling import com.pinterest.ktlint.core.ast.parent @@ -92,6 +93,7 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings * 7. Ensures that in multiline lambda newline follows arrow or, in case of lambda without explicit parameters, opening brace * 8. Checks that functions with single `return` are simplified to functions with expression body * 9. parameter or argument lists and supertype lists that have more than 2 elements should be separated by newlines + * 10. Complex expression inside condition replaced with new variable */ @Suppress("ForbiddenComment") class NewlinesRule(private val configRules: List) : Rule("newlines") { @@ -154,18 +156,24 @@ class NewlinesRule(private val configRules: List) : Rule("newlines" } } - @Suppress("ComplexMethod") + @Suppress("ComplexMethod", "TOO_LONG_FUNCTION") private fun handleOperatorWithLineBreakBefore(node: ASTNode) { if (node.isDotFromPackageOrImport()) { return } val isIncorrect = (if (node.elementType == ELVIS) node.treeParent else node).run { if (isCallsChain()) { + if (node.isInParentheses()) { + COMPLEX_EXPRESSION.warn(configRules, emitWarn, isFixMode, node.text, node.startOffset, node) + } val isSingleLineIfElse = parent({ it.elementType == IF }, true)?.isSingleLineIfElse() ?: false // to follow functional style these operators should be started by newline (isFollowedByNewline() || !isBeginByNewline()) && !isSingleLineIfElse && (!isFirstCall() || !isMultilineLambda(treeParent)) } else { + if (isCallsChain(false) && node.isInParentheses()) { + COMPLEX_EXPRESSION.warn(configRules, emitWarn, isFixMode, node.text, node.startOffset, node) + } // unless statement is simple and on single line, these operators cannot have newline after isFollowedByNewline() && !isSingleDotStatementOnSingleLine() } @@ -375,11 +383,11 @@ class NewlinesRule(private val configRules: List) : Rule("newlines" if (psi.children.isNotEmpty() && (!psi.isFirstChildElementType(DOT_QUALIFIED_EXPRESSION) && !psi.isFirstChildElementType(SAFE_ACCESS_EXPRESSION))) { val firstChild = psi.firstChild + if (firstChild.isFirstChildElementType(DOT_QUALIFIED_EXPRESSION) || + firstChild.isFirstChildElementType(SAFE_ACCESS_EXPRESSION)) { + getOrderedCallExpressions(firstChild.firstChild, result) + } if (firstChild.isFirstChildElementType(POSTFIX_EXPRESSION)) { - if (firstChild.isFirstChildElementType(DOT_QUALIFIED_EXPRESSION) || - firstChild.isFirstChildElementType(SAFE_ACCESS_EXPRESSION)) { - getOrderedCallExpressions(firstChild.firstChild, result) - } result.add(firstChild.node) } result.add(firstChild.node @@ -439,17 +447,23 @@ class NewlinesRule(private val configRules: List) : Rule("newlines" * * @return true - if there is error, and false if there is no error */ - private fun ASTNode.isCallsChain() = getCallChain()?.isNotValidCalls(this) ?: false - - private fun ASTNode.getCallChain() = getParentExpressions() - .lastOrNull() - ?.run { - mutableListOf().also { - getOrderedCallExpressions(psi, it) + private fun ASTNode.isCallsChain(dropLeadingProperties: Boolean = true) = getCallChain(dropLeadingProperties)?.isNotValidCalls(this) ?: false + + private fun ASTNode.getCallChain(dropLeadingProperties: Boolean = true): List? { + val parentExpressionList = getParentExpressions() + .lastOrNull() + ?.run { + mutableListOf().also { + getOrderedCallExpressions(psi, it) + } } + return if (dropLeadingProperties) { + // fixme: we can't distinguish fully qualified names (like java.lang) from chain of property accesses (like list.size) for now + parentExpressionList?.dropWhile { !it.treeParent.textContains('(') && !it.treeParent.textContains('{') } + } else { + parentExpressionList } - // fixme: we can't distinguish fully qualified names (like java.lang) from chain of property accesses (like list.size) for now - ?.dropWhile { !it.treeParent.textContains('(') && !it.treeParent.textContains('{') } + } private fun List.isNotValidCalls(node: ASTNode): Boolean { if (this.size == 1) { @@ -504,6 +518,15 @@ class NewlinesRule(private val configRules: List) : Rule("newlines" firstChildNode.elementType == IDENTIFIER && treeParent.elementType == BINARY_EXPRESSION + /** + * This method checks that complex expression should be replace with new variable + */ + private fun ASTNode.isInParentheses() = parent({it.elementType == DOT_QUALIFIED_EXPRESSION || it.elementType == SAFE_ACCESS_EXPRESSION}) + ?.treeParent + ?.elementType + ?.let { it in parenthesesTypes } + ?: false + /** * [RuleConfiguration] for newlines placement */ @@ -527,5 +550,6 @@ class NewlinesRule(private val configRules: List) : Rule("newlines" private val expressionTypes = TokenSet.create(DOT_QUALIFIED_EXPRESSION, SAFE_ACCESS_EXPRESSION, CALLABLE_REFERENCE_EXPRESSION, BINARY_EXPRESSION) private val chainExpressionTypes = TokenSet.create(DOT_QUALIFIED_EXPRESSION, SAFE_ACCESS_EXPRESSION) private val dropChainValues = TokenSet.create(EOL_COMMENT, WHITE_SPACE, BLOCK_COMMENT, KDOC) + private val parenthesesTypes = TokenSet.create(CONDITION, WHEN, VALUE_ARGUMENT) } } diff --git a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml index 3e7f60fdb6..dcec48653b 100644 --- a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml +++ b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml @@ -232,6 +232,9 @@ maxSpaces: '1' # Whether formatting for enums should be kept without checking saveInitialFormattingForEnums: false +# Inspection that checks if a long dot qualified expression is used in condition or as an argument +- name: COMPLEX_EXPRESSION + enabled: true # Checks that blank lines are used correctly. # For example: triggers when there are too many blank lines between function declaration - name: TOO_MANY_BLANK_LINES diff --git a/diktat-rules/src/main/resources/diktat-analysis.yml b/diktat-rules/src/main/resources/diktat-analysis.yml index 0caa29ff1e..bd942dc57f 100644 --- a/diktat-rules/src/main/resources/diktat-analysis.yml +++ b/diktat-rules/src/main/resources/diktat-analysis.yml @@ -229,6 +229,9 @@ maxSpaces: '1' # Whether formatting for enums should be kept without checking saveInitialFormattingForEnums: false +# Inspection that checks if a long dot qualified expression is used in condition or as an argument +- name: COMPLEX_EXPRESSION + enabled: true # Checks that blank lines are used correctly. # For example: triggers when there are too many blank lines between function declaration - name: TOO_MANY_BLANK_LINES diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/files/NewlinesRuleWarnTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/files/NewlinesRuleWarnTest.kt index 05878c2f7c..3d95d8603d 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/files/NewlinesRuleWarnTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/files/NewlinesRuleWarnTest.kt @@ -1,6 +1,7 @@ package org.cqfn.diktat.ruleset.chapter3.files import org.cqfn.diktat.common.config.rules.RulesConfig +import org.cqfn.diktat.ruleset.constants.Warnings.COMPLEX_EXPRESSION import org.cqfn.diktat.ruleset.constants.Warnings.REDUNDANT_SEMICOLON import org.cqfn.diktat.ruleset.constants.Warnings.WRONG_NEWLINES import org.cqfn.diktat.ruleset.rules.DIKTAT_RULE_SET_ID @@ -11,6 +12,7 @@ import com.pinterest.ktlint.core.LintError import generated.WarningNames import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Tag +import org.junit.jupiter.api.Tags import org.junit.jupiter.api.Test @Suppress("LargeClass") @@ -905,6 +907,22 @@ class NewlinesRuleWarnTest : LintTestBase(::NewlinesRule) { ) } + @Test + @Tag(WarningNames.WRONG_NEWLINES) + fun `test for not first prefix`() { + lintMethod( + """ + |fun foo() { + | a().b!!.c() + | a().b.c()!! + |} + """.trimMargin(), + LintError(2, 11, ruleId, "$functionalStyleWarn .", true), + LintError(3, 9, ruleId, "$functionalStyleWarn .", true), + rulesConfigList = rulesConfigListShort + ) + } + @Test @Tag(WarningNames.WRONG_NEWLINES) fun `test for null safety several lines`() { @@ -955,4 +973,39 @@ class NewlinesRuleWarnTest : LintTestBase(::NewlinesRule) { rulesConfigList = rulesConfigListShort ) } + + @Test + @Tags(Tag(WarningNames.WRONG_NEWLINES), Tag(WarningNames.COMPLEX_EXPRESSION)) + fun `complex expression in condition`() { + lintMethod( + """ + |fun foo() { + | if(a.b.c) {} + | while(a?.b?.c) {} + | when(a.b!!.c) {} + | goo(a?.b.c) + |} + """.trimMargin(), + LintError(2, 10, ruleId, "${COMPLEX_EXPRESSION.warnText()} .", false), + LintError(3, 14, ruleId, "${COMPLEX_EXPRESSION.warnText()} ?.", false), + LintError(4, 14, ruleId, "${COMPLEX_EXPRESSION.warnText()} .", false), + LintError(5, 12, ruleId, "${COMPLEX_EXPRESSION.warnText()} .", false), + rulesConfigList = rulesConfigListShort + ) + } + + @Test + @Tags(Tag(WarningNames.WRONG_NEWLINES), Tag(WarningNames.COMPLEX_EXPRESSION)) + fun `complex expression in condition with double warnings`() { + lintMethod( + """ + |fun foo() { + | if(a().b().c()) {} + |} + """.trimMargin(), + LintError(2, 14, ruleId, "${COMPLEX_EXPRESSION.warnText()} .", false), + LintError(2, 14, ruleId, "$functionalStyleWarn .", true), + rulesConfigList = rulesConfigListShort + ) + } } diff --git a/info/available-rules.md b/info/available-rules.md index 6af0e09a05..68ad3c0ed3 100644 --- a/info/available-rules.md +++ b/info/available-rules.md @@ -67,6 +67,7 @@ | 3 | 3.5.1 | LONG_LINE | Check: warns if length doesn't exceed the specified length | no | lineLength | handle json method in KDoc | | 3 | 3.6.2 | REDUNDANT_SEMICOLON | Check: warns if semicolons are used at the end of line.
Fix: removes semicolon. | yes | no | - | | 3 | 3.6.2 | WRONG_NEWLINES | Check: warns if line breaks do not follow code style guid.
Fix: fixes incorrect line breaks. | yes | no | - | +| 3 | 3.6.2 | COMPLEX_EXPRESSION | Check: warns if a long dot qualified expression is used in condition or as an argument | no | no | - | | 3 | 3.15.1 | STRING_CONCATENATION | Check: warns if in a single line concatenation of strings is used | yes | no | - | | 3 | 3.7.1 | TOO_MANY_BLANK_LINES | Check: warns if blank lines are used placed incorrectly.
Fix: removes redundant blank lines. | yes | no | | | 3 | 3.8.1 | WRONG_WHITESPACE | Check: warns if usage of horizontal spaces violates code style guide.
Fix: fixes incorrect whitespaces. | yes | no | - | diff --git a/info/guide/guide-chapter-3.md b/info/guide/guide-chapter-3.md index 5e47c6cdf9..ff20ad9c30 100644 --- a/info/guide/guide-chapter-3.md +++ b/info/guide/guide-chapter-3.md @@ -366,6 +366,22 @@ Note that all comparison operators, such as `==`, `>`, `<`, should not be split. ```kotlin if (condition) list.map { foo(it) }.filter { bar(it) } else list.drop(1) ``` + +**Note:** If dot qualified expression is inside condition or passed as an argument - it should be replaced with new variable. + +**Invalid example**: +```kotlin + if (node.treeParent.treeParent.findChildByType(IDENTIFIER) != null) {} +``` + +**Valid example**: +```kotlin + val grandIdentifier = node + .treeParent + .treeParent + .findChildByType(IDENTIFIER) + if (grandIdentifier != null) {} +``` 2) Newlines should be placed after the assignment operator (`=`). 3) In function or class declarations, the name of a function or constructor should not be split by a newline from the opening brace `(`. From 526bc52677bdf8ac7e634f2d0c68ed7e4ff2786b Mon Sep 17 00:00:00 2001 From: Alexander Tsay <48321920+aktsay6@users.noreply.github.com> Date: Sun, 17 Jan 2021 15:01:09 +0300 Subject: [PATCH 09/11] Codestyle fixed. (#683) ### What's done: * Deleted suppress --- .../kotlin/org/cqfn/diktat/ruleset/rules/NullChecksRule.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/NullChecksRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/NullChecksRule.kt index 61c8bb9996..57438aec78 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/NullChecksRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/NullChecksRule.kt @@ -160,9 +160,8 @@ class NullChecksRule(private val configRules: List) : Rule("null-ch } } - @Suppress("WRONG_INDENTATION") private fun ASTNode.extractLinesFromBlock(type: IElementType): List? = - treeParent + treeParent .getFirstChildWithType(type) ?.text ?.trim('{', '}') From 373b609cb8b112e142ca6055707297d5fb5c002e Mon Sep 17 00:00:00 2001 From: Denis Kumar Date: Mon, 18 Jan 2021 11:27:03 +0300 Subject: [PATCH 10/11] AsyncAndSyncRule (#707) * AsyncAndSyncRule ### What's done: Implemented rule, added tests and documentation --- diktat-analysis.yml | 3 + .../src/main/kotlin/generated/WarningNames.kt | 2 + .../cqfn/diktat/ruleset/constants/Warnings.kt | 1 + .../diktat/ruleset/rules/AsyncAndSyncRule.kt | 48 ++++++++++++ .../ruleset/rules/DiktatRuleSetProvider.kt | 1 + .../main/resources/diktat-analysis-huawei.yml | 3 + .../src/main/resources/diktat-analysis.yml | 3 + .../ruleset/chapter5/AsyncAndSyncRuleTest.kt | 74 +++++++++++++++++++ info/available-rules.md | 1 + info/guide/guide-chapter-5.md | 11 +++ 10 files changed, 147 insertions(+) create mode 100644 diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/AsyncAndSyncRule.kt create mode 100644 diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/AsyncAndSyncRuleTest.kt diff --git a/diktat-analysis.yml b/diktat-analysis.yml index 0bfeaabaae..969a9f8f50 100644 --- a/diktat-analysis.yml +++ b/diktat-analysis.yml @@ -353,6 +353,9 @@ # Checks that function use default values, instead overloading - name: WRONG_OVERLOADING_FUNCTION_ARGUMENTS enabled: true +# Checks that using runBlocking inside async block code +- name: RUN_BLOCKING_INSIDE_ASYNC + enabled: true # Checks that property in constructor doesn't contains comment - name: KDOC_NO_CONSTRUCTOR_PROPERTY enabled: true diff --git a/diktat-rules/src/main/kotlin/generated/WarningNames.kt b/diktat-rules/src/main/kotlin/generated/WarningNames.kt index 277a04125d..ffe5893e2a 100644 --- a/diktat-rules/src/main/kotlin/generated/WarningNames.kt +++ b/diktat-rules/src/main/kotlin/generated/WarningNames.kt @@ -201,6 +201,8 @@ public object WarningNames { public const val WRONG_OVERLOADING_FUNCTION_ARGUMENTS: String = "WRONG_OVERLOADING_FUNCTION_ARGUMENTS" + public const val RUN_BLOCKING_INSIDE_ASYNC: String = "RUN_BLOCKING_INSIDE_ASYNC" + public const val SINGLE_CONSTRUCTOR_SHOULD_BE_PRIMARY: String = "SINGLE_CONSTRUCTOR_SHOULD_BE_PRIMARY" diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt index 3fb16abd45..6725faede4 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt @@ -132,6 +132,7 @@ enum class Warnings( TOO_MANY_PARAMETERS(false, "5.2.2", "function has too many parameters"), NESTED_BLOCK(false, "5.1.2", "function has too many nested blocks and should be simplified"), WRONG_OVERLOADING_FUNCTION_ARGUMENTS(false, "5.2.3", "use default argument instead of function overloading"), + RUN_BLOCKING_INSIDE_ASYNC(false, "5.2.4", "avoid using runBlocking in asynchronous code"), // ======== chapter 6 ======== SINGLE_CONSTRUCTOR_SHOULD_BE_PRIMARY(true, "6.1.1", "if a class has single constructor, it should be converted to a primary constructor"), diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/AsyncAndSyncRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/AsyncAndSyncRule.kt new file mode 100644 index 0000000000..7f7f08f7c0 --- /dev/null +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/AsyncAndSyncRule.kt @@ -0,0 +1,48 @@ +package org.cqfn.diktat.ruleset.rules + +import org.cqfn.diktat.common.config.rules.RulesConfig +import org.cqfn.diktat.ruleset.constants.EmitType +import org.cqfn.diktat.ruleset.constants.Warnings.RUN_BLOCKING_INSIDE_ASYNC +import org.cqfn.diktat.ruleset.utils.hasChildOfType + +import com.pinterest.ktlint.core.Rule +import com.pinterest.ktlint.core.ast.ElementType.CALL_EXPRESSION +import com.pinterest.ktlint.core.ast.ElementType.FUN +import com.pinterest.ktlint.core.ast.ElementType.LAMBDA_ARGUMENT +import com.pinterest.ktlint.core.ast.ElementType.REFERENCE_EXPRESSION +import com.pinterest.ktlint.core.ast.parent +import org.jetbrains.kotlin.com.intellij.lang.ASTNode +import org.jetbrains.kotlin.psi.KtFunction +import org.jetbrains.kotlin.psi.psiUtil.hasSuspendModifier + +/** + * This rule finds if using runBlocking in asynchronous code + */ +class AsyncAndSyncRule(private val configRules: List) : Rule("sync-in-async") { + private val asyncList = listOf("async", "launch") + private var isFixMode: Boolean = false + private lateinit var emitWarn: EmitType + + override fun visit(node: ASTNode, + autoCorrect: Boolean, + emit: EmitType) { + emitWarn = emit + isFixMode = autoCorrect + + if (node.isRunBlocking()) { + checkRunBlocking(node) + } + } + + private fun checkRunBlocking(node: ASTNode) { + node.parent({it.isAsync() || it.isSuspend()})?.let { + RUN_BLOCKING_INSIDE_ASYNC.warn(configRules, emitWarn, isFixMode, node.text, node.startOffset, node) + } + } + + private fun ASTNode.isAsync() = this.elementType == CALL_EXPRESSION && this.findChildByType(REFERENCE_EXPRESSION)?.text in asyncList + + private fun ASTNode.isSuspend() = this.elementType == FUN && (this.psi as KtFunction).modifierList?.hasSuspendModifier() ?: false + + private fun ASTNode.isRunBlocking() = this.elementType == REFERENCE_EXPRESSION && this.text == "runBlocking" && this.treeParent.hasChildOfType(LAMBDA_ARGUMENT) +} diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt index 7640a6f678..f05a80f906 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt @@ -137,6 +137,7 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS ::FunctionArgumentsSize, ::BlankLinesRule, ::FileSize, + ::AsyncAndSyncRule, ::NullableTypeRule, ::NullChecksRule, ::ImmutableValNoVarRule, diff --git a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml index dcec48653b..281df43f9b 100644 --- a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml +++ b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml @@ -353,6 +353,9 @@ # Checks that function use default values, instead overloading - name: WRONG_OVERLOADING_FUNCTION_ARGUMENTS enabled: true +# Checks that using runBlocking inside async block code +- name: RUN_BLOCKING_INSIDE_ASYNC + enabled: true # Checks that property in constructor doesn't contains comment - name: KDOC_NO_CONSTRUCTOR_PROPERTY enabled: true diff --git a/diktat-rules/src/main/resources/diktat-analysis.yml b/diktat-rules/src/main/resources/diktat-analysis.yml index bd942dc57f..cdff6358f4 100644 --- a/diktat-rules/src/main/resources/diktat-analysis.yml +++ b/diktat-rules/src/main/resources/diktat-analysis.yml @@ -350,6 +350,9 @@ # Checks that function use default values, instead overloading - name: WRONG_OVERLOADING_FUNCTION_ARGUMENTS enabled: true +# Checks that using runBlocking inside async block code +- name: RUN_BLOCKING_INSIDE_ASYNC + enabled: true # Checks that property in constructor doesn't contain comment - name: KDOC_NO_CONSTRUCTOR_PROPERTY enabled: true diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/AsyncAndSyncRuleTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/AsyncAndSyncRuleTest.kt new file mode 100644 index 0000000000..8d904c8ea1 --- /dev/null +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/AsyncAndSyncRuleTest.kt @@ -0,0 +1,74 @@ +package org.cqfn.diktat.ruleset.chapter5 + +import org.cqfn.diktat.ruleset.constants.Warnings.RUN_BLOCKING_INSIDE_ASYNC +import org.cqfn.diktat.ruleset.rules.AsyncAndSyncRule +import org.cqfn.diktat.ruleset.rules.DIKTAT_RULE_SET_ID +import org.cqfn.diktat.util.LintTestBase + +import com.pinterest.ktlint.core.LintError +import generated.WarningNames +import org.junit.jupiter.api.Tag +import org.junit.jupiter.api.Test + +class AsyncAndSyncRuleTest : LintTestBase(::AsyncAndSyncRule) { + private val ruleId = "$DIKTAT_RULE_SET_ID:sync-in-async" + + @Test + @Tag(WarningNames.RUN_BLOCKING_INSIDE_ASYNC) + fun `test wrong case`() { + lintMethod( + """ + |fun foo() { + | GlobalScope.launch { + | c.addAndGet(i) + | } + | + | GlobalScope.async { + | n + | } + | + | GlobalScope.async { + | runBlocking { + | + | } + | } + |} + | + |suspend fun foo() { + | runBlocking { + | delay(2000) + | } + |} + | + """.trimMargin(), + LintError(11, 8, ruleId, "${RUN_BLOCKING_INSIDE_ASYNC.warnText()} runBlocking", false), + LintError(18, 4, ruleId, "${RUN_BLOCKING_INSIDE_ASYNC.warnText()} runBlocking", false) + ) + } + + @Test + @Tag(WarningNames.RUN_BLOCKING_INSIDE_ASYNC) + fun `test dot qualified expression case`() { + lintMethod( + """ + |fun foo() { + | GlobalScope.async { + | node.runBlocking() + | runBlocking { + | n++ + | } + | } + |} + | + |fun goo() { + | runBlocking { + | GlobalScope.async { + | n++ + | } + | } + |} + """.trimMargin(), + LintError(4, 8, ruleId, "${RUN_BLOCKING_INSIDE_ASYNC.warnText()} runBlocking", false) + ) + } +} diff --git a/info/available-rules.md b/info/available-rules.md index 68ad3c0ed3..f2ce918049 100644 --- a/info/available-rules.md +++ b/info/available-rules.md @@ -96,6 +96,7 @@ | 5 | 5.2.1 | LAMBDA_IS_NOT_LAST_PARAMETER | Checks that lambda inside function parameters isn't in the end | no | no | | 5 | 5.2.2 | TOO_MANY_PARAMETERS | Check: if function contains more parameters than allowed | no | maxParameterListSize | | 5 | 5.2.3 | WRONG_OVERLOADING_FUNCTION_ARGUMENTS | Check: function has overloading instead use default arguments | no | no | +| 5 | 5.2.4 | RUN_BLOCKING_INSIDE_ASYNC | Check: using runBlocking inside async block code | no | no | - | | 6 | 6.1.1 | SINGLE_CONSTRUCTOR_SHOULD_BE_PRIMARY | Check: warns if there is only one secondary constructor in a class
Fix: converts it to a primary constructor | yes | no | Support more complicated logic of constructor conversion | | 6 | 6.1.2 | USE_DATA_CLASS | Check: if class can be made as data class | no | no | yes | | 6 | 6.1.3 | EMPTY_PRIMARY_CONSTRUCTOR | Check: if there is empty primary constructor | yes | no | yes | diff --git a/info/guide/guide-chapter-5.md b/info/guide/guide-chapter-5.md index 294418dce4..6eef6ca3a7 100644 --- a/info/guide/guide-chapter-5.md +++ b/info/guide/guide-chapter-5.md @@ -132,3 +132,14 @@ private fun foo() { // ... } ``` +####
5.2.4 Synchronizing code inside asynchronous code +Try to avoid using runBlocking in asynchronous code + +**Invalid example**: +```kotlin +GlobalScope.async { + runBlocking { + count++ + } +} +``` \ No newline at end of file From 0b61701262a43a4fec6ce2313170cea81c408663 Mon Sep 17 00:00:00 2001 From: Vladislav Frolov <50615459+Cheshiriks@users.noreply.github.com> Date: Mon, 18 Jan 2021 12:22:52 +0300 Subject: [PATCH 11/11] New rule 5.2.4 for lambda length (#705) * New rule 5.2.4 for lambda length ### What's done: * Added rule logic * Added new warning * Added new test * New rule 5.2.4 for lambda length ### What's done: * Added rule logic * Added new warning * Added new test * New rule 5.2.4 for lambda length ### What's done: * Added rule logic * Added new warning * Added new test * New rule 5.2.4 for lambda length ### What's done: * Added rule logic * Added new warning * Added new test * New rule 5.2.4 for lambda length ### What's done: * Added rule logic * Added new warning * Added new test --- diktat-analysis.yml | 5 + .../src/main/kotlin/generated/WarningNames.kt | 2 + .../cqfn/diktat/ruleset/constants/Warnings.kt | 1 + .../ruleset/rules/BlockStructureBraces.kt | 10 +- .../ruleset/rules/DiktatRuleSetProvider.kt | 1 + .../diktat/ruleset/rules/FunctionLength.kt | 7 +- .../diktat/ruleset/rules/LambdaLengthRule.kt | 71 +++++++ .../cqfn/diktat/ruleset/rules/LineLength.kt | 8 +- .../rules/MultipleModifiersSequence.kt | 14 +- .../ruleset/rules/SingleLineStatementsRule.kt | 18 +- .../diktat/ruleset/rules/SmartCastRule.kt | 16 +- .../ruleset/rules/classes/SingleInitRule.kt | 4 +- .../ruleset/rules/files/NewlinesRule.kt | 10 +- .../cqfn/diktat/ruleset/utils/AstNodeUtils.kt | 11 ++ .../diktat/ruleset/utils/StringCaseUtils.kt | 24 +-- .../main/resources/diktat-analysis-huawei.yml | 5 + .../src/main/resources/diktat-analysis.yml | 5 + .../ruleset/chapter5/LambdaLengthWarnTest.kt | 175 ++++++++++++++++++ .../kotlin/org/cqfn/diktat/util/TestUtils.kt | 12 +- info/available-rules.md | 1 + info/guide/guide-TOC.md | 1 + info/guide/guide-chapter-5.md | 5 +- 22 files changed, 343 insertions(+), 63 deletions(-) create mode 100644 diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/LambdaLengthRule.kt create mode 100644 diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/LambdaLengthWarnTest.kt diff --git a/diktat-analysis.yml b/diktat-analysis.yml index 969a9f8f50..af4695f9e4 100644 --- a/diktat-analysis.yml +++ b/diktat-analysis.yml @@ -356,6 +356,11 @@ # Checks that using runBlocking inside async block code - name: RUN_BLOCKING_INSIDE_ASYNC enabled: true +# Checks that the long lambda has parameters +- name: TOO_MANY_LINES_IN_LAMBDA + enabled: true + configuration: + maxLambdaLength: 10 # max length of lambda without parameters # Checks that property in constructor doesn't contains comment - name: KDOC_NO_CONSTRUCTOR_PROPERTY enabled: true diff --git a/diktat-rules/src/main/kotlin/generated/WarningNames.kt b/diktat-rules/src/main/kotlin/generated/WarningNames.kt index ffe5893e2a..5332a3e099 100644 --- a/diktat-rules/src/main/kotlin/generated/WarningNames.kt +++ b/diktat-rules/src/main/kotlin/generated/WarningNames.kt @@ -235,4 +235,6 @@ public object WarningNames { public const val OBJECT_IS_PREFERRED: String = "OBJECT_IS_PREFERRED" public const val INVERSE_FUNCTION_PREFERRED: String = "INVERSE_FUNCTION_PREFERRED" + + public const val TOO_MANY_LINES_IN_LAMBDA: String = "TOO_MANY_LINES_IN_LAMBDA" } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt index 6725faede4..e8e088167b 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt @@ -133,6 +133,7 @@ enum class Warnings( NESTED_BLOCK(false, "5.1.2", "function has too many nested blocks and should be simplified"), WRONG_OVERLOADING_FUNCTION_ARGUMENTS(false, "5.2.3", "use default argument instead of function overloading"), RUN_BLOCKING_INSIDE_ASYNC(false, "5.2.4", "avoid using runBlocking in asynchronous code"), + TOO_MANY_LINES_IN_LAMBDA(false, "5.2.5", "long lambdas should have a parameter name instead of it"), // ======== chapter 6 ======== SINGLE_CONSTRUCTOR_SHOULD_BE_PRIMARY(true, "6.1.1", "if a class has single constructor, it should be converted to a primary constructor"), diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/BlockStructureBraces.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/BlockStructureBraces.kt index acf64f92ac..e381be9235 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/BlockStructureBraces.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/BlockStructureBraces.kt @@ -221,14 +221,14 @@ class BlockStructureBraces(private val configRules: List) : Rule("b allMiddleSpace: List, node: ASTNode, keyword: IElementType) { - allMiddleSpace.forEach { - if (checkBraceNode(it, true)) { + allMiddleSpace.forEach { space -> + if (checkBraceNode(space, true)) { BRACES_BLOCK_STRUCTURE_ERROR.warnAndFix(configRules, emitWarn, isFixMode, "incorrect new line after closing brace", - it.startOffset, it) { - if (it.elementType != WHITE_SPACE) { + space.startOffset, space) { + if (space.elementType != WHITE_SPACE) { node.addChild(PsiWhiteSpaceImpl(" "), node.findChildByType(keyword)) } else { - (it as LeafPsiElement).replaceWithText(" ") + (space as LeafPsiElement).replaceWithText(" ") } } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt index f05a80f906..60aba56ab6 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt @@ -143,6 +143,7 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS ::ImmutableValNoVarRule, ::AvoidNestedFunctionsRule, ::ExtensionFunctionsSameNameRule, + ::LambdaLengthRule, // formatting: moving blocks, adding line breaks, indentations etc. ::BlockStructureBraces, ::ConsecutiveSpacesRule, diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/FunctionLength.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/FunctionLength.kt index 82d3f02592..a9c619fae2 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/FunctionLength.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/FunctionLength.kt @@ -43,11 +43,10 @@ class FunctionLength(private val configRules: List) : Rule("functio ?.node ?.clone() ?: return) as ASTNode } - copyNode.findAllNodesWithCondition({ it.elementType in commentType }).forEach { it.treeParent.removeChild(it) } - val functionText = copyNode.text.lines().filter { it.isNotBlank() } - if (functionText.size > configuration.maxFunctionLength) { + val sizeFun = countCodeLines(copyNode) + if (sizeFun > configuration.maxFunctionLength) { TOO_LONG_FUNCTION.warn(configRules, emitWarn, isFixMode, - "max length is ${configuration.maxFunctionLength}, but you have ${functionText.size}", + "max length is ${configuration.maxFunctionLength}, but you have $sizeFun", node.startOffset, node) } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/LambdaLengthRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/LambdaLengthRule.kt new file mode 100644 index 0000000000..681b9bd077 --- /dev/null +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/LambdaLengthRule.kt @@ -0,0 +1,71 @@ +package org.cqfn.diktat.ruleset.rules + +import org.cqfn.diktat.common.config.rules.RuleConfiguration +import org.cqfn.diktat.common.config.rules.RulesConfig +import org.cqfn.diktat.common.config.rules.getRuleConfig +import org.cqfn.diktat.ruleset.constants.EmitType +import org.cqfn.diktat.ruleset.constants.Warnings +import org.cqfn.diktat.ruleset.utils.* + +import com.pinterest.ktlint.core.Rule +import com.pinterest.ktlint.core.ast.ElementType +import org.jetbrains.kotlin.com.intellij.lang.ASTNode + +/** + * Rule 5.2.5 check lambda length without parameters + */ +class LambdaLengthRule(private val configRules: List) : Rule("lambda-length") { + private val configuration by lazy { + LambdaLengthConfiguration( + this.configRules.getRuleConfig(Warnings.TOO_MANY_LINES_IN_LAMBDA)?.configuration ?: emptyMap() + ) + } + private var isFixMode: Boolean = false + private lateinit var emitWarn: EmitType + + override fun visit( + node: ASTNode, + autoCorrect: Boolean, + emit: EmitType + ) { + emitWarn = emit + isFixMode = autoCorrect + + if (node.elementType == ElementType.LAMBDA_EXPRESSION) { + checkLambda(node, configuration) + } + } + + private fun checkLambda(node: ASTNode, configuration: LambdaLengthConfiguration) { + val copyNode = node.clone() as ASTNode + val sizeLambda = countCodeLines(copyNode) + if (sizeLambda > configuration.maxLambdaLength) { + copyNode.findAllNodesWithCondition({ it.elementType == ElementType.LAMBDA_EXPRESSION }).forEachIndexed { index, node -> + if (index > 0) { + node.treeParent.removeChild(node) + } + } + val isIt = copyNode.findAllNodesWithSpecificType(ElementType.REFERENCE_EXPRESSION).map {re -> re.text}.contains("it") + val parameters = node.findChildByType(ElementType.FUNCTION_LITERAL)?.findChildByType(ElementType.VALUE_PARAMETER_LIST) + if (parameters == null && isIt) { + Warnings.TOO_MANY_LINES_IN_LAMBDA.warn(configRules, emitWarn, isFixMode, + "max length lambda without arguments is ${configuration.maxLambdaLength}, but you have $sizeLambda", + node.startOffset, node) + } + } + } + + /** + * [RuleConfiguration] for lambda length + */ + class LambdaLengthConfiguration(config: Map) : RuleConfiguration(config) { + /** + * Maximum allowed lambda length + */ + val maxLambdaLength = config["maxLambdaLength"]?.toLong() ?: MAX_LINES_IN_LAMBDA + } + + companion object { + private const val MAX_LINES_IN_LAMBDA = 10L + } +} diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/LineLength.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/LineLength.kt index f7685c1e2b..e6ad7f6dbb 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/LineLength.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/LineLength.kt @@ -84,21 +84,21 @@ class LineLength(private val configRules: List) : Rule("line-length @Suppress("UnsafeCallOnNullableType") private fun checkLength(node: ASTNode, configuration: LineLengthConfiguration) { var offset = 0 - node.text.lines().forEach { - if (it.length > configuration.lineLength) { + node.text.lines().forEach { line -> + if (line.length > configuration.lineLength) { val newNode = node.psi.findElementAt(offset + configuration.lineLength.toInt())!!.node if ((newNode.elementType != KDOC_TEXT && newNode.elementType != KDOC_MARKDOWN_INLINE_LINK) || !isKdocValid(newNode)) { positionByOffset = node.treeParent.calculateLineColByOffset() val fixableType = isFixable(newNode, configuration) LONG_LINE.warnAndFix(configRules, emitWarn, isFixMode, - "max line length ${configuration.lineLength}, but was ${it.length}", + "max line length ${configuration.lineLength}, but was ${line.length}", offset + node.startOffset, node, fixableType != LongLineFixableCases.None) { fixError(fixableType) } } } - offset += it.length + 1 + offset += line.length + 1 } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/MultipleModifiersSequence.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/MultipleModifiersSequence.kt index 1a58810826..c1c6ba14e4 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/MultipleModifiersSequence.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/MultipleModifiersSequence.kt @@ -59,19 +59,19 @@ class MultipleModifiersSequence(private val configRules: List) : Ru node .getChildren(null) .filterIndexed { index, astNode -> astNode.elementType == ANNOTATION_ENTRY && index > firstModifierIndex } - .forEach { + .forEach { astNode -> WRONG_MULTIPLE_MODIFIERS_ORDER.warnAndFix(configRules, emitWarn, isFixMode, - "${it.text} annotation should be before all modifiers", - it.startOffset, it) { - val spaceBefore = it.treePrev - node.removeChild(it) + "${astNode.text} annotation should be before all modifiers", + astNode.startOffset, astNode) { + val spaceBefore = astNode.treePrev + node.removeChild(astNode) if (spaceBefore != null && spaceBefore.elementType == WHITE_SPACE) { node.removeChild(spaceBefore) node.addChild(spaceBefore, node.firstChildNode) - node.addChild(it.clone() as ASTNode, spaceBefore) + node.addChild(astNode.clone() as ASTNode, spaceBefore) } else { node.addChild(PsiWhiteSpaceImpl(" "), node.getChildren(null).first()) - node.addChild(it.clone() as ASTNode, node.getChildren(null).first()) + node.addChild(astNode.clone() as ASTNode, node.getChildren(null).first()) } } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/SingleLineStatementsRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/SingleLineStatementsRule.kt index 439dc40442..b1a3e3bd4c 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/SingleLineStatementsRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/SingleLineStatementsRule.kt @@ -33,18 +33,18 @@ class SingleLineStatementsRule(private val configRules: List) : Rul } private fun checkSemicolon(node: ASTNode) { - node.getChildren(semicolonToken).forEach { - if (!it.isFollowedByNewline()) { - MORE_THAN_ONE_STATEMENT_PER_LINE.warnAndFix(configRules, emitWarn, isFixMode, it.extractLineOfText(), - it.startOffset, it) { - if (it.treeParent.elementType == ENUM_ENTRY) { + node.getChildren(semicolonToken).forEach { astNode -> + if (!astNode.isFollowedByNewline()) { + MORE_THAN_ONE_STATEMENT_PER_LINE.warnAndFix(configRules, emitWarn, isFixMode, astNode.extractLineOfText(), + astNode.startOffset, astNode) { + if (astNode.treeParent.elementType == ENUM_ENTRY) { node.treeParent.addChild(PsiWhiteSpaceImpl("\n"), node.treeNext) } else { - if (!it.isBeginByNewline()) { - val nextNode = it.parent({ parent -> parent.treeNext != null }, strict = false)?.treeNext - node.appendNewlineMergingWhiteSpace(nextNode, it) + if (!astNode.isBeginByNewline()) { + val nextNode = astNode.parent({ parent -> parent.treeNext != null }, strict = false)?.treeNext + node.appendNewlineMergingWhiteSpace(nextNode, astNode) } - node.removeChild(it) + node.removeChild(astNode) } } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/SmartCastRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/SmartCastRule.kt index 60497b7e81..9e5b3c07c0 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/SmartCastRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/SmartCastRule.kt @@ -90,16 +90,16 @@ class SmartCastRule(private val configRules: List) : Rule("smart-ca */ @Suppress("NestedBlockDepth", "TYPE_ALIAS") private fun handleGroups(groups: Map>) { - groups.keys.forEach { - val parentText = it.node.treeParent.text + groups.keys.forEach { key -> + val parentText = key.node.treeParent.text if (parentText.contains(" is ")) { - groups.getValue(it).forEach { asCall -> + groups.getValue(key).forEach { asCall -> if (asCall.node.hasParent(THEN)) { raiseWarning(asCall.node) } } } else if (parentText.contains(" !is ")) { - groups.getValue(it).forEach { asCall -> + groups.getValue(key).forEach { asCall -> if (asCall.node.hasParent(ELSE)) { raiseWarning(asCall.node) } @@ -234,12 +234,12 @@ class SmartCastRule(private val configRules: List) : Rule("smart-ca val identifier = node.getFirstChildWithType(REFERENCE_EXPRESSION)?.text - node.getAllChildrenWithType(WHEN_ENTRY).forEach { - if (it.hasChildOfType(WHEN_CONDITION_IS_PATTERN) && identifier != null) { - val type = it.getFirstChildWithType(WHEN_CONDITION_IS_PATTERN)!! + node.getAllChildrenWithType(WHEN_ENTRY).forEach { entry -> + if (entry.hasChildOfType(WHEN_CONDITION_IS_PATTERN) && identifier != null) { + val type = entry.getFirstChildWithType(WHEN_CONDITION_IS_PATTERN)!! .getFirstChildWithType(TYPE_REFERENCE)?.text - val callExpr = it.findAllNodesWithSpecificType(BINARY_WITH_TYPE).firstOrNull() + val callExpr = entry.findAllNodesWithSpecificType(BINARY_WITH_TYPE).firstOrNull() val blocks = listOf(IsExpressions(identifier, type ?: "")) callExpr?.let { diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/classes/SingleInitRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/classes/SingleInitRule.kt index ade3e358e9..4a15f4ad12 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/classes/SingleInitRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/classes/SingleInitRule.kt @@ -106,11 +106,11 @@ class SingleInitRule(private val configRule: List) : Rule("multiple !(property.psi as KtProperty).hasBody() && assignments.size == 1 } .takeIf { it.isNotEmpty() } - ?.let { + ?.let { map -> Warnings.MULTIPLE_INIT_BLOCKS.warnAndFix(configRule, emitWarn, isFixMode, "`init` block has assignments that can be moved to declarations", initBlock.startOffset, initBlock ) { - it.forEach { (property, assignments) -> + map.forEach { (property, assignments) -> val assignment = assignments.single() property.addChild(PsiWhiteSpaceImpl(" "), null) property.addChild(LeafPsiElement(EQ, "="), null) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/files/NewlinesRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/files/NewlinesRule.kt index f32760c2ae..c2e86a3767 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/files/NewlinesRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/files/NewlinesRule.kt @@ -471,15 +471,15 @@ class NewlinesRule(private val configRules: List) : Rule("newlines" } val callsByNewLine: ListOfList = mutableListOf() var callsInOneNewLine: MutableList = mutableListOf() - this.forEach { - if (it.treePrev.isFollowedByNewline() || it.treePrev.isWhiteSpaceWithNewline()) { + this.forEach { node -> + if (node.treePrev.isFollowedByNewline() || node.treePrev.isWhiteSpaceWithNewline()) { callsByNewLine.add(callsInOneNewLine) callsInOneNewLine = mutableListOf() - callsInOneNewLine.add(it) + callsInOneNewLine.add(node) } else { - callsInOneNewLine.add(it) + callsInOneNewLine.add(node) } - if (it.treePrev.elementType == POSTFIX_EXPRESSION && !it.treePrev.isFollowedByNewline() && configuration.maxCallsInOneLine == 1) { + if (node.treePrev.elementType == POSTFIX_EXPRESSION && !node.treePrev.isFollowedByNewline() && configuration.maxCallsInOneLine == 1) { return true } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt index 157dddcb5f..ebd6f425b7 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt @@ -789,3 +789,14 @@ private fun ASTNode.calculateLineNumber() = getRootNode() require(it >= 0) { "Cannot calculate line number correctly, node's offset $startOffset is greater than file length ${getRootNode().textLength}" } it + 1 } + +/** + * Count number of lines in code block. Note: only *copy* of a node should be passed to this method, because the method changes the node. + * + * @return the number of lines in a block of code. + */ +fun countCodeLines(copyNode: ASTNode): Int { + copyNode.findAllNodesWithCondition({ it.isPartOfComment() }).forEach { it.treeParent.removeChild(it) } + val text = copyNode.text.lines().filter { it.isNotBlank() } + return text.size +} diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/StringCaseUtils.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/StringCaseUtils.kt index a3e907f4d9..775da020d2 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/StringCaseUtils.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/StringCaseUtils.kt @@ -145,24 +145,24 @@ private fun convertUnknownCaseToCamel(str: String, isFirstLetterCapital: Boolean // [p]a[SC]a[_]l -> [P]a[Sc]a[L] var isPreviousLetterCapital = isFirstLetterCapital var isPreviousLetterUnderscore = false - return str.map { - if (it.isUpperCase()) { - val result = if (isPreviousLetterCapital && !isPreviousLetterUnderscore) it.toLowerCase() else it + return str.map { char -> + if (char.isUpperCase()) { + val result = if (isPreviousLetterCapital && !isPreviousLetterUnderscore) char.toLowerCase() else char isPreviousLetterCapital = true isPreviousLetterUnderscore = false result.toString() } else { - val result = if (it == '_') { + val result = if (char == '_') { isPreviousLetterUnderscore = true "" } else if (isPreviousLetterUnderscore) { isPreviousLetterCapital = true isPreviousLetterUnderscore = false - it.toUpperCase().toString() + char.toUpperCase().toString() } else { isPreviousLetterCapital = false isPreviousLetterUnderscore = false - it.toString() + char.toString() } result } @@ -172,17 +172,17 @@ private fun convertUnknownCaseToCamel(str: String, isFirstLetterCapital: Boolean private fun convertUnknownCaseToUpperSnake(str: String): String { // [p]a[SC]a[_]l -> [P]A_[SC]_A_[L] var alreadyInsertedUnderscore = true - return str.map { - if (it.isUpperCase()) { + return str.map { char -> + if (char.isUpperCase()) { if (!alreadyInsertedUnderscore) { alreadyInsertedUnderscore = true - "_$it" + "_$char" } else { - it.toString() + char.toString() } } else { - alreadyInsertedUnderscore = (it == '_') - it.toUpperCase().toString() + alreadyInsertedUnderscore = (char == '_') + char.toUpperCase().toString() } }.joinToString("") } diff --git a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml index 281df43f9b..58c2966f91 100644 --- a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml +++ b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml @@ -356,6 +356,11 @@ # Checks that using runBlocking inside async block code - name: RUN_BLOCKING_INSIDE_ASYNC enabled: true +# Checks that the long lambda has parameters +- name: TOO_MANY_LINES_IN_LAMBDA + enabled: true + configuration: + maxLambdaLength: 10 # max length of lambda without parameters # Checks that property in constructor doesn't contains comment - name: KDOC_NO_CONSTRUCTOR_PROPERTY enabled: true diff --git a/diktat-rules/src/main/resources/diktat-analysis.yml b/diktat-rules/src/main/resources/diktat-analysis.yml index cdff6358f4..84f0a7275f 100644 --- a/diktat-rules/src/main/resources/diktat-analysis.yml +++ b/diktat-rules/src/main/resources/diktat-analysis.yml @@ -356,6 +356,11 @@ # Checks that property in constructor doesn't contain comment - name: KDOC_NO_CONSTRUCTOR_PROPERTY enabled: true +# Checks that the long lambda has parameters +- name: TOO_MANY_LINES_IN_LAMBDA + enabled: true + configuration: + maxLambdaLength: 10 # max length of lambda without parameters # Checks that property in KDoc present in class - name: KDOC_EXTRA_PROPERTY enabled: true diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/LambdaLengthWarnTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/LambdaLengthWarnTest.kt new file mode 100644 index 0000000000..5280bf48d8 --- /dev/null +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/LambdaLengthWarnTest.kt @@ -0,0 +1,175 @@ +package org.cqfn.diktat.ruleset.chapter5 + +import org.cqfn.diktat.common.config.rules.RulesConfig +import org.cqfn.diktat.ruleset.constants.Warnings +import org.cqfn.diktat.ruleset.rules.DIKTAT_RULE_SET_ID +import org.cqfn.diktat.ruleset.rules.LambdaLengthRule +import org.cqfn.diktat.util.LintTestBase + +import com.pinterest.ktlint.core.LintError +import generated.WarningNames +import org.junit.jupiter.api.Tag +import org.junit.jupiter.api.Test + +class LambdaLengthWarnTest : LintTestBase(::LambdaLengthRule) { + private val ruleId = "$DIKTAT_RULE_SET_ID:lambda-length" + private val rulesConfigList: List = listOf( + RulesConfig( + Warnings.TOO_MANY_LINES_IN_LAMBDA.name, true, + mapOf("maxLambdaLength" to "3")) + ) + + @Test + @Tag(WarningNames.TOO_MANY_LINES_IN_LAMBDA) + fun `less than max`() { + lintMethod( + """ + |fun foo() { + | val x = 10 + | val list = listOf(1, 2, 3, 4, 5) + | .map {element -> element + x} + |} + """.trimMargin(), + rulesConfigList = rulesConfigList + ) + } + + @Test + @Tag(WarningNames.TOO_MANY_LINES_IN_LAMBDA) + fun `nested lambda with implicit parameter`() { + lintMethod( + """ + |fun foo() { + | private val allTestsFromResources: List by lazy { + | val fileUrl: URL? = javaClass.getResource("123") + | val resource = fileUrl + | ?.let { File(it.file) } + | } + |} + """.trimMargin(), + rulesConfigList = rulesConfigList + ) + } + + @Test + @Tag(WarningNames.TOO_MANY_LINES_IN_LAMBDA) + fun `lambda doesn't expect parameters`() { + lintMethod( + """ + |fun foo() { + | private val allTestsFromResources: List by lazy { + | val fileUrl: URL? = javaClass.getResource("123") + | list = listOf(1, 2, 3, 4, 5) + | .removeAt(1) + | } + |} + """.trimMargin(), + rulesConfigList = rulesConfigList + ) + } + + @Test + @Tag(WarningNames.TOO_MANY_LINES_IN_LAMBDA) + fun `less than max without argument`() { + lintMethod( + """ + |fun foo() { + | val x = 10 + | val list = listOf(1, 2, 3, 4, 5) + | .map {it + x} + |} + """.trimMargin(), + rulesConfigList = rulesConfigList + ) + } + + @Test + @Tag(WarningNames.TOO_MANY_LINES_IN_LAMBDA) + fun `more than max with argument`() { + lintMethod( + """ + |fun foo() { + | val calculateX = { x : Int -> + | when(x) { + | in 0..40 -> "Fail" + | in 41..70 -> "Pass" + | in 71..100 -> "Distinction" + | else -> false + | } + | } + |} + """.trimMargin(), + rulesConfigList = rulesConfigList + ) + } + + @Test + @Tag(WarningNames.TOO_MANY_LINES_IN_LAMBDA) + fun `more than maximum without argument`() { + lintMethod( + """ + |fun foo() { + | val list = listOf(1, 2, 3, 4, 5) + | .map { + | val x = 0 + | val y = x + 1 + | val z = y + 1 + | it + z + | + | + | + | + | } + |} + """.trimMargin(), + LintError(3, 13, ruleId, "${Warnings.TOO_MANY_LINES_IN_LAMBDA.warnText()} max length lambda without arguments is 3, but you have 6", false), + rulesConfigList = rulesConfigList + ) + } + + @Test + @Tag(WarningNames.TOO_MANY_LINES_IN_LAMBDA) + fun `two lambda more than maximum without argument`() { + lintMethod( + """ + |fun foo() { + | val list = listOf(1, 2, 3, 4, 5) + | .filter { n -> n % 2 == 1 } + | .map { + | val x = 0 + | val y = x + 1 + | val z = y + 1 + | it + z + | + | + | + | + | } + |} + """.trimMargin(), + LintError(4, 13, ruleId, "${Warnings.TOO_MANY_LINES_IN_LAMBDA.warnText()} max length lambda without arguments is 3, but you have 6", false), + rulesConfigList = rulesConfigList + ) + } + + @Test + @Tag(WarningNames.TOO_MANY_LINES_IN_LAMBDA) + fun `lambda in lambda`() { + lintMethod( + """ + |fun foo() { + | val list = listOf(listOf(1,2,3), listOf(4,5,6)) + | .map {l -> l.map { + | val x = 0 + | val y = x + 1 + | val z = y + 1 + | println(it) + | } + | } + | } + """.trimMargin(), + LintError(3, 25, ruleId, "${Warnings.TOO_MANY_LINES_IN_LAMBDA.warnText()} max length lambda without arguments is 3, but you have 6", false), + rulesConfigList = rulesConfigList + ) + } +} diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/TestUtils.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/TestUtils.kt index 4fbc326d14..053e56d20d 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/TestUtils.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/TestUtils.kt @@ -34,24 +34,24 @@ internal fun List.assertEquals(vararg expectedLintErrors: LintError) Assertions.assertThat(this) .allSatisfy { actual -> val expected = expectedLintErrors[this.indexOf(actual)] - SoftAssertions.assertSoftly { - it + SoftAssertions.assertSoftly { sa -> + sa .assertThat(actual.line) .`as`("Line") .isEqualTo(expected.line) - it + sa .assertThat(actual.col) .`as`("Column") .isEqualTo(expected.col) - it + sa .assertThat(actual.ruleId) .`as`("Rule id") .isEqualTo(expected.ruleId) - it + sa .assertThat(actual.detail) .`as`("Detailed message") .isEqualTo(expected.detail) - it + sa .assertThat(actual.canBeAutoCorrected) .`as`("Can be autocorrected") .isEqualTo(expected.canBeAutoCorrected) diff --git a/info/available-rules.md b/info/available-rules.md index f2ce918049..88375589e2 100644 --- a/info/available-rules.md +++ b/info/available-rules.md @@ -97,6 +97,7 @@ | 5 | 5.2.2 | TOO_MANY_PARAMETERS | Check: if function contains more parameters than allowed | no | maxParameterListSize | | 5 | 5.2.3 | WRONG_OVERLOADING_FUNCTION_ARGUMENTS | Check: function has overloading instead use default arguments | no | no | | 5 | 5.2.4 | RUN_BLOCKING_INSIDE_ASYNC | Check: using runBlocking inside async block code | no | no | - | +| 5 | 5.2.5 | TOO_MANY_LINES_IN_LAMBDA | Check: that the long lambda has parameters | no | maxLambdaLength | | 6 | 6.1.1 | SINGLE_CONSTRUCTOR_SHOULD_BE_PRIMARY | Check: warns if there is only one secondary constructor in a class
Fix: converts it to a primary constructor | yes | no | Support more complicated logic of constructor conversion | | 6 | 6.1.2 | USE_DATA_CLASS | Check: if class can be made as data class | no | no | yes | | 6 | 6.1.3 | EMPTY_PRIMARY_CONSTRUCTOR | Check: if there is empty primary constructor | yes | no | yes | diff --git a/info/guide/guide-TOC.md b/info/guide/guide-TOC.md index 6b693af349..e8e7a8c9a9 100644 --- a/info/guide/guide-TOC.md +++ b/info/guide/guide-TOC.md @@ -88,6 +88,7 @@ I [Preface](#c0) * [5.2.1 The lambda parameter of the function should be placed at the end of the argument list](#r5.2.1) * [5.2.2 Number of function parameters should be limited to five](#r5.2.2) * [5.2.3 Use default values for function arguments instead of overloading them](#r5.2.3) + * [5.2.5 Long lambdas should have explicit parameters](#r5.2.4) [6. Classes, interfaces, and extension functions](#c6) * [6.1 Classes](#c6.1) diff --git a/info/guide/guide-chapter-5.md b/info/guide/guide-chapter-5.md index 6eef6ca3a7..ea27034443 100644 --- a/info/guide/guide-chapter-5.md +++ b/info/guide/guide-chapter-5.md @@ -142,4 +142,7 @@ GlobalScope.async { count++ } } -``` \ No newline at end of file +``` +#### 5.2.5 Long lambdas should have explicit parameters +The lambda without parameters shouldn't be too long. +If a lambda is too long, it can confuse the user. Lambda without parameters should consist of 10 lines (non-empty and non-comment) in total.