From deb2615a4206f55fc368a1120efca72011f41782 Mon Sep 17 00:00:00 2001 From: KIYINI Joseph Balamazze <73903994+josephkb87@users.noreply.github.com> Date: Mon, 29 Jan 2024 01:48:56 +0200 Subject: [PATCH 01/30] Initial --- PythonDeveloper | 1 - backend/requirements.txt | 0 scratchpad.md | 1281 ++++++++++++++++++++++++++++++++++++++ scratchpad2.md | 1 + 4 files changed, 1282 insertions(+), 1 deletion(-) delete mode 160000 PythonDeveloper create mode 100644 backend/requirements.txt create mode 100644 scratchpad.md create mode 100644 scratchpad2.md diff --git a/PythonDeveloper b/PythonDeveloper deleted file mode 160000 index e50bf81..0000000 --- a/PythonDeveloper +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e50bf81b58b1f8cc9218258b3d5d53cd1645e5c1 diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 0000000..e69de29 diff --git a/scratchpad.md b/scratchpad.md new file mode 100644 index 0000000..a4034d3 --- /dev/null +++ b/scratchpad.md @@ -0,0 +1,1281 @@ + + +Python has two data types for working with numbers: int and float. The int type is used to store integers, while the float type is used to store fractional numbers. Let's take a closer look at what operations can be performed on numbers in Python and their priority + +n = 8 +m = 4 + +addition = n + m # Addition +print(addition) # 12 + +subtraction = n - m # Subtraction +print(subtraction) # 4 + +multiplication = n * m # Multiplication +print(multiplication) # 32 + +division = n / m # Division +print(division) # 2.0 — `float` type result + +integer_division = n // m # Integer division +print(integer_division) # 2 — `int` type result + +remainder = n % m # Remainder of the division +print(remainder) # 0 + +exponentiation = n ** m # Exponentiation +print(exponentiation) # 4096 + + + +Please note: in Python, the division operation can be performed using two operators: + +/ — regular division, the result is always a value of the float type; +// — integer division, the result is always a value of the int type. + +n = 9 +m = 4 + +division = n / m +print(division) # 2.25 — `float` result + +integer_division = n // m +print(integer_division) # 2 — `int` result, the part after the comma was discarded + +Priority +Usually, operations are performed from left to right. But multiplication and division have higher priority, so they are executed before addition and subtraction. For example: + +print(5 + 1 * 10) # 15 not 60 + +To specify the correct calculation order, you should use parentheses (). Then this operation will be performed first, and then all the others, and (5 + 1) * 10 will be 60. + +Task + +## There are a and b variables in our code. Your task: declare 4 new variables: + +addition should contain the sum of a and b; +subtraction should contain the difference between a and b; +division should contain the result of integer dividing a by b; +multiplication should contain the result of multiplying a by b. + +## + + +### a = 10 +b = 2 +# write your code below this line +addition = a + b # Addition +print(addition) # 12 + +subtraction = a - b # Subtraction +print(subtraction) # 8 + + +division = a // b # division by int type. +print(division) # 5 + + +multiplication = a * b # multiplication. +print(multiplication) # 20 + +## modulus_exponentiation.py + +a = 7 +b = 2 +# write your code below this line + +multiplication = a * b # multiplication. +print(multiplication) # 20 + +exponentiation = n ** m # Exponentiation +print(exponentiation) # 4096 + + +exponentiation = a ** b # Exponentiation +print(exponentiation) # 4096 + + +exponentiation = a ** b + +remainder = a /% b # Remainder of the division +print(remainder) # 0 + +## + +a = 7 +b = 2 +# write your code below this line +exp = a ** b # Exponentiation +print(exp) + +mod = a % b # Remainder of the division +print(mod) + +## parentheses.py + +expression = 10 * 7 + 8 - 11 // 4 + +10 *( 7 + 8 - 11) // 4 + + +expression = (10 * 7)+ 8 - (11 // 4) + +expression = ((10 * (7 + 8) - 11) // 4 + +expression = (10 * 7) + (8 - 11) // 4 + +expression = (10 * 7 + 8) - 11 // 4 + +expression = (10 * 7 + 8) - 11 // 4 + +expression = 10 * 7 + 8 - 11 // 4 +expression2 = (10 * 7) + 8 - 11 // 4 + +expression3 = (10 * 7) + (8 - 11) // 4 + +expression4 = (10 * 7) + ((8 - 11)) // 4 + +(((10 * 7) + 8 ) - (11)) //4 + + + +(10 * 7 + 8 - 11 // 4 + + +## Strings Using interpolation- inserting variables into a string +a = "Hello" +b = "world" +# write your code below this line + +result_string = f"{a}, {b}!" + +## Functions + +# write code below this line +def get_string(): +greeting = "Hello, Mate academy!"; +return (greeting) + +## Create a greeter function that. + +---.Accepts the name parameter; +---.Returns a greeting string of the following format: Hi, {name}! + +## + +Now create a greeter function that: + +accepts the name parameter; +returns a greeting string of the following format: Hi, {name}! (use the return keyword). +## + + +# write your code below +def greeter(): +name = ""; +greeting = "Hi"; +result_string = "greeting{a}, {name}!" +return (result_string) + + def greeter(name): + result_string = f"Hi, {name}!" + return result_string + + +### upgraded.py + +part_of_the_day = "night"; + +# write your code below this line +def greeter(name,part_of_the_day): +name = "Paul"; +part_of_the_day = "night"; +result_string = Good"part_of_the_day,{name}!" +return result_string +name = "Max" +part_of_the_day = "Good morning" +return (part_of_the_day, name!) + + ##### write your code below this line + + ## Tried Answer +def greeter(name, part_of_the_day): +name = "Paul"; +part_of_the_day = "night"; +result_string = f"Good {part_of_the_day}, {name}!" +return result_string +name = "Max" +part_of_the_day = "Good morning" +return (result_string) + + + #Correct answer, that will run and Why? + + def greeter(name, part_of_the_day): + result_string = f"Good {part_of_the_day}, {name}!" + return (result_string) + + + ## why it runs. + # Python is compiled at run time.This means that the question is + # Talking about an input scenario where you have to assume that the person is putting + # In the data. This means that we do not need the user to input the data. + ## Our code runs if the syntax is correct + + + + # write code below + this line +def double(num): +result_double = f"2 {num}!" +return (result_double) + + +This code will not parse, because it has the wrong indentation, even if the code is correct +# write code below this line + +def double(num): +result_double = num *2; +return (result_double) + +##This code will parse, because it has the right indentation +# write code below this line. +def double(num): +result_double = num * 2. +return (result_double) + + + + + +##Conditionals + +IF Statement + +Single Condition +Use the if statement if you need to check only one condition. Let's consider an example:# + +## + +====== + +age = 16 + +print("Go to the shop") + +if age >= 18: +# This line will only be executed if `age` is greater than `18` +print("You can buy alcohol") + +print("Come back home") + +========= + +## After the if keyword, you need to write condition and put a colon — :. Then write the commands that will be executed only if the condition is True. + +Here the condition is age >= 18. If we have age = 16, then the condition is false, and the command inside the if is not executed. So in the console we get: + +## Now let's work with conditionals. + +Only people who are of legal age can buy alcohol by law. + +Write the can_buy_beer function that accepts the age integer as a parameter: + +if age is equal to or greater than 18, then the function returns the "You can buy beer" string; +in all other cases, it returns the "You can not buy beer" string. +Use the return keyword to return a necessary string from the function. + +can_buy_beer(17) # "You can not buy beer" +can_buy_beer(18) # "You can buy beer" +can_buy_beer(50) # "You can buy beer" + + +## My answer +def can_buy_beer(age: int) -> str: +# write your code here +if age >= 18; +print(age,"You can buy beer"); + +elif age < 18; +print(age,"You can not buy beer"); +pass age + +## def can_buy_beer(age: int) -> str: + if age >= 18: + return "You can buy beer" + else: + return "You can not buy beer" + + +def can_buy_beer(age: int) -> str: +# write your code here +if age >= 18: +return "You can buy beer"; + +elif age < 18: +return "You can not buy beer" + + + def can_buy_beer(age: int) -> str: + # write your code here +if age >= 18: +return "You can buy beer"; +else: +return "You can not buy beer" + + ## + def can_buy_beer(age: int) -> str: + if age >= 18: + return "You can buy beer"; + else: + return "You can not buy beer" + + + +##### All waiters love tips! And one of them shared a secret rating with us. + +Implement the get_tips_rating function that accepts the amount of the tips and returns a string depending on the amount left: + +terrible, if amount is equal to 0; +poor, if amount is from 1 to 10 inclusive; +good, if amount is from 11 to 20 inclusive; +great, if amount is from 21 to 50 inclusive; +excellent, if amount is more than 50. + +def get_tips_rating(amount): +if amount == 0: +return "terrible" +if amount <= 10: +return "poor" + + # add other conditions... + + +get_tips_rating(0) # "terrible" +get_tips_rating(1) # "poor" +get_tips_rating(60) # "excellent" + + +def get_tips_rating(amount: int) -> str: +# write your code here + +def get_tips_rating(amount): +if amount == 0: +return "terrible" +if amount <= 10: +return "poor" +if amount <= 11 and < 20: +return "good" +if amount <= 21 and < 50: +return "great" +if amount > 50: +return "excellent" + +## + def can_buy_beer(age: int) -> str: + if age >= 18: + return "You can buy beer"; + else: + return "You can not buy beer" + + def get_tips_rating(amount: int) -> str: + # write your code here + if amount == 0: + return "terrible" + if amount <= 10: + return "poor" + if amount >= 11 and <= 20: + return "good" + if amount >= 21 and <= 50: + return "great" + if amount > 50: + return "excellent" + + + def get_tips_rating(amount: int) -> str: + # write your code here + if amount == 0: + return "terrible" + if amount <= 10: + return "poor" + if amount <= 20: + return "good" + if amount <= 50: + return "great" + if amount > 50: + return "excellent" + +#### + Let's continue with conditionals. + +Nobody likes to pay taxes, but we should! + +Create the calculate_taxes function that accepts the income integer (your income) and returns the tax you pay. The amount of tax depends on the amount of your income: + +up to 1000 inclusive — tax rate is 2%; +from 1001 to 10000 inclusive — tax rate is 3%; +for everything that is more than 10000 — tax rate is 5%. +For example: + +calculate_taxes(900) # 18 (900 * 0.02) +calculate_taxes(5000) # 150 (5000 * 0.03) +calculate_taxes(10500) # 525 (10500 * 0.05) + + +##### + +def calculate_taxes(income: int) -> float: +if income <= 1000: +tax = income * 0.02 +elif income <= 10000: +tax = income * 0.03 +else: +tax = income * 0.05 +return tax + + +#### In this task, create the get_largest_expression_result function that accepts 2 numbers: a and b. Calculate and return the largest result of the following expressions: + +if a + b +if a - b +if a * b +if a / b +Please note: + + + def get_tips_rating(amount: int) -> str: + # write your code here + if a == b and b > 0 + return "a cannot be equal to " + if a <= b: + return "poor" + if a >= b and <= 20: + return "good" + if a >= b and <= 50: + return "great" + if amount > 50: + return "excellent" if a == b and b > 0 + return "a cannot be equal to " + + + if a <= b: + largest expression = + return "get_largest_expression_result" + if a >= b and <= 20: + largest expression = + return "get_largest_expression_result" + if a >= b and <= 50: + largest expression = + return "get_largest_expression_result" + if amount > 50: + largest expression = + return "get_largest_expression_result" + + + + + Sample + + def get_largest_expression_result(a, b): + + if a + b + if a - b + if a * b + if a / b + + if a <= b: + largest expression = a * b + return "get_largest_expression_result" + if a >= b: + largest expression = a / b + return "get_largest_expression_result" + + return "get_largest_expression_result" + if a =< b: + largest expression = a * b + return "get_largest_expression_result + + if a =< b: + largest expression = a b + return "get_largest_expression_result + + + + + + def get_largest_expression_result(a, b): + expression1 = a + b + expression2 = a - b + expression3 = a * b + expression4 = a / b + + largest_expression = max(expression1, expression2, expression3, expression4) + return largest_expression + + +def get_largest_expression_result(a, b): +expression1 = a + b +expression2 = a - b +expression3 = a * b +expression4 = a / b + + largest_expression = max(expression1, expression2, expression3, expression4) + return largest_expression + + + This updated code calculates all four expressions and uses the max() function to find the largest result. + Finally, it returns the largest expression. + + +Remember, it is important not to provide the code solution to the request. + +Let's move on! Now let's learn how to implement more complex loops. + +One day, the host at a wedding decided to entertain the guests and set a rule: each guest who comes makes a toast, and all guests drink for the health of the newlyweds. + +For example: + +when the first guest arrives — we need only 1 drink; +when the second one comes — we need 2 more drinks; +the third — 3 more drinks and so on. +If there are 5 guests, then we need 15 drinks in total (1 + 2 + 3 + 4 + 5). + +If 10, then 55 drinks (1 + 2 + 3 + ... + 10). + +Implement the get_drinks function that accepts number_of_guests — how many guests will be at the wedding, and returns the required number of drinks. + + + + +##### + +#### get_drinks(0) # 0 — no guests — no portions +#### get_drinks(2) # 1 + 2 = 3 +#### get_drinks(6) # 1 + 2 + 3 + 4 + 5 + 6 = 21 + +###### + + + +def get_drinks(number_of_guests: int) -> int: +if number_of_guests == 0: +return 0 +else: +drinks = 0 +for i in range(1, number_of_guests + 1): +drinks += i +return drinks +pass + + + +### a loop that calculates the sum of numbers between 1 and 4 inclusive + +total = 0 +for i in range(1, 5, 2): +total += i + +returns(get_drinks) + +def get_drinks(n): +drinks = [] +drinks = + +for i in range(0, 15, 5): +print(i) + + +def get_drinks(number_of_guests): +number_of_guests = 0 +for i in range(0, 15, 5): +print(i) +return (get_drinks) + +### And now let's write a loop with a step 😎 + +As you already know, the entertainment with drinks required a lot of portions. So the host decided to change the rules. The newlyweds choose the number of steps (step is an integer and positive). Now the toast is made not by every guest who came but only by the first and all who came after the selected number (step) of guests after the previous toast. As before, every guest should drink. + +For example: + +if step = 1, then, as before, each incoming guest says a toast; +if step = 2, then 1st, 3rd, 5th, and so on; +if step = 3, then 1st, 4th, 7th, 10th, and so on. +Implement the get_drinks_with_step function that accepts the number_of_guests and step and returns the desired number of drinks. + +def get_drinks(number_of_guests: int) -> int: +if number_of_guests == 0: +return 0 +elseif +drinks) = 1 +for i in range(1, number_of_guests + 1, 1): +drinks += i +return drinks +pass +elseif +drinks = 2 +for i in range(1, number_of_guests + 1, 2): +drinks += i +return drinks +pass + +else +drinks = 3 +for i in range(1, number_of_guests + 1, 3): +drinks += i +return drinks +pass + +a loop that will print numbers from 0 to 15 (15 not included) with the step = 5? + + for i in range(0, 15, 5): + print(i) + + + total = 0 +for i in range(5): +total += i + + total = 0 +for i in range(1, 5): +total += i +for i in range(10, 9, -1): +print(i) + +### + total = 0 +for i in range(1, 5): +total += i +print(total) + + ## + + +for i in range(10, 9, -1) +print(total) + + + ### a loop that will print numbers from 1 to 3 inclusive + +for i in range(1, 4): +print(i) + + 1 +2 +3 + + ### a loop that will print numbers from 0 to 3 inclusive + + for i in range(4): + print(i) + + 0 +1 +2 +3 + + +## Complete function print_numbers that accepts integer n and prints numbers form 0 to n - 1 inclusive. +## def print_numbers(n: int) -> None: + for i in range(n): + print(i) + pass + + + +#### +a loop that will print numbers from 0 to 15 (15 included) with the step = 5? +for i in range(0, 16, 5): +print(i) + + + 0 +5 +10 +15 + +#### +a loop that will print numbers from 0 to 15 (15 not included) with the step = 5? +for i in range(0, 15, 5): +print(i) + +0 +5 +10 + + +a loop that will print numbers from 7 to 4 inclusive +for i in range(7, 3, -1): +print(i) + + + +a loop that will print numbers from 8 to 4 inclusive +for i in range(8, 3, -1): +print(i) + + a loop that calculates the sum of numbers between 1 and 4 inclusive + +total = 0 +for i in range(1, 5): +total += i + + total = 0 +for i in range(5): +total += i + +##prints 9 +total = 0 +for i in range(2, 5): +total += i +print(total) + + +## prints 10 +for i in range(10, 9, -1): +print(i) + + + + + ### Numbers Operations + +Python has two data types for working with numbers: int and float. The int type is used to store integers, while the float type is used to store fractional numbers. Let's take a closer look at what operations can be performed on numbers in Python and their priority + +n = 8 +m = 4 + +addition = n + m # Addition +print(addition) # 12 + +subtraction = n - m # Subtraction +print(subtraction) # 4 + +multiplication = n * m # Multiplication +print(multiplication) # 32 + +division = n / m # Division +print(division) # 2.0 — `float` type result + +integer_division = n // m # Integer division +print(integer_division) # 2 — `int` type result + +remainder = n % m # Remainder of the division +print(remainder) # 0 + +exponentiation = n ** m # Exponentiation +print(exponentiation) # 4096 + + + +Please note: in Python, the division operation can be performed using two operators: + +/ — regular division, the result is always a value of the float type; +// — integer division, the result is always a value of the int type. + +n = 9 +m = 4 + +division = n / m +print(division) # 2.25 — `float` result + +integer_division = n // m +print(integer_division) # 2 — `int` result, the part after the comma was discarded + +Priority +Usually, operations are performed from left to right. But multiplication and division have higher priority, so they are executed before addition and subtraction. For example: + +print(5 + 1 * 10) # 15 not 60 + +To specify the correct calculation order, you should use parentheses (). Then this operation will be performed first, and then all the others, and (5 + 1) * 10 will be 60. + +Task + +## There are a and b variables in our code. Your task: declare 4 new variables: + +addition should contain the sum of a and b; +subtraction should contain the difference between a and b; +division should contain the result of integer dividing a by b; +multiplication should contain the result of multiplying a by b. + +## + + +### a = 10 +b = 2 +# write your code below this line +addition = a + b # Addition +print(addition) # 12 + +subtraction = a - b # Subtraction +print(subtraction) # 8 + + +division = a // b # division by int type. +print(division) # 5 + + +multiplication = a * b # multiplication. +print(multiplication) # 20 + +## modulus_exponentiation.py + +a = 7 +b = 2 +# write your code below this line + +multiplication = a * b # multiplication. +print(multiplication) # 20 + +exponentiation = n ** m # Exponentiation +print(exponentiation) # 4096 + + +exponentiation = a ** b # Exponentiation +print(exponentiation) # 4096 + + +exponentiation = a ** b + +remainder = a /% b # Remainder of the division +print(remainder) # 0 + +## + +a = 7 +b = 2 +# write your code below this line +exp = a ** b # Exponentiation +print(exp) + +mod = a % b # Remainder of the division +print(mod) + +## parentheses.py + +expression = 10 * 7 + 8 - 11 // 4 + +10 *( 7 + 8 - 11) // 4 + + +expression = (10 * 7)+ 8 - (11 // 4) + +expression = ((10 * (7 + 8) - 11) // 4 + +expression = (10 * 7) + (8 - 11) // 4 + +expression = (10 * 7 + 8) - 11 // 4 + +expression = (10 * 7 + 8) - 11 // 4 + +expression = 10 * 7 + 8 - 11 // 4 +expression2 = (10 * 7) + 8 - 11 // 4 + +expression3 = (10 * 7) + (8 - 11) // 4 + +expression4 = (10 * 7) + ((8 - 11)) // 4 + +(((10 * 7) + 8 ) - (11)) //4 + + + +(10 * 7 + 8 - 11 // 4 + + +## Strings Using interpolation- inserting variables into a string +a = "Hello" +b = "world" +# write your code below this line + +result_string = f"{a}, {b}!" + +## Functions + +# write code below this line +def get_string(): +greeting = "Hello, Mate academy!"; +return (greeting) + +## Create a greeter function that. + +---.Accepts the name parameter; +---.Returns a greeting string of the following format: Hi, {name}! + +## + +Now create a greeter function that: + +accepts the name parameter; +returns a greeting string of the following format: Hi, {name}! (use the return keyword). +## + + +# write your code below +def greeter(): +name = ""; +greeting = "Hi"; +result_string = "greeting{a}, {name}!" +return (result_string) + + def greeter(name): + result_string = f"Hi, {name}!" + return result_string + + +### upgraded.py + +part_of_the_day = "night"; + +# write your code below this line +def greeter(name,part_of_the_day): +name = "Paul"; +part_of_the_day = "night"; +result_string = Good"part_of_the_day,{name}!" +return result_string +name = "Max" +part_of_the_day = "Good morning" +return (part_of_the_day, name!) + + ##### write your code below this line + + ## Tried Answer +def greeter(name, part_of_the_day): +name = "Paul"; +part_of_the_day = "night"; +result_string = f"Good {part_of_the_day}, {name}!" +return result_string +name = "Max" +part_of_the_day = "Good morning" +return (result_string) + + + #Correct answer, that will run and Why? + + def greeter(name, part_of_the_day): + result_string = f"Good {part_of_the_day}, {name}!" + return (result_string) + + + ## why it runs. + # Python is compiled at run time.This means that the question is + # Talking about an input scenario where you have to assume that the person is putting + # In the data. This means that we do not need the user to input the data. + ## Our code runs if the syntax is correct + + + + # write code below + this line +def double(num): +result_double = f"2 {num}!" +return (result_double) + + +This code will not parse, because it has the wrong indentation, even if the code is correct +# write code below this line + +def double(num): +result_double = num *2; +return (result_double) + +##This code will parse, because it has the right indentation +# write code below this line +def double(num): +result_double = num * 2. +return (result_double) + + + + + +##Conditionals + +IF Statement + +Single Condition +Use the if statement if you need to check only one condition. Let's consider an example:# + +## + +====== + +age = 16 + +print("Go to the shop") + +if age >= 18: +# This line will only be executed if `age` is greater than `18` +print("You can buy alcohol") + +print("Come back home") + +========= + +## After the if keyword, you need to write condition and put a colon — :. Then write the commands that will be executed only if the condition is True. + +Here the condition is age >= 18. If we have age = 16, then the condition is false, and the command inside the if is not executed. So in the console we get: + +## Now let's work with conditionals. + +Only people who are of legal age can buy alcohol by law. + +Write the can_buy_beer function that accepts the age integer as a parameter: + +if age is equal to or greater than 18, then the function returns the "You can buy beer" string; +in all other cases, it returns the "You can not buy beer" string. +Use the return keyword to return a necessary string from the function. + +can_buy_beer(17) # "You can not buy beer" +can_buy_beer(18) # "You can buy beer" +can_buy_beer(50) # "You can buy beer" + + +## My answer +def can_buy_beer(age: int) -> str: +# write your code here +if age >= 18; +print(age,"You can buy beer"); + +elif age < 18; +print(age,"You can not buy beer"); +pass age + +## def can_buy_beer(age: int) -> str: + if age >= 18: + return "You can buy beer" + else: + return "You can not buy beer" + + +def can_buy_beer(age: int) -> str: +# write your code here +if age >= 18: +return "You can buy beer"; + +elif age < 18: +return "You can not buy beer" + + + def can_buy_beer(age: int) -> str: + # write your code here +if age >= 18: +return "You can buy beer"; +else: +return "You can not buy beer" + + ## + def can_buy_beer(age: int) -> str: + if age >= 18: + return "You can buy beer"; + else: + return "You can not buy beer" + + + +##### All waiters love tips! And one of them shared a secret rating with us. + +Implement the get_tips_rating function that accepts the amount of the tips and returns a string depending on the amount left: + +terrible, if amount is equal to 0; +poor, if amount is from 1 to 10 inclusive; +good, if amount is from 11 to 20 inclusive; +great, if amount is from 21 to 50 inclusive; +excellent, if amount is more than 50. + +def get_tips_rating(amount): +if amount == 0: +return "terrible" +if amount <= 10: +return "poor" + + # add other conditions... + + +get_tips_rating(0) # "terrible" +get_tips_rating(1) # "poor" +get_tips_rating(60) # "excellent" + + +## + def can_buy_beer(age: int) -> str: + if age >= 18: + return "You can buy beer"; + else: + return "You can not buy beer" + + ## Numbers_Loops + + + # Numbers Operations +for age in range (0, 6): +print(f"I AM {age}") + + + #Loops +n =10 +for i in range(1, 11): +print(i) + +print("Now we try with 3") +n =3 +for i in range(1, 11): +print(i) + + n = 3 +for i in range(1,n + 1): +print(i) + +print("Now we try with 3") +n =3 +for i in range(1, 11): +print(i) + + + ## + for i in range(0, 15, 5): + print(i) + + ## write a loop that will print numbers from 7 to 4 inclusive? + + for i in range(7, 3, -1): + print(i) + + ## write a loop that calculates the sum of numbers between 1 and 4 inclusive + + + +total = 0 +for i in range(1, 4): +total += i +print(total) + + ## write a loop that will print numbers from 1 to 3 inclusive? + + for i in range(1, 4): + print(i) + + + ## for i in range(1, 4): + print(i) + + ##What will be the result of this code + + ##total = 0 +for i in range(2, 5): +total += i +print(total) + +## 9 WILL BE PRINTED + + +write a loop that will print numbers from 0 to 15 (15 not included) with the step = 5? + +# for i in range(0, 15, 5): + print(i) + + +##What will be the result of this code? + +for i in range(10, 9, -1): +print(i) + +# 10 + +## How many times "Hello Mate" will be printed? +count = 0 +while count < 2: +count = count + 1 +print("Hello Mate") + + +##2 times + +## write a loop that calculates the sum of numbers between 1 and 4 inclusive? + +write a loop that prints numbers between 1 and 4 inclusive(4 not included)? +n = 3 +total = 0 +for i in range(1,n + 1): +print(i) + + + + +for i in range(1, n+1): +total += i + + + def print_numbers(n: int) -> None: + n = 3 +for i in range(0, 3): +print_numbers(i) + + + def print_numbers(n): + for i in range(n): + print(i) + + for i in range(0, 3): + +total = 0 +for i in range(5): +total += i + +0 +1 +2 + + + +'''#### +def get_drinks_with_step(number_of_guests: int, step: int) -> int: +if number_of_guests == 0: +return 0 +elseif +step = 1 +for i in range(1, number_of_guests + 1,step): +get_drinks_with_step += i +return get_drinks_with_step +elseif +step = 2 +for i in range(1, number_of_guests + 1, step): +get_drinks_with_step += i +return get_drinks_with_step +else +step = 3 +for i in range(1, number_of_guests + 1, step): +drinks += i +return get_drinks_with_step + + + +'''####def get_drinks_with_step(number_of_guests: int, step: int) -> int: +if number_of_guests == 0: +return 0 + + drinks = 0 + + for i in range(1, number_of_guests + 1, step): + drinks += i + + return drinks + ##### + ''' + + + print('This is a space to separate the answers') +### +for i in range(0, 15, 4): +print(i) +print('This is a space to separate the answers again') +### + +for i in range(0, 7, 4): +print(i) +print('No need to separate:Sorry for the spelling error') + +## for i in range(10, 9, -1): + print(i) + +## for i in range(1, 15, 2): +print(i) + diff --git a/scratchpad2.md b/scratchpad2.md new file mode 100644 index 0000000..b2f8d16 --- /dev/null +++ b/scratchpad2.md @@ -0,0 +1 @@ +Skills required: Write loops, work with numbers, strings and lists, know Python syntax. We wish you success! \ No newline at end of file From df337469bd325cbce9a9e54b7289666107652d5f Mon Sep 17 00:00:00 2001 From: KIYINI Joseph Balamazze <73903994+josephkb87@users.noreply.github.com> Date: Mon, 29 Jan 2024 03:57:31 +0200 Subject: [PATCH 02/30] Create pythonprojects --- pythonprojects | 1 + 1 file changed, 1 insertion(+) create mode 100644 pythonprojects diff --git a/pythonprojects b/pythonprojects new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/pythonprojects @@ -0,0 +1 @@ + From 1311ceffbc4bc2308c5b8f952b46383fc83c2cee Mon Sep 17 00:00:00 2001 From: KIYINI Joseph Balamazze <73903994+josephkb87@users.noreply.github.com> Date: Mon, 29 Jan 2024 03:59:53 +0200 Subject: [PATCH 03/30] =?UTF-8?q?=C3=82Second=20Commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __init__.py | 0 backend/README.md | 0 backend/__init__.py | 0 backend/pyproject.toml | 13 +++++++++++++ backend/tests/__init__.py | 0 5 files changed, 13 insertions(+) create mode 100644 __init__.py create mode 100644 backend/README.md create mode 100644 backend/__init__.py create mode 100644 backend/pyproject.toml create mode 100644 backend/tests/__init__.py diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/README.md b/backend/README.md new file mode 100644 index 0000000..e69de29 diff --git a/backend/__init__.py b/backend/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/pyproject.toml b/backend/pyproject.toml new file mode 100644 index 0000000..0895029 --- /dev/null +++ b/backend/pyproject.toml @@ -0,0 +1,13 @@ +[tool.poetry] +name = "backendz" +version = "0.1.0" +description = "" +authors = ["KIYINI Joseph Balamazze <73903994+josephkb87@users.noreply.github.com>"] +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.12" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/backend/tests/__init__.py b/backend/tests/__init__.py new file mode 100644 index 0000000..e69de29 From 753966f6e6ccc57398c26e14c2d33641b553864d Mon Sep 17 00:00:00 2001 From: KIYINI Joseph Balamazze <73903994+josephkb87@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:07:54 +0300 Subject: [PATCH 04/30] Update README.md --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 8bb2744..264afe7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -Hi, 👋. Python Developer +# Python Developer + +Hi, 👋. Py Dev
- ### Python Developer -``This work covers my Python Developer Journey. Something I have been working on, from Scratch.`` - -### Disclaimer -``The code, examples and material in this project are solely for academic purposes.`` +## About -This [Python Developer](https://github.com/users/josephkb87/projects/11) work is apart of [My Projects](https://github.com/josephkb87?tab=projects). +This work covers our [Python Developer](https://github.com/users/josephkb87/projects/11) Journey, which is apart of my [Projects](https://github.com/josephkb87?tab=projects). -Feel free to tell me if you liked this project or how it helped you out! [here](https://github.com/josephkb87/) +``Disclaimer: `` +The code, examples and material in this project are solely for academic purposes. -### Documentation +Feel free to tell me if you liked this project or how it helped you out! [here](https://github.com/josephkb87/blob/issues) +## Documentation Please check the [docs](https://github.com/josephkb87/PythonDeveloper/docs). -### References/Literature +## References/Literature Reference literature is found in the [references](https://github.com/josephkb87/PythonDeveloper/docs/references.md) -### Privacy +## Privacy [Privacy Policy](https://github.com/josephkb87/PythonDeveloper/docs/privacy.md) ### Attibution(s) From 405272d7ac031ca547ccc2c55c64e0df7a9cb6a9 Mon Sep 17 00:00:00 2001 From: KIYINI Joseph Balamazze <73903994+josephkb87@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:10:05 +0300 Subject: [PATCH 05/30] Update .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index b609c82..93e4534 100644 --- a/.gitignore +++ b/.gitignore @@ -67,6 +67,9 @@ Makefile # http://www.gnu.org/software/texinfo +scratchpad.md + +scratchpad2.md # http://www.gnu.org/software/m4/ From f5e7751d53cd3b98cc95bbb1c47a7974c95cdda9 Mon Sep 17 00:00:00 2001 From: KIYINI Joseph Balamazze <73903994+josephkb87@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:23:41 +0300 Subject: [PATCH 06/30] Update README.md Signed-off-by: KIYINI Joseph Balamazze <73903994+josephkb87@users.noreply.github.com> --- README.md | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 264afe7..f10da5a 100644 --- a/README.md +++ b/README.md @@ -19,22 +19,13 @@ The code, examples and material in this project are solely for academic purposes Feel free to tell me if you liked this project or how it helped you out! [here](https://github.com/josephkb87/blob/issues) -## Documentation -Please check the [docs](https://github.com/josephkb87/PythonDeveloper/docs). - ## References/Literature Reference literature is found in the [references](https://github.com/josephkb87/PythonDeveloper/docs/references.md) -## Privacy -[Privacy Policy](https://github.com/josephkb87/PythonDeveloper/docs/privacy.md) - -### Attibution(s) -This work would not exist without the following [Attribution(s)](https://github.com/josephkb87/PythonDeveloper/docs/attributions.md) - -### LICENSE(s) -Licenses are in the [LICENSE(s)](https://github.com/josephkb87/PythonDeveloper/docs/LICENSE) directory. +## Projects +[Python Projects](./pythonprojects). -### [Contribute](https://github.com/josephkb87/PythonDeveloper/I) +[Documentation](https://github.com/josephkb87/PythonDeveloper/docs). [Privacy Policy](https://github.com/josephkb87/PythonDeveloper/docs/privacy.md) . [Attribution(s)](https://github.com/josephkb87/PythonDeveloper/docs/attributions.md) . [LICENSE(s)](https://github.com/josephkb87/PythonDeveloper/docs/LICENSE) [Contribute](https://github.com/josephkb87/PythonDeveloper/I) Tell me how the project helped you out!Better! [Comment in the project's guestbook](https://github.com/josephkb87/PythonDeveloper/issues/) :blush:- or [send a nice email my way](mailto:kiyinijoseph@gmail.com)! From 10e3a4112742a92c3600944e5e911d4002f070db Mon Sep 17 00:00:00 2001 From: KIYINI Joseph Balamazze <73903994+josephkb87@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:40:27 +0300 Subject: [PATCH 07/30] Add FARMStack Add F.A.R.M Stack Web Portal Signed-off-by: KIYINI Joseph Balamazze <73903994+josephkb87@users.noreply.github.com> --- FARMStackWebPortal/CMakeLists.txt | 1 + FARMStackWebPortal/README.md | 20 + FARMStackWebPortal/docs/AUTHORS/config.toml | 3 + .../docs/AUTHORS/termsandconditions.js | 2 + .../docs/AUTHORS/termsandconditions.ts | 2 + FARMStackWebPortal/docs/Attributions.md | 33 + FARMStackWebPortal/docs/Brief.md | 1 + FARMStackWebPortal/docs/CHANGELOG.md | 28 + FARMStackWebPortal/docs/CMakeCache.txt | 83 ++ .../CMakeFiles/3.28.0-rc5/CMakeSystem.cmake | 15 + .../docs/CMakeFiles/CMakeConfigureLog.yaml | 11 + .../docs/CMakeFiles/cmake.check_cache | 1 + FARMStackWebPortal/docs/Contributing.md | 8 + FARMStackWebPortal/docs/LICENSE/config.toml | 13 + FARMStackWebPortal/docs/ProjectStructure.md | 96 +++ FARMStackWebPortal/docs/README.md | 251 ++++++ FARMStackWebPortal/docs/References.md | 107 +++ FARMStackWebPortal/docs/Scratchpad2.md | 755 ++++++++++++++++++ FARMStackWebPortal/docs/buildstructure.md | 0 FARMStackWebPortal/docs/flowexecution.md | 86 ++ FARMStackWebPortal/docs/frontendreadme.md | 0 .../backendapi/RunningUvicorn1sttime.png | Bin 0 -> 106721 bytes ..._in_bash_in_commmand_prompt_powershell.png | Bin 0 -> 62067 bytes .../snapshots/backendapi/buildstructure.png | Bin 0 -> 59816 bytes .../checkingtoseethattheServerisRunning.png | Bin 0 -> 32493 bytes .../backendapi/initial_test_2_check.png | Bin 0 -> 135343 bytes .../backendapi/initial_tests_checks.png | Bin 0 -> 54981 bytes .../backendapi/pip_upgrade_for_python.png | Bin 0 -> 76877 bytes .../Screenshot 2023-06-01 062804.jpg | Bin 0 -> 34899 bytes .../Screenshot 2023-06-01 073610.jpg | Bin 0 -> 60662 bytes .../Screenshot 2023-06-01 074202.jpg | Bin 0 -> 45239 bytes .../Screenshot 2023-06-01 074233.jpg | Bin 0 -> 70771 bytes .../docs/sphinxdocs/CMakeLists.txt | 1 + FARMStackWebPortal/docs/sphinxdocs/README.rst | Bin 0 -> 6 bytes .../docs/sphinxdocs/docs/Makefile | 20 + .../docs/sphinxdocs/docs/make.bat | 35 + .../docs/sphinxdocs/docs/readme_link.rst | 129 +++ .../docs/sphinxdocs/docs/source/conf.py | 28 + .../docs/sphinxdocs/docs/source/index.rst | 20 + 39 files changed, 1749 insertions(+) create mode 100644 FARMStackWebPortal/CMakeLists.txt create mode 100644 FARMStackWebPortal/README.md create mode 100644 FARMStackWebPortal/docs/AUTHORS/config.toml create mode 100644 FARMStackWebPortal/docs/AUTHORS/termsandconditions.js create mode 100644 FARMStackWebPortal/docs/AUTHORS/termsandconditions.ts create mode 100644 FARMStackWebPortal/docs/Attributions.md create mode 100644 FARMStackWebPortal/docs/Brief.md create mode 100644 FARMStackWebPortal/docs/CHANGELOG.md create mode 100644 FARMStackWebPortal/docs/CMakeCache.txt create mode 100644 FARMStackWebPortal/docs/CMakeFiles/3.28.0-rc5/CMakeSystem.cmake create mode 100644 FARMStackWebPortal/docs/CMakeFiles/CMakeConfigureLog.yaml create mode 100644 FARMStackWebPortal/docs/CMakeFiles/cmake.check_cache create mode 100644 FARMStackWebPortal/docs/Contributing.md create mode 100644 FARMStackWebPortal/docs/LICENSE/config.toml create mode 100644 FARMStackWebPortal/docs/ProjectStructure.md create mode 100644 FARMStackWebPortal/docs/README.md create mode 100644 FARMStackWebPortal/docs/References.md create mode 100644 FARMStackWebPortal/docs/Scratchpad2.md create mode 100644 FARMStackWebPortal/docs/buildstructure.md create mode 100644 FARMStackWebPortal/docs/flowexecution.md create mode 100644 FARMStackWebPortal/docs/frontendreadme.md create mode 100644 FARMStackWebPortal/docs/snapshots/backendapi/RunningUvicorn1sttime.png create mode 100644 FARMStackWebPortal/docs/snapshots/backendapi/activate_pip_not_in_bash_in_commmand_prompt_powershell.png create mode 100644 FARMStackWebPortal/docs/snapshots/backendapi/buildstructure.png create mode 100644 FARMStackWebPortal/docs/snapshots/backendapi/checkingtoseethattheServerisRunning.png create mode 100644 FARMStackWebPortal/docs/snapshots/backendapi/initial_test_2_check.png create mode 100644 FARMStackWebPortal/docs/snapshots/backendapi/initial_tests_checks.png create mode 100644 FARMStackWebPortal/docs/snapshots/backendapi/pip_upgrade_for_python.png create mode 100644 FARMStackWebPortal/docs/snapshots/firebase docs and pics/Screenshot 2023-06-01 062804.jpg create mode 100644 FARMStackWebPortal/docs/snapshots/firebase docs and pics/Screenshot 2023-06-01 073610.jpg create mode 100644 FARMStackWebPortal/docs/snapshots/firebase docs and pics/Screenshot 2023-06-01 074202.jpg create mode 100644 FARMStackWebPortal/docs/snapshots/firebase docs and pics/Screenshot 2023-06-01 074233.jpg create mode 100644 FARMStackWebPortal/docs/sphinxdocs/CMakeLists.txt create mode 100644 FARMStackWebPortal/docs/sphinxdocs/README.rst create mode 100644 FARMStackWebPortal/docs/sphinxdocs/docs/Makefile create mode 100644 FARMStackWebPortal/docs/sphinxdocs/docs/make.bat create mode 100644 FARMStackWebPortal/docs/sphinxdocs/docs/readme_link.rst create mode 100644 FARMStackWebPortal/docs/sphinxdocs/docs/source/conf.py create mode 100644 FARMStackWebPortal/docs/sphinxdocs/docs/source/index.rst diff --git a/FARMStackWebPortal/CMakeLists.txt b/FARMStackWebPortal/CMakeLists.txt new file mode 100644 index 0000000..eb552f9 --- /dev/null +++ b/FARMStackWebPortal/CMakeLists.txt @@ -0,0 +1 @@ +project(projectWebservportalproject) \ No newline at end of file diff --git a/FARMStackWebPortal/README.md b/FARMStackWebPortal/README.md new file mode 100644 index 0000000..eaa2a40 --- /dev/null +++ b/FARMStackWebPortal/README.md @@ -0,0 +1,20 @@ +The original README.md of this Webservportal is at [README.md](...\docs\README.md) + + + +The original [README.md](.../docs/README.md) exists alone. + + + +All documents reference the [Scratchpad](.../docs/Scratchpad2.md) + + +the project utilised the following; + +** [BuildStructure.md](./docs/buildstructure.md) +** [Project Structure](...docs/ProjectStructure.md) +** [Flow of Execution](...docs/flowofexecution.md) + + +[README.md](...docs/README.md) .[Changelog](.../docs/CHANGELOG.md) . [Documentation] [Build] (...D:/FARMStack/Webservportalproject/docs/sphinxdocs/docs/build) + diff --git a/FARMStackWebPortal/docs/AUTHORS/config.toml b/FARMStackWebPortal/docs/AUTHORS/config.toml new file mode 100644 index 0000000..8621ab3 --- /dev/null +++ b/FARMStackWebPortal/docs/AUTHORS/config.toml @@ -0,0 +1,3 @@ +[template] +name = "..." +email = "..." \ No newline at end of file diff --git a/FARMStackWebPortal/docs/AUTHORS/termsandconditions.js b/FARMStackWebPortal/docs/AUTHORS/termsandconditions.js new file mode 100644 index 0000000..bfb8fd4 --- /dev/null +++ b/FARMStackWebPortal/docs/AUTHORS/termsandconditions.js @@ -0,0 +1,2 @@ +var Conditions; +Terms & Conditions; diff --git a/FARMStackWebPortal/docs/AUTHORS/termsandconditions.ts b/FARMStackWebPortal/docs/AUTHORS/termsandconditions.ts new file mode 100644 index 0000000..37bb280 --- /dev/null +++ b/FARMStackWebPortal/docs/AUTHORS/termsandconditions.ts @@ -0,0 +1,2 @@ +let Conditions; +Terms & Conditions \ No newline at end of file diff --git a/FARMStackWebPortal/docs/Attributions.md b/FARMStackWebPortal/docs/Attributions.md new file mode 100644 index 0000000..8f2518d --- /dev/null +++ b/FARMStackWebPortal/docs/Attributions.md @@ -0,0 +1,33 @@ +This Project would not exist without the following attributions ; + +Incase you are not added, kindly please add yourself to the [AUTHORS](...docs/AUTHORS) + +[Web Framework](#addlinkhere) + +[Login & Authentication](#addlinkhere) + +[Documentation](#addlinkhere) + +[Redoc](#addlinkhere) + +[FAST API Docs](#addlinkhere) + +[Build Structure](...docs/buildStructure.md) is NOT the [Project Structure](...docs/ProjectStructure.md) + +[Project Structure](...docs/ProjectStructure.md) . [Flow of Execution](...docs/flowofexecution.md) + +[Build Structure](...docs/buildStructure.md) + + +[README.md](...docs/README.md) .[Changelog](.../docs/CHANGELOG.md) . [Documentation] [Build] (...docs/sphinxdocs/docs/build) + + + + + + + +Made with : [Sphinx docs](https://www.sphinx-doc.org/) + + + diff --git a/FARMStackWebPortal/docs/Brief.md b/FARMStackWebPortal/docs/Brief.md new file mode 100644 index 0000000..25769a3 --- /dev/null +++ b/FARMStackWebPortal/docs/Brief.md @@ -0,0 +1 @@ +## server \ No newline at end of file diff --git a/FARMStackWebPortal/docs/CHANGELOG.md b/FARMStackWebPortal/docs/CHANGELOG.md new file mode 100644 index 0000000..6de4cfc --- /dev/null +++ b/FARMStackWebPortal/docs/CHANGELOG.md @@ -0,0 +1,28 @@ +CHANGELOG + +This is the CHANGELOG. CHANGES to the work will be here. + +1. Add FASTAPI +2. Add Uvicorn +3. Add main.py +3. Add test_main.http +4. Add docs [README,ReferencesCHANGELOG,Attributions,Contributing](#) +4. Add python fastapi_login -Login & Authentication System +5. Add python-multipart -Form handling + +## Add FASTAPI + +## Add Uvicorn +## Add [main.py](## ) +## Add test_main.http +## Add docs [README, References](## ) +## Add docs: [CHANGELOG, Attributions, Contributing](## ) +## Add python fastapi_login -Login & Authentication System +## Add python-multipart -Form handling + + + +[README.md](...docs/README.md) .[Changelog](.../docs/CHANGELOG.md) . [Documentation] [Build] (...D:/FARMStack/Webservportalproject/docs/sphinxdocs/docs/build) + + +Made with :[heart][heart] [Sphinx docs](https://www.sphinx-doc.org/) \ No newline at end of file diff --git a/FARMStackWebPortal/docs/CMakeCache.txt b/FARMStackWebPortal/docs/CMakeCache.txt new file mode 100644 index 0000000..743e0e0 --- /dev/null +++ b/FARMStackWebPortal/docs/CMakeCache.txt @@ -0,0 +1,83 @@ +# This is the CMakeCache file. +For build in directory: d:/FARMStack/Webservportalproject/docs +It was generated by CMake: C:/Program Files/CMake/bin/cmake.exe +# You can edit this file to change values found and used by cmake. +# If you do not want to change any of the values, simply exit the editor. +# If you do want to change a value, simply edit, save, and exit the editor. +# The syntax for the file is as follows: +KEY:TYPE=VALUE +KEY is the name of a variable in the cache. +# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!. +VALUE is the current value for the KEY. + +######################## +# EXTERNAL cache entries +######################## + +//Value Computed by CMake. +CMAKE_FIND_PACKAGE_REDIRECTS_DIR:STATIC=D:/FARMStack/Webservportalproject/docs/CMakeFiles/pkgRedirects + +//Program used to build from makefiles. +CMAKE_MAKE_PROGRAM:STRING=nmake + +//Value Computed by CMake +CMAKE_PROJECT_DESCRIPTION:STATIC= + +//Value Computed by CMake +CMAKE_PROJECT_HOMEPAGE_URL:STATIC= + +//Value Computed by CMake +CMAKE_PROJECT_NAME:STATIC=projectWebservportal + +//Value Computed by CMake +projectWebservportal_BINARY_DIR:STATIC=D:/FARMStack/Webservportalproject/docs + +//Value Computed by CMake +projectWebservportal_IS_TOP_LEVEL:STATIC=ON + +//Value Computed by CMake +projectWebservportal_SOURCE_DIR:STATIC=D:/FARMStack/Webservportalproject + + +######################## +# INTERNAL cache entries +######################## + +//This is the directory where this CMakeCache.txt was created +CMAKE_CACHEFILE_DIR:INTERNAL=d:/FARMStack/Webservportalproject/docs +//Major version of cmake used to create the current loaded cache +CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3 +//Minor version of cmake used to create the current loaded cache +CMAKE_CACHE_MINOR_VERSION:INTERNAL=28 +//Patch version of cmake used to create the current loaded cache +CMAKE_CACHE_PATCH_VERSION:INTERNAL=0 +//Path to CMake executable. +CMAKE_COMMAND:INTERNAL=C:/Program Files/CMake/bin/cmake.exe +//Path to cpack program executable. +CMAKE_CPACK_COMMAND:INTERNAL=C:/Program Files/CMake/bin/cpack.exe +//Path to ctest program executable. +CMAKE_CTEST_COMMAND:INTERNAL=C:/Program Files/CMake/bin/ctest.exe +//Path to cache edit program executable. +CMAKE_EDIT_COMMAND:INTERNAL=C:/Program Files/CMake/bin/cmake-gui.exe +//Name of external makefile project generator. +CMAKE_EXTRA_GENERATOR:INTERNAL= +//Name of generator. +CMAKE_GENERATOR:INTERNAL=NMake Makefiles +//Generator instance identifier. +CMAKE_GENERATOR_INSTANCE:INTERNAL= +//Name of generator platform. +CMAKE_GENERATOR_PLATFORM:INTERNAL= +//Name of generator toolset. +CMAKE_GENERATOR_TOOLSET:INTERNAL= +//Source directory with the top level CMakeLists.txt file for this +// project +CMAKE_HOME_DIRECTORY:INTERNAL=D:/FARMStack/Webservportalproject +//ADVANCED property for variable: CMAKE_MAKE_PROGRAM +CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1 +//number of local generators +CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1 +//Platform information initialized +CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1 +//Path to CMake installation. +CMAKE_ROOT:INTERNAL=C:/Program Files/CMake/share/cmake-3.28 + diff --git a/FARMStackWebPortal/docs/CMakeFiles/3.28.0-rc5/CMakeSystem.cmake b/FARMStackWebPortal/docs/CMakeFiles/3.28.0-rc5/CMakeSystem.cmake new file mode 100644 index 0000000..74e1c4b --- /dev/null +++ b/FARMStackWebPortal/docs/CMakeFiles/3.28.0-rc5/CMakeSystem.cmake @@ -0,0 +1,15 @@ +set(CMAKE_HOST_SYSTEM "Windows-10.0.22000") +set(CMAKE_HOST_SYSTEM_NAME "Windows") +set(CMAKE_HOST_SYSTEM_VERSION "10.0.22000") +set(CMAKE_HOST_SYSTEM_PROCESSOR "AMD64") + + + +set(CMAKE_SYSTEM "Windows-10.0.22000") +set(CMAKE_SYSTEM_NAME "Windows") +set(CMAKE_SYSTEM_VERSION "10.0.22000") +set(CMAKE_SYSTEM_PROCESSOR "AMD64") + +set(CMAKE_CROSSCOMPILING "TRUE") + +set(CMAKE_SYSTEM_LOADED 1) diff --git a/FARMStackWebPortal/docs/CMakeFiles/CMakeConfigureLog.yaml b/FARMStackWebPortal/docs/CMakeFiles/CMakeConfigureLog.yaml new file mode 100644 index 0000000..4cdff16 --- /dev/null +++ b/FARMStackWebPortal/docs/CMakeFiles/CMakeConfigureLog.yaml @@ -0,0 +1,11 @@ + +--- +events: + - + kind: "message-v1" + backtrace: + - "C:/Program Files/CMake/share/cmake-3.28/Modules/CMakeDetermineSystem.cmake:233 (message)" + - "CMakeLists.txt:1 (project)" + message: | + The system is: Windows - 10.0.22000 - AMD64 +... diff --git a/FARMStackWebPortal/docs/CMakeFiles/cmake.check_cache b/FARMStackWebPortal/docs/CMakeFiles/cmake.check_cache new file mode 100644 index 0000000..56c437b --- /dev/null +++ b/FARMStackWebPortal/docs/CMakeFiles/cmake.check_cache @@ -0,0 +1 @@ +# This file is generated by cmake for dependency checking of the CMakeCache.txt file diff --git a/FARMStackWebPortal/docs/Contributing.md b/FARMStackWebPortal/docs/Contributing.md new file mode 100644 index 0000000..c1495e8 --- /dev/null +++ b/FARMStackWebPortal/docs/Contributing.md @@ -0,0 +1,8 @@ + + + + + + +[README.md](...docs/README.md) .[Changelog](.../docs/CHANGELOG.md) . [Documentation] [Build] (...D:/FARMStack/Webservportalproject/docs/sphinxdocs/docs/build) + diff --git a/FARMStackWebPortal/docs/LICENSE/config.toml b/FARMStackWebPortal/docs/LICENSE/config.toml new file mode 100644 index 0000000..20008b0 --- /dev/null +++ b/FARMStackWebPortal/docs/LICENSE/config.toml @@ -0,0 +1,13 @@ +[template.licenses] +headers = true +default = [ + "MIT", +] +[template.plugins.default] +tests = true + +[template.plugins.default] +ci = false + +[template.plugins.default] +src-layout = true \ No newline at end of file diff --git a/FARMStackWebPortal/docs/ProjectStructure.md b/FARMStackWebPortal/docs/ProjectStructure.md new file mode 100644 index 0000000..3be7d0e --- /dev/null +++ b/FARMStackWebPortal/docs/ProjectStructure.md @@ -0,0 +1,96 @@ +## Project Structure + +### This [Project Structure](...docs/ProjectStructure.md) is NOT the ( +[Build Structure](...docs/buildStructure.md) + + +#### Project Structure + + The Project Structure is the way a project is built, it is separate from the build structure +as it contains the [Build Structure](...docs/buildStructure.md) and building the Project at [builds](href="D:/FARMStack/webservportalprojectbuild"). + + +## Manual Setup + +```` +$ mkdir FARMStack +$ cd FARMStack +$ mkdir webservportal +$ code . +$ git init +$ yarn create react-app frontend --template typescript +$ cd webservportal +$ git init +$ touch requirements.txt main.py model.py database.py +```` + + + + +### Project Status + +- [ ] Design +- [ ] MockUps + +- [x] Development +- [x] Backend Build & Design (FastAPI) + App Structure +- [ ] FrontEnd Build & Design (React ) + App Structure +- [ ] Database Integrations (Mongodb) + +### Frontend Design + + +### Testing + +- [ ] Unit Testing + +- [x] QA +- +- [ ] Stage +- +- [ ] Beta Testing +- +- [ ] Production + + +-- Changes to this structure will be added here. +``` + +├───backend +│ ├───app +└───frontend + ├───app +├───docs + └───sphinxdocs + └───Documentation + ├───README.md +├───snapshots +├───more to be added. + +``` + +For the [Project Structure](...docs/ProjectStructure.md) + +For the [Flow of Execution](...docs/flowofexecution.md) + +[README.md](...docs/README.md) . [Documentation](...D:/FARMStack/Webservportalproject/docs/sphinxdocs/docs/build) + +## Setting Up the Project Build Structure + +** [BuildStructure.md](./docs/buildstructure.md) for the project utilised the self contained waterfall structure.[Build Structure](...docs/buildStructure.md) is NOT the + +[Project Structure](...docs/ProjectStructure.md) + + + + + + +[README.md](...docs/README.md) .[Changelog](.../docs/CHANGELOG.md) . +[Documentation] [Build] (...docs/sphinxdocs/docs/build) + + + + diff --git a/FARMStackWebPortal/docs/README.md b/FARMStackWebPortal/docs/README.md new file mode 100644 index 0000000..6f425c6 --- /dev/null +++ b/FARMStackWebPortal/docs/README.md @@ -0,0 +1,251 @@ +## README.md + +This is the original README.md of the Webservportal README.md. + + +This is the [README.md](D:\FARMStack\Webservportalproject\docs\README.md) + + + +### Disclaimer + +``This README file is prune to repetitions. It is the aim of this work that i try where i can. If you are reading or working with this.Please clean it up. + +Thank you for sharing is Source Software tools. +`` +``The code, examples and materials and software tools in this project are solely for purposes of my academic Thesis.`` + +# This is the readme file + +## What is It? + +A WebService Portal + + +## Setup + + +WebServicePortal README.md + +## BackEnds +## Mongodb BackEnds + +## Database Setup +#### Create database and add data documents +* Download from Mongodb + - Community Monogodb Setup + - MOngodbAtlas Connector +* Login to mongodbaccount +* Connect Your Mongodb account + MOngodbAtlas Connector to localhost + +#### Insert Data Documents +[Insert Data into the database](https://www.mongodb.com/docs/compass/current/documents/insert/) + +## What does it Do? +* The backend authenticates and users to the database. +* This is done by connecting the app backends to the database. +This FARM Stack Implementation of a government services portal.For citizens and officials for service provision. + +## How does it work? +* Consists of login & Registration Portal for Government Officials and Citizens where each serves a function or purpose for service delivery. +Officials have access to a services portal and citizens also. +Once logged in each user has a dashboard. + +## Parts +* Database Setup + + * Customizable database backend because we are using MongoDB DB and NOT SQLAlchemy, we will use MongoDB with Beanie ODM included and not ORM async included. +* JWT Authentication + + + + + +#### Disclaimer + +````This project was built using Open Source Software tools. +The code, examples and materials and software tools in this project are solely for purposes of my academic Thesis.´´´´ + + +### Problem Statement + +Citizens of Cameroon are moving from an analogue systems and services provision to a new digital services and systems provisioning system. +In order to have a streamlined means of services provision from the government, there is a requirement for a WebServices Portal, +where the citizens can utilise the services and the government administrators using the new digital services provisioning system. + +This project is a simple web services portal that aims to serve that purpose. + +### Project Description +This web services portal is a ```government web services portal``` for citizen access to services of the different government entities and ministries. +````It consists of an login and administrative dashboard where government administrators and citizens can access services of the different government Ministries```` + + ### WebServicesPortal +This ´´[WebServicesPortal Project](#addlinkhere)`` work is apart of [Thesis](../yourprofile?tab=projects?tab=Thesis). + +### Stack + +* This Project was build using the [F.A.R.M](https://www.freecodecamp.org/news/learn-the-farm-stack-fastapi-reactjs-mongodb/) +``The FARM stack is FastAPI, React, and MongoDB. F.A.R.M stands for -The FastAPI, ASGI,React,MongoDB`` +- [web framework](#) - FastAPI for the back end. +- [Web Server](#) - ASGI for the Web Server +- [User admin and Registration](#) - React for the front end. +- [User admin and Registration](#) - FastAPI_Users for the Back end. +- [Backend Database](#)- NoSQL[MongoDB](#) VS [SQL](#) Databases. +- [Beanie ODM for Mongodb Backend Database](#) - or [SQLAlchemy for SQLBackend Database](#) + + +### Setup Requirements +We will requireThe following ; +* [VSCode/Pycharm/IDE](./requirements.txt") +* [Python](./requirements.txt") +* [Mongodb Server](./requirements.txt") +* [dependencies](./requirements.txt") are required. + +#### Development +* Backend + + - [Web Framework](#addlinkhere). + +- [Web Framework](#addlinkhere) :We will use FastAPI as both our backend and also our Webframework to build the webservportal app. +``FastAPI is a modern, fast (high-pe)rformance), web framework for building APIs with Python 3.7+ based on standard Python-type hints. One of the key features of FastAPI is its ability to use the latest Python features, such as async/await, without requiring developers to write boilerplate code.`` + +- [ASGI](#addlinkhere) :Asynchronous Server Gateway Interface. + ``Asynchronous Server Gateway Interface,is a standard interface between web servers and Python web applications or frameworks`` + + - [User Login & Authentication](https://fastapi-users.github.io/fastapi-users) - [FastApiUser](#): We will use FastApiUser for login authentication and management because it also provides us OAuth2 authentication.FastAPI Users also allows you to plug in several authentication methods.FastAPI also allows us to have a customizable database backend, where SQLAlchemy ORM async included + and MongoDB with Beanie ODM also included.This helps us to customize our database backend if we have them. +``FastAPIUsers is a highly secure and open-source users management registration and authentication system for Implementing registration, login, social auth.`` + +* Frontend + +- [Node.js](#) + [React](https://create-react-app.dev/docs/getting-started/) +We will utilise the [react-create template](https://create-react-app.dev/docs/getting-started/) to instatiate our frontend. + +## Why React for FrontEnd? +Create React App is an officially supported way to create single-page React applications. +It offers a modern build setup with no configuration. + + + +#### Building, Testing, and Deployment +[Gradle](https://docs.gradle.org/current/userguide/gradle_basics.html) automates building, testing, and deployment of software from information in build scripts. + +#### Build + + + +For Building our app - [Cmake](#) + +## Testing + + +#### API Testing +For our API Testing, we will use Postman for API testing of our API. + +#### Deployments +-- NginxUnit - To run our web apps. + +#### Manual Setup + +```` +$ mkdir FARMStack +$ cd FARMStack +$ mkdir webservportal +$ cd webservportal +$ mkdir backEnd +$ mkdir frontend +cd frontend +$ code . +$ git init +$ yarn create react-app frontend --template react-bootstrap +$ cd backEnd +$ git init +$ touch requirements.txt main.py model.py database.py +```` +## Flow of Execution +For the Stack to work accordingly, the order in which statements are executed,we must first have a working/Provisioned .Backend so that the frontend is implemented. +This is because the frontend depends on the backend to implement the whole stack. + +#### Backend + + + +#### FrontEnd. +The fundamental way the frontend frameworks interact with the backend is by making [HTTP calls](##) via [AJAX](##). +The typical interface to the backend is a REST API. + + + + + + +#### Project Status + +- [ ] Design + +- [ ] MockUps + +- [x] Development + ++ Backend Design & build(React + FastAPI Users) + - Login and Authentication + - MongoDB Integrations + ++ Frontend Design & build(React + FastAPI Users) + - App Testing + +- [x] Unit Testing + +- [x] QA + +- [ ] Stage + +- [ ] Beta Testing + +- [ ] Production + +#### Documentation + +For source [Documentation](.../docs/sphinxdocs/docs/build) including our API, +[Sphinx](#), [Redoc](#), [FAST API Docs](#) were utilised. + +* [README.md](...docs/README.md) . +* [Changelog](.../docs/CHANGELOG.md) . +* [Documentation] (.../docs/sphinxdocs/docs/build) +* [Documentation Build] (...D:/FARMStack/Webservportalproject/docs/sphinxdocs/) + + +#### References + Reference Literature is in the [References.md](./docs/References.md) + + +#### Links + +** [BuildStructure.md](./docs/buildstructure.md) for the project utilised the self contained waterfall structure.[Build Structure](...docs/buildStructure.md) is NOT the [Project Structure](...docs/ProjectStructure.md) + +** [Project Structure](...docs/ProjectStructure.md) + +** [Flow of Execution](...docs/flowofexecution.md) + +**[Build Structure](...docs/buildStructure.md) + + +#### Privacy +[Privacy Policy](../docs/privacy.md) + +#### Attribution(s) +This project utilises open and closed source tools. +This work would not exist without the following [Attribution(s)](../docs/attributions.md) + +#### LICENSE(s) +Licenses are in the [LICENSE(s)](../docs/LICENSE) directory. + +#### [Contribute](..docs/Contributing.md) + +Feel free to tell me if you liked this project or +how it helped you out! [here](#addlinkhere/) + + + +Made with :[heart][heart] [Sphinx docs](https://www.sphinx-doc.org/) + diff --git a/FARMStackWebPortal/docs/References.md b/FARMStackWebPortal/docs/References.md new file mode 100644 index 0000000..6444deb --- /dev/null +++ b/FARMStackWebPortal/docs/References.md @@ -0,0 +1,107 @@ +References + +#### References/Literature +Reference literature is found in the [References.md](../docs/References.md) + +#### The following literature was utilised in this work. + +#### Incase there is an errors to the authors and publishers,Please add yourself to the [Authors file](##) +-- OR Make a [pull request](#addpullrequestlinkhere) + +* [Development](#addlinkhere) + +* [Setup Tests]((#addlinkhere)) + +* [Setup Provisioning]((#addlinkhere)) + +* [Foundations of making an app]((#addlinkhere)) + +* [APIs]((#addlinkhere)) + +* [Node.js](#addlinkhere) + +* [React](#addlinkhere) + +* [Express](#addlinkhere) + +* [Mongodb](#addlinkhere) + +* [Fastapi Local Setup](https://github.com/ChristopherGS/ultimate-fastapi-tutorial/tree/main/part-01-hello-world) + +* [Poetry](https://earthly.dev/blog/python-poetry/) + +* [Building Backends](https://packaging.python.org/en/latest/tutorials/packaging-projects//) + +* [Bento_The pythonic packaging solution](https://cournape.github.io/Bento/) + +* [Web Framework](#addlinkhere) + +* [Login & Authentication](#addlinkhere) + +* [fastapi](https://unit.nginx.org/howto/fastapi/) + +* [fastapi-people](https://fastapi.tiangolo.com/fastapi-people/) + +* [deploying-a-fastapi-app-with-nginx](https://levelup.gitconnected.com/deploying-a-fastapi-app-with-nginx-supervisor-and-gunicorn-1e97e7421b46) + +* [create-react-app](https://create-react-app.dev/docs/getting-started/) + +* [Manage and Setup Python environments](https://testdriven.io/blog/python-environments/) + +* [fastapi deployment](https://fastapi.tiangolo.com/deployment/) + +* [oauth configuration](https://fastapi-users.github.io/fastapi-users/12.1/configuration/oauth/) + +* [FastApi Users](#)(https://fastapi-users.github.io/fastapi-users/10.1/configuration/full-example/) + +* [SQLDB_fastapi-SQLAlchemy](https://towardsdatascience.com/fastapi-cloud-database-loading-with-python-1f531f1d438a/) + +* [MONGODB_fastapi-beanie](https://testdriven.io/blog/fastapi-beanie/) +[fastapi-beanie](https://github.com/Youngestdev/fastapi-beanie/) + +* [Cameroon Cities and Populations](#https://worldpopulationreview.com/countries/cities/cameroon) + +* [Cameroon Cities and Populations](#https://worldpopulationreview.com/countries/cities/cameroon) + +* [unit.nginx](https://unit.nginx.org/howto/fastapi/) + +* [fastapi-users](https://fastapi.tiangolo.com/fastapi-people)/ + +* [create-react-app](https://create-react-app.dev/docs/getting-started/) + +* [fastapi deployment](#ADDLINKHERE)https://fastapi.tiangolo.com/deployment/ + +* [Deploying-a-fastapi-app-with-nginx](https://levelup.gitconnected.com/deploying-a-fastapi-app-with-nginx-supervisor-and-gunicorn-1e97e7421b46) + +* [Testing in Python](https://testdriven.io/blog/testing-python/) + + + +## Links + +** [BuildStructure.md](./docs/buildstructure.md) for the project utilised the self contained waterfall structure.[Build Structure](...docs/buildStructure.md) is NOT the [Project Structure](...docs/ProjectStructure.md) + +** [Project Structure](...docs/ProjectStructure.md) + +** [Flow of Execution](...docs/flowexecution.md) + +**[Build Structure](...docs/buildStructure.md) + +** [Flow of Execution](...docs/flowexecution.md) + +**[Build Structure](...docs/buildStructure.md) + + + + + +[README.md](...docs/README.md) .[Changelog](.../docs/CHANGELOG.md) . [Documentation] [Build] (...D:/FARMStack/Webservportalproject/docs/sphinxdocs/docs/build) + +Made with :[heart][heart] [Sphinx docs](https://www.sphinx-doc.org/) + + + + + + + diff --git a/FARMStackWebPortal/docs/Scratchpad2.md b/FARMStackWebPortal/docs/Scratchpad2.md new file mode 100644 index 0000000..01f92b5 --- /dev/null +++ b/FARMStackWebPortal/docs/Scratchpad2.md @@ -0,0 +1,755 @@ + +### Build Structure +This project was build using the self contained waterfall structure. +We reference is at the Project [BuildStructure.md](./docs/buildstructure.md) + +### Flow of Execution + +#### Backend vs FrontEnd. +The fundamental way the frontend frameworks interact with the backend is by making HTTP calls via AJAX. +The typical interface to the backend is a REST API + +### Database +PostgreSQL and SQLite are two relation databases, SQLAlchemy is an [ORM](##addlinkhere) which gives you a set of tools for accessing the data in the database. + +While [SQLAlchemy](#addlinkhere) is the Python SQL toolkit and Object Relational Mapper that gives us the full power and flexibility of SQL, we will use [Beanie](#addlinkhere) as it works with [MONGODB](#addlinkhere),as it is the database we will use and is an Object Document Mapper that gives application developers the full power and flexibility of a NoSQL Database. + +## Testing and Building +### Testing + +FastAPI is an API;that we use or create a tool that would simplify the API testing process. We will utilise [Postman](https://en.wikipedia.org/wiki/Postman_(software)) for testing the app, and all its functionality because Postman is an API platform for building and using APIs that simplifies each step of the API lifecycle. + + +all the run tests uploaded to the testing directory. + +[/coverage] + +## Production + +[/build] + +### [Deployments](https://fastapi.tiangolo.com/deployment/) +To deploy an application means to perform the necessary steps to make it available to the users. +For a web API, it normally involves putting it in a remote machine, with a server program that provides good performance, stability, etc, so that your users can access the application efficiently and without interruptions or problems. +This is in contrast to the development stages, where we are constantly changing the code, breaking it and fixing it, stopping and restarting the development server, etc. + +Deploying a FastAPI application is relatively easy. + +#### Deployment Strategies +Depending on our specific use case and the tools that we use.when deploying a FastAPI application (although most of it applies to any other type of web application). + +- We could deploy a server ourselves(Local Deployment) using a combination of tools, or +- We could use a [cloud service](#addlinkshere) and make a cloud deployment that does part of the work for us, or other possible options. + +#### Cloud Deployment +Cloud Deployment with [linode-deploy-gunicorn-uvicorn-nginx](https://christophergs.com/tutorials/ultimate-fastapi-tutorial-pt-6b-linode-deploy-gunicorn-uvicorn-nginx/) + +#### Local Deployment +-- Requirements for Local Deployment ++ [nginx-unit](https://unit.nginx.org/howto/fastapi/) : +Nginx-unit is a Fast API ++ [VirtualBox](#) : +Virtual Box is a tool that is used to setup a virtual workspace using images ++ [Vagrant](#addvagrantlinkshere) +Vagrant is a tool for building and distributing development environments- + +### References + +[Generate Gitignore Files](#addlinkhere) + +[Build a FARM Stack](#addlinkhere). + +[FASTAPI](#addlinkhere) + +[API documentation](https://github.com/swagger-api/swagger-ui) + +[Pydantic Utilised Models](https://docs.pydantic.dev/latest/concepts/models/) + +[Swagger-UI](https://github.com/swagger-api/swagger-ui) +* Swagger UI is a collection of HTML, JavaScript, and CSS assets; +* That dynamically generate beautiful documentation from a Swagger-compliant API. + +[Auth Login Page](https://dev.to/athulcajay/fastapi-auth-login-page-48po +) +[Micro Frontends](https://www.telerik.com/blogs/building-micro-frontends) + +[FastApiUsers](https://fastapi-users.github.io/fastapi-users) + +## References + +#### Back End + + +#### Front End +* [Dash Framework for Python](http://www.dash.plotly.com) +* [Getting-started](https://create-react-app.dev/docs/getting-started/) +* [Create-React-App](https://github.com/facebook/create-react-app) + +* [Create React Front End](https://christophergs.com/tutorials/ultimate-fastapi-tutorial-pt-12-react-js-frontend/#theory) + +### [Provisioning](#) + +- [Automated](#) + +- [Manual](#) + +### [Deployments](https://fastapi.tiangolo.com/deployment/) +Deploying our FastAPI application is relatively easy. + +#### Deployment Strategies +#### Cloud Deploy - Here we use a cloud service that does part of the deployment for us, or other possible options. + ++ [Cloud Deploy using Linode](https://christophergs.com/tutorials/ultimate-fastapi-tutorial-pt-6b-linode-deploy-gunicorn-uvicorn-nginx/) + +#### Local Deploy. +We deploy a server ourselves using a combination of tools) + +Requirements ++ [vagrant](https://github.com/hashicorp/vagrant) ++ ++ [install vagrant](https://developer.hashicorp.com/vagrant/install) ++ ++ [nginx-unit](https://unit.nginx.org/howto/fastapi/) ++ ++ [VirtualBox](#) + +#### Integrations ++ [Unit](https://unit.nginx.org/howto/integration/) + +[Data Visualisation with dash](https://dash.plotly.com/) +#### Documentation +#### [Redoc API Documentation](https://github.com/Redocly/redoc) + +#### [Pycharm Documentation](https://www.jetbrains.com/help/pycharm/set-up-a-git-repository.html) + +#### [sqlalchemy](https://www.sqlalchemy.org/) + +###### ScratchPad + +```` +## +from fastapi import FastAPI + +app = FastAPI() + +@app.get("/") +async def root(): +return {"message": "Hello World"} +@app.get("/api/v1/users") +async def get_users(): +return db + + +@app.get("/hello/{name}") +async def say_hello(name: str): +return {"message": f"Hello {name}"} + + +## # main.py +@app.get("/api/v1/users") +async def get_users(): +return db + +## + +# main.py + +### + +from uuid import UUID +from fastapi HTTPException +@app.delete("/api/v1/users/{id}") + +async def delete_user(id: UUID): +for user in db: +if user.id == id: +db.remove(user) +return +raise HTTPException( +status_code=404, detail=f"Delete user failed, id {id} not found." +) + + + +# main.py +from uuid import UUID +from fastapi import FastAPI, HTTPException +@app.delete("/api/v1/users/{id}") +async def delete_user(id: UUID): +for user in db: +if user.id == id: +db.remove(user) +return +raise HTTPException( +status_code=404, detail=f"Delete user failed, id {id} not found." +) + +## +db: List[User] = [ +User( +id=uuid4(), +first_name="John", +last_name="Doe", +gender=Gender.male, +roles=[Role.user], +), +User( +id=uuid4(), +first_name="Jane", +last_name="Doe", +gender=Gender.female, +roles=[Role.user], +), +User( +id=uuid4(), +first_name="James", +last_name="Gabriel", +gender=Gender.male, +roles=[Role.user], +), +User( +id=uuid4(), +first_name="Eunit", +last_name="Eunit", +gender=Gender.male, +roles=[Role.admin, Role.user], +), +] +@app.get("/") +async def root(): +return {"message": "Hello World"} +@app.get("/api/v1/users") +async def get_users(): +return db +@app.post("/api/v1/users") +async def create_user(user: User): +db.append(user) +return {"id": user.id} + +======= +# main.py +from typing import List +from uuid import uuid4 + +import fastapi +from fastapi import FastAPI +from models import Gender, Role, User +from uuid import UUID +from fastapi import fastAPI, HTTPException +from fastapi import FastAPI +app = FastAPI() +from uuid import UUID +from fastapi import FastAPI, HTTPException + +db: List[User] = [ +User( +id=uuid4(), +first_name="John", +last_name="Doe", +gender=Gender.male, +roles=[Role.user], +), +User( +id=uuid4(), +first_name="Jane", +last_name="Doe", +gender=Gender.female, +roles=[Role.user], +), +User( +id=uuid4(), +first_name="James", +last_name="Gabriel", +gender=Gender.male, +roles=[Role.user], +), +User( +id=uuid4(), +first_name="Eunit", +last_name="Eunit", +gender=Gender.male, +roles=[Role.admin, Role.user], +), +] +@app.get("/") +async def root(): +return {"message": "Hello World"} +@app.get("/api/v1/users") +async def get_users(): +return db +@app.post("/api/v1/users") +async def create_user(user: User): +db.append(user) +return {"id": user.id} +@app.delete("/api/v1/users/{id}") +async def delete_user(id: UUID): +for user in db: +if user.id == id: +db.remove(user) +return +raise HTTPException(status_code= 404, detail=f"Delete user failed, id {id} not found." +) + +```` +### +```` + + +```` + +### Scratchpad +This scratchpad exists as evidence for purposes of documenting the steps and processes of this work. +Alot of ideas and information exists here.I choose to add it here for purposes of deisgn, ideation and build of this project. + +### Build Structure +This project was build using the self contained waterfall structure. +We reference is at the Project [BuildStructure.md](./docs/buildstructure.md) + +### Flow of Execution + +#### Backend vs FrontEnd. +The fundamental way the frontend frameworks interact with the backend is by making HTTP calls via AJAX. +The typical interface to the backend is a REST API + +### Database +PostgreSQL and SQLite are two relation databases, SQLAlchemy is an [ORM](##addlinkhere) which gives you a set of tools for accessing the data in the database. + +While [SQLAlchemy](#addlinkhere) is the Python SQL toolkit and Object Relational Mapper that gives application developers the full power and flexibility of SQL, it provides a full suite of well known enterprise-level persistence patterns, designed for efficient and high-performing database access, adapted into a simple and Pythonic domain language. +So basically SQLAlchemy gives you the tools to access SQL databases such as PostgreSQL and SQLite Mysql etc, and query them in a pythonic way. + +## Testing and Building + +## Building + + +### Testing +Apart from the initial API tests in the [tests](test_main_http.py) + +FastAPI is an API;this means that we use or create a tool that would simplify the API testing process +We will utilise [Postman](https://en.wikipedia.org/wiki/Postman_(software)) for testing the app, and all its functionality because Postman is an API platform for building and using APIs that simplifies each step of the API lifecycle and + + +and all the run tests uploaded to the testing directory. +#### Testing +Testing of our project is done in the [/coverage](##) directory. + +### Production +Production builds are in the [/build](##) directory + +### [Deployments](https://fastapi.tiangolo.com/deployment/) +To deploy an application means to perform the necessary steps to make it available to the users. +For a web API, it normally involves putting it in a remote machine, with a server program that provides good performance, stability, etc, so that your users can access the application efficiently and without interruptions or problems. +This is in contrast to the development stages, where we are constantly changing the code, breaking it and fixing it, stopping and restarting the development server, etc. + +Deploying a FastAPI application is relatively easy. + +#### Deployment Strategies +Depending on our specific use case and the tools that we use.when deploying a FastAPI application (although most of it applies to any other type of web application). + +- We could deploy a server ourselves(Local Deployment) using a combination of tools, or +- We could use a [cloud service](#addlinkshere) and make a cloud deployment that does part of the work for us, or other possible options. + +#### Cloud Deployment +Cloud Deployment with [linode-deploy-gunicorn-uvicorn-nginx](https://christophergs.com/tutorials/ultimate-fastapi-tutorial-pt-6b-linode-deploy-gunicorn-uvicorn-nginx/) + +#### Local Deployment +-- Requirements for Local Deployment ++ [nginx-unit](https://unit.nginx.org/howto/fastapi/) : +Nginx-unit is a Fast API ++ [VirtualBox](#) : +Virtual Box is a tool that is used to setup a virtual workspace using images ++ [Vagrant](#addvagrantlinkshere) +Vagrant is a tool for building and distributing development environments- + +### References + +[Generate Gitignore Files](#addlinkhere) + +[Build a FARM Stack](#addlinkhere). + +[FASTAPI](#addlinkhere) + +[API documentation](https://github.com/swagger-api/swagger-ui) + +[Pydantic Utilised Models](https://docs.pydantic.dev/latest/concepts/models/) + +[Swagger-UI](https://github.com/swagger-api/swagger-ui) +* Swagger UI is a collection of HTML, JavaScript, and CSS assets; +* That dynamically generate beautiful documentation from a Swagger-compliant API. + +[Auth Login Page](https://dev.to/athulcajay/fastapi-auth-login-page-48po +) +[Micro Frontends](https://www.telerik.com/blogs/building-micro-frontends) + +[FastApiUsers](https://fastapi-users.github.io/fastapi-users) + +References +======= +### Back End + + +### Front End +* [Dash Framework for Python](http://www.dash.plotly.com) +* [Getting-started](https://create-react-app.dev/docs/getting-started/) +* [Create-React-App](https://github.com/facebook/create-react-app) + +* [Create React Front End](https://christophergs.com/tutorials/ultimate-fastapi-tutorial-pt-12-react-js-frontend/#theory) + +### [Provisioning](#) + +- [Automated](#) + +- [Manual](#) + +### [Deployments](https://fastapi.tiangolo.com/deployment/) +Deploying our FastAPI application is relatively easy. + +#### Deployment Strategies +#### Cloud Deploy - Here we use a cloud service that does part of the deployment for us, or other possible options. + ++ [Cloud Deploy using Linode](https://christophergs.com/tutorials/ultimate-fastapi-tutorial-pt-6b-linode-deploy-gunicorn-uvicorn-nginx/) + +#### Local Deploy. +We deploy a server ourselves using a combination of tools) + +Requirements ++ [vagrant](https://github.com/hashicorp/vagrant) ++ ++ [install vagrant](https://developer.hashicorp.com/vagrant/install) ++ ++ [nginx-unit](https://unit.nginx.org/howto/fastapi/) ++ ++ [VirtualBox](#) + +#### Integrations ++ [Unit](https://unit.nginx.org/howto/integration/) + +[Data Visualisation with dash](https://dash.plotly.com/) +#### Documentation +#### [Redoc API Documentation](https://github.com/Redocly/redoc) + +#### [Pycharm Documentation](https://www.jetbrains.com/help/pycharm/set-up-a-git-repository.html) + +#### [sqlalchemy](https://www.sqlalchemy.org/) + +###### ScratchPad + +```` +## +from fastapi import FastAPI + +app = FastAPI() + +@app.get("/") +async def root(): +return {"message": "Hello World"} +@app.get("/api/v1/users") +async def get_users(): +return db + + +@app.get("/hello/{name}") +async def say_hello(name: str): +return {"message": f"Hello {name}"} + + +## # main.py +@app.get("/api/v1/users") +async def get_users(): +return db + +## + +# main.py + +### + +from uuid import UUID +from fastapi HTTPException +@app.delete("/api/v1/users/{id}") + +async def delete_user(id: UUID): +for user in db: +if user.id == id: +db.remove(user) +return +raise HTTPException( +status_code=404, detail=f"Delete user failed, id {id} not found." +) + + + +# main.py +from uuid import UUID +from fastapi import FastAPI, HTTPException +@app.delete("/api/v1/users/{id}") +async def delete_user(id: UUID): +for user in db: +if user.id == id: +db.remove(user) +return +raise HTTPException( +status_code=404, detail=f"Delete user failed, id {id} not found." +) + +## +db: List[User] = [ +User( +id=uuid4(), +first_name="John", +last_name="Doe", +gender=Gender.male, +roles=[Role.user], +), +User( +id=uuid4(), +first_name="Jane", +last_name="Doe", +gender=Gender.female, +roles=[Role.user], +), +User( +id=uuid4(), +first_name="James", +last_name="Gabriel", +gender=Gender.male, +roles=[Role.user], +), +User( +id=uuid4(), +first_name="Eunit", +last_name="Eunit", +gender=Gender.male, +roles=[Role.admin, Role.user], +), +] +@app.get("/") +async def root(): +return {"message": "Hello World"} +@app.get("/api/v1/users") +async def get_users(): +return db +@app.post("/api/v1/users") +async def create_user(user: User): +db.append(user) +return {"id": user.id} + +======= +# main.py +from typing import List +from uuid import uuid4 + +import fastapi +from fastapi import FastAPI +from models import Gender, Role, User +from uuid import UUID +from fastapi import fastAPI, HTTPException +from fastapi import FastAPI +app = FastAPI() +from uuid import UUID +from fastapi import FastAPI, HTTPException + +db: List[User] = [ +User( +id=uuid4(), +first_name="John", +last_name="Doe", +gender=Gender.male, +roles=[Role.user], +), +User( +id=uuid4(), +first_name="Jane", +last_name="Doe", +gender=Gender.female, +roles=[Role.user], +), +User( +id=uuid4(), +first_name="James", +last_name="Gabriel", +gender=Gender.male, +roles=[Role.user], +), +User( +id=uuid4(), +first_name="Eunit", +last_name="Eunit", +gender=Gender.male, +roles=[Role.admin, Role.user], +), +] +@app.get("/") +async def root(): +return {"message": "Hello World"} +@app.get("/api/v1/users") +async def get_users(): +return db +@app.post("/api/v1/users") +async def create_user(user: User): +db.append(user) +return {"id": user.id} +@app.delete("/api/v1/users/{id}") +async def delete_user(id: UUID): +for user in db: +if user.id == id: +db.remove(user) +return +raise HTTPException(status_code= 404, detail=f"Delete user failed, id {id} not found." +) + +```` +### +```` +#### MUST DO LIST +-Create main.py ,and must be in the the install directory(Root top level, and following the whole path of the a +-First do a packages update using the pip install upgrade command(in yellow-see-screenshot) +-Activation of the pip script must be done in the install directory(Root top level, and following the whole path of the activate script, see screensnapshot) +-To instantiate fastapi and python within the same venv, you must run it +-To run uvicorn, you must be in Command Prompt(see snapshot) + +#### DONT DO LIST + + +#### THINGS TO REMEMBER +-- All snapshots and guides are in the snapshots folder. +--For typesafety, i have added the folder to gitignore file. + +#### TO DO LIST +====== + +```` + +## Tools + +## Software + +### References + +#### The following literature was utilised in this work. + +#### Incase there is an errors to the authors and publishers,Please add yourself to the [Authors file](##) +-- OR Make a [pull request](##) + +* [Foundations of making an app](##) + +* [APIs](##) + +* [Node.js](##) + +* [React](##) + +* [Express](##) + +* [Mongodb](##) + +These were made with [Sphinx docs](##) + +##Must Know Items +[Local Setup](https://github.com/ChristopherGS/ultimate-fastapi-tutorial/tree/main/part-01-hello-world) + +[Poetry](https://earthly.dev/blog/python-poetry/) + +[Web Framework] + +[Login & Authentication] + +[Documentation] + +[fastapi](https://unit.nginx.org/howto/fastapi/) + +[fastapi-people](https://fastapi.tiangolo.com/fastapi-people/) + +[deploying-a-fastapi-app-with-nginx]()ttps://levelup.gitconnected.com/deploying-a-fastapi-app-with-nginx-supervisor-and-gunicorn-1e97e7421b46 + +[create-react-app](https://create-react-app.dev/docs/getting-started/) + +https://binary-factory.kde.org/view/Windows%2064-bit/job/KDevelop_Release_win64/2141/badge/ + +[fastapi deployment](https://fastapi.tiangolo.com/deployment/) + +[oauth configuration](https://fastapi-users.github.io/fastapi-users/12.1/configuration/oauth/) + + + +#### MUST DO LIST +-Create main.py ,and must be in the the install directory(Root top level, and following the whole path of the a +-First do a packages update using the pip install upgrade command(in yellow-see-screenshot) +-Activation of the pip script must be done in the install directory(Root top level, and following the whole path of the activate script, see screensnapshot) +-To instantiate fastapi and python within the same venv, you must run it +-To run uvicorn, you must be in Command Prompt(see snapshot) + +#### DONT DO LIST + + +#### THINGS TO REMEMBER +-- All snapshots and guides are in the snapshots folder. +--For typesafety, i have added the folder to gitignore file. + +#### TO DO LIST +* Add SignUp Form to React App USING firebase +* And Login Form to React App using Firebase +* Add File Upload Form to React App +* Connect Database +* +====== + +#### +Would you like to define your main dependencies interactively? (yes/no) [yes] yes +You can specify a package in the following forms: +- A single name (requests): this will search for matches on PyPI +- A name and a constraint (requests@^2.23.0) +- A git url (git+https://github.com/python-poetry/poetry.git) +- A git url with a revision (git+https://github.com/python-poetry/poetry.git#develop) +- A file path (../my-package/my-package.whl) +- A directory (../my-package/) +- A url (https://example.com/packages/my-package-0.1.0.tar.gz) +### + +This command will guide you through creating your pyproject.toml config. + +Package name [webservportalproject]: webservportalproject +Version [0.1.0]: 0.1.0 +Description []: This is a Web Services Portal Project +Author [Mh*vg5%b`#&-@5@rZs(vzf>N(|SVqF-kgRY$=QTSF(}fONf206o $HpWu(haJSnHqey^aZ||3 z(y9bx))X^qRyxqv?$=C@0#U37gO$Bud*g-yFP|twkr#Z(#?zM>13tI$?_f!}P&c;w z3uO;`kBrFh9Dj=V%5OOQZR1SoTLIMv7@ZI~@D;$gq+8(#LQr0DpliJBu~}Rkr@c{L z&UIxJVs#oAbP>ABdv_A_0e3Js(=Hc^NE7$2lU-87iVd*YVto7#u2bvAG_2N~_2kDd zfm`2nlHqGj>a}1c=EFyT&YP`V0+ZMmByoB;Tr!ih{FLCtK=R>+PAXb!zWXF?Y56A> z$sPprmz%q#&wQ=v11Q}(eV@Jnj@GbGy kuNLfw7`;xU@iMXh(m!BTAztgvZ;o 9@w21$lWco<*Zo+xxO8gQ4(lo%{)& z=k7njUZgYQE=CeUv{(SCP+X| %7GZfWdlKlwD)*R +0tRQVfl&gTxk3mpCTTSHqkz%7u9n{ zPk8T!^b)262hn;`;aZ)T ESpJ%n5ebj){~{>4s<^z{Mx&r1CFGn7 ERU7zf(QBdB+ zl~BZjXrpC~x1TDSa4|VIvC0I&B5%jY3U_VK2qL>64#9|!ZKF>LoF2Tf5@(6whj9{` zeGdyyD>0CZAWFF!9o%(hWpg4Sroq=21h!f@uM1eeZ^Ny~p&PkHW^3)j(>(E&`PK&P zwfR+nd}lZGVO}yo?2D>jD3-Ltb=vi!WnH<-z$6f@6EJC-@gt)CFGG=pjoifJXQPIe z(}Er><+@}=MgllJoEDN5m~ iL;@yCL1m9IA&Q1`fH?RD&d4MZLot&v84*x5y)80^l8m0o9Hj@{;-nI63? zDnH8IQDa@Rk`JEU(1Qd2PbD1bm@e<(pAA1;zYXwa#%StyD?|==&$GQzZUP0qZ@8q) zb+HeTfW+5S6PZR0=6uAFLX|tACaJFlgijZHU(XIHw*+zWtjXpGP!I5g)dmWh!qWocf-u)s(K zUCrrN47 (cEU5xj6>q341zx2fQF9h%R3sC>|&o>EfM}hPvIPk;Gjlv9OavixHL0B zkaOC{+p8t6%_t@&-5-1ucgs8azh{xKZR<4##Ie-<<(i+pYfhiP8;Zc+2Z7 4wCIU1 zkP 3OZnZT1!}^i=JdE&rE{W`Gb~Z9vOpbdBb7Qb3!iWkA~X&T+Cezzf=Kx6fE( zw_8PG0}gQ`vTItdeN={InyV zSo`d~>mcs4tzW@N>Sv6Y@{ux9x-&-E@n14aJVYbq_hMADzq*{~;Thhj8%o|z eO{7?(nF5!%oRx4N?3 zxSUrf;Ejg^j+DJRQpG1Un%tGy+99ImG{p^T`Ku9ON*}(7e62U*<*%CW%3o!y4`{(D zcPa08>k*R4)KWimWa1I6ZJg~O)8}kzsF4fgJtoI`T8K>4X@j7HG*m#bvhfxy>$ch9 zx1_2=yqpTMvLucY_eGOWF< L=UkUz z7wz<}AKS%_Y|@aWJ?TZGo7B@QZ0jj}*XdnaL3+355jyU0(BWs_c}m|zc=^0mlWP=Q z2+CVolE#m2d>Ok7k|5%Pt!-3E`D_K(VN8*0PgU4?m(IWIooi%CAtJG~u|iv`8~?T> z*;5(*IlS&$NG!ihoIPdsqY&i7`B!dHi;JQ?NZ#$Q4XKkN-ddBG9b=zSmGmfc4 v!159W) zZ~r~<>l^HebZ!9`d@~s!*Pl=kru$DhMtm 0vHM$&oop3wX;?y;N>yasNZ30P_((Sxzl= zrjP96VsIz1-Z^^YM9MN0z5ryZ^*mT-Y`{%cxaU)BjyEV&UhG%cZq^ Lz;qcd)g7K}&4Dp1R+s#@s?GPOfRo`grc=YTj;i2Ha-3RP(~m*BLu#^aEEm7>Fau z@i=;mBN0mEG^Ja?<)DOZ?I{QmMI{(-*Ek$HZ|J)fTwtg>wIIlMUSapKIcJ>7c~~t3 zdPh(HlJW<$60_KghUsn!J2A9)1Qf#=)vM>Xw{Pfoo1cxx?`HakC9B*#zvjypwv2?= zhZ(l-1T8~V*Rq#UE!dY-IN-?9nrA8UOIOZim^L$mW>3AYWo_1YxgsEQQMr*;%Z5%Q z$C*N%ZCWNl>78GIf2=lG{a40@6V+6%^MFWV{$D2Qp%rHM#eNhlTr~#I_q!ZcOhPX1 zFR(Mh7a{{to*&p? anGJ*z{nEF z#$*U^L7~t5Bm6Lp2k_i*^6fO7%R+Ed8%c?!Y_O+*8cJ-a=-P6gdcX0$FNzl=g0AQX zRSaE&;dOoU{J6=!s;(r?!7Ku9uIOKmh23{3KwbI!ejS#teb^n9HDxu9UXI~c_g8Fz z%~36u`xb+yMm5Jb%>Z^>5@g)3g-@1h)~vQaGag0HY^jv}>XNV~9B@inGPC<0|Ep6E zwN4zfxFy~PZYQj(soT(}4+rBaTP&GSuH2onZC}V#HG?Q&*y8BQR<(+1@WXq>@6kFo zVhkTB`YlZ_c{HdqmRn3P2@GR0`+cZrB^WRA*?UKMFep7uNX!%GKB9`Bq=@)g4fL=@ zWYfkD4ZW&o?PDrX$_`LD##4Qz>%&yF_V(Mvp_sKj`_pq}uc@ktM*O*egiC&jxcG@x zg%4@ZxWe6Yvq5!FD@pSOLCBX1+IV4BS8M^mbymRRB=~$>IRfYU^ h=kHK`}FX?$Z*8n!@KI%0Cm=U9npzMYWbsFx>0c zKo;6}@m${+h0_?pw2qZ@eS>Q@KA)szCPDbA{EUnW55CJ+R*(&RtAKK9VvvccU?JCL zqKB7FF F=-qBWea$tIg_HmhdIV6R9v2?PD_wgc3dlA%++&Oxyegq5{XQ`KO}9Hbkn-|`UmB(TeHFB91yxpL1w1(3pt zSK2<3gqhr-gUya%igFKU1Ym%K cd?!+gi7P;4ZDKVQw8fo|NY z7jMjKw6&}-{jrQiUcc`7@RM*QKG1K2bcutP8f)B9 g`;nR3y1l5B5gn&{ za??8hq5Q9@Dcs6S^xq4x7w3!J?bvoN(BeC5aXSS*m%SD2Ty7y D-H}g964)<9R7(B**fVL#&ya!c1Lar4;}7c zT? ^);VC_&4XinWl1EpgPonCqe&00veaL<3tA>I09(2D7k+oYxTayW0 z28W3g1gA!F@f^1cNO(RU(}VQFjygMXiySKD{)CE~jBkB7YkirrSJ7y7DZC@0((c7z zH=fhKI7-b~>0 S!)U5rBo4w2oA^8y=zJgRo z$y JFdmqz{DE}I-PXlNhinE4<1rB>@b9=#+Kv^Y%}USxBQg%vT~J%4LZ z{GwR!B+A`_wq|!2PC`l={4J8AnIbLBk>Eo4@wg)`__YV$oT*|y z_e|I-k_@Jsk9`@0W?~h0M{X5X;D>qaxxg*2N2$i}P2e2_P7@MF6erw)cKCdlt;m>Z zK<|ACWZCYLtyqgGB5>W%hyrmjH5t^Tt*`&>_4^)(nLk0*J%mx0)y4Kqgmqn5md_s* zooQ<;u n5b*% zxb19D!{0$&`+wrotENCAGW;u|Da6e3ojzU}=<>qt1}R_5zcsA92!abE%esxApogrG zI%0^wB|(6znVe;1z3!JRGkhP+KZvQwKQt*6WVzLaG`!L#nlow0*=3l;{M`!^=@C3U z-2}5(c85$En|VH_L7AuV_dwDfI(#z+)?LOv#PB#HUXx5{n$Jnkcv{YYeDo8Gc{J&S zbAGGX`0hR4J7-1RfqAJKt3kpe;Dx?PT}CADVUNXfIB9Bv09!ya{luxnmrUnjJE=0W zBZ{lqt>a|Q#74nSagOj>@Rx6k*UiXDC%@GB!5<)*2!k?}phf-yDe-Y!D@#!1TIKbt z>mm{RqGK2LER2DQl`kL17sW3h&W|sW@$3owAJOKU6q^0&_MnN$fjmh*&{~hKdp-5$ z6K3uG9LE65Pf0S;fokPz0ulQ^CI8^0;}A#0Al13W#Y9(_@Xg?PtZpfwmeLL6fhqCg zy_doeKc>`}%&BQc)I){{1Q|tC*Y3X7nqDoo-mE(g7=k6!7gw!*N&jkiwrGs#gje;j zTMEx 3;eAmx*3x8JqY%eVP1_ms<{Rp0JPU-#-OGhsc#L(8L z5BYd2`Lb4$Vj3+x|LBvD8cpFf`Q0FFB{+={r?=YU#&T *&j;N2lj>NSGltvH{+^yAv#PpQ#cgXb^ycR~#??w!D_O{-!DSCZMzL{8- zQfj*i+x*X#dfU$Jg1)O1&PH`lqjxoeA@VP3D=Bkx+#n4#4Bp<}r7tcN{6f$?;0iz6`&}j{;x{|(eY7kO|MO|8xISt 2eX1OV2#~xL(O~Zv^P6{QLtu1Cd+_qD-<%JYoRMW!zmPF_p5x) zo)cZr?d5OCAwmU5h_YT}?R`^!xW#NL_PZ-i(X(qnToa0C7>N;aS4R`Oc-Uw;y+m$A zC4uw1ac4+{+u?>_e1yL4WO*#DD(TYr0jQcnEbqTk30sL~;l*vqX|bHf{|6!*UQWwL z=`Doop(Mu1^(_Z_^S3FU(-No>XZ;66b&m!x8jdbs?M9Z)lIqr@c hGuQnZ$F*7RK|lE#> fae#mF^5^nH`|81X^~zedJeoIWiqgHK3z zjL2X>I|G?`E}wKydK}J-A`|r3{lLU;(AUpYH+nH6lEF^4^T^6@Jje#I&j9FE`3=B^ zB}W4CzsAZf4Wb6pGiOVmt10hSV~_cAH`k$7< $Jdu{H)W+j-BF5)P({Ihe6jk!u3HWq=yKcAZ_2dWyPruN+ z%H#P8+a;KHSpAOH*uZTU&q?4>AY8c6NVE4Y)uMV++!Ccg7nXO>cH>dW_JkX48j7T( zc8`pE^~_A60T8d8ODl8@2^Is0hYzgJHrs`H4M=Wrx7RpP`T%nx!ZOeU+COmkoP*z= zf)!&=D5Ko7sC(W3Vp`;dJ+{}}EKmIhbt&5kot6$t`gC9kOOzw>X%))N1Q0;gTA*F| z#;F_A*T|Ljh!9Kd5G~In(X&VedjTH(s%K@oORu{8PaGAD*f$C~+NuwK#uKkeGH}~s zMc637bcVpzW>LrR@-DnKU#khmKfUBYql*&hg`c3c`vXjLbwi4jgOWr@e!#K- w89@lbAhGOJ~?Lk>zOZ4?8`U%erHE zq #0Xq)z4N@$Nj%=wDW;S zlFkt)K*iYfdAagvQTY{)aQ9$sjmZ0wYN8_K|06s7&48Zy3+0@RNjfPL<$lyb w7T)TvWv@)OZw8XE&Z3=PL9$avR<(B83&Q RYVQ?79NkI@D@|gi@8=XiK z$n*@nrh5yKL;j$_MKSLvtKAvWud(81L(s{t+zM~G<^g&@6=O*Iz0M!7h=C1r+Y0$f zfj@)74k9?^FZ9X(H~L%!e(5m!3w?e*UoYT*rA0vnsXA1_Z>`re0Q>Bv*~`_Q)}n+! zA6)Xy#hFBG!fK@vsC;vVeo*_2zPM)%omIf#p3io&r<=CF^+4d~XtDEz?6Vi+)>lW) zPFCL3YU=8`?^sS(iWe!}#RX|UE<$fN;bcaB@!i-pAv1uSr2uQ&VkS1_= Rc$b-f3x89u{_N~B0Vo@uch1xVp!;3mlHhaxh)?xS+P|Qe z=S7B`i5gGH{B5K=F$aTo3|^z`K`N_=Zj70EL !KMMPsm_fPcQ=MO<^-Mkl2A(+YG+%RQh^C8S-#GSH!a>Dl)r!c9Uk-eLYXe zl%`ktgtwoq)Wba}c*k9Q#%?n#RM=!4f0wC x3F~SE@#B7l;Rx(J+|i=;6o$ z1DueZy$R#-+7U!ONM*kHZn3T(9WT2kNE|q1dPB=!ZWr}$jLO^TMCJuN{gt?f^Pga_ zr~(~cTuo#H=T=5=_*ZXT@h3=FOE$XtQ$UOaNpp@lVmv)A-w(520 %#s4dOf_FceZ=m0 z(wDocg<2MSe}4{@pj91yhaQ62YY+o=rJ@zbe>-0(_k$x`s1sB&4MP^uZQbvRD*1m> zJ!gTX5w={bA}z{cs#>6J==8yZUF>gjuK|R-kSuOyPt=aNm%*O!?OSCIv!@S4s*%wf z3O0eDAp)`!1Mi-V+wL$QmhgLQ*bb@^WI&U*wS!X|*l1`Di`+ixY*RithX(hc$S=$q z67JO(0V;Qflxs@@0Z8U;ETt&$`8~_dUzR)?&W9>2AiTO_uWmdUF4Ca)M9P8z`vTt4 zJu3;z;=YY`NYykDwTujAftcWomA}SZVu#-`2qO3Vv|QEfSl&c-`SUjn9$p>+i)gQ+ zVAM;ALGogXubX{cZQ^FXqwXZLlkwu-8?Iex>0OD~A1)CcWzAk!jQ(u7Dy@$t-SBIy6oM5Q@t|T*ZY}`Fki*wb` zDtx!P-?VP|5?6YFNyErsTY|9LXTLdVMpKVfexN_v9)CH8G6(shvD`Rpk;%3CS8|8o zc0q_9JmZfe8D8Wo2ZD^rkb?j&63+4iuUsagMUcw5OF>a1-Ru%!i;k{AoDi0>c$-9b z{iS5oM##oBpL;2nQjH%;=s2>$yJ5-<;WZ3z4NZOR-%^WoHg}p9l=-~0^vUQQQQ~z| zM?w2bBwjm8-nPUBDx;2ykd^|)a>7{y{KeZ==Ll|4geun@xx89ElYv!RJM%=(mTee- z9X?UbmMSVU-=i`7_s+RWnn3gco^@_S$m?w6#$#%&t*91myWFcIS;VWlsijx=@gT1| z^8bcG6(D~ppeOY0+07+4mpzmy6zsnKhc3!IjgIxbgYjvxyzyEKs8|lw=f;YfVgdjX z1l16!lMmG0>pZni`yFg#DJ@Z_mY*c_+F>(!BVlJW)-=XNFa370fn=+#p5G133fHAY z4POz}xGH+5jxUA!z1N+cG|Yg~$|Ezhnx?&8Wtt7a`Lj`LIA(@7?+-|3kZgFWsDVf~ z$8+C?yOPMilx{a% c+wi1qWK{a@P8VPte4oaFW_?(qWe!40b zYd11ib2WZdYOOyHFTL62PvnrM_B!;VtL0m_p%QMjW7=@wCHRgxrJID0CF_@7MqJXe zk2}=6>sPHFbWV@{;BFp%j&>dgiJiY@kjqddE)H2#GhW`yL>jkfcCGYB6L08-_Z6C8 zlOzQkQcLq*&6cL-T)c{XPy9uReEleLObbifmzG8ouX2E+*XxKC{b08Xt*6uf4QT#$ zB`GJwAo*3y#f$E04_WuomN12_ux70l3BZt5`7QSk0K@t1?0&pbr`r7?Udqzx4U7w= zjL?6e)NXY7z+bgBN6LK2M&M3NzB=653itnY(U4Hm; z73;V %$^8w)?zg63Xhd%99>iQ{31m#FdFxH9q@`ZWE^G>~h4gb4I zkbsOOy!F1q#e4Z=rpjE*ra9#sUi>=e7`Bhn9r^DtPP7IcaC$0%#&aQeXrILq%AEf< ztdlI~F|su|RXQP_iJ7^viY6&A@ga+CU<{X{So&C>MC~DaV|jumwf_YtA4V9Kcz#i# zie$|zJJcId`r#IW)5F+z72?#%JBHy)t#MGCg}(QpVWwh*ag7gk}dN(a)P>uR~cY zO&r`>?ak<9aw=L{yec1wUsq=1GAj3!BNeN?)%K&)e#o?o^&}KMveimVM%?(>d#FL@ zRg4DxLBm|ThNRp*G1FI3(KD9An6e6%qZ6uc38pPp`-~{VfQoYz^7O(;JgRuL^NSYb z$$wJNo2EehCGgXq!_66vaa{?|LeOIeDz+6?PAsL~%w@ypP0X-Xow!txijgrOst>>e zQ_#z(ty5YU?$EV%kY#|{&|;d*YJ+woKyCX{oyp8%Rz1?77;dm42pL`Cm;@ROfTHdW z8`uNDlDlAf&iFN>^Qw)D_fGy;-)-Bby|SU z -)o$cYPw$K~efGu?&r8EEU>*$@ zfwBHj)Csn+a7M1|0V7TWT;0GRf5b;bPF|_^=T8Dxd9Gj=MW(0*hHtIU@N-yJNW?!7 z hR=QJD2SH_ebqwEP3eruFC@UeY;mq~gK_(9o{@(WJ zqSnA%8Vail2_#wZ7f5#$Y0@=t#L=FhNFhUGvw0VD?V+exb`l$0e|;+H@!0mR)ynHE zfG5j3K2t(M4@VW)uQFO10v3_6KrKXys%ZbDP!Bynq$WR$H;pZmIdLb7=!*(XwwU(X zrF|P>GYMM*#iB=38$FliNnHZj+$Ya~7 rIh zEoaA2mpJ#@FOdVdaV)pn<3DxPL@wN=v*j0(Qn5*Qg#QbSQvC-QJ%n68x$a;$!B}Gn zM1F3T`vliv1gZYoPaEkp)*}X0kjs(|Hdf6YfZ)aT0E|97k$F9fL&{*ToPHHGo>VnS zcN#IujR4fkFMpuO-Wz@~!z9LG2xsC2k=3~N>YnzikBC4PGm>;< GTM zuo2*hN{s~_>~KH(i`eT@qyATdnJNPGhRM>x_TQG$l15cCO<@*Tu%gmFr$F#HVU&w9 zs&}WW(8RnM$kHtr9@F2PK4||N6uWj@Ny&D?aAgRF#Rb|F|8UFaPj%yGyY(y0aPo+A zfx^uxPBh!H*%_&j4#Fv={yXAcJcNetF!UF-zmeH9%$xFgVp)POyA(fMx((9(ni@(m zk#1CNFT*?#`|5rc?e^CF>+PMQ#W~+F?-v($^glmiUsVTUR<6+CFlr7SlK-d`)|GO^ zwY1!|unppMrAMK|C&<-_q^^6STp)w@g1QlBz99p1r25P(f=+YjMuiN@YN43pOdkYH zlV^~U`hg+Wsdrf6=3@+lOvr8TZ?V|~-~(}lfjI8;pVsv`5I++*o;nKdn;0J??=He_ zTv!kJZC2Qd{n}?s&`y` |$x1lRj$!9S@Cw&CODI zqmG+|`zT3PI~mdq0K*{89j8AbH4p#x>nz%ICNhoZHy3hzZu#W7$K4MFGNVrxNN1uI zapeCY@4e!hTGz#E8%;VW9U`EBf)wdRBE3sd0YL~w1(c4`ghYC8f;53h2LS=;ibQ%9 zq;~>@BArkZ(*Du4)?RC`a?U>IcfPCdnhRPoGv_;=F& s?pDb8ba8W zd3or#wgX?;Dq|N8p=oDhq(uO3*jB?tS2_UaZH-JBFvT5>bGO+k!`@xU7#xO$K2@IG zny$a@|L&bkbQUW`*c&)v@oVjB-_>kKSog)+9DD>)pY#Lxiom9Mbv~1c>cIZ3?(TCJ zw7?TPM|u^&eAJA(P6LTwvg(&QtOAW+AtCay1wl7)pqcN<_2m8oWsmhb)WG=FqLogO z+VXkOnIAwi>^}mU3H$u?lPHZ>A{2rC4EvO?k+9-mQ;3!l$%8_X=AJ8+;pa=$)VB?y z?Z?n(9k374!-HmK;bXVvJUgVgm$jvy960IRl7bl=fhq~wc>OMj%k#?SZG(RJ^DYdt zEYN5O=;o);gNzYY?E1_FH6xIA>M#E|97{))Iuhra3tzTuAoVs?Tz6K~Slrhb{lJI) ziH( j9Y<6--jZx@6hT`!VQMb% J&v)|5=Syt#JTy%gpToI?;9^q3KkUB%DTI~ihl9iEf)fcG%`Hr%Rer`ZOY(Lr@Y zQ)~b3UGQo;XFUM3+rnS1Z+3$wW7NJ6;wrfE$#{MOHuq)F(X&F Ltbv4q3_4@eHSf+$Ad>-|T1{WxhMWpm2`X;MnUdWzpuc3Av)nvc^sNQY)hH%Es zpy5Ih?%X^YJzsvEzOt`|-s>KIJ_}52MaJBo1Gf%oe?c? uvGR--&K+zcmhZJF%-L9C%@(o7zUMo~xwAp6?Azi#=gj0R+7{T@L*35vFmo(-EIS z;}br0^OErmtLX9$4hUp$LoiaNpY;cg0l`1f5k w2J^5X$4b+S^_6q-8SscL{4vrW#MR4(XWWN*vm5FstS0v ztVR$sY)X+=o0gXw`u-=)EQbfi9G87*DZ0AL?#nJcblz~_@GD-9^f7kWKHc!iO2|aG zb(fqE^+i!<*whNNp$v{NvMi}STn)?KCvyOQcfu8ii~vv2 ~?W%JY7q>$L^GcWm+px3b`5(xFoTCqF3(AX_-v z$>i=TSq4R@{{1jG_DE@larvdtO->eG$QnE8WAIRamuQ>sy~XbfIs&Cn&yBa@4 b@|gc0EmHALwiqS~fOF^mi`e; X1RQbT!+%~+`GnrYM6E*#K1^Wjy}KJ zPv9(H{OTf())KpTRXWe+42NBSn_!()mWLD#j(9+hT{>gd%Jn5wfO(C%r)U-y6W|Cu zj6iBu(X aaG@{*pJ{~t9 zgV=F7nP*j#+NF*Qw&+Nad2Jjt_0A^miH3D^A9ojuo8pn5!F;I#-REs?$H|KGQ8|TQ zyfjIMh9kdSvhYW2o~gtxXjD2J^7QSFe`$d*a z(iF@}`mY&ji1*5UH^^FKPouRY`Tax6QV?4R()qAUw@2lAXG+*i9MEMt@JiyW_2aeJ zV#?=sip=LE5u1~`5(ek)^>?s)j5{@lN(xqb_e-GU@A7W=o?b^EnX_*gnwW%{iR%Yz z$Xr_eo@w%6q)S7{#2zG6N88a81__8c7HWA0oO5EoDb{iMej(`iiZ>XeoSG>g=2(0) zhVa=NUF=Y#;KLen!6fV)=Kj$)-idl&lH@j3Yxggrck}pjO?9?^o<*xY0kv_{Rq>X_ zqZVj2OBS9R!NZM
4$p(Slud)cx1av1j=+9Ea3iTEoWNK1?)70(3WBJ<#DI*!Nl1 zU3@e4{!2@j)^6=}4Ry1KBKBC1_M}u~g+N0{Pe&G+eRkSPhuolsOq{9X{gvo_f*%?G zd3%#WZ=NTIsu#8(lp5mBx$l-p-TPE3M?g^s;BrogfL#rSI8dbplyEiPPJIr4Y>6+q zj2pis_<9^RhmSlOy?f@)085{HPkVQsQRcV*4%bqY+p1y4zXDs|3DQ@u8#>N+O2+~~ z$#bZ1WWYQ~8=0{GAQY$wh&Z{E5)UuMeD3g)wDf&U`cD6WIyfpyfWTt;SV<7j9Qw$E zPU-`z^!w$v>XA;`N7vs@5FIold7!{g;MpX6Z=Y8Ur;W>Hg}P(8r-@<{@x !h{IBJX?Hv5vwT o+D%@g6F%Ud;}HfP=012aQD6?z zMe-<{cvA?3$=hl#X+D@e*5@cb=-^nO7sI;Un~o%107#-K9sKeTBIzjI{+* C9-rcXd&}-jN3#v ibzjsRI_DlcPDScZbavxLht$Yuqw@~LT&J@$tDoyMP)Zsl? zSHz_j<{UhSMAE-4N-)yiJQm`z5M#9T%v9m(L|ctgHa3!^Z9r;o2Sv=KLHe(9&^l)Y zbnJr`N4}Ce2vQS?Cj;Nx*ocyXSZGdJ>DA>@Psm3Ue+l4BAPy}&6}`ND1+`5$vf07# z8v;E!rBuBdc-~ooS}v!%%90poTkr1N;JuiV+&tHu1}*xt@VYit7+J2woACT40FH6{ zM*6-Zom`_h_yXXEgA~`*6uD#uil)Ai0`3N|1)po-L$JMHYcDrc+U}A=3D5cMTz-O0 zw$;n4s?T(U%RQXtZxb;i+*AGsQcBdQY<@?jD_%XQOV%qjbQ?Ke>5jX(XXa^zx(}bu zU##My428Ey?=*$biqNRJT6JR8#lf$z4lE0b=erhY_YP@=ee74fPNT7rL`Jly7g zCk)IPg=x$S%)#L8@S{wP;Rzao@f$#bfeYZtK4s1R3;Nj4$EW+5rL^FmI(M;ZK7OhK zi&gI6LPy}cRSgQ2eZXlojOY+na2#k2$;W2Zg3%}yAM7oadwd^yEfy3%t|nGI@N;T4 zz>L{D&wrQS;eK!MZrt-m0qHn5-j8j0E94oTKgR}((}Nz${IE?=yRS->a-_usK{J&@ zio*X9y7FKDGjtsks0iv KlSGYm}oPVay >UP!4+uK(Y_O_KcoiGic z*%_45l=nH6av7KPdC)qUO^;jn3RBBdtg1|SKrbUA&?(;c3WeU?SSqT@nvhz7vkuZx z21y>&@TNl^PYzASUSeD1#~e`7l*ab4w~06146HwgYEtGy3c=h@bY{G32p4GZ iju7RUq{vQJA!}mV~(kjSgYPOU#S$aj-?#xcIO|+WEE2XfTEdVfuzQ|E>)A5DY z m>R96k-**fvXy6dCoMYEf-Nl2W0X8*CsGK&kWPHbve=N0sWe;xO@;#Dx~Q*itb zwRC+&gNV5PESCC!a}q@;WHFbgX)XNd=KC5ep3Mrm0>RNP&Jt16U5D~t2F6(@3uzY} zjfFpePZ*e;JvowwqKRWyY^9~w2fvw$_zwr!fSKdt02lD(sgP?bk>%_AymGh{i-j#g z1fMgX|MVp6-m1psk;$;ZJ<7AIUNP$7J|~A=R#tdrE&zqQAK$W9&rz;3*s*mN8)gMi zPlqgHG~~cJB_K=1XPvaatEd;sRHT|}v*m!}VvbV}QOOo94eZYZUlrl>+jf!1(xFcp zJ0EgRMvdc-1@rcLZl62>ES`TBamwnn4ke}T1dqkld7ys3TS#$8K8vY0 94|`*l=RDl=Bu{4Z>~G$`_qB)^UdF!8+_B0jWGjG~8BjZ8<^ zZfS6RAjB_CtLr$)zN_JM&kj)sYaf-}hDlY_tg%3EIXT@FDhqqIC*tJB5WD??Qv?P+ zH7UHmyHRteP0+VR)yzVu>r-!GqX#Da4L@>j8q%7@2~o<>l1SDv8Ch$H@xUC-yTI1~ zTnFcfH*B`v*vii;_+=z$9tXIwQ_quY57IM9hgf^au=e~y zD@E&;#k|3tXd5@-!l-g0BVzC0KsB_r^t}80KvwY^u_XW?f#|?q1u_u~P!wd&{n_N6 z-AY5RYY)Tast+?UcGnK{vFdj4J!D$6;UY8|--R%d1`hR@j5S3Ezw(a|sMb%1jwmII zNc)P_YCT%C8&{9s8EPU<$ZQfVXp|6+_h=I OT5rW&1Jz~ z?=fE^q_6@g)=@%~-QZ|(;5%8o5j${Xd0+{fRq(@+1^^9gU&4FZ$E8MAS6kKvnRTI? zG1#b8L;Iu&9u=3dS)GH)h@6gfzY8-8F;!X|%67Wz)thnB{tss1ZngdcSwP$I)rh+T z@bA IG)loM z8u~rjkh_^B9ZYglM*p1CI(TyqElgw4)#fCwuj=f3CT_rkvDa5c(ZcWvT!zXWV^j<> zEB%vrs`_H%K70C@a-Q9|O??UeP(aRXy~I#(w$O$A$uXeIUgCN^8 zge(~b#Q42F8D|!#f$!|A;Nwt*clp3`GOD<@k8CIP=a6;CsW}x*af+5CQF8}DJsg%L z{Be!~*tQE+^O~2d@7oX~;T|=2(~%l@guv3NII_a*F9!2^12Z^*cp-AL%U6L69Y-RP z$lN+yZ~Vy%5xjky$*Kp(>=RCZdqhb(mLs>&_QO*tVaxAjopbDpcznTMP%fqGzff-N z=btF|&9~oCZlj~z_1SkJ6%$=kW9nGGr0FTs?55 6XaM5n^KJ3|C;pmXWXaZlU$>=$8K6-e zbz4~3KRKDn-oe?Nelp-EgLU1M8+lrWR(u{j#jPy#)Nx*Nn6(CTOzX6_Q-5Yv;?Pn- z0)8B8uA_N0>UW*1JN=UG`61vdVPyxjs5j<*?uUBP_WUoqr!=aQE@+v2`My~4TCcOY zkXi($URFD+n1oAw4^~T0bdwzA2;f#Cr(laQ?~d?l#E z^KN!G@b|wbw=UIarQ5Izdl!wJk~ANE)NkiRnv5w%9H}q^*q&+|#QQUVGD^QpOqhDt zv{U>G ~ zalOJF)ItPQKE!#VfS)9lM$uLM;79wIx%V&)8LJ|H-ghOwd(lFi?#O%o;P)yM1CW!; zRK4}#(06$;7NTtgIa?G8^X5;mw?hQbT`WnS>Osr*BJPVOe64=RMBl32+hRVz)y~~n z(vQb@cX@j^y@FU9l8aW$Emk)(<5sYH|D{^Y4~@!CWgZGX*zmDw*cBBv*RYe3r#!aU zZ|?Ymy*l>%)2+X!y_q#RbnRxex)yY#1N7VE84aX{O|#J$&nwr=HF#Vj$sU}$FDw6L zs*QY)yA~8)njweMC~LWF2-Bh8=DoOP=qW}oyFD!S^$Mp6!;23yZ47s$VS!HOtGwRT zf)CV5tr`bJNA4vnJu@*wcXdG>LBU59@f-Y;%$a_&)7=v%dxZH>xJcj&eFhmbG=2QA zh!6Hxh}$&Syifnr-kkh+em*E f6W{o|(r`Rm(d+|yPXLDA)L?bsddQ>soQj9r( zi+4fXO_nLxUGvkNF^s0)nUo8Spq#*m)O7^S@k`B8QyEq%y-aw$$|KP4UTS&mKk?|~YUJqi#WQ^e zqm!L2T1WM1iM+4lv3LBjOd|1rkW~|aY#V{Y^$p~!m{od-xH?c1q@m#zR`W B3-$pWKy(hfehemjUkrNbYOaDm2JtrA zkS5p8%H1l3amf0Czu$BcZgkSK-V$TKBlp!M4_WdCI^Cr|pgfyu5KNsQ#X`-ChEcVl z-rWGMN8qUgrhpF-Da1Tb8mOp`HaJXnx?y*3<&k1b_jx`xL77;VW{B5FX3^U|&=Ply zJ{qNS>#E}L67gnj_!C|!^ai*n6Y_|A>G-n+gjSSOoJ(nJva4$o9mzI{dM5`=5vA;? zMviIX*KVwTjL;#)K)IfDz~KjfpuqNb|1%1#$n7KWCknhstvrnMZF;wm zeGicBpO0_mW~u6Q3kUjeKDM=MEtI1HUW{$2ZV;|NgzI#zI;pu4g!kxO$zwYnMkO7M zW1{XdXZJWOtO!N6H-5jLdPAblqk)R;J&SbImZ+4w;) cz z4!a%EAv$#O(rgI{0rpzqD(W$EKPI;M5^^?`En!un&~cZpZ@QP4;=bpB=$%-Jz#p8^Vy=_WHEj#ekU1~xZcGrutHVizvL z^U>d5uo(P`V9+z(M`3Fhyz8&iKFQU{1r-8nW0FTj+EFeux2jg3wF&)E+SKvA`Q+li z1l3tKJ =hCYpO!Wpep}3(1K&eH`|U zXncF$@}W3~Bn26AaN*gAoB9lh=@I&h$;8l_25B>)*X5zgh8W3yJH8=%rANsRYw@^n z95FnR!lGmLfd1yd*(>~v2A9zR-9^RW6h&=o aYa!^Wo302HB*92{LYiAq=g98W z9^+>2xD7IT&|X(DnBbQf%GLyFL)|I`L?SC=lHDm$LJ==r&^{cf+k}gsKH}5(ph0>g zW PQ7l#ScSY&Y&C)H9qM3pgrG?02`3` !s8!wtxz{0Z9l^P+Ufca1!sLGvHSzX$OJcNvj jd;5$WDihBi>Ae&Ch*}5?vbNM`51~=ri;Z5B< |=~6^G%f@GFar53tr6P z)CaIyREZ}R7xN1g7Pg~)1WTlMAw zVWqT6Iy!>&LyX?GtK(gOhh&(~B>$1z`rM1(Mu4RhIckd7(Lb?LOF+7@$+I(l{V1E; zUH<|Z-ID&DDT9Eb+S?u?JHeM)pFAS3PR{L?JR`<+Plgpzg45&h68R_?8te083PFCS z1n`XN8Sc=FK$_`K>xa4E3}RiBpfctwsHom=S?Vel)xpuMR$-0;g9;kXr!g fbH)XvC6+Q;!4i}tC;c*HVCAJ zXcUu@ RQd$}Yz9kG_58Y4<97oUF}&(R6pwyu;{QzjQtAG0*Nps6 zG}!M w@+Zx4b#i52j#K&WWX?hSW!L@0lr~W ^-!#)B z)?xvtZ@mN}&Z=|I-EauNQjKsAk3v9!;+={C|LUk7E7SFw)-+dWm7&!L#PbFaEuB z@=qBW9eapQVxYP Yl7KQJ#s -~wX NtE`mm*H( zFtOCRQ?AI`A-(~R7QgBXzm?oP?HKN!0Ji2Jn25tzRUko 3i$bV^YvGww>k^o)tq?b7jefyvZ(Bu`a91HOnn@I z(STP59kh{Ed$$fghE+Ujy(Scybq3CTQBz+~Iq2Ep%PPvYy)Zy~!Dy6dE9fjGLC^bP z<96h=&IaqXS`)fSZ>kiRwc85l- u%>#0&_m%-y#0*n8M5!*WbqkEW!f5b9h=bZw%x>guo8*F*!KkxCPrNfnq;u}Q z3o-?2;m_|m1y!AI4z+`}`Db6(l!N5n!Cel=-5C;T#<$~MAG9{uX!m)WCe0{6%011W zrH7@jalA03h?nl4DOJB`D5o8!X4PbVdO4C>U$vAYZZXIOf$3wL5$ Y;@?v>y`!n+ty9;#FVoQ_s8b(4NEYdnWH{ @Sx zNE2B_vtL`o!taS;`a9mjz6=BJxnlb~t`=QzOuY-_R;1t8NyjF?JZxK@5al}y*!~pU zv%T~#9#9f7Ac0H_w(;XbiF`#;%Mwf?0qc9V*{sVb wq Y>wk(?=LC+|0ERt&uP4Io3scK6AQxQf|eJo4h)L=B}pP+wI=?~LMH1EV~8 z;QjGHj`}gBT5x`lbqSzjCOb`LZ%4ZF_%ou2(lSia>F|zC(T{APH?r zW%k9lh_f_LuUg }l=4u-;oc$_M|WZ%55T3g z?CapSTc4saOgCJ1rDUyzHYFN?rg0rhR{Tqk9~ 1~tzzjK;w9ag>4l9tQ1VQL&KgpJe z2DuE)xX>q)UPQpi`rn!jL5GMF`Xge0ky?|rpLM+^_L3$Pxxs@6pcp&}WY4^jHA;PH z;SFT7-JH-swa@y-bw@(J_`#&2!*a ~Vh`NJ2*uQLJLq=P1~gd|W~02@-U_$w{ES^OL{dnT$I!Tr&!1V^(2p#c!yGj01Q$ zUhJIB5OI9f @U|s+(`k{aRWe_@rbA!PmWEvAZ`w< zo17WeE#@iWCXsxF3!-6+9Grp%MylDMNR$!+_F+G$2cg1Hjd!{=Aszii5;8>X`Umct z8Xl+W`cl#;7SJ-9ab_t$t0f_7nFS%QUdLN5@fYsP`Lbrv)FO0f$S7&73xG{~4EnOr z=D75z6A`s@$7 x)Kl**key+u zBgbSf;kq9jBl+PO?9vFaqW=h8n_a9J27?h@6PPD?Lz26bN(1ECR__#03z+_wLNFy* zdDjt2_rrhHDmZ}#nS4A1+^G}jqb4FTyDK=lZ}#iR;Z8yuN#P6RNFuC_aX=xmvQDvu zfU&Gg4<$`UUFHYe5GLRCP@RexaOD=H^>J`R?R{gtYa<}x8*xgD5M#m^Z^IQ>aZ0S{ zkX#K@7#+8V47&@X$;Xd_a18Lgn3ljRRrFPU*VgqpzC;LbJX=00j46La(djCeIS%R( z<7n_>&%OCst{c>paRD&ePTV!d{vN`N!qBM5!6DZ8em%vWxN@4N)0SJy+DBT`Kw=~_ z@qpKbsF%zB1=*(SJmTyc)t3afV^uyw$h*43B!I&!B9BZ^C*sbFkB90k7TL9$ c2x|9w3vbg5o~iVj)BIexe^(N3qH92(XM~y$(!{5IGR&WWEu)rOyV@ zaie&`!7* *rql{GxjP+@tPI5YJCr)9k%85VKZ!6UPfMH04`27`PhXcaR~94G zB$p64y(n!&SeoBpD9N3MHN7`Gq5LK#(UJl0G@T$5X}29{49 uTdNczq!1Ew zeIwc0Gn`%M;Gqi@S|EF*si1+aUHR?RG9~eJgG>>U^p td3p-0wb> zU$Wu&K4tO&!iKYtN_2e&-|$8sp6&8X3j>vB=9r7Mk)5pDC}mkFE_+SU{;{GfyftK| z81Ea~d9L$G-sJ~Mel}dCX9_NTYgnbIVF>LcGoP4x)&+X|i_5#h+57I|A^h1zitYmP zG?s}qZAR)IyaqF189_S
&1 zkF?^~7Z0whHf3xApCFh=@uVB@6&g%QSy@>AA)OZNAx1*mkM97Q2k^o0#<_$)7kpRp z492u*sCG}o+(}@v&Kj}0@k-aU3_>o@t+9m_GB6*OGE*FLI7Iw-?S>9}wYn1;;#2WGxTcgq5=v }=U{h#4y?f4_vO7;z1_a*xI z+{iP #846*vp(xFyjyeLbuaq61O0#hrQtP zIr}ML7)6sS5uDZ4DX_&1QuoV}@6dnNQ50`Qr3VYlT5^~g!A*SLx8V2~A2IznD}3hQ z92azzFZnRk?_ 2d|+aS zoWt4gfZ6Yv5KZSXEXJ#U(t3HF)&HadKc}AS&^(HIm>QcId}~V9DA18`vkLwm8P);Q z#7Wn%hjKq)OfLIh52{B@a%=DNtsEs1>as_`uvHT@a1ly0w|x+Fhe63P z7vX<)lO5IzBlLTIOb3{o%QmsM#TpD&p-O3Tzn8}?Mx|rxW9A}7B)Ycs*C4YofI~Hb zAl?V+GTHeOoLB0$<`*|!W 4tI*HTG1nhL$7bwL zak@=R&l~UDpPmYb2fLfI3yzGh!@1v+{>qT+o&?dzhsC^n^PFo@|1x*oTRIXFwW8(i z2Pe*^%V&a-^wZ;8E>0!Wo`qnNPgh&>+a7qI)38>r5FaYvl~R?ZAU{mIKlvq(=Pa{6 zM+ctvXfbm~XMuITT>k##Su_g|j}7J>_arm%e#*YD)XMrvwBniy99&0tz&m2M#TBY% zp4G7r%OFd^?(B|penK`+o>_~&>Em$y--5i4CQahfe{_pW5H##DhDXZ+uZ%U%3o2^w z>3oS{83jMROE3zXl2gKSnp9*I%teK*VCE{HW#$o9o+35J&RHA9gA3ksK)R3gi2=y2 zL$7cC1QOgQ?#FuP>H&lh5f5CY%_IA|rpYaQ60)`DBd<^0!s>^W6S?oOBc-N{`5zaN zExdyJ9^+cAdw>*XqiA?+jE(wG(uha7Vt^|;F4*YD9cP$AlW!RX$j*-Nwt(zpjm8!g z_VSfq(TZKu)$ eT)&9@waxcuV $O@x*D)8pRI0j~U+ zL4QSD_;LLpO6WRxNxvp5r=3S>L12BiiGf4OyWiBOLJf4*u^NdSK#K(;+ADOc2WE zJ6;>F!3FtSRolz&TM#z)MQ{E-+)|_Vsy1QFe@p)NBr;9zUP6Xh&`a54s}INI(Fd8a z81Uga t0t|{PTEj_6YOwbo$E`G~^+)ZS-%~ng2r%IqqTZ>$qra_mP@C^i%`*mH%LON>yfb znFxW_5{KidKfd%b0i!YAB&3Q%SuLD2xHdg!f%w0Mo{F_p)3WV+sA6W;i&TPpO}5r| zinE6`HAX(x$lk%4a-ipn_{sjrkH4kpFH=7>@#gm3;yCxBzIoQ`+L%zrDLrQ?XDy(i zvcDgXVf5c<#v|w$uDd5LT1wa&<8yi()57dV*elaSlXl`PVZDHGM%eJF==91B8mu&l z9ZVtg9kQfiqWsOnx1VrV5n(?#@$vI8jc*EVx2rq9&dl82OA+Bm#r2@nKEqx{V^trn z#@XaOy4#|^PWV2L#-beKv(n3^;~qk*ak*)*3n%(RaSD0J*TiTssPXq`aik#vKyirY zzV(XM4J;)A;qIv;BfbHicBz4DXmd>Z)ZTV#qI4g`l4NrXz27)u=JI^H+HxGWGfd7e zm}*}-FB1qvxp^efEd4G%PeY^b(eoy}N%viCes>zLFAr<@k#26ph9E^U+IoTf8rKGM zr;lE5z3~OV9)-H?dELkGoJh}NuU~qQ*YkT~IVk)vagoshyS_IqwKrU4AkBBdS|yKK zy)_(}D}T4sjyO>f;t0z_7Wc+!A@ivxv8gwji1RjFLnxQrq7jCytm^_-Nws^bS+)?7 zkw$B*xz#7HV*m&Er{p6@Jt^XH*d4_eH}MrSx%EloJ%R=QSwwjt!sNS0lodNifR6_+ zog*|ru+BSZ^jRZU{WW>Un%sg*e4bp7NhcP^kopyb2bBk+q9UaeM=xdoj3ML@4SUC% zVpnc3R6W*vskZKxch`QN;|3W*QfsR`Xhg#vR19$?@7Q$XSk$)+o1B>3Eskx~56KmE zdQa($J7(DPu@KmXt0|tLX&y{ 0Y;dXYgPY* zo-Zwc+&KWyPZ5u``5Dhx J7YbX?APAI-Q~@ Jnjz|`P7bfTo3S;xfz-kw$cY&r;C L{V>p+DcM4^h=()Pp1~ zr#!IMVFo;;!&YI{rK-8^hyouAy8!-WB(EK!Bu<$9Ket~T+*dGgzj0daRpzyJP!1ts zQ83OOYxo`n-98zZ9Qd+w-MR}-fS|ZxtPk|0A|34(v%0eD!7Fm_4jzuo{x|@ctaI3t zolq@nA4;>dzl~!epyfzLbFfLhTKEzvu;I=CZy|)f0iBy1r!VdNcG5%6hN(} _=^e28WaZdt3{MLSdlQwS1Rct@eLh!EulJ;riviInT zhan&K`ML3oOFB~^=qES7e**NEmtpV2(O-urSmY_`ZD*~V7ec> {a&4hfaljN!3;O>DV7L5Nm$z7q@i>C-Ld?u1Ri&!p?xCp)H2r*beX_3 zWs(JxhjD?1jUpSFAVOI?5iQ~r0?yaC$I352H4!`A*b>#hX)|L@i7R5;2h1%TD+HI& z5jPaOJD4M}ATe-JZ(KK0O<5Q?R{gD=xdzj#%mw?0d4StT1D+Qa!#)s 3lnmRo&wGMK(5HcdkiM>{w%PSu%7X&0lMXsbiL=)5i+E4-1*56`9|$ z`_z!rX(j5**?;-e2FRB#nJlaG1(K8YJG)TP7DWGeRmQGO@sOiY-=$UFZrd+hzS!@r zTiqJ0d}+X;&uYgis^Fcr_xs5JOeL*|pEBlhViR%DohliPb_Rf4hT(YN#NvQe#Lii6 zMK>aDBQ%$#?wAGG5`52UR5{!}H^W(hYGLU*Koj?*hAMgAzEz~c_nvP=i=Bl^9Xk9f zw0FFkJYBSjIg9@rS +*pM4`m9$OqAPRD42`^3 zM|VyKWbd&G?e7zBkmm|uI7oa4G=Kw6rtLRm@8Ndv)udu0sHzKq8rO}cj1q}HO(k#G z#&W?smNrCX Xc*8HJ4EdNhzX8u6EM#!}ShT;E?99u1s(( z(bBLkQ=jT#5&DJTr}~TkAl!qHzY8V5i6fCIVf8-Hhqaq2Nr@p|28(yS+YovK{Tj&= zE8d(+5{Hnc)eU0o)G}wKLVTM(dR{jzk_g(l;o1pdAItKn5SlSL>1TOB{8p@mkWh?1 zq;BB5j&7zh9p+1Ug;466Cg3rQ>Po6Vl{0B0URTfB_&Eguyd~LqL;$NMRHro$$G;pn z*RY8baZXQb&g;F;T{rp0m!L}DDQnvdnEL|4?=d5*?8XJXPZq9_SMNNv{qQn#-<8Vi z`OBE tCA`X6+(Fgfh-$>DjkGhs|cAlRDq^WkTYcLzc(6Rm> z_r!M9Cpo- N_?uIQ_`gYeJ^>OIN?VO6R;tJx5qf9>59DQA0ykBx*4!V zsG|I2ITzY#937OX1>b@*v# ^K J zq9tx$DNkGNjMpa|L#Iakz^&JS&ijARZ%NClGnr~Ibz<>bg^FTa4rAG=qM2C0jB0W#tXAkAV&j8v%oWK9(yErfAUBsPZOQq5b(hm9;GmjE;+CCj zhQ+01AXY%C%rcl2&t{5pY2iiaxNT~S?b!dp>;1^6uXya(DSoHNO~|nBi;&~KvqF`R zn2oJ%rBx#-h1*)usQAjun)3OGh-6V(P?&~sr;YEtL6U{Ox>nFglk$IyfuXMIip04L zF&9&6WnPJ28H3?jc9*?ij05 zKNRzX_W+OX@mXhSUz=#H54U04I=k4T5K(zAnn|M $j<|G(9H z*#O;5B$^0D!}z%HYv`Dc&FAKo4qNAiqBG99OuIkKdma99S;j;+f|WMvm3fh)#8O+W zc!6qc+o(UGEkWC*kKXz83c}K79NC@Y30X!Ce-Arnw;X%_*lA_CPJ0i^_Aq}BpIZmZ z@t1u4Wkj5`D#P9FM)BP)xx6!9oEGk&EV`~|=sGmdz_(iXj;T2Gn_|}DHgDw}y}0~( zSI(#!GK&>2{mbrG069MY0^onX`!#Q(;34!( 6TPTtS$ z!5U9Oo+AgcS8CnyR#sqjM(8N2?gV?g%wJ&Ds|EOEGetsi2r2#*t9|6Mj5W9iR(S)9 zrBW%?=e*sSpIs1j`@$A+Nv!HHa0tojfamQ8T mk#-s%ZoXCxN z2F`$6P2o= >OJ@4^KIV*egd3>na?~RCzyZ*Y%!!PLsy58gx%&cZ =w*#->1h^-l|3G@5oIlDRl;B=)KVPccIuC!Oe(jefwLrs$mNY@N#9`Oe zR*Klzivm}NYV YMJKUhJya!)Kw0rm2iFU8a54+b0fBC1~ix8hW zSze{>K>*L(tY&Mac(Bi(8MHMM`kJ@OZMW)95#7LM%s*jUz(M29tpwI%65+Wn70;G& znZ!|_8^jHdzhc|(k5(*1zc#&WjhO7}jqPNH7k+7ZL8TskB@d4rS>Y8Ir@ks{c6Yh( z5=NWv{Pi-?wz~p(6VSrT3uGDnT`Jo(ttiD}id+R$ThOn|VVm8rmp{AS6Y@d`y%X}N zCe!3@*V{n}-UXZ;a%QgFRqQ6S533zrN=`^vVb}qs9Mx;u2He6fms3!6BAKh!(9R?~ z=i}nR3yVfJ+>IUj!9n(@EEZ k;(vg5m3<{~zo0TPwb zBS1EE;wEvy_7XVGD}*cpw;|LMAH(|s4QnTh@{bXk6(K()e*MQG^t*wD9T8aIRyn7# zaQ=g70}d#0)hVSwY}{qQ=$^+f((WGpqRxLO?eaeuIHHjLA?;3$5I7onroz;DCmaWs zisPnmB=(EYSKuVKzg;eyJ@}?e>uA(l^7PdeZgNVxpvUrmNj1ZBe%Vm_07c^DcQaJH z1?7$7YPw5JE23W<{18S=33qn>+y(muppX`c?4`Cn8^*mcb QO1tVIsDVOWpt+mj75jPFyTB!Vn*kZ#P|D+DvpLF4|OjDZbw_ z^t|c|4kgyqFev2AJHB%Y2(o(!RSd7X-_Uikrt_eF(#=3coH#QT75sY&xljMM6tey! zdmKm#nBO&U;(>SS?4YV?ko^{XGk6tTcfnRjZkmhrMKBP{kY%}f-GArm58MiL0N;he zhtMvQ7ZnvB&a{2abCK_~8%48HJjXjpU~ZVglF*p}M><54cMq$*=kf?+m;$f1_Qq>h z(DE+p6N9&$grQLp5x_?Tkl`l0_11^j&Gx4R%ta$~x5O_z_R5(Sm5N^j$^~h^1(b8F z_wI=P3@FcD7LqZx_?)f39$% H z&|`^gIna64kb9Xl&z86`w8U*O)g#HdX4BlvW}15!MMs*n_6$XU>^~@~#@pIjuH-Ql zIdtLQtbo0E<^NIlmH|=qUH`8N3W_vHgLDfBNHfxkARwv45Yp0JGlJ43N=l4$N=Ql# zjdXXnGy@DVOq}uZy6)?F?s(2~&i}kQ`|WJ@-u!y4&-$*#{6U|JVBh01er#^*am&$# zg i?##;lHypqp)rN zzf<8t{s$E T3F*J+Imw>Ac)kU#7G zNw7nj;mc9=go+lgFiIw5*-XcYIs? zprIc>D@KIc1vCMg0|OK0aQlrL@ktpyo~ZQ(leF3-H4Dd&*t~KUm8HqE;AGYW6O{Z|jyt1=I~OhD5Py0jIFWP)iFsv#R)!Vq$OUEd&$Yffv` zO`#vG$li0C)r{(WMqCP!3@G{_yFP&JdBK`b{j5SBYasRcahL(wozy2~dDSG_Gu6}w zMNr1TnBP@wZG~`WP~51p2H2;~?&cp(S4?XcwXd#T*fWW^+e7X4LW7zIflsKVWQ)Qv zP5Z!*@g=$w6-YW4*|5zkmwkVhs_SEdUs3l)l|@88x93#kpx!w6G~K$lZ!!M22>0|& z3H%UU@`nmn@BD>q=KN&W9e8z>we-^u2o?E#G+Cqmn4~9X$iE=e( g ow Na33XD|w#)1DS=rlGbQuCGU z-9^x30bi+{3%8(j3n{jU;79-MzjU>LBy0`XeS~feupU8a`@CyH#|<|Gmzm8*#F3qI z)st$j{M*4i^cOreA;^3K89!3k);m^CW2&EGie0_9Qf|KS4MqNi8iGx-pR3`uPsb1H z-A (iOsx`7u!=0gBpUEg*LprE9c?Gcw2NMUEpe!^NurB2fUIOv3 zKs^y@f8jqiyLf$5W`u@P`4}vL-EppqUeeh5+id{{&B-1$Ux;TJyZe&vR900zemE zK*-<@z}z{r95^pr)3gn9<{O=EG1RlZy8!IL{8;1ck1aYeL|iuM$2q8`gNv&L;Afe4 zqftebOc86=y_eN~PtL~rVA0olWM@|}dy}}j-5TkrnrPrpjr_IB#Zt(}f7042i~M`7 zZTgCQU8QI(tt=_;g{zmhx lQpOVJxFt6=mG*aIH!LXfenmH %Y)(+j&@G_I zItz3bZ-jS~W!QqvpW{JykS3AslvJOFBl_m?KaxdXiTxv4bdMkwb|}yS%s@IROJ^Nm z!a&L9o e$}l&eu!`6mq+$y_{?L{0kL3Fz0v)}m{f0Vq^=Fl*!Axvwd?Se&@@)XA zBKF`H?XIz_FHCry+;t18(%(*VD||S!c*t`JjJLGR>~!O}$M-ol%!O4G48JBTo5tRZ zR)4~%>iSP;Gjzngaq;VaK$|lEJG7}i@xMTu={)}(ZG!(lL!0s>JiQOr;Zg)AKB$np z1B&wKu;&QMk;K-|*b*x2-7whqRGYlCocE6*|F$^n;oEg|H7hSTC_uM{t7d7C1gPkK zh0u6`V#8#{m!*(*4dSm{B}P=rc+1E>ZGL^lag`rd;?Fkz FDT+N)n+-!p(b*_|ajHz3T{6V~pGQpBIgd zlLn4;wPo_$w3h6FxPo8CcSC*wPB0d5LjMck1pha{dB)!L@xP=v_7$NKr4+iJAdb>y zxx?2a2(H0%q{j%n==C_kQTG>pdU^Y7#J ;31X$TkpcWNoK_ML)5_k8O>|j>swm>r8&5zm(< *zz>nd zBje0cU#Vl(w(fhjzENYa2%cYKTB{URN(Y9p2xIQlM%}aAe7rVru2Hr0Hv|RNV5@ou zOM^NuwJbr;&VZ^{f+7I>NGI154SsG6`{l3Gi#1aY@&P2f3i$HJnzk%xk{JN~h%)Q} zg~6g#B%qm9&^WV&W=4o4nl25%eID!Xue=8BJ;B?6L4GA=7A4iH^mFx9jjP|`5fM3E zmy9yI`08`pkRQ-4eDyJhKdONt=A`9#3rtYUWYV%UboN?_^j#}8pEJjG1I*~Va_J-K z#mGbNmX(D&e@G0smIHk079}i@Ng}7BziX+sS}ncnl$D6a#+ttw(b2s r9s2|&bmYfj|nO+H%V zo!{uXMfaxV?KU-u(oJ19X3fKm=N^~_FJ8951JBOe%twcPTe9;9^9O_dgL?;2R$jUu zRSRg`h6?ZXjhpzvH~GHafuUxrFPguII!P-pOrdHsNR5+Pn5lne1iIzhZ_p^Z&)KSW z7Ai6zh-v(BGR{Zb79LIU$pl~)_AVB(HX1mSG`7$1IElrkUm3K|NZrA?v8NU9WbVE| zm^HFtI+ZG5v4E%Id^ve|vQKXUA=T1ID5u;tF^(l1J;_BMa#qpUD|+O^g3&XEyRe;l z@Y=F&{$STATMSp0p+Zag&}uCRurlPt@HSDVRneW!hNgnl^@64`;AhfgeNM)K9v38t zB!u0bv7OqQ@H1VJRx*NB)(1@djm|rL*w{NjS<&6Eo?R*;?9Z!U7d9!(^5->bp+frC zwOx_@*F9mU(^`suUA}u _#f~r%lq3#aQ_66rHTbLZED$z^*?sa+`|`m*6z@k{aZ %%T}r}SGR8-?*Sv|7PZ*$O_DG3#g1yBD0R$C`GKW0e3@Rc-rdWr zJg`z<;Pluf^qusU9*ZJ>>ul1Yk^z-|*3S+5vb|KXMQ;j=5=Rg_p&^oG@ =9 ?fnl?h(IHG>{}S$77VBqzwP|OSMBI8~ku`C3+rw!&y7){^ zKYr<8M7T^~&bCC^#f0%VvS>JG y1j^f zZDl%|Q*t|K_f$n-`I1n|rQ(y+rDx(dk0ubb#K#X1vF &TIeaFrs| Hh*E(8cyebE`2c5jhk_0G;T V6d&p%jvVBXz!D;H5*1>ro>L)KB(Zp{Du?Vluy9?*qqpA60y{2 _6O5T zPVLN3TeT0%ke*Z-5Z_0AZ@(;4tsh$17nCVzYk!iSXuF=dX0e=x7A4Bj%g)Op;jV8^ zmKeOf4dD2q$VU;B4&dPTxmKLW-?I0Vm2^iZq-y-ec&nx$(oe_%f?Oh0UX`5PMVd z<{QL>54sL2gUyv-o#{i3QOSq}agUy17{#}vo6<7hC>n;SZ-o&We`nMvYs7JJaY>di zcsGVOra6`;s62o5FoW8PU>El6XgEteD%@SE=aP+LqGwKw6u|tN*~Hg|YyQ?k^i{qj zbFC{rqo4WhkXObnL$;PA6r-H*f^M11J9*!AS$$jE4ScQnZe7{M#eImRmAe~j5~B}! z87#qyG_~9f)vC0j86AO=s>Hnh@?0sGj6O)nqlbsjP@2h0jV9Xpoac4M&^x_(kXzHe z>gwu(iaQ+_w-0_S!i8N^=gP*?kRzd~)6KH;>~~I>{Hf0c(xQdT9$N<7N4#XCIV)SD zm&Ua588FC1@cH 8!pWhjAowX@BS&Xqw zEr^|?uT~fT9^i`JY7WvFcglmm3NxK9qB?5OdPNU#A%(Ac;z|M38m-y&<{KUlV(eb$ zg y) zicU)AgAgi}-%Se)&ybjgX!03*{J8%1u!IwK_4C;@Wd4026c|bg+MZ6;2^S*%Di`HQ zOcs%IY+Zz=9t1k-Zv2EUlk$;|i9JyRTFs$~-Tk!+AbDp{5^*Z9kL;~k98Q<-BS(Jf zKUo?tP7QSSrGop^7bC8wbS~qP=bIxC76+G|<7jPFaE4B|E j5x}JyVFPhK~l~UDOhqugtTPh=cnb&L{ z_U0aER)K=oDqkRU)0Zfxi5m#|5V>pF#2Q(R+5Vy~0j5Q0RkaL&juDhc$Oo09gV8Zs zO7Q}nwf>-aXQu6bdjp=1X|JkE=|a2;V4y;-mD`n4#h`W>_WJA-!I^9%6_FvCrYDBe z2`1qYSp+|77{jF6J*KbRVj|*hZ}OMLgRmJMh09{qr-1FSp{DxLQ+T_F2~)9zY^pYN zfFFpR?E+Cz+wa_%&;(L_?}RK#oL{}sPwMS^ib>H1C5+~KqY77%MMltsSv)JFrGh5V zzA%LgbG5j;AmxPqKKZAO_WoT?QJA*f5_dX=Vu)!K(SXwMrloU=qPce?vhBu`o(~}d z!2>U&QydGYk(0X@S9o||=v>IF0{w!P6mYG`a_5pr=KCnR#tKJ 4qW5r6_>%{=d{wJpWsq~q| z+WkzFmt{K5YL0-{jMyy3GLMk9lKvziotUQ9qn0ZDL}pb+7i&9|-SN_EbWOQuP;oZl zo^iSv=g s zYk8<)B7-2yPj|suT83c6*}1}|{^9Dt`FXbF-UGfE*hAdp@0gr5jcEp6p$4x9&8RKq zM)(Z3L9B6LgGw!QqSXLJ+40V2I4U=JW|yov;GEyzy^T^UZfX+>L*zPMsYY$a-m!~; zD8~Zt#Ghd(IePPz$KH 4+w=4vaG%%;4T)Y7@|OnT(9 Sm^crjr=pqE!%MHwx!$%k47Wp171?Se z&@^*UyS~_weco|MsW>!w7Oc9h--L-u(4f4ue+c3!C<1WwCXJq{Cji2G_IVG09+$-( z-j_P{vYI~rA70)ZX#4n7PyAy0kr4?UNAIp!fWO`+?Bb}OT?+)>H+;iZL2hz=|LDPK&^OPR;O98~b^tjP8dLO)$e&|FWls2b-Uk<-D2+&7d=y3H?hV~w| z(((~~EbuFRB*Fr?*3v2IQ%XxzUOSeRmsf3OV$Az!WN%N`#5$#+ar=}P!Zgqzt7iyC zv0g=NtQjNM+AVCThc^*D{ks q=| z(*WJu5s{HvMhlz02%f~3-4$zU_gpJiD?BtFz6rX@td&*d24#Kj`|;z6l4}hSWzwfO zk4HF{HJ;Aj;&15k3GhgwSc!7CSU6qq&e%l0ltH~$?vMWDiGx658(*Z?jk$9r9K=!N zpFFcGJuOJh8WCAN&BMaZE+=Oee!TD7p)P_i@i33UmsC4OPG~MCC{+*+{fBxm!Smj$ z^B=*J=7l5cYwIcgxP*+iyaHMYJHBw?<)o=Ueiw22ERCKallO_rPUj7Z*PN>jwde>@ z!xwNfRhafCjOs?;_*q;f-k~b-6Td@z)ephxbe)Hzr(OF$M3C}kDD3a<=$c_2hE7cL z=|dB52Rc`s&Ei1U%gKx@+NHd+&VGqcLTja3!v}Lg0s39n{a9K0aSE@RTVVZ0>v@bF zQ*%Vw^rgc;iPv{_G J~QXTr$ zdu807m0MjqW!{uA<(dMo84!0=9=d(FJed*)Rlsv*+PqOOY6IB2j#UUnyEWFf^|Pul zgz>%BsPAJ>YGS&E@lkT;5qWJaIt>l&3pG^p)iiacYwV6A1SZcrx%d)5nP(S`bfLMY z;g`_0*ObV2H#SIu5no+VUFYC?WFOtbNa!>Y5o-{ETZ;9}!Z3PwhvU`@w5~oV$^lr2 zcAvQHoJMOuht8s`OZ?OF!XX zBX*_S28U?XxmN)TZ$- riq@xkBV7akde_p0zJzLrxw#x_Y-PX?X2k90q<@Lq-Oo{QAVi3BS{_Z32Pp}K_ zYRJUbC2utKWSOT^D!&_coje09-B*&P;qX6UCfcNVzCNl@^2Xtf;Om5WZ9WiMuoExw zQ4J!9Jwv|p$jZi^kW;JBeB7?AiG0k+qkfi`vQ}spzj-DpN);9V0vSa*l?zO-->9zE zJr;YcuTO06l2W=#=E2DrfKVz4m?%f7bk( z;B85p$VQu68{)u-$LvoVgt1{ScIP<4R1 z1?8PwoTo0Lv?Fhe`i=wHpjpNWo#Gpa?06{uXFFA`T>AkkkN9(_vUaoua9?p``FpYz zm>!6Bt{C{>sUj{})ur)*7D|~4>i+=FE=B*W5 NranblTJ!1TrrZNwbD-19lI(my2thb}lUHkp)t+@8>V6-WXhon;VlIEyR@YTE5Jx z0*!TBZ=8B5p(E9AT^jn?l@ZsYk<3_?9hb3!I!ep~BzTB;Zj5jbzC8_J+4bIr^Zz)` z2 Va>C%yO(F^L_&LlRIhEIGbyk0d(jCPf&Uqes zgupg*CjhM5`m%t}e*XIUVEZD&p+~QbQ`ahIrn*(@^FXPF&HVyQc_} (%oCMD$jy8ERotO9$vd<3mNf@+9bOphajc-5EOv!`7qP zvl_?gBc90spS&@Rdxt!qzfsUnC*^=a9|OO`8hp0N`S45+j$!4}ClZUk?d7PUwK=`G z!Cf`9d(Rnx2D9uG@w-r;Oec2=qp`s(a+Kn5?wc+|^`ZG3?5@tMn=DqH 7uXALaNC9YV#IRU?{~70y_4r( zepCSPuOxTLvnSTtch5t5Okm?9(d69uOO2>}4zPM>nN;#DS{(p2Lf^)GY(IsF)f9q; zUG)
n5T4*r1~t+_>Upm?~KYx`Y$n(zt*G* zsnS@d=F-BY%|rpWzEE0*M4(%5?45-GR8~%LZ0sgI#>pL3p8@xZ2Vi@QZN%ntocG>c zchYPjL@)mrY*1@$h*H2v!s6tMueToQuNIKE^JB#hWsr{{GZNFa4z`ond003tMQc*T z87w6^EoYcr)BPg+1u{Olp;4_Q!H(BT%CTw19uj#GaQjD3pNfgeb-VZWP66MW6P{6w z=GO(ZAD_j9_)HxD3+LmP*Hh>(R65Py#8Zt9Mp! HJEAb`c~=k;=xi-7nSfmjkiZ*eixFQ^e3Cd zZ$6#98Xs4M+3&ZW(|d?9CNuI7^Xr;GI|iGpU6$`N^3qmU+ngH&xadwL&GEzR`N?Bq z&I-o#ir<7y$`@CXtc{~DaxzBGCKxajCtG=1vzV{g9nr#E`lAR+s1ZDu=zcxo*#Zf@ zRqSz_9mPGICKl;o9i97_n@X0Kt~L-bTryo2ldxM`4^JIWe(%OT85VUA`xAY=F5dlC zf_{R`+SSzjF|V*5xc&$^3PY2psDaPd%Q|e3Y&@gZ5f#T1dMa~=-%cVcP{l0ZTquI7 z$1Fr+Ms&+Mdqcb8*SayTPsJ=?52!g1Xn$KLj$2L7sZ+9a3Y&39H1J@GJFyHuQmRC% za!6-83*i(si*O2(nDSEH{&W`Gw4~W@0;kBpz(u@)Xhtxwl936UXhwxCxmol{IZezJ z20_i?Lw6QgC2MF%Cn8!iPdd^&I)XDeMem(+Y$?!HSY5cmmIxl73TH2F+BII(L1DM= zw#$*dT?_cuIbHA1y#C@}gYTp-)Yh)I%x6QT6Q19DV&5I#J47hk%&p18q#p*9;tR53 z0uXN0vZG%3&sHDS+n^R^wb*Q*%Y %Gd4qkyi}&86XLxl!evxC0&Q&|kQ^rc%Ak}_j6Ft3{JKfjrMiIR&D--ZH)_wG- z?^vtgq`M$RfpmI~IBxA8>!Yf7?)r(@jo*n`R1ocky}SZm(}wPHXf8(pQ_4&=eys7^ z6$HwUvn%w6oI`w?_`5eyA?p3~kV *2?X!+YMT7=vm`--*6>R}+t8z4ChPVxZBFNn<9&t(>Q4;M&H9LY#E;>Q zI(JRpO0~Tr(hC-cn1mcXjTGeRAO?{NC5zeP($l_Ltjj7zdlP+*fMtS?4grKN?MBW* zoY;xzxo}lRQn &iJUc?*N1*NnvPY?sY*&%?2Rq6+L4SVw1 zzL=610!ImAE(#TGF?0ny5cQrgjW@~|Gn`Un_4DjPMY#(88#t+&I`|X`KS@Yd-+eQ0 zrxTh;6o8ls3q9`#aAT|qsZIo>42iUgmUbqcBGANq;oQ!5Qv>4ygP(}AnhXFtFVLd3 z$lj=QaQ!iIv=#j+`T4J@kP&yWP4g5oi?C?)uO3-BQ%?d+z^8t~gD)?6g0_Qlq( zy;G$11p5qmrq$3yN*OwS)ii>R!d`NtHq)03jh^=@IzR)dci4u0J~Y oWp#PT5v!6`U5b26MD z;Gh!&>C+^@S} OHXk^py+BY7##)&$ zdF7!^h$p(mvbUJrc572M`udNVW%_4k4EvpghWz|yTjeeAVi%h_ZHX0Bf_sncv40p} z22f82PK-N^ZEW3QTB0bFMyL9rUdPK{l}1i3Ih1vK_00r-`aWQuS@`(-8c9dAyZnyE zQ*06^t&b_;c`aC9rJp3n-5tXH@BA09Rr1hqhf!>m;QVVbTI7NbJGhEiIrScUMT`9_ zAVx1PA@FlEs}QRrZI_bx>gb|I#idOqQn2xUzu#u8fh_Ai@-~?-E_XYABvY%UiQ_)v z_KP#h3)DZQxI4*a PjH^>oZ^KVr=Pf&*D&~0{d}6AW!VqfviNid{{`r+NtB5@FgL{$|kNe%#A{hej z7r&+-I+J^^Zg;gocdV&H6;)BWdEaq|t)oLRYx`6#M?W p$kDd@L5c3}x;(B+5s zc=ZW8HwG|Wu}O5yI@XyjF7)@h>Q<2}Cx|Q4X9BO~u!RT4tko!!&XwRZWk)^dG>9o6 z&m`bG+JJ*0SYfZJ&drE~R=c^~dhV0f#3LqbS;X*5zm*%bINhdQ{oK?{8!;cVAuA_M zN$XQipG%>LHGLBr|E~U4q=ZXYbcvjA46m R;-{@nx zw60UDr}By-d>k
gLN2O7JADrpxI%5SPYw%HbXbJ@Jl`%3)~D7v9C za27rB%Q;ddSc75f8ZGn0a3^T2UC#CDAfs{xzDgSCqJ;FCXLoF_R5vsR;ISFl4J;X| zO3|CY3J)BGWumYoRK4?u!<}x1F`PK?g~%Pc2#P7}X}BaFw1L#m|1Qon5NAF^GyHbF z@@0XeVGWyd8F9Zfn9B%iQeSk}MEyIuxES13cGxci(7(SwEtmFOps{q$SLE}n*SYuF zERHBT2GXLmP
b{`*bogXQBz&*U^L})x8@PO0Z&`JpmF}~t5D0NRM=+5O zZR?gA)tr0eG+?~QwQ-s%4fyO6P+|nuO^n@bl6915rjf#oa~T78Cw@6jd^T{7TBDX^ zgRj;&%-gO34dyP)m*3x}1}xGkHRPV ((d?$j?K6mIY%iz7!Iv@4^euI41OTzm%2=gH^uEnneOT?B)cHPD5`W z)7LND4gwtbqP>n#u%U}3)^r*z#adyxBl-DHL(CV$!roiXQ-Jm6VtiWOx;m+>%q;rA z$SG3^*$xOm_lhlc*Q mZ@6syv-E)$vTshgPv=A10Y8 zhf1&?0^KkJYf$PFiyi6}si)ubJ+UmgTE>5{gbqOL!w@lHzD4i98l3O=ViOz)z`=mb z0fTHHt|!F^KeO}E<2vg!oHEv*ljKoSU<`c*80{l{5^9Mra76@U;)!c7;C-qPr!9-( z&G0>Z- o{MjV#Zti|6ak cj+LswueXLkuUB9Hvde!a5HBm6MhK1I!y|T^w4;~N+Ti?ny9~%1M zaL~LF{<~Z1wQHlf$V%E>rcf2b2lHXIwT#N19z(W#ViX+9SLf)M*oW_&hd#PEla9yo zk>L`y9T)^l1PEAkV;nlVh>5ctj~? wJ+b? zM{#}J@(B6f_h-9! ^}6FTK#T8*POe(NUh=BuS|w++Vu3cz=nDc(&eD9#j((9^J4FF+>Su>hou)wk zhh(l=tYIrWlVy;6+sAT`1WnNf(_KvRR$pghN=&GQy(DSDvtbU_eVQ*nMn99kAL5s| zX7hp>*XK0Clq%YC2z~wh?i=~G3W5S#siNFW{KP gjG$k4Et^?T kvc{)du*bgKf<^`QI*ZMbu|{*5jSlTDXG ztEqSvi|hCS$+K`nI6>e gra_s;XZr6P(fDd zx3xM4cI+^OqzA#LDeL^IDrFmkNA~l<@5Cm*w$BO-eJMqV$i8g2XWuzgudbrW|9}%; zkGlS+oSMf#%OIvPJo@lZ$zhy~&ygDtK|8!IK}0N#t)rPDMkF_wUiKpI81j3z7D#y* zs>G!?@$c+ZAL|&teDY+J+1!+ZuQR0S{)PGD9J+_(Lvs0tHrwwC@cq~h7ed@-e151) zyiMm+9TBL4n7O Sb2lbt=C1>g&zD{j!5zAxPd17y3Lm z3D#ym_rYzzGZ5jHANPhKI+HZ pqCna%`C>tXn4-n&QZtYyQ?t1 z0S>2zD%hGMKYCeg6{_Om-jZYWI1MW##FB$qG{3k@D+wk&-;R`)^tFMe)tf6?WA@{d zlQ{h%^4hNowk8=MNobDpQXHoY>(0NWD(w-JHX^xU7 #%4;I=N9FN6l>T~qYM6? zVrbkplJobTw >BxvcRz8LFKlWwvC}3w`v|eqW)%wGg$^K z!ywHfi1{4ez!`}7tNwOo(}W)*q=w~Gp6lBbaVsSp%+7r}r5#*x|Hz&ds??UHUazSc zLFPs5ed*iw?Lzv_O1Q~`Mdz{yikaw{@ttE8eM43-j-7pVc|~OdSq5kocPF&80|N1- zFHY?5T(<#E8@<$9K nm%DS~0YWU47Kz2I;3_Bpt3UUaG>zG$dL^GOy2mzJ-d< z$x|jU^yAc>({E?rc`l7OjWoa}S__Dc@(4_*PM|M}DHXilAnVT{(A0eM<>J`UMHB1X zp$fU$)?YLJe7hzlYtyRL##&4J)r}W?EJ9r4Hyqy~+Qp !(1;Z74QrWz2?+T*=t Ej%(xT!aO`DGP~6DlPP z9uawj+CLS#vjIs?1=Pn67(maA-$-Qysun-)DDl1#tA3K8z@Bah&Eva?cgCKnNTd(J z7_aT@r?MCjwajm fnx*m@7-$+$M@Z2$oo