From b5229fe5a2c2a6d9bd528dc5e43c53414be5c114 Mon Sep 17 00:00:00 2001 From: Zhang Wenqing <110718225+z-wenqing@users.noreply.github.com> Date: Thu, 7 Mar 2024 13:25:19 +0800 Subject: [PATCH 001/162] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f82e2494b7..d3cf87934b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Duke project template +# Timetable Comparer This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it. From 025020efac563bc51df526ba1a92c07fb8952701 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Thu, 7 Mar 2024 13:46:22 +0800 Subject: [PATCH 002/162] Update AboutUs --- docs/AboutUs.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..69f351cbb9 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,6 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +Display | Name | Github Profile | Portfolio +--------|:--------------:|:--------------:|:---------: +![](https://via.placeholder.com/100.png?text=Photo) | Leong Zhe Ming | [Github](https://github.com/Leong-ZM) | [Portfolio](docs/team/johndoe.md) + From 702e617f1efe17c8ed8125703cfc93380e8503ce Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Thu, 7 Mar 2024 13:56:03 +0800 Subject: [PATCH 003/162] edited About Us --- docs/AboutUs.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..58d11597fc 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,5 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +Display | Name | Github Profile | Portfolio +--------|:-----------:|:-------------------------------------:|:---------: +![](https://via.placeholder.com/100.png?text=Photo) | John Nguyen | [Github](https://github.com/john-nng) | [Portfolio](docs/team/johndoe.md) From 535c46ffb5aa1afd3d4f16b2f157086a62a91a7c Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Thu, 7 Mar 2024 15:15:13 +0800 Subject: [PATCH 004/162] Add aboutUs in doc --- docs/AboutUs.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..53ee891d13 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,6 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +Display | Name | Github Profile | Portfolio +--------|:-------------:|:--------------:|:---------: +![](https://via.placeholder.com/100.png?text=Photo) | Zhang Wenqing | [Github](https://github.com/z-wenqing) | [Portfolio](docs/team/johndoe.md) + From 0410deaaea2f8ead43eb312350c02df31a636460 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Thu, 7 Mar 2024 15:24:00 +0800 Subject: [PATCH 005/162] add user story --- docs/DeveloperGuide.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 64e1f0ed2b..0c327c7154 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -12,7 +12,7 @@ ## Product scope ### Target user profile -{Describe the target user profile} +{Describe the target user profile}: Students (NUS student?) ### Value proposition @@ -20,10 +20,12 @@ ## User Stories -|Version| As a ... | I want to ... | So that I can ...| -|--------|----------|---------------|------------------| -|v1.0|new user|see usage instructions|refer to them when I forget how to use the application| -|v2.0|user|find a to-do item by name|locate a to-do without having to go through the entire list| +|Version| As a ... | I want to ... | So that I can ... | +|--------|----------|---------------|-------------------------------------------------------------| +|v1.0| new user |see usage instructions| refer to them when I forget how to use the application | +|v2.0| user |find a to-do item by name| locate a to-do without having to go through the entire list | +| | user |add a task to the timetable| record when a task needs to be done | + ## Non-Functional Requirements From 684cc1f506fe40f41568a34a9aef110e58d46045 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Thu, 7 Mar 2024 15:43:52 +0800 Subject: [PATCH 006/162] Add my name --- docs/AboutUs.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..c47f00741a 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,6 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +Display | Name | Github Profile | Portfolio +--------|:---------:|:--------------:|:---------: +![](https://via.placeholder.com/100.png?text=Photo) | Zhu Sijia | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) + From 70d2a107e79425d7ccdee214a34bc1aa934fa9af Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Thu, 14 Mar 2024 15:10:35 +0800 Subject: [PATCH 007/162] Add basic user functions --- src/main/java/seedu/duke/Duke.java | 21 ----------- src/main/java/seedu/duke/Main.java | 47 +++++++++++++++++++++++++ src/main/java/seedu/duke/Parser.java | 4 +++ src/main/java/seedu/duke/Timetable.java | 5 +++ src/main/java/seedu/duke/User.java | 12 +++++++ src/main/java/seedu/duke/UserList.java | 34 ++++++++++++++++++ src/main/java/seedu/duke/ui/UI.java | 22 ++++++++++++ 7 files changed, 124 insertions(+), 21 deletions(-) delete mode 100644 src/main/java/seedu/duke/Duke.java create mode 100644 src/main/java/seedu/duke/Main.java create mode 100644 src/main/java/seedu/duke/Parser.java create mode 100644 src/main/java/seedu/duke/Timetable.java create mode 100644 src/main/java/seedu/duke/User.java create mode 100644 src/main/java/seedu/duke/UserList.java create mode 100644 src/main/java/seedu/duke/ui/UI.java diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java deleted file mode 100644 index 5c74e68d59..0000000000 --- a/src/main/java/seedu/duke/Duke.java +++ /dev/null @@ -1,21 +0,0 @@ -package seedu.duke; - -import java.util.Scanner; - -public class Duke { - /** - * Main entry-point for the java.duke.Duke application. - */ - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - System.out.println("What is your name?"); - - Scanner in = new Scanner(System.in); - System.out.println("Hello " + in.nextLine()); - } -} diff --git a/src/main/java/seedu/duke/Main.java b/src/main/java/seedu/duke/Main.java new file mode 100644 index 0000000000..1069e47b6b --- /dev/null +++ b/src/main/java/seedu/duke/Main.java @@ -0,0 +1,47 @@ +package seedu.duke; + +import seedu.duke.ui.UI; + +import java.util.Objects; +import java.util.Scanner; + +public class Main { + static Scanner in = new Scanner(System.in); + + public static void main(String[] args) { + UI.printGreeting(); + UserList userList = new UserList(); + + + //replace this with parser + while (true) { + String input = in.nextLine(); + //extracts first word as command + String command = input.contains(" ") ? input.split(" ")[0] : input; + String description = ""; + if (input.contains(" ")) { + description = input.split(" ", 2)[1]; + } + + if (Objects.equals(command, "switch")) { + int index = (new Scanner(description).useDelimiter("\\D+").nextInt()) - 1; + userList.setActiveUser(index); + UI.printSetActiveUser(userList.getActiveUser().getName()); + } else if (Objects.equals(command, "list")) { + UI.printListingUsers(); + userList.listAll(); + } else if (Objects.equals(command, "bye")) { + UI.printBye(); + break; + } else if (Objects.equals(command, "add")) { + UI.printAddUser(description); + User newUser = new User(description); + userList.addUser(newUser); + } else if (Objects.equals(command, "current")) { + UI.printSetActiveUser(userList.getActiveUser().getName()); + } else { + UI.printInvalidCommand(); + } + } + } +} diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java new file mode 100644 index 0000000000..2f1d28ed92 --- /dev/null +++ b/src/main/java/seedu/duke/Parser.java @@ -0,0 +1,4 @@ +package seedu.duke; + +public class Parser { +} diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java new file mode 100644 index 0000000000..1edb815345 --- /dev/null +++ b/src/main/java/seedu/duke/Timetable.java @@ -0,0 +1,5 @@ +package seedu.duke; + +public class Timetable { + //todo +} diff --git a/src/main/java/seedu/duke/User.java b/src/main/java/seedu/duke/User.java new file mode 100644 index 0000000000..1809b701a6 --- /dev/null +++ b/src/main/java/seedu/duke/User.java @@ -0,0 +1,12 @@ +package seedu.duke; + +public class User { + private final String name; + private Timetable timetable = new Timetable(); + public User(String name) { + this.name = name; + } + public String getName() { + return name; + } +} diff --git a/src/main/java/seedu/duke/UserList.java b/src/main/java/seedu/duke/UserList.java new file mode 100644 index 0000000000..5a01f53f4e --- /dev/null +++ b/src/main/java/seedu/duke/UserList.java @@ -0,0 +1,34 @@ +package seedu.duke; + +import java.util.ArrayList; + +public class UserList { + private int listLength; + private ArrayList allUsers; + private User activeUser; + public UserList() { + listLength = 0; + allUsers = new ArrayList(); + } + public int getListLength() { + return listLength; + } + public void addUser(User user) { + allUsers.add(user); + listLength += 1; + if (listLength == 1) { + this.activeUser = allUsers.get(0); + } + } + public void setActiveUser(int index) { + this.activeUser = allUsers.get(index); + } + public User getActiveUser() { + return activeUser; + } + public void listAll() { + for (User user : allUsers) { + System.out.println(user.getName()); + } + } +} diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java new file mode 100644 index 0000000000..fc8a0c70c1 --- /dev/null +++ b/src/main/java/seedu/duke/ui/UI.java @@ -0,0 +1,22 @@ +package seedu.duke.ui; + +public class UI { + public static void printGreeting() { + System.out.println("Timetable comparison app opened. "); + } + public static void printBye() { + System.out.println("Bye. "); + } + public static void printListingUsers() { + System.out.println("The current users are: "); + } + public static void printAddUser(String description) { + System.out.println("New user added: " + description); + } + public static void printSetActiveUser(String description) { + System.out.println("The active user is: " + description); + } + public static void printInvalidCommand() { + System.out.println("Invalid command. "); + } +} From 511b33d7d4f6bdc8fd6c6fc5c70d79d5bb51b857 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Thu, 14 Mar 2024 15:15:31 +0800 Subject: [PATCH 008/162] Rename main --- src/main/java/seedu/duke/{Main.java => Duke.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/java/seedu/duke/{Main.java => Duke.java} (98%) diff --git a/src/main/java/seedu/duke/Main.java b/src/main/java/seedu/duke/Duke.java similarity index 98% rename from src/main/java/seedu/duke/Main.java rename to src/main/java/seedu/duke/Duke.java index 1069e47b6b..758721efb6 100644 --- a/src/main/java/seedu/duke/Main.java +++ b/src/main/java/seedu/duke/Duke.java @@ -5,7 +5,7 @@ import java.util.Objects; import java.util.Scanner; -public class Main { +public class Duke { static Scanner in = new Scanner(System.in); public static void main(String[] args) { From eb5cf7494f6a8ec7b79dce87d3b0677ccd079fc3 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Thu, 14 Mar 2024 15:17:22 +0800 Subject: [PATCH 009/162] Update tests --- text-ui-test/EXPECTED.TXT | 11 ++--------- text-ui-test/input.txt | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 892cb6cae7..fd31a3aa5b 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,9 +1,2 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| - -What is your name? -Hello James Gosling +Timetable comparison app opened. +Bye. diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index f6ec2e9f95..0abaeaa993 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1 +1 @@ -James Gosling \ No newline at end of file +bye \ No newline at end of file From b080c9bc6077425e61b9923d95dc389a344d6519 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Fri, 15 Mar 2024 12:42:29 +0800 Subject: [PATCH 010/162] Add Junit Test --- src/test/java/seedu/duke/DukeTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index 2dda5fd651..4306c3939b 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -1,12 +1,31 @@ package seedu.duke; +import seedu.duke.UserList; +import +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; +import java.io.ByteArrayInputStream; + class DukeTest { @Test public void sampleTest() { assertTrue(true); } + @Test + public void testInvalidCommand() { + // Arrange + UserList userList = new UserList(); + ByteArrayInputStream in = new ByteArrayInputStream("invalid\nbye\n".getBytes()); + System.setIn(in); + String expectedOutput = "Welcome to Duke!\nInvalid command!\nGoodbye!\n"; + + // Act + Duke.main(new String[0]); + + // Assert + assertEquals(expectedOutput, UI.printInvalidCommand()); + } } From fe572ce2071cb1a89eb9b852ed110f81ef51d7da Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Fri, 15 Mar 2024 13:00:26 +0800 Subject: [PATCH 011/162] Bug Fixing for Junit --- src/test/java/seedu/duke/DukeTest.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index 4306c3939b..bed58a33ad 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -1,6 +1,6 @@ package seedu.duke; import seedu.duke.UserList; -import +import seedu.duke.ui.UI; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -8,6 +8,8 @@ import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; class DukeTest { @Test @@ -20,12 +22,15 @@ public void testInvalidCommand() { UserList userList = new UserList(); ByteArrayInputStream in = new ByteArrayInputStream("invalid\nbye\n".getBytes()); System.setIn(in); - String expectedOutput = "Welcome to Duke!\nInvalid command!\nGoodbye!\n"; + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + System.setOut(new PrintStream(out)); + String expectedOutput = "Timetable comparison app opened. \r\nInvalid command. \r\nBye. \r\n"; // Act Duke.main(new String[0]); // Assert - assertEquals(expectedOutput, UI.printInvalidCommand()); + assertEquals(expectedOutput, out.toString()); } } From 9e2581ef2d7898340ffc3a144a2daf2ad0824dd1 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Fri, 15 Mar 2024 14:10:55 +0800 Subject: [PATCH 012/162] add test for testAddUser --- src/main/java/seedu/duke/UserList.java | 3 +++ src/test/java/seedu/duke/DukeTest.java | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/main/java/seedu/duke/UserList.java b/src/main/java/seedu/duke/UserList.java index 5a01f53f4e..b23cbda1c0 100644 --- a/src/main/java/seedu/duke/UserList.java +++ b/src/main/java/seedu/duke/UserList.java @@ -31,4 +31,7 @@ public void listAll() { System.out.println(user.getName()); } } + public ArrayList getUsers() { + return allUsers; + } } diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index bed58a33ad..7790de6b59 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -33,4 +33,15 @@ public void testInvalidCommand() { // Assert assertEquals(expectedOutput, out.toString()); } + @Test + public void testAddUser() { + UserList userList = new UserList(); + User user = new User("Test User"); + userList.addUser(user); + + // Verify that the user is added to the list + assertEquals(1, userList.getListLength()); + assertEquals(user, userList.getActiveUser()); + assertTrue(userList.getUsers().contains(user)); + } } From b6fc114d913e5b59c3483bd003154faf8a71cdd0 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Sun, 17 Mar 2024 12:34:58 +0800 Subject: [PATCH 013/162] Create a task class and add delete function --- src/main/java/seedu/duke/Parser.java | 47 +++++++++++++++++++++++++++- src/main/java/seedu/duke/Task.java | 13 ++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/main/java/seedu/duke/Task.java diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 2f1d28ed92..e82b17406b 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -1,4 +1,49 @@ package seedu.duke; - +import java.util.Scanner; +import java.util.ArrayList; public class Parser { + private static void addTask(Scanner scanner, ArrayList tasks) { + System.out.println("Enter task details:"); + System.out.print("Description: "); + String description = scanner.nextLine(); + System.out.print("From: "); + String from = scanner.nextLine(); + System.out.print("To: "); + String to = scanner.nextLine(); + + // Creating Task object from user input + Task task = new Task(description, from, to); + + // Adding task to the ArrayList + tasks.add(task); + + System.out.println("Task added successfully."); + } + private static void deleteTask(Scanner scanner, ArrayList tasks) { + // Printing tasks + System.out.println("\nAll tasks:"); + for (int i = 0; i < tasks.size(); i++) { + Task t = tasks.get(i); + System.out.println("Index: " + (i + 1)); + System.out.println("Description: " + t.description); + System.out.println("From: " + t.from); + System.out.println("To: " + t.to); + System.out.println(); + } + + // Option to delete a task + System.out.print("Enter the index of the task to delete: "); + String deleteInput = scanner.nextLine(); + try { + int index = Integer.parseInt(deleteInput); + if (index >= 1 && index <= tasks.size()) { + tasks.remove(index - 1); + System.out.println("Task at index " + index + " deleted successfully."); + } else { + System.out.println("Invalid index."); + } + } catch (NumberFormatException e) { + System.out.println("Invalid input. Please enter a valid index."); + } + } } diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java new file mode 100644 index 0000000000..109d33485f --- /dev/null +++ b/src/main/java/seedu/duke/Task.java @@ -0,0 +1,13 @@ +package seedu.duke; + +public class Task { + protected String description; + protected String from; + protected String to; + + public Task(String description, String from, String to){ + this.description = description; + this.from = from; + this.to = to; + } +} From 5fecb764206dca82167d74a1a71d55fdeab67dc8 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Sun, 17 Mar 2024 15:53:30 +0800 Subject: [PATCH 014/162] Add timetable class --- src/main/java/seedu/duke/Timetable.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 1edb815345..ad0bcd449e 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -1,5 +1,19 @@ package seedu.duke; +import java.util.ArrayList; + public class Timetable { //todo + private ArrayList[] daysOfWeek; + public Timetable() { + daysOfWeek = new ArrayList[7]; + initializeTimetable(); + } + + private void initializeTimetable() { + for (int i = 0; i < 7; i++) { + daysOfWeek[i] = new ArrayList<>(); + } + } + protected String name; } From e72572333d1b268468dd63d72cddf37610ba046e Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Sun, 17 Mar 2024 23:28:22 +0800 Subject: [PATCH 015/162] structure --- src/main/java/seedu/duke/Parser.java | 102 ++++++++++++++++--------- src/main/java/seedu/duke/Task.java | 4 +- src/main/java/seedu/duke/TaskList.java | 23 ++++++ src/main/java/seedu/duke/User.java | 33 +++++++- 4 files changed, 123 insertions(+), 39 deletions(-) create mode 100644 src/main/java/seedu/duke/TaskList.java diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index e82b17406b..e2efc13b06 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -2,48 +2,76 @@ import java.util.Scanner; import java.util.ArrayList; public class Parser { - private static void addTask(Scanner scanner, ArrayList tasks) { - System.out.println("Enter task details:"); - System.out.print("Description: "); - String description = scanner.nextLine(); - System.out.print("From: "); - String from = scanner.nextLine(); - System.out.print("To: "); - String to = scanner.nextLine(); - - // Creating Task object from user input - Task task = new Task(description, from, to); - - // Adding task to the ArrayList - tasks.add(task); - - System.out.println("Task added successfully."); + private final User user; + + public Parser(User user) { + this.user = user; } - private static void deleteTask(Scanner scanner, ArrayList tasks) { - // Printing tasks - System.out.println("\nAll tasks:"); - for (int i = 0; i < tasks.size(); i++) { - Task t = tasks.get(i); - System.out.println("Index: " + (i + 1)); - System.out.println("Description: " + t.description); - System.out.println("From: " + t.from); - System.out.println("To: " + t.to); - System.out.println(); + public void parseCommand(String command) { + String[] parts = command.split("/"); // Splitting command into parts using slash + + if (parts.length != 4 || !parts[0].trim().startsWith("add")) { + System.out.println("Invalid command format."); + return; + } + + // Extracting description, day, start time, and end time from the parts + String description = parts[0].trim().substring(4).trim(); + String day = parts[1].trim().substring(3).trim(); // Removing "on" from day + String from = parts[2].trim().substring(5).trim(); // Removing "from" from start time + String to = parts[3].trim().substring(3).trim(); // Removing "to" from end time + + Task task = new Task(description, day, from, to); + + // Adding task to the User's task list + int dayOfWeek = parseDayOfWeek(day); + if (dayOfWeek != -1) { + user.addTask(dayOfWeek, task); + System.out.println("Task added successfully."); + } else { + System.out.println("Invalid day of the week."); + } + } + + private int parseDayOfWeek(String day) { + // Mapping day of the week to index (0-6) + switch (day.toLowerCase()) { + case "sunday": + return 0; + case "monday": + return 1; + case "tuesday": + return 2; + case "wednesday": + return 3; + case "thursday": + return 4; + case "friday": + return 5; + case "saturday": + return 6; + default: + return -1; // Invalid day + } + } + + public void deleteTask(String command) { + String[] parts = command.split(" "); // Splitting command into parts using space + + if (parts.length != 2 || !parts[0].trim().equalsIgnoreCase("delete")) { + System.out.println("Invalid delete command format."); + return; } - // Option to delete a task - System.out.print("Enter the index of the task to delete: "); - String deleteInput = scanner.nextLine(); try { - int index = Integer.parseInt(deleteInput); - if (index >= 1 && index <= tasks.size()) { - tasks.remove(index - 1); - System.out.println("Task at index " + index + " deleted successfully."); - } else { - System.out.println("Invalid index."); - } + int index = Integer.parseInt(parts[1].trim()); + int dayOfWeek = 0; // Assume we are always deleting from Sunday for now + user.deleteTask(dayOfWeek, index - 1); // Adjust index by -1 to match array index + System.out.println("Task deleted successfully."); } catch (NumberFormatException e) { - System.out.println("Invalid input. Please enter a valid index."); + System.out.println("Invalid task index."); } } } + +} diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index 109d33485f..09ed3fa735 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -2,11 +2,13 @@ public class Task { protected String description; + protected String date; protected String from; protected String to; - public Task(String description, String from, String to){ + public Task(String description, String date, String from, String to){ this.description = description; + this.date = date; this.from = from; this.to = to; } diff --git a/src/main/java/seedu/duke/TaskList.java b/src/main/java/seedu/duke/TaskList.java new file mode 100644 index 0000000000..dab6f2a164 --- /dev/null +++ b/src/main/java/seedu/duke/TaskList.java @@ -0,0 +1,23 @@ +package seedu.duke; + +import java.util.ArrayList; + +public class TaskList { + private ArrayList tasks; + public TaskList() { this.tasks = new ArrayList<>(); + } + public void addTask(Task task){ + tasks.add(task); + } + public void deleteTask(int index){ + tasks.remove(index); + } + + public int size() { + return tasks.size(); + } + + public Task get(int index) { + return tasks.get(index); + } +} diff --git a/src/main/java/seedu/duke/User.java b/src/main/java/seedu/duke/User.java index 1809b701a6..67b76f49a9 100644 --- a/src/main/java/seedu/duke/User.java +++ b/src/main/java/seedu/duke/User.java @@ -1,7 +1,10 @@ package seedu.duke; +import java.lang.reflect.Array; +import java.util.ArrayList; public class User { - private final String name; + private String name; + private ArrayList taskLists; //THIS COULD BE TIMETABLE private Timetable timetable = new Timetable(); public User(String name) { this.name = name; @@ -9,4 +12,32 @@ public User(String name) { public String getName() { return name; } + + public User() { + taskLists = new ArrayList<>(); + for (int i = 0; i < 7; i++) { + taskLists.add(new TaskList()); + } + } + + public void addUserTask(int dayOfWeek, Task task){ + if(dayOfWeek >= 0 && dayOfWeek < 7){ + taskLists.get(dayOfWeek).addTask(task); + } + } + public void deleteUserTask(int dayOfWeek, int index){ + if (dayOfWeek >= 0 && dayOfWeek < 7) { + TaskList tasks = taskLists.get(dayOfWeek); + if (index >= 0 && index < tasks.size()){ + Task taskDeleted = tasks.get(index); + tasks.deleteTask(index); + System.out.println("Task " + taskDeleted.description + "is deleted from " + dayOfWeek); + + } else{ + System.out.println("Invalid task index. Please try again"); + } + } else{ + System.out.println("Invalid day of the week."); + } + } } From 4e3cf166a9398a7a012b177c8f88ced48dfbe03c Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 18 Mar 2024 00:24:28 +0800 Subject: [PATCH 016/162] fix adding task and deleting task using timetable class --- src/main/java/seedu/duke/Duke.java | 10 ++++++++- src/main/java/seedu/duke/Parser.java | 12 +++++------ src/main/java/seedu/duke/Timetable.java | 24 +++++++++++++++++++++- src/main/java/seedu/duke/User.java | 27 +------------------------ src/main/java/seedu/duke/UserList.java | 1 + src/main/java/seedu/duke/ui/UI.java | 5 +++++ 6 files changed, 45 insertions(+), 34 deletions(-) diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 758721efb6..ad8b44f3f3 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -6,6 +6,7 @@ import java.util.Scanner; public class Duke { + private static final int ADD_TASK_INDEX = 9; static Scanner in = new Scanner(System.in); public static void main(String[] args) { @@ -39,7 +40,14 @@ public static void main(String[] args) { userList.addUser(newUser); } else if (Objects.equals(command, "current")) { UI.printSetActiveUser(userList.getActiveUser().getName()); - } else { + } else if (Objects.equals(command, "delete")) { + String[] words = input.split(" "); + int weekOfDay = Integer.parseInt(words[1]); + int index = Integer.parseInt(words[2]) - 1; + + userList.getActiveUser().timetable.deleteUserTask(weekOfDay, index); + } + else { UI.printInvalidCommand(); } } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index e2efc13b06..08b9d7341e 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -2,7 +2,7 @@ import java.util.Scanner; import java.util.ArrayList; public class Parser { - private final User user; + private static final User user; public Parser(User user) { this.user = user; @@ -26,7 +26,7 @@ public void parseCommand(String command) { // Adding task to the User's task list int dayOfWeek = parseDayOfWeek(day); if (dayOfWeek != -1) { - user.addTask(dayOfWeek, task); + user.timetable.addUserTask(dayOfWeek, task); System.out.println("Task added successfully."); } else { System.out.println("Invalid day of the week."); @@ -55,8 +55,10 @@ private int parseDayOfWeek(String day) { } } + private static final int NAME_PART = 1; + public void deleteTask(String command) { - String[] parts = command.split(" "); // Splitting command into parts using space + String[] parts = command.split("/"); // Splitting command into parts using space if (parts.length != 2 || !parts[0].trim().equalsIgnoreCase("delete")) { System.out.println("Invalid delete command format."); @@ -66,12 +68,10 @@ public void deleteTask(String command) { try { int index = Integer.parseInt(parts[1].trim()); int dayOfWeek = 0; // Assume we are always deleting from Sunday for now - user.deleteTask(dayOfWeek, index - 1); // Adjust index by -1 to match array index + user.timetable.deleteUserTask(dayOfWeek, index - 1); // Adjust index by -1 to match array index System.out.println("Task deleted successfully."); } catch (NumberFormatException e) { System.out.println("Invalid task index."); } } } - -} diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index ad0bcd449e..3bd655d462 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -4,7 +4,7 @@ public class Timetable { //todo - private ArrayList[] daysOfWeek; + private ArrayList[] daysOfWeek; public Timetable() { daysOfWeek = new ArrayList[7]; initializeTimetable(); @@ -16,4 +16,26 @@ private void initializeTimetable() { } } protected String name; + public void addUserTask(int dayOfWeek, Task task){ + if(dayOfWeek >= 0 && dayOfWeek < 7){ + daysOfWeek[dayOfWeek - 1].add(task); + } + } + + public void deleteUserTask(int dayOfWeek, int index){ + if (dayOfWeek >= 0 && dayOfWeek < 7) { + + ArrayList tasks = daysOfWeek[dayOfWeek - 1]; + if (index >= 0 && index < tasks.size()){ + Task taskDeleted = tasks.get(index); + tasks.remove(index); + System.out.println("Task " + taskDeleted.description + "is deleted from " + dayOfWeek); + + } else{ + System.out.println("Invalid task index. Please try again"); + } + } else{ + System.out.println("Invalid day of the week."); + } + } } diff --git a/src/main/java/seedu/duke/User.java b/src/main/java/seedu/duke/User.java index 67b76f49a9..6105f6cff8 100644 --- a/src/main/java/seedu/duke/User.java +++ b/src/main/java/seedu/duke/User.java @@ -5,7 +5,7 @@ public class User { private String name; private ArrayList taskLists; //THIS COULD BE TIMETABLE - private Timetable timetable = new Timetable(); + public Timetable timetable = new Timetable(); public User(String name) { this.name = name; } @@ -13,31 +13,6 @@ public String getName() { return name; } - public User() { - taskLists = new ArrayList<>(); - for (int i = 0; i < 7; i++) { - taskLists.add(new TaskList()); - } - } - public void addUserTask(int dayOfWeek, Task task){ - if(dayOfWeek >= 0 && dayOfWeek < 7){ - taskLists.get(dayOfWeek).addTask(task); - } - } - public void deleteUserTask(int dayOfWeek, int index){ - if (dayOfWeek >= 0 && dayOfWeek < 7) { - TaskList tasks = taskLists.get(dayOfWeek); - if (index >= 0 && index < tasks.size()){ - Task taskDeleted = tasks.get(index); - tasks.deleteTask(index); - System.out.println("Task " + taskDeleted.description + "is deleted from " + dayOfWeek); - } else{ - System.out.println("Invalid task index. Please try again"); - } - } else{ - System.out.println("Invalid day of the week."); - } - } } diff --git a/src/main/java/seedu/duke/UserList.java b/src/main/java/seedu/duke/UserList.java index b23cbda1c0..1cdb228b87 100644 --- a/src/main/java/seedu/duke/UserList.java +++ b/src/main/java/seedu/duke/UserList.java @@ -19,6 +19,7 @@ public void addUser(User user) { if (listLength == 1) { this.activeUser = allUsers.get(0); } + } public void setActiveUser(int index) { this.activeUser = allUsers.get(index); diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index fc8a0c70c1..f903986dc5 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -19,4 +19,9 @@ public static void printSetActiveUser(String description) { public static void printInvalidCommand() { System.out.println("Invalid command. "); } + + public static void printAddTask(String description) { + System.out.println("The following task is added: "); + System.out.println(description); + } } From 14f8e03141089e128091ed4e3b015634ce05e563 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Mon, 18 Mar 2024 14:16:23 +0800 Subject: [PATCH 017/162] change --- src/main/java/seedu/duke/Parser.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index e2efc13b06..e617225a94 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -26,7 +26,7 @@ public void parseCommand(String command) { // Adding task to the User's task list int dayOfWeek = parseDayOfWeek(day); if (dayOfWeek != -1) { - user.addTask(dayOfWeek, task); + user.addUserTask(dayOfWeek, task); System.out.println("Task added successfully."); } else { System.out.println("Invalid day of the week."); @@ -66,7 +66,7 @@ public void deleteTask(String command) { try { int index = Integer.parseInt(parts[1].trim()); int dayOfWeek = 0; // Assume we are always deleting from Sunday for now - user.deleteTask(dayOfWeek, index - 1); // Adjust index by -1 to match array index + user.deleteUserTask(dayOfWeek, index - 1); // Adjust index by -1 to match array index System.out.println("Task deleted successfully."); } catch (NumberFormatException e) { System.out.println("Invalid task index."); From 000225d2cebe105d38daa1668c1ae4964c57f0d6 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Mon, 18 Mar 2024 14:26:10 +0800 Subject: [PATCH 018/162] delete the word"final" in parser class --- src/main/java/seedu/duke/Parser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 08b9d7341e..25a9b4d50b 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -2,7 +2,7 @@ import java.util.Scanner; import java.util.ArrayList; public class Parser { - private static final User user; + private static User user; public Parser(User user) { this.user = user; From 9b34a6b2b2efb570e2a1788ec0b88d681e6f32ee Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Mon, 18 Mar 2024 15:04:26 +0800 Subject: [PATCH 019/162] Add assertions and tests for addUserTask and deleteUserTsk --- build.gradle | 1 + src/main/java/seedu/duke/Timetable.java | 5 ++- src/test/java/seedu/duke/TimetableTest.java | 45 +++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/test/java/seedu/duke/TimetableTest.java diff --git a/build.gradle b/build.gradle index ea82051fab..593bf8299e 100644 --- a/build.gradle +++ b/build.gradle @@ -43,4 +43,5 @@ checkstyle { run{ standardInput = System.in + enableAssertions = true } diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 3bd655d462..693b1fa5c2 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -4,7 +4,7 @@ public class Timetable { //todo - private ArrayList[] daysOfWeek; + protected ArrayList[] daysOfWeek; public Timetable() { daysOfWeek = new ArrayList[7]; initializeTimetable(); @@ -17,12 +17,15 @@ private void initializeTimetable() { } protected String name; public void addUserTask(int dayOfWeek, Task task){ + assert dayOfWeek >= 0 && dayOfWeek <= 6 : "Invalid day of a week, please try again!"; if(dayOfWeek >= 0 && dayOfWeek < 7){ daysOfWeek[dayOfWeek - 1].add(task); } } public void deleteUserTask(int dayOfWeek, int index){ + assert dayOfWeek >= 0 && dayOfWeek <= 6 : "Invalid day of a week, please try again!"; + assert index >= 0 && index < daysOfWeek[dayOfWeek - 1].size() : "Invalid task index, please try again!"; if (dayOfWeek >= 0 && dayOfWeek < 7) { ArrayList tasks = daysOfWeek[dayOfWeek - 1]; diff --git a/src/test/java/seedu/duke/TimetableTest.java b/src/test/java/seedu/duke/TimetableTest.java new file mode 100644 index 0000000000..5eae3093fa --- /dev/null +++ b/src/test/java/seedu/duke/TimetableTest.java @@ -0,0 +1,45 @@ +package seedu.duke; +import seedu.duke.UserList; +import seedu.duke.ui.UI; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +class TimetableTest { + @Test + public void testAddUserTask() { + Timetable timetable = new Timetable(); + Task task = new Task("Study","2024-03-18", "09:00", "11:00"); + int dayOfWeek = 1; // assume Tuesday + + timetable.addUserTask(dayOfWeek, task); + + assertEquals(1, timetable.daysOfWeek[dayOfWeek - 1].size()); + assertEquals(task, timetable.daysOfWeek[dayOfWeek - 1].get(0)); + } + @Test + public void testDeleteUserTask() { + Timetable timetable = new Timetable(); + Task task1 = new Task("Study", "2024-03-18", "09:00", "11:00"); + Task task2 = new Task("Exercise", "2024-03-18", "15:00", "16:30"); + int dayOfWeek = 1; // assume Tuesday + + // Add tasks to the timetable + timetable.addUserTask(dayOfWeek, task1); + timetable.addUserTask(dayOfWeek, task2); + + // Delete the first task + timetable.deleteUserTask(dayOfWeek, 0); + + // Check if the task is deleted + assertEquals(1, timetable.daysOfWeek[dayOfWeek - 1].size()); + assertEquals(task2, timetable.daysOfWeek[dayOfWeek - 1].get(0)); + + } +} \ No newline at end of file From 926c1ed72057c47090b565e336addf69bf52252a Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 18 Mar 2024 16:59:55 +0800 Subject: [PATCH 020/162] Add viewTimetable function --- src/main/java/seedu/duke/Duke.java | 7 ++++++ src/main/java/seedu/duke/Parser.java | 19 ++++++++------ src/main/java/seedu/duke/Task.java | 14 ++++++++--- src/main/java/seedu/duke/Timetable.java | 33 +++++++++++++++++++++++++ src/main/java/seedu/duke/User.java | 8 +++--- 5 files changed, 68 insertions(+), 13 deletions(-) diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index ad8b44f3f3..7733de3b89 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -14,6 +14,7 @@ public static void main(String[] args) { UserList userList = new UserList(); + //replace this with parser while (true) { String input = in.nextLine(); @@ -46,6 +47,12 @@ public static void main(String[] args) { int index = Integer.parseInt(words[2]) - 1; userList.getActiveUser().timetable.deleteUserTask(weekOfDay, index); + } else if (Objects.equals(command, "addtask")) { + User currentUser = userList.getActiveUser(); + Parser parser = new Parser(currentUser); + parser.parseCommand(input); + } else if (Objects.equals(command, "view")) { + userList.getActiveUser().viewTimetable(); } else { UI.printInvalidCommand(); diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 25a9b4d50b..b0e0398200 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -3,23 +3,28 @@ import java.util.ArrayList; public class Parser { private static User user; + private static final int NAME_INDEX = 1; + private static final int DAY_INDEX = 2; + private static final int DESCRIPTION_INDEX = 3; + private static final int FROM_INDEX = 4; + private static final int TO_INDEX = 5; public Parser(User user) { - this.user = user; + Parser.user = user; } public void parseCommand(String command) { String[] parts = command.split("/"); // Splitting command into parts using slash - if (parts.length != 4 || !parts[0].trim().startsWith("add")) { + if (parts.length != 6 || !parts[0].trim().startsWith("add")) { System.out.println("Invalid command format."); return; } // Extracting description, day, start time, and end time from the parts - String description = parts[0].trim().substring(4).trim(); - String day = parts[1].trim().substring(3).trim(); // Removing "on" from day - String from = parts[2].trim().substring(5).trim(); // Removing "from" from start time - String to = parts[3].trim().substring(3).trim(); // Removing "to" from end time + String description = parts[DESCRIPTION_INDEX].trim().substring(5).trim(); + String day = parts[DAY_INDEX].trim().substring(3).trim(); // Removing "on" from day + String from = parts[FROM_INDEX].trim().substring(5).trim(); // Removing "from" from start time + String to = parts[TO_INDEX].trim().substring(3).trim(); // Removing "to" from end time Task task = new Task(description, day, from, to); @@ -37,7 +42,7 @@ private int parseDayOfWeek(String day) { // Mapping day of the week to index (0-6) switch (day.toLowerCase()) { case "sunday": - return 0; + return 7; case "monday": return 1; case "tuesday": diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index 09ed3fa735..2056945391 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -2,14 +2,22 @@ public class Task { protected String description; - protected String date; + protected String day; protected String from; protected String to; - public Task(String description, String date, String from, String to){ + public Task(String description, String day, String from, String to){ this.description = description; - this.date = date; + this.day = day; this.from = from; this.to = to; } + + public String getDay() { + return day; + } + @Override + public String toString() { + return description + " (" + day + " from " + from + " to " + to + ")"; + } } diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 693b1fa5c2..2489ef66ae 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -41,4 +41,37 @@ public void deleteUserTask(int dayOfWeek, int index){ System.out.println("Invalid day of the week."); } } + + public void printTasksOfTheDay(int dayOfWeek) { + String day; + switch (dayOfWeek) { + case (0): + day = "Monday"; + break; + case (1): + day = "Tuesday"; + break; + case (2): + day = "Wednesday"; + break; + case (3): + day = "Thursday"; + break; + case (4): + day = "Friday"; + break; + case (5): + day = "Saturday"; + break; + case (6): + day = "Sunday"; + break; + default: + throw new IllegalStateException("Unexpected value: " + dayOfWeek); + } + System.out.println(day + ": "); + for (Task task : daysOfWeek[dayOfWeek]) { + System.out.println(task.toString()); + } + } } diff --git a/src/main/java/seedu/duke/User.java b/src/main/java/seedu/duke/User.java index 6105f6cff8..b15a44fae9 100644 --- a/src/main/java/seedu/duke/User.java +++ b/src/main/java/seedu/duke/User.java @@ -12,7 +12,9 @@ public User(String name) { public String getName() { return name; } - - - + public void viewTimetable() { + for (int i = 0; i < 7; i++) { + timetable.printTasksOfTheDay(i); + } + } } From 2c32ea50114b5eadf379f2a9e7d3143777467fab Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 18 Mar 2024 17:13:46 +0800 Subject: [PATCH 021/162] Remove used imports and class --- src/main/java/seedu/duke/Duke.java | 1 - src/main/java/seedu/duke/Parser.java | 10 ++++------ src/main/java/seedu/duke/Task.java | 4 ---- src/main/java/seedu/duke/TaskList.java | 23 ----------------------- src/main/java/seedu/duke/Timetable.java | 16 +++++----------- src/main/java/seedu/duke/User.java | 6 +----- 6 files changed, 10 insertions(+), 50 deletions(-) delete mode 100644 src/main/java/seedu/duke/TaskList.java diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 7733de3b89..c9535183c5 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -6,7 +6,6 @@ import java.util.Scanner; public class Duke { - private static final int ADD_TASK_INDEX = 9; static Scanner in = new Scanner(System.in); public static void main(String[] args) { diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index b0e0398200..67c00838ed 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -1,9 +1,9 @@ package seedu.duke; -import java.util.Scanner; -import java.util.ArrayList; + +import seedu.duke.ui.UI; + public class Parser { private static User user; - private static final int NAME_INDEX = 1; private static final int DAY_INDEX = 2; private static final int DESCRIPTION_INDEX = 3; private static final int FROM_INDEX = 4; @@ -32,7 +32,7 @@ public void parseCommand(String command) { int dayOfWeek = parseDayOfWeek(day); if (dayOfWeek != -1) { user.timetable.addUserTask(dayOfWeek, task); - System.out.println("Task added successfully."); + UI.printAddTask(description); } else { System.out.println("Invalid day of the week."); } @@ -60,8 +60,6 @@ private int parseDayOfWeek(String day) { } } - private static final int NAME_PART = 1; - public void deleteTask(String command) { String[] parts = command.split("/"); // Splitting command into parts using space diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index 2056945391..c4b558a945 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -12,10 +12,6 @@ public Task(String description, String day, String from, String to){ this.from = from; this.to = to; } - - public String getDay() { - return day; - } @Override public String toString() { return description + " (" + day + " from " + from + " to " + to + ")"; diff --git a/src/main/java/seedu/duke/TaskList.java b/src/main/java/seedu/duke/TaskList.java deleted file mode 100644 index dab6f2a164..0000000000 --- a/src/main/java/seedu/duke/TaskList.java +++ /dev/null @@ -1,23 +0,0 @@ -package seedu.duke; - -import java.util.ArrayList; - -public class TaskList { - private ArrayList tasks; - public TaskList() { this.tasks = new ArrayList<>(); - } - public void addTask(Task task){ - tasks.add(task); - } - public void deleteTask(int index){ - tasks.remove(index); - } - - public int size() { - return tasks.size(); - } - - public Task get(int index) { - return tasks.get(index); - } -} diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 2489ef66ae..726fab48bf 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -15,30 +15,24 @@ private void initializeTimetable() { daysOfWeek[i] = new ArrayList<>(); } } - protected String name; public void addUserTask(int dayOfWeek, Task task){ assert dayOfWeek >= 0 && dayOfWeek <= 6 : "Invalid day of a week, please try again!"; - if(dayOfWeek >= 0 && dayOfWeek < 7){ - daysOfWeek[dayOfWeek - 1].add(task); - } + daysOfWeek[dayOfWeek - 1].add(task); + } public void deleteUserTask(int dayOfWeek, int index){ assert dayOfWeek >= 0 && dayOfWeek <= 6 : "Invalid day of a week, please try again!"; assert index >= 0 && index < daysOfWeek[dayOfWeek - 1].size() : "Invalid task index, please try again!"; - if (dayOfWeek >= 0 && dayOfWeek < 7) { - ArrayList tasks = daysOfWeek[dayOfWeek - 1]; - if (index >= 0 && index < tasks.size()){ + ArrayList tasks = daysOfWeek[dayOfWeek - 1]; + if (index < tasks.size()){ Task taskDeleted = tasks.get(index); tasks.remove(index); System.out.println("Task " + taskDeleted.description + "is deleted from " + dayOfWeek); - } else{ - System.out.println("Invalid task index. Please try again"); - } } else{ - System.out.println("Invalid day of the week."); + System.out.println("Invalid task index. Please try again"); } } diff --git a/src/main/java/seedu/duke/User.java b/src/main/java/seedu/duke/User.java index b15a44fae9..67250eeb94 100644 --- a/src/main/java/seedu/duke/User.java +++ b/src/main/java/seedu/duke/User.java @@ -1,10 +1,6 @@ package seedu.duke; -import java.lang.reflect.Array; -import java.util.ArrayList; - public class User { - private String name; - private ArrayList taskLists; //THIS COULD BE TIMETABLE + private final String name; public Timetable timetable = new Timetable(); public User(String name) { this.name = name; From e3a7da9af593d5dddcec5805564d52d9218994d1 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 18 Mar 2024 17:33:44 +0800 Subject: [PATCH 022/162] Fix PR run issues --- src/main/java/seedu/duke/Duke.java | 2 -- src/main/java/seedu/duke/Timetable.java | 14 +++++++------- src/test/java/seedu/duke/TimetableTest.java | 16 ++++------------ 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index c9535183c5..c3765c439a 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -12,8 +12,6 @@ public static void main(String[] args) { UI.printGreeting(); UserList userList = new UserList(); - - //replace this with parser while (true) { String input = in.nextLine(); diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 726fab48bf..2083307c32 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -1,31 +1,31 @@ package seedu.duke; +import java.lang.reflect.Array; import java.util.ArrayList; public class Timetable { //todo - protected ArrayList[] daysOfWeek; + protected ArrayList> daysOfWeek = new ArrayList<>(7);; public Timetable() { - daysOfWeek = new ArrayList[7]; initializeTimetable(); } private void initializeTimetable() { for (int i = 0; i < 7; i++) { - daysOfWeek[i] = new ArrayList<>(); + daysOfWeek.add(new ArrayList<>()); } } public void addUserTask(int dayOfWeek, Task task){ assert dayOfWeek >= 0 && dayOfWeek <= 6 : "Invalid day of a week, please try again!"; - daysOfWeek[dayOfWeek - 1].add(task); + daysOfWeek.get(dayOfWeek - 1).add(task); } public void deleteUserTask(int dayOfWeek, int index){ assert dayOfWeek >= 0 && dayOfWeek <= 6 : "Invalid day of a week, please try again!"; - assert index >= 0 && index < daysOfWeek[dayOfWeek - 1].size() : "Invalid task index, please try again!"; + assert index >= 0 && index < daysOfWeek.get(dayOfWeek - 1).size() : "Invalid task index, please try again!"; - ArrayList tasks = daysOfWeek[dayOfWeek - 1]; + ArrayList tasks = daysOfWeek.get(dayOfWeek - 1); if (index < tasks.size()){ Task taskDeleted = tasks.get(index); tasks.remove(index); @@ -64,7 +64,7 @@ public void printTasksOfTheDay(int dayOfWeek) { throw new IllegalStateException("Unexpected value: " + dayOfWeek); } System.out.println(day + ": "); - for (Task task : daysOfWeek[dayOfWeek]) { + for (Task task : daysOfWeek.get(dayOfWeek)) { System.out.println(task.toString()); } } diff --git a/src/test/java/seedu/duke/TimetableTest.java b/src/test/java/seedu/duke/TimetableTest.java index 5eae3093fa..3b2fa0829d 100644 --- a/src/test/java/seedu/duke/TimetableTest.java +++ b/src/test/java/seedu/duke/TimetableTest.java @@ -1,16 +1,8 @@ package seedu.duke; -import seedu.duke.UserList; -import seedu.duke.ui.UI; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - import org.junit.jupiter.api.Test; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - class TimetableTest { @Test public void testAddUserTask() { @@ -20,8 +12,8 @@ public void testAddUserTask() { timetable.addUserTask(dayOfWeek, task); - assertEquals(1, timetable.daysOfWeek[dayOfWeek - 1].size()); - assertEquals(task, timetable.daysOfWeek[dayOfWeek - 1].get(0)); + assertEquals(1, timetable.daysOfWeek.get(0).size()); + assertEquals(task, timetable.daysOfWeek.get(0).get(0)); } @Test public void testDeleteUserTask() { @@ -38,8 +30,8 @@ public void testDeleteUserTask() { timetable.deleteUserTask(dayOfWeek, 0); // Check if the task is deleted - assertEquals(1, timetable.daysOfWeek[dayOfWeek - 1].size()); - assertEquals(task2, timetable.daysOfWeek[dayOfWeek - 1].get(0)); + assertEquals(1, timetable.daysOfWeek.get(0).size()); + assertEquals(task2, timetable.daysOfWeek.get(0).get(0)); } } \ No newline at end of file From 160ffcbfe05c756784e7084a226eeb0ba5fbfa36 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 18 Mar 2024 17:40:47 +0800 Subject: [PATCH 023/162] Remove redundant imports and fix indentations --- src/main/java/seedu/duke/Timetable.java | 14 +++++--------- src/test/java/seedu/duke/DukeTest.java | 3 --- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 2083307c32..03183b837b 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -1,15 +1,12 @@ package seedu.duke; - -import java.lang.reflect.Array; import java.util.ArrayList; public class Timetable { //todo - protected ArrayList> daysOfWeek = new ArrayList<>(7);; + protected ArrayList> daysOfWeek = new ArrayList<>(7); public Timetable() { initializeTimetable(); } - private void initializeTimetable() { for (int i = 0; i < 7; i++) { daysOfWeek.add(new ArrayList<>()); @@ -27,12 +24,11 @@ public void deleteUserTask(int dayOfWeek, int index){ ArrayList tasks = daysOfWeek.get(dayOfWeek - 1); if (index < tasks.size()){ - Task taskDeleted = tasks.get(index); - tasks.remove(index); - System.out.println("Task " + taskDeleted.description + "is deleted from " + dayOfWeek); - + Task taskDeleted = tasks.get(index); + tasks.remove(index); + System.out.println("Task " + taskDeleted.description + "is deleted from " + dayOfWeek); } else{ - System.out.println("Invalid task index. Please try again"); + System.out.println("Invalid task index. Please try again"); } } diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index 7790de6b59..d9b980a6eb 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -1,6 +1,4 @@ package seedu.duke; -import seedu.duke.UserList; -import seedu.duke.ui.UI; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -19,7 +17,6 @@ public void sampleTest() { @Test public void testInvalidCommand() { // Arrange - UserList userList = new UserList(); ByteArrayInputStream in = new ByteArrayInputStream("invalid\nbye\n".getBytes()); System.setIn(in); From 6c30e11e37be76a53c8dac87fd5ce695e7105fbf Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 18 Mar 2024 17:46:05 +0800 Subject: [PATCH 024/162] Add newline at end of file --- src/main/java/seedu/duke/User.java | 3 ++- src/test/java/seedu/duke/TimetableTest.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/duke/User.java b/src/main/java/seedu/duke/User.java index 67250eeb94..7ba169e4b4 100644 --- a/src/main/java/seedu/duke/User.java +++ b/src/main/java/seedu/duke/User.java @@ -1,7 +1,8 @@ package seedu.duke; public class User { - private final String name; public Timetable timetable = new Timetable(); + private final String name; + public User(String name) { this.name = name; } diff --git a/src/test/java/seedu/duke/TimetableTest.java b/src/test/java/seedu/duke/TimetableTest.java index 3b2fa0829d..f49ea1695d 100644 --- a/src/test/java/seedu/duke/TimetableTest.java +++ b/src/test/java/seedu/duke/TimetableTest.java @@ -34,4 +34,4 @@ public void testDeleteUserTask() { assertEquals(task2, timetable.daysOfWeek.get(0).get(0)); } -} \ No newline at end of file +} From 7f0f0028ccf432b0cfe7c0d1d0819b9175ecde74 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 18 Mar 2024 17:51:51 +0800 Subject: [PATCH 025/162] Fix ifelse format issue --- src/main/java/seedu/duke/Duke.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index c3765c439a..5f15be56be 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -50,8 +50,7 @@ public static void main(String[] args) { parser.parseCommand(input); } else if (Objects.equals(command, "view")) { userList.getActiveUser().viewTimetable(); - } - else { + } else { UI.printInvalidCommand(); } } From 0b2d8e31985c968b1fcb25c0eb796e341c8c9946 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 18 Mar 2024 18:21:45 +0800 Subject: [PATCH 026/162] Fix testinvalidcommand --- src/test/java/seedu/duke/DukeTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index d9b980a6eb..d9e5686b84 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -17,12 +17,12 @@ public void sampleTest() { @Test public void testInvalidCommand() { // Arrange - ByteArrayInputStream in = new ByteArrayInputStream("invalid\nbye\n".getBytes()); + ByteArrayInputStream in = new ByteArrayInputStream("invalid\n".getBytes()); System.setIn(in); ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); - String expectedOutput = "Timetable comparison app opened. \r\nInvalid command. \r\nBye. \r\n"; + String expectedOutput = "Timetable comparison app opened. \r\nInvalid command. \r\n"; // Act Duke.main(new String[0]); From 11d636454d00f0ff31103833ff52d7a1390c6e46 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 18 Mar 2024 18:29:12 +0800 Subject: [PATCH 027/162] Fix testinvalid command --- src/test/java/seedu/duke/DukeTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index d9e5686b84..d9b980a6eb 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -17,12 +17,12 @@ public void sampleTest() { @Test public void testInvalidCommand() { // Arrange - ByteArrayInputStream in = new ByteArrayInputStream("invalid\n".getBytes()); + ByteArrayInputStream in = new ByteArrayInputStream("invalid\nbye\n".getBytes()); System.setIn(in); ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); - String expectedOutput = "Timetable comparison app opened. \r\nInvalid command. \r\n"; + String expectedOutput = "Timetable comparison app opened. \r\nInvalid command. \r\nBye. \r\n"; // Act Duke.main(new String[0]); From 450a5e6514fda94bb58c5ae83f834db039fb213d Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 18 Mar 2024 18:33:54 +0800 Subject: [PATCH 028/162] Fix testinvalid command --- src/test/java/seedu/duke/DukeTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index d9b980a6eb..dd8dc421b0 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -22,7 +22,7 @@ public void testInvalidCommand() { ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); - String expectedOutput = "Timetable comparison app opened. \r\nInvalid command. \r\nBye. \r\n"; + String expectedOutput = "Timetable comparison app opened." + System.lineSeparator() + "Invalid command." + System.lineSeparator() + "Bye."; // Act Duke.main(new String[0]); From b441343cccbbb66d63b19a74422624c43bf1a6a8 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 18 Mar 2024 18:37:38 +0800 Subject: [PATCH 029/162] Fix testinvalidcommand --- src/test/java/seedu/duke/DukeTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index dd8dc421b0..5ed45507ea 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -17,12 +17,12 @@ public void sampleTest() { @Test public void testInvalidCommand() { // Arrange - ByteArrayInputStream in = new ByteArrayInputStream("invalid\nbye\n".getBytes()); + ByteArrayInputStream in = new ByteArrayInputStream("invalid\r\nbye\r\n".getBytes()); System.setIn(in); ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); - String expectedOutput = "Timetable comparison app opened." + System.lineSeparator() + "Invalid command." + System.lineSeparator() + "Bye."; + String expectedOutput = "Timetable comparison app opened. \r\nInvalid command. \r\nBye. \r\n"; // Act Duke.main(new String[0]); From 9168655b59a286520bab8999c1f317303cbdfedd Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Wed, 20 Mar 2024 02:59:47 +0800 Subject: [PATCH 030/162] Refactored Timetable object into a HashMap. --- src/main/java/seedu/duke/Duke.java | 2 +- .../java/seedu/duke/InvalidDayException.java | 7 ++ src/main/java/seedu/duke/Parser.java | 35 ++---- src/main/java/seedu/duke/Timetable.java | 104 +++++++++--------- src/main/java/seedu/duke/User.java | 4 +- src/test/java/seedu/duke/TimetableTest.java | 19 ++-- 6 files changed, 81 insertions(+), 90 deletions(-) create mode 100644 src/main/java/seedu/duke/InvalidDayException.java diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 5f15be56be..8b302cf5ec 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -43,7 +43,7 @@ public static void main(String[] args) { int weekOfDay = Integer.parseInt(words[1]); int index = Integer.parseInt(words[2]) - 1; - userList.getActiveUser().timetable.deleteUserTask(weekOfDay, index); + //userList.getActiveUser().timetable.deleteUserTask(weekOfDay, index); } else if (Objects.equals(command, "addtask")) { User currentUser = userList.getActiveUser(); Parser parser = new Parser(currentUser); diff --git a/src/main/java/seedu/duke/InvalidDayException.java b/src/main/java/seedu/duke/InvalidDayException.java new file mode 100644 index 0000000000..2bfa00797b --- /dev/null +++ b/src/main/java/seedu/duke/InvalidDayException.java @@ -0,0 +1,7 @@ +package seedu.duke; + +public class InvalidDayException extends Exception { + public InvalidDayException() { + super("Invalid day. Please enter a day from Monday to Sunday."); + } +} diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 67c00838ed..d2688dbbca 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -12,6 +12,7 @@ public class Parser { public Parser(User user) { Parser.user = user; } + public void parseCommand(String command) { String[] parts = command.split("/"); // Splitting command into parts using slash @@ -29,34 +30,12 @@ public void parseCommand(String command) { Task task = new Task(description, day, from, to); // Adding task to the User's task list - int dayOfWeek = parseDayOfWeek(day); - if (dayOfWeek != -1) { - user.timetable.addUserTask(dayOfWeek, task); + try { + Timetable.checkDay(day); + user.timetable.addUserTask(day, task); UI.printAddTask(description); - } else { - System.out.println("Invalid day of the week."); - } - } - - private int parseDayOfWeek(String day) { - // Mapping day of the week to index (0-6) - switch (day.toLowerCase()) { - case "sunday": - return 7; - case "monday": - return 1; - case "tuesday": - return 2; - case "wednesday": - return 3; - case "thursday": - return 4; - case "friday": - return 5; - case "saturday": - return 6; - default: - return -1; // Invalid day + } catch (InvalidDayException e) { + System.out.println(e.getMessage()); } } @@ -71,7 +50,7 @@ public void deleteTask(String command) { try { int index = Integer.parseInt(parts[1].trim()); int dayOfWeek = 0; // Assume we are always deleting from Sunday for now - user.timetable.deleteUserTask(dayOfWeek, index - 1); // Adjust index by -1 to match array index + user.timetable.deleteUserTask("sunday", index - 1); // Adjust index by -1 to match array index System.out.println("Task deleted successfully."); } catch (NumberFormatException e) { System.out.println("Invalid task index."); diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 03183b837b..73fc8f3147 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -1,67 +1,73 @@ package seedu.duke; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; public class Timetable { - //todo - protected ArrayList> daysOfWeek = new ArrayList<>(7); - public Timetable() { - initializeTimetable(); + private Map> weeklyTasks; // Map to store tasks for each day + protected static final String[] days = new String[]{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; + + public Map> getWeeklyTasks() { + return weeklyTasks; } - private void initializeTimetable() { - for (int i = 0; i < 7; i++) { - daysOfWeek.add(new ArrayList<>()); + + public Timetable() { + weeklyTasks = new HashMap<>(); + //Initialize the map with empty lists for each day + for (String day: days) { + weeklyTasks.put(day, new ArrayList<>()); } } - public void addUserTask(int dayOfWeek, Task task){ - assert dayOfWeek >= 0 && dayOfWeek <= 6 : "Invalid day of a week, please try again!"; - daysOfWeek.get(dayOfWeek - 1).add(task); + public void addUserTask(String dayOfWeek, Task task){ + try { + checkDay(dayOfWeek); + String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); + weeklyTasks.get(capitalizedDay).add(task); + System.out.println("Added: " + task + " to " + capitalizedDay); + } catch (InvalidDayException e) { + System.out.println(e.getMessage()); + } } - public void deleteUserTask(int dayOfWeek, int index){ - assert dayOfWeek >= 0 && dayOfWeek <= 6 : "Invalid day of a week, please try again!"; - assert index >= 0 && index < daysOfWeek.get(dayOfWeek - 1).size() : "Invalid task index, please try again!"; - - ArrayList tasks = daysOfWeek.get(dayOfWeek - 1); - if (index < tasks.size()){ - Task taskDeleted = tasks.get(index); - tasks.remove(index); - System.out.println("Task " + taskDeleted.description + "is deleted from " + dayOfWeek); - } else{ - System.out.println("Invalid task index. Please try again"); + public void deleteUserTask(String dayOfWeek, int index){ + try { + checkDay(dayOfWeek); + //check if index is a valid number within a day's tasklist + if (index >= 0 && index < weeklyTasks.get(dayOfWeek).size()) { + Task taskDeleted = weeklyTasks.get(dayOfWeek).get(index); + weeklyTasks.get(dayOfWeek).remove(index); + System.out.println("Task " + taskDeleted.description + "is deleted from " + dayOfWeek); + } + else { + System.out.println("Invalid task index. Please try again."); + } + } catch (InvalidDayException e) { + System.out.println(e.getMessage()); } } - public void printTasksOfTheDay(int dayOfWeek) { - String day; - switch (dayOfWeek) { - case (0): - day = "Monday"; - break; - case (1): - day = "Tuesday"; - break; - case (2): - day = "Wednesday"; - break; - case (3): - day = "Thursday"; - break; - case (4): - day = "Friday"; - break; - case (5): - day = "Saturday"; - break; - case (6): - day = "Sunday"; - break; - default: - throw new IllegalStateException("Unexpected value: " + dayOfWeek); + public void printTasksOfTheDay(String day) { + String capitalizedDay = day.substring(0, 1).toUpperCase() + day.substring(1); + if (weeklyTasks.get(capitalizedDay) == null) { + System.out.println("NO TASK FOR " + day); } - System.out.println(day + ": "); - for (Task task : daysOfWeek.get(dayOfWeek)) { + System.out.println(capitalizedDay + ":"); + for (Task task : weeklyTasks.get(capitalizedDay)) { System.out.println(task.toString()); } } + + public static void checkDay(String input) throws InvalidDayException { + boolean validDay = false; + for (String day : days) { + if (day.equalsIgnoreCase(input)) { + validDay = true; + break; + } + } + if (!validDay) { + throw new InvalidDayException(); + } + } } diff --git a/src/main/java/seedu/duke/User.java b/src/main/java/seedu/duke/User.java index 7ba169e4b4..8baf6f8e11 100644 --- a/src/main/java/seedu/duke/User.java +++ b/src/main/java/seedu/duke/User.java @@ -10,8 +10,8 @@ public String getName() { return name; } public void viewTimetable() { - for (int i = 0; i < 7; i++) { - timetable.printTasksOfTheDay(i); + for (String day : Timetable.days) { + timetable.printTasksOfTheDay(day); } } } diff --git a/src/test/java/seedu/duke/TimetableTest.java b/src/test/java/seedu/duke/TimetableTest.java index f49ea1695d..2ae4fa5bc0 100644 --- a/src/test/java/seedu/duke/TimetableTest.java +++ b/src/test/java/seedu/duke/TimetableTest.java @@ -8,30 +8,29 @@ class TimetableTest { public void testAddUserTask() { Timetable timetable = new Timetable(); Task task = new Task("Study","2024-03-18", "09:00", "11:00"); - int dayOfWeek = 1; // assume Tuesday - timetable.addUserTask(dayOfWeek, task); + timetable.addUserTask("Tuesday", task); - assertEquals(1, timetable.daysOfWeek.get(0).size()); - assertEquals(task, timetable.daysOfWeek.get(0).get(0)); + timetable.printTasksOfTheDay("Tuesday"); + assertEquals(1, timetable.getWeeklyTasks().get("Tuesday").size()); + assertEquals(task, timetable.getWeeklyTasks().get("Tuesday").get(0)); } @Test public void testDeleteUserTask() { Timetable timetable = new Timetable(); Task task1 = new Task("Study", "2024-03-18", "09:00", "11:00"); Task task2 = new Task("Exercise", "2024-03-18", "15:00", "16:30"); - int dayOfWeek = 1; // assume Tuesday // Add tasks to the timetable - timetable.addUserTask(dayOfWeek, task1); - timetable.addUserTask(dayOfWeek, task2); + timetable.addUserTask("tuesday", task1); + timetable.addUserTask("tuesday", task2); // Delete the first task - timetable.deleteUserTask(dayOfWeek, 0); + timetable.deleteUserTask("tuesday", 0); // Check if the task is deleted - assertEquals(1, timetable.daysOfWeek.get(0).size()); - assertEquals(task2, timetable.daysOfWeek.get(0).get(0)); + assertEquals(1, timetable.getWeeklyTasks().get("tuesday").size()); + assertEquals(task2, timetable.getWeeklyTasks().get("tuesday").get(0)); } } From bfdc3bbfe555b4d2df58596fffa73031d0bae5b5 Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Wed, 20 Mar 2024 11:30:39 +0800 Subject: [PATCH 031/162] Finished comparison timetable method, working on parsing functionality. --- src/main/java/seedu/duke/InputValidator.java | 24 +++++++++ .../seedu/duke/InvalidFormatException.java | 10 ++++ src/main/java/seedu/duke/Parser.java | 12 +++++ src/main/java/seedu/duke/Task.java | 43 +++++++++++++-- src/main/java/seedu/duke/Timetable.java | 54 +++++++++++++++++++ src/test/java/seedu/duke/TimetableTest.java | 13 +++++ 6 files changed, 151 insertions(+), 5 deletions(-) create mode 100644 src/main/java/seedu/duke/InputValidator.java create mode 100644 src/main/java/seedu/duke/InvalidFormatException.java diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java new file mode 100644 index 0000000000..191064b7f4 --- /dev/null +++ b/src/main/java/seedu/duke/InputValidator.java @@ -0,0 +1,24 @@ +package seedu.duke; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class InputValidator { + /** + * Validates correctly formatted compare command. + * + * @param input String Input. + * @throws InvalidFormatException if input does not match "compare " format + */ + public static void validateCompareInput(String input) throws InvalidFormatException { + // Define the regex pattern for the expected format with case-insensitive flag + String regex = "(?i)^compare\\s+\\w+\\s+\\w+$"; + + Pattern pattern = Pattern.compile(regex); + // Create a matcher object to match the input against the pattern + Matcher matcher = pattern.matcher(input); + + if (!input.matches(regex)) { + throw new InvalidFormatException("[ERROR] Invalid compare format. Expected format: compare ."); + } + } +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/InvalidFormatException.java b/src/main/java/seedu/duke/InvalidFormatException.java new file mode 100644 index 0000000000..db2ba7fbff --- /dev/null +++ b/src/main/java/seedu/duke/InvalidFormatException.java @@ -0,0 +1,10 @@ +package seedu.duke; + +/** + * This class represents Expections expected from the InputValidator class. + */ +public class InvalidFormatException extends Exception{ + public InvalidFormatException(String message) { + super(message); + } +} diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index d2688dbbca..c3b74182b0 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -21,6 +21,18 @@ public void parseCommand(String command) { return; } + //Parse the compare command and split them into parts "compare user1 user2" + if (command.toLowerCase().startsWith("compare")) { + String[] parts = command.split("\\s+"); + try { + InputValidator.validateCompareInput(command); + User user1 = parts[1]; + User user2 = parts[2]; + } catch (InvalidFormatException e) { + System.out.println(e.getMessage()); + } + } + // Extracting description, day, start time, and end time from the parts String description = parts[DESCRIPTION_INDEX].trim().substring(5).trim(); String day = parts[DAY_INDEX].trim().substring(3).trim(); // Removing "on" from day diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index c4b558a945..01e436fa2e 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -1,19 +1,52 @@ package seedu.duke; +import java.time.LocalTime; public class Task { protected String description; protected String day; - protected String from; - protected String to; + protected LocalTime startTime; + protected LocalTime endTime; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDay() { + return day; + } + + public void setDay(String day) { + this.day = day; + } + + public LocalTime getStartTime() { + return startTime; + } + + public void setStartTime(LocalTime startTime) { + this.startTime = startTime; + } + + public LocalTime getEndTime() { + return endTime; + } + + public void setEndTime(LocalTime endTime) { + this.endTime = endTime; + } public Task(String description, String day, String from, String to){ this.description = description; this.day = day; - this.from = from; - this.to = to; + this.startTime = LocalTime.parse(from); + this.endTime = LocalTime.parse(to); } @Override public String toString() { - return description + " (" + day + " from " + from + " to " + to + ")"; + return description + " (" + day + " from " + startTime + " to " + endTime + ")"; } } diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 73fc8f3147..c0d1f65456 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -1,8 +1,14 @@ package seedu.duke; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.Map; +/** + * This class represents the Timetable object consisting of Arraylist of Tasks for each day of the week. + */ public class Timetable { private Map> weeklyTasks; // Map to store tasks for each day protected static final String[] days = new String[]{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; @@ -47,6 +53,54 @@ public void deleteUserTask(String dayOfWeek, int index){ } } + /** + * Compares and prints overlapping free time between two Timetables. + * + * @param table1 first Timetable. + * @param table2 second Timetable + * + * Prints the overlapping free time for each day in the format: + * ---------------------- + * Shared Free Time on [day] + * HH:mm - HH:mm: Overlapping Free Time + */ + public static void compareTimetable(Timetable table1, Timetable table2){ + for (String day : Timetable.days) { + System.out.println("----------------------\n" + + "Shared Free Time on " + day + ":"); + // Merge tasks from both timetables and sort them by start time + ArrayList mergedTasks = mergeAndSortTasks(table1.getWeeklyTasks().get(day), table2.getWeeklyTasks().get(day)); + // Calculate overlapping free time intervals then print them + calculateAndPrintOverlappingFreeTime(mergedTasks, day); + } + } + + private static ArrayList mergeAndSortTasks(ArrayList taskList1, ArrayList taskList2) { + ArrayList mergedTasks = new ArrayList<>(taskList1); + mergedTasks.addAll(taskList2); + mergedTasks.sort(Comparator.comparing(Task::getStartTime)); + return mergedTasks; + } + + private static void calculateAndPrintOverlappingFreeTime(ArrayList tasks, String day) { + if (!tasks.isEmpty()) { + LocalTime previousEndTime = LocalTime.MIN; + for (Task task : tasks) { + if (task.getStartTime().isAfter(previousEndTime)) { + System.out.println(previousEndTime + " - " + task.getStartTime() + ": Overlapping Free Time"); + } + previousEndTime = task.getEndTime(); + } + if (previousEndTime.isBefore(LocalTime.MAX)) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm"); + System.out.println(previousEndTime + " - " + LocalTime.MAX.format(formatter) + ": Overlapping Free Time"); + } + } else { + System.out.println("** Whole day is free on " + day); + } + + } + public void printTasksOfTheDay(String day) { String capitalizedDay = day.substring(0, 1).toUpperCase() + day.substring(1); if (weeklyTasks.get(capitalizedDay) == null) { diff --git a/src/test/java/seedu/duke/TimetableTest.java b/src/test/java/seedu/duke/TimetableTest.java index 2ae4fa5bc0..69f89f9f73 100644 --- a/src/test/java/seedu/duke/TimetableTest.java +++ b/src/test/java/seedu/duke/TimetableTest.java @@ -3,6 +3,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; +import java.sql.Time; + class TimetableTest { @Test public void testAddUserTask() { @@ -16,6 +18,17 @@ public void testAddUserTask() { assertEquals(task, timetable.getWeeklyTasks().get("Tuesday").get(0)); } @Test + public void testCompareTimetables() { + Timetable timetable1 = new Timetable(); + Timetable timetable2 = new Timetable(); + Task task1 = new Task("Study","2024-03-18", "09:00", "11:00"); + Task task2 = new Task("Study","2024-03-18", "07:00", "10:00"); + timetable1.addUserTask("Monday", task1); + timetable2.addUserTask("Monday", task2); + + Timetable.compareTimetable(timetable1, timetable2); + } + @Test public void testDeleteUserTask() { Timetable timetable = new Timetable(); Task task1 = new Task("Study", "2024-03-18", "09:00", "11:00"); From f45aad66545963df01a8d8c9bfbb35651e7bc689 Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Wed, 20 Mar 2024 16:12:40 +0800 Subject: [PATCH 032/162] Implemented Parser functionality and added command error handling. --- build.gradle | 1 + src/main/java/seedu/duke/Duke.java | 53 ++----- src/main/java/seedu/duke/InputValidator.java | 117 ++++++++++++++- .../java/seedu/duke/InvalidDayException.java | 5 +- .../java/seedu/duke/InvalidUserException.java | 10 ++ src/main/java/seedu/duke/Parser.java | 139 +++++++++++------- src/main/java/seedu/duke/Timetable.java | 94 ++++++------ src/main/java/seedu/duke/User.java | 6 +- src/main/java/seedu/duke/UserList.java | 54 ++++--- src/main/java/seedu/duke/ui/UI.java | 6 +- src/test/java/seedu/duke/DukeTest.java | 6 +- 11 files changed, 316 insertions(+), 175 deletions(-) create mode 100644 src/main/java/seedu/duke/InvalidUserException.java diff --git a/build.gradle b/build.gradle index 593bf8299e..0aa8c3246f 100644 --- a/build.gradle +++ b/build.gradle @@ -26,6 +26,7 @@ test { showStackTraces true showStandardStreams = false } + } application { diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 8b302cf5ec..133a4ecb31 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -7,52 +7,27 @@ public class Duke { static Scanner in = new Scanner(System.in); + static boolean finished = false; + + public static void setFinished(boolean b) { + finished = b; + } public static void main(String[] args) { UI.printGreeting(); UserList userList = new UserList(); - //replace this with parser - while (true) { - String input = in.nextLine(); - //extracts first word as command - String command = input.contains(" ") ? input.split(" ")[0] : input; - String description = ""; - if (input.contains(" ")) { - description = input.split(" ", 2)[1]; - } - - if (Objects.equals(command, "switch")) { - int index = (new Scanner(description).useDelimiter("\\D+").nextInt()) - 1; - userList.setActiveUser(index); - UI.printSetActiveUser(userList.getActiveUser().getName()); - } else if (Objects.equals(command, "list")) { - UI.printListingUsers(); - userList.listAll(); - } else if (Objects.equals(command, "bye")) { - UI.printBye(); - break; - } else if (Objects.equals(command, "add")) { - UI.printAddUser(description); - User newUser = new User(description); - userList.addUser(newUser); - } else if (Objects.equals(command, "current")) { - UI.printSetActiveUser(userList.getActiveUser().getName()); - } else if (Objects.equals(command, "delete")) { - String[] words = input.split(" "); - int weekOfDay = Integer.parseInt(words[1]); - int index = Integer.parseInt(words[2]) - 1; - - //userList.getActiveUser().timetable.deleteUserTask(weekOfDay, index); - } else if (Objects.equals(command, "addtask")) { - User currentUser = userList.getActiveUser(); - Parser parser = new Parser(currentUser); + //Replaced with Parser Logic + while (!finished) { + try { + String input = in.nextLine(); + Parser parser = new Parser(); parser.parseCommand(input); - } else if (Objects.equals(command, "view")) { - userList.getActiveUser().viewTimetable(); - } else { - UI.printInvalidCommand(); + + } catch (Exception e) { + System.out.println(e.getMessage()); } + } } } diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 191064b7f4..6a8a7276ef 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -1,6 +1,4 @@ package seedu.duke; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class InputValidator { /** @@ -13,12 +11,119 @@ public static void validateCompareInput(String input) throws InvalidFormatExcept // Define the regex pattern for the expected format with case-insensitive flag String regex = "(?i)^compare\\s+\\w+\\s+\\w+$"; - Pattern pattern = Pattern.compile(regex); - // Create a matcher object to match the input against the pattern - Matcher matcher = pattern.matcher(input); + if (!input.matches(regex)) { + throw new InvalidFormatException("[ERROR] Invalid compare format. Expected format: compare "); + } + } + + /** + * Validates correctly formatted addTask command. + * + * @param input String Input. + * @throws InvalidFormatException if input does not match "addTask /on [date] /task [description] /from [start time] /to [start time]" format + * Note: Start and End times should be formatted as such: HH:mm + */ + public static void validateAddTaskInput(String input) throws InvalidFormatException { + // Define the regex pattern for the expected format with case-insensitive flag + String regex = "(?i)^addtask\\s+/on\\s+(\\w+)\\s+/task\\s+(.+?)\\s+/from\\s+(\\d{2}:\\d{2})\\s+/to\\s+(\\d{2}:\\d{2})$"; if (!input.matches(regex)) { - throw new InvalidFormatException("[ERROR] Invalid compare format. Expected format: compare ."); + throw new InvalidFormatException("[ERROR] Invalid addTask format. " + + "Expected format: addTask /on [day] /task [description] /from [start time] /to [start time]"); + } + } + + /** + * Validates correctly formatted deleteTask command. + * + * @param input String Input. + * @throws InvalidFormatException if input does not match "deleteTask /on [day] /index [index]" format + * Note: index is the index of the task in the task list for the given day + */ + public static void validateDeleteTaskInput(String input) throws InvalidFormatException { + // Define the regex pattern for the expected format with case-insensitive flag + String regex = "(?i)^deletetask\\s+/on\\s+(\\w+)\\s+/index\\s+(\\d+)$"; + + if (!input.matches(regex)) { + throw new InvalidFormatException("[ERROR] Invalid deleteTask format. " + + "Expected format: deleteTask /on [day] /index [index]"); + } + } + + /** + * Validates correctly formatted addUser command. + * + * @param input String Input. + * @throws InvalidFormatException if input does not match "addUser " format + */ + public static void validateAddUserInput(String input) throws InvalidFormatException { + // Define the regex pattern for the expected format with case-insensitive flag + String regex = "(?i)^adduser\\s+\\w+$"; + + if (!input.matches(regex)) { + throw new InvalidFormatException("[ERROR] Invalid addUser format. Expected format: addUser "); + } + } + + /** + * Validates correctly formatted switch command. + * + * @param input String Input. + * @throws InvalidFormatException if input does not match "switch " format + */ + public static void validateSwitchInput(String input) throws InvalidFormatException { + // Define the regex pattern for the expected format with case-insensitive flag + String regex = "(?i)^switch\\s+\\w+$"; + + if (!input.matches(regex)) { + throw new InvalidFormatException("[ERROR] Invalid switch format. Expected format: switch "); + } + } + + /** + * Validates correctly spelled user names that currently exist in the user database. + * + * @param input String Input. + * @throws InvalidUserException if input does not match any current user's name in the user database. + */ + public static void validateUserInput(String input) throws InvalidUserException { + if (UserList.GetUsers().isEmpty()) { + throw new InvalidUserException("[ERROR] Current User List is empty. Please add users."); + } + for (User u : UserList.GetUsers()) { + if (u.getName().toLowerCase().equals(input)) { + return; + } + } + throw new InvalidUserException("[ERROR] Invalid User: " + input + ". Please input a existing user name"); + } + + /** + * Validates if the inputted string is an actual day. + * + * @param input String Input. + * @throws InvalidDayException if the input is not an actual day. + */ + public static void validateDay(String input) throws InvalidDayException { + String[] validDays = new String[]{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"}; + + for (String day : validDays) { + if (day.equals(input.toLowerCase())) { + return; + } + } + throw new InvalidDayException("[ERROR] Invalid day. Please enter a day from Monday - Sunday."); + } + + /** + * Validates whether a Timetable exist or not. + * + * @param table inputted Timetable. + * @throws NullPointerException if input Timetable does not exist. + */ + public static void validateTableExistence(Timetable table) throws NullPointerException { + if (table == null) { + throw new NullPointerException("Timetable object is null."); } } } \ No newline at end of file diff --git a/src/main/java/seedu/duke/InvalidDayException.java b/src/main/java/seedu/duke/InvalidDayException.java index 2bfa00797b..99dfff6a7b 100644 --- a/src/main/java/seedu/duke/InvalidDayException.java +++ b/src/main/java/seedu/duke/InvalidDayException.java @@ -1,7 +1,8 @@ package seedu.duke; public class InvalidDayException extends Exception { - public InvalidDayException() { - super("Invalid day. Please enter a day from Monday to Sunday."); + public InvalidDayException(String message) { + super(message); } + } diff --git a/src/main/java/seedu/duke/InvalidUserException.java b/src/main/java/seedu/duke/InvalidUserException.java new file mode 100644 index 0000000000..bd836c0681 --- /dev/null +++ b/src/main/java/seedu/duke/InvalidUserException.java @@ -0,0 +1,10 @@ +package seedu.duke; + +/** + * This class represents user Expections expected from the InputValidator class. + */ +public class InvalidUserException extends Exception{ + public InvalidUserException(String message) { + super(message); + } +} diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index c3b74182b0..630a3d16e1 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -2,70 +2,103 @@ import seedu.duke.ui.UI; -public class Parser { - private static User user; - private static final int DAY_INDEX = 2; - private static final int DESCRIPTION_INDEX = 3; - private static final int FROM_INDEX = 4; - private static final int TO_INDEX = 5; +import java.util.Arrays; +import java.util.List; - public Parser(User user) { - Parser.user = user; - } +public class Parser { + public Parser() {} + /** + * Parses User Input and Identifies the command used. + * + * @param command The users text input. + */ public void parseCommand(String command) { - String[] parts = command.split("/"); // Splitting command into parts using slash - - if (parts.length != 6 || !parts[0].trim().startsWith("add")) { - System.out.println("Invalid command format."); - return; - } - - //Parse the compare command and split them into parts "compare user1 user2" - if (command.toLowerCase().startsWith("compare")) { - String[] parts = command.split("\\s+"); + if (command.toLowerCase().equals("list")) { + UI.printListingUsers(); + UserList.ListAll(); + } else if (command.toLowerCase().equals("bye")) { + UI.printBye(); + Duke.setFinished(true); + } else if (command.toLowerCase().equals("current")) { + UI.printActiveUser(UserList.GetActiveUser().getName()); + } else if (command.toLowerCase().equals("view")) { + UserList.GetActiveUser().viewTimetable(); + } else if (command.toLowerCase().startsWith("adduser")) { try { - InputValidator.validateCompareInput(command); - User user1 = parts[1]; - User user2 = parts[2]; + InputValidator.validateAddUserInput(command); + String[] parts = command.split("\\s+"); + String userName = parts[1]; + User newUser = new User(userName); + UI.printNewUser(newUser.getName()); + UserList.AddUser(newUser); } catch (InvalidFormatException e) { System.out.println(e.getMessage()); } - } - - // Extracting description, day, start time, and end time from the parts - String description = parts[DESCRIPTION_INDEX].trim().substring(5).trim(); - String day = parts[DAY_INDEX].trim().substring(3).trim(); // Removing "on" from day - String from = parts[FROM_INDEX].trim().substring(5).trim(); // Removing "from" from start time - String to = parts[TO_INDEX].trim().substring(3).trim(); // Removing "to" from end time - - Task task = new Task(description, day, from, to); + } else if (command.toLowerCase().startsWith("switch")) { + try { + InputValidator.validateSwitchInput(command); + String[] parts = command.split("\\s+"); + String userName = parts[1]; + UserList.SetActiveUser(UserList.FindUser(userName)); + UI.printActiveUser(UserList.GetActiveUser().getName()); + } catch (InvalidFormatException e) { + System.out.println(e.getMessage()); + } + } else if (command.toLowerCase().startsWith("addtask")) { + try { + InputValidator.validateAddTaskInput(command); + String[] parts = command.split("\\s+"); + List wordList = Arrays.asList(parts); + String day = parts[2]; + String description = parseDescription(wordList); + String startTime = parts[wordList.indexOf("/from") + 1]; + String endTime = parts[wordList.indexOf("/to") + 1]; + InputValidator.validateDay(day); + Task task = new Task(description, day, startTime, endTime); + UserList.GetActiveUser().getTimetable().addUserTask(day, task); + } catch (InvalidFormatException | InvalidDayException e) { + System.out.println(e.getMessage()); + } + } else if (command.toLowerCase().startsWith("deletetask")) { + try { + InputValidator.validateDeleteTaskInput(command); + String[] parts = command.split("\\s+"); + String day = parts[2]; + int index = Integer.parseInt(parts[4]); + InputValidator.validateDay(day); + UserList.GetActiveUser().getTimetable().deleteUserTask(day, index); + } catch (InvalidFormatException | InvalidDayException e) { + System.out.println(e.getMessage()); + } + } else if (command.toLowerCase().startsWith("compare")) { + try { + InputValidator.validateCompareInput(command); + String[] parts = command.split("\\s+"); + String user1 = parts[1]; + String user2 = parts[2]; + InputValidator.validateUserInput(user1); + InputValidator.validateUserInput(user2); + Timetable.compareTimetable(UserList.FindUser(user1).getTimetable(), UserList.FindUser(user2).getTimetable()); - // Adding task to the User's task list - try { - Timetable.checkDay(day); - user.timetable.addUserTask(day, task); - UI.printAddTask(description); - } catch (InvalidDayException e) { - System.out.println(e.getMessage()); + } catch (InvalidFormatException | InvalidUserException | NullPointerException e) { + System.out.println(e.getMessage()); + } + } else { + UI.printInvalidCommand(); } } - public void deleteTask(String command) { - String[] parts = command.split("/"); // Splitting command into parts using space - - if (parts.length != 2 || !parts[0].trim().equalsIgnoreCase("delete")) { - System.out.println("Invalid delete command format."); - return; - } - - try { - int index = Integer.parseInt(parts[1].trim()); - int dayOfWeek = 0; // Assume we are always deleting from Sunday for now - user.timetable.deleteUserTask("sunday", index - 1); // Adjust index by -1 to match array index - System.out.println("Task deleted successfully."); - } catch (NumberFormatException e) { - System.out.println("Invalid task index."); + private String parseDescription(List words) { + int startIndex = words.indexOf("/task") + 1; + int endIndex = words.indexOf("/from") - 1; + StringBuilder description = new StringBuilder(); + for (int i = startIndex; i <= endIndex; i++) { + description.append(words.get(i)); + if (i < endIndex) { + description.append(" "); + } } + return description.toString(); } } diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index c0d1f65456..949170fdf3 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -13,10 +13,6 @@ public class Timetable { private Map> weeklyTasks; // Map to store tasks for each day protected static final String[] days = new String[]{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; - public Map> getWeeklyTasks() { - return weeklyTasks; - } - public Timetable() { weeklyTasks = new HashMap<>(); //Initialize the map with empty lists for each day @@ -25,31 +21,40 @@ public Timetable() { } } + public Map> getWeeklyTasks() { + return weeklyTasks; + } + + /** + * Adds task on dayOfWeek at an index + * + * @param dayOfWeek first Timetable. + * @param task task to add. + */ public void addUserTask(String dayOfWeek, Task task){ - try { - checkDay(dayOfWeek); - String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); - weeklyTasks.get(capitalizedDay).add(task); - System.out.println("Added: " + task + " to " + capitalizedDay); - } catch (InvalidDayException e) { - System.out.println(e.getMessage()); - } + String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); + weeklyTasks.get(capitalizedDay).add(task); + System.out.println("Added: " + task); } + /** + * Deletes task on dayOfWeek at an index + * + * @param dayOfWeek first Timetable. + * @param index index of task within task list + */ public void deleteUserTask(String dayOfWeek, int index){ - try { - checkDay(dayOfWeek); - //check if index is a valid number within a day's tasklist - if (index >= 0 && index < weeklyTasks.get(dayOfWeek).size()) { - Task taskDeleted = weeklyTasks.get(dayOfWeek).get(index); - weeklyTasks.get(dayOfWeek).remove(index); - System.out.println("Task " + taskDeleted.description + "is deleted from " + dayOfWeek); - } - else { - System.out.println("Invalid task index. Please try again."); - } - } catch (InvalidDayException e) { - System.out.println(e.getMessage()); + String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); + //check if index is a valid number within a day's tasklist + if (index >= 0 && index < weeklyTasks.get(capitalizedDay).size()) { + Task taskDeleted = weeklyTasks.get(capitalizedDay).get(index); + weeklyTasks.get(capitalizedDay).remove(index); + System.out.println("Task " + taskDeleted.description + " is deleted from " + dayOfWeek); + System.out.println("New task list for " + capitalizedDay + ":"); + printTasksOfTheDay(dayOfWeek); + } + else { + System.out.println("Invalid task index. Please try again."); } } @@ -65,13 +70,19 @@ public void deleteUserTask(String dayOfWeek, int index){ * HH:mm - HH:mm: Overlapping Free Time */ public static void compareTimetable(Timetable table1, Timetable table2){ - for (String day : Timetable.days) { - System.out.println("----------------------\n" + - "Shared Free Time on " + day + ":"); - // Merge tasks from both timetables and sort them by start time - ArrayList mergedTasks = mergeAndSortTasks(table1.getWeeklyTasks().get(day), table2.getWeeklyTasks().get(day)); - // Calculate overlapping free time intervals then print them - calculateAndPrintOverlappingFreeTime(mergedTasks, day); + try { + InputValidator.validateTableExistence(table1); + InputValidator.validateTableExistence(table2); + for (String day : Timetable.days) { + System.out.println("----------------------\n" + + "Shared Free Time on " + day + ":"); + // Merge tasks from both timetables and sort them by start time + ArrayList mergedTasks = mergeAndSortTasks(table1.getWeeklyTasks().get(day), table2.getWeeklyTasks().get(day)); + // Calculate overlapping free time intervals then print them + FindOverlappingFreeTime(mergedTasks, day); + } + } catch (NullPointerException e) { + System.out.println(e.getMessage()); } } @@ -82,7 +93,7 @@ private static ArrayList mergeAndSortTasks(ArrayList taskList1, Arra return mergedTasks; } - private static void calculateAndPrintOverlappingFreeTime(ArrayList tasks, String day) { + private static void FindOverlappingFreeTime(ArrayList tasks, String day) { if (!tasks.isEmpty()) { LocalTime previousEndTime = LocalTime.MIN; for (Task task : tasks) { @@ -98,30 +109,17 @@ private static void calculateAndPrintOverlappingFreeTime(ArrayList tasks, } else { System.out.println("** Whole day is free on " + day); } - } public void printTasksOfTheDay(String day) { String capitalizedDay = day.substring(0, 1).toUpperCase() + day.substring(1); - if (weeklyTasks.get(capitalizedDay) == null) { + if (weeklyTasks.get(capitalizedDay).isEmpty()) { System.out.println("NO TASK FOR " + day); + return; } System.out.println(capitalizedDay + ":"); for (Task task : weeklyTasks.get(capitalizedDay)) { System.out.println(task.toString()); } } - - public static void checkDay(String input) throws InvalidDayException { - boolean validDay = false; - for (String day : days) { - if (day.equalsIgnoreCase(input)) { - validDay = true; - break; - } - } - if (!validDay) { - throw new InvalidDayException(); - } - } } diff --git a/src/main/java/seedu/duke/User.java b/src/main/java/seedu/duke/User.java index 8baf6f8e11..372d66ec5d 100644 --- a/src/main/java/seedu/duke/User.java +++ b/src/main/java/seedu/duke/User.java @@ -1,10 +1,11 @@ package seedu.duke; public class User { - public Timetable timetable = new Timetable(); + private Timetable timetable; private final String name; public User(String name) { this.name = name; + this.timetable = new Timetable(); } public String getName() { return name; @@ -14,4 +15,7 @@ public void viewTimetable() { timetable.printTasksOfTheDay(day); } } + public Timetable getTimetable() { + return timetable; + } } diff --git a/src/main/java/seedu/duke/UserList.java b/src/main/java/seedu/duke/UserList.java index 1cdb228b87..6a24b8a64a 100644 --- a/src/main/java/seedu/duke/UserList.java +++ b/src/main/java/seedu/duke/UserList.java @@ -1,38 +1,52 @@ package seedu.duke; +import seedu.duke.ui.UI; + import java.util.ArrayList; public class UserList { - private int listLength; - private ArrayList allUsers; - private User activeUser; + private static ArrayList allUsers; + private static User activeUser; + public UserList() { - listLength = 0; - allUsers = new ArrayList(); + allUsers = new ArrayList<>(); } - public int getListLength() { - return listLength; - } - public void addUser(User user) { - allUsers.add(user); - listLength += 1; - if (listLength == 1) { - this.activeUser = allUsers.get(0); - } + public static User GetActiveUser() { + return activeUser; } - public void setActiveUser(int index) { - this.activeUser = allUsers.get(index); + + public static void SetActiveUser(User user) { + if (user != null) { + UserList.activeUser = user; + } else { + System.out.println("User does not exist!"); + } } - public User getActiveUser() { - return activeUser; + + public static void AddUser(User user) { + allUsers.add(user); + if (allUsers.size() == 1) { + UserList.activeUser = allUsers.get(0); //If this was the first user added, set them as the current user + UI.printActiveUser(user.getName()); + } } - public void listAll() { + + public static void ListAll() { for (User user : allUsers) { System.out.println(user.getName()); } } - public ArrayList getUsers() { + public static ArrayList GetUsers() { return allUsers; } + + public static User FindUser(String name) { + for (User u : allUsers) { + if (name.toLowerCase().equals(u.getName().toLowerCase())) { + return u; + } + } + return null; + } } diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index f903986dc5..eedeacae16 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -10,10 +10,10 @@ public static void printBye() { public static void printListingUsers() { System.out.println("The current users are: "); } - public static void printAddUser(String description) { - System.out.println("New user added: " + description); + public static void printNewUser(String name) { + System.out.println("New user added: " + name); } - public static void printSetActiveUser(String description) { + public static void printActiveUser(String description) { System.out.println("The active user is: " + description); } public static void printInvalidCommand() { diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index d9e5686b84..2c39e325ee 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -34,11 +34,11 @@ public void testInvalidCommand() { public void testAddUser() { UserList userList = new UserList(); User user = new User("Test User"); - userList.addUser(user); + userList.AddUser(user); // Verify that the user is added to the list assertEquals(1, userList.getListLength()); - assertEquals(user, userList.getActiveUser()); - assertTrue(userList.getUsers().contains(user)); + assertEquals(user, userList.GetActiveUser()); + assertTrue(userList.GetUsers().contains(user)); } } From 25336fee1e7470c8e71b3548d768c241b01adb76 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Wed, 20 Mar 2024 18:54:25 +0800 Subject: [PATCH 033/162] Allow inputs of the time in the format of both "09:00" and "9:00" --- src/main/java/seedu/duke/InputValidator.java | 2 +- src/main/java/seedu/duke/Task.java | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 6a8a7276ef..c3002417ca 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -25,7 +25,7 @@ public static void validateCompareInput(String input) throws InvalidFormatExcept */ public static void validateAddTaskInput(String input) throws InvalidFormatException { // Define the regex pattern for the expected format with case-insensitive flag - String regex = "(?i)^addtask\\s+/on\\s+(\\w+)\\s+/task\\s+(.+?)\\s+/from\\s+(\\d{2}:\\d{2})\\s+/to\\s+(\\d{2}:\\d{2})$"; + String regex = "(?i)^addtask\\s+/on\\s+(\\w+)\\s+/task\\s+(.+?)\\s+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})$"; if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid addTask format. " + diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index 01e436fa2e..0f1bb168e0 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -42,8 +42,18 @@ public void setEndTime(LocalTime endTime) { public Task(String description, String day, String from, String to){ this.description = description; this.day = day; - this.startTime = LocalTime.parse(from); - this.endTime = LocalTime.parse(to); + String fromHour = from.split(":")[0]; + String fromMinute = from.split(":")[1]; + String toHour = to.split(":")[0]; + String toMinute = to.split(":")[1]; + String formattedFrom = formatDates(fromHour) + ":" + formatDates(fromMinute); + String formattedTo = formatDates(toHour) + ":" + formatDates(toMinute); + this.startTime = LocalTime.parse(formattedFrom); + this.endTime = LocalTime.parse(formattedTo); + } + + private String formatDates(String time) { + return time.length() == 1 ? "0" + time : time; } @Override public String toString() { From bf21be65c67eb70aabf75be12ee04e9cc8969177 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Wed, 20 Mar 2024 20:14:50 +0800 Subject: [PATCH 034/162] Clean up code, add help command --- docs/UserGuide.md | 2 +- src/main/java/seedu/duke/Duke.java | 16 +++--- src/main/java/seedu/duke/InputValidator.java | 57 +++++++++++--------- src/main/java/seedu/duke/Parser.java | 39 +++++++------- src/main/java/seedu/duke/Task.java | 42 ++++----------- src/main/java/seedu/duke/Timetable.java | 43 ++++++++------- src/main/java/seedu/duke/User.java | 6 ++- src/main/java/seedu/duke/UserList.java | 27 ++++++---- src/main/java/seedu/duke/ui/UI.java | 24 +++++++-- src/test/java/seedu/duke/DukeTest.java | 6 +-- src/test/java/seedu/duke/TimetableTest.java | 2 - text-ui-test/EXPECTED.TXT | 47 ++++++++++++++++ text-ui-test/input.txt | 12 ++++- 13 files changed, 198 insertions(+), 125 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index abd9fbe891..b0294989ce 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -9,7 +9,7 @@ {Give steps to get started quickly} 1. Ensure that you have Java 11 or above installed. -1. Down the latest version of `Duke` from [here](http://link.to/duke). +2. Down the latest version of `Duke` from [here](http://link.to/duke). ## Features diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 133a4ecb31..811b4a97a9 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -2,27 +2,25 @@ import seedu.duke.ui.UI; -import java.util.Objects; import java.util.Scanner; public class Duke { - static Scanner in = new Scanner(System.in); - static boolean finished = false; + static final Scanner IN = new Scanner(System.in); + static boolean isFinished = false; - public static void setFinished(boolean b) { - finished = b; + public static void setIsFinished(boolean b) { + isFinished = b; } public static void main(String[] args) { UI.printGreeting(); UserList userList = new UserList(); - //Replaced with Parser Logic - while (!finished) { + while (!isFinished) { try { - String input = in.nextLine(); + String input = IN.nextLine(); Parser parser = new Parser(); - parser.parseCommand(input); + parser.parseCommand(input, userList); } catch (Exception e) { System.out.println(e.getMessage()); diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index c3002417ca..49bc488ba3 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -2,30 +2,34 @@ public class InputValidator { /** - * Validates correctly formatted compare command. + * Validates correctly formatted compare command. The expected format is + * "compare user1 user2" * * @param input String Input. - * @throws InvalidFormatException if input does not match "compare " format + * @throws InvalidFormatException If the input does not match the expected format. */ public static void validateCompareInput(String input) throws InvalidFormatException { // Define the regex pattern for the expected format with case-insensitive flag String regex = "(?i)^compare\\s+\\w+\\s+\\w+$"; if (!input.matches(regex)) { - throw new InvalidFormatException("[ERROR] Invalid compare format. Expected format: compare "); + throw new InvalidFormatException("[ERROR] Invalid compare format. " + + "Expected format: compare "); } } /** - * Validates correctly formatted addTask command. + * Validates correctly formatted addTask command. The expected format is + * "addtask /on [date] /task [description] /from [start time] /to [start time]" format + * Note: Start and End times should be formatted as such: HH:mm * * @param input String Input. - * @throws InvalidFormatException if input does not match "addTask /on [date] /task [description] /from [start time] /to [start time]" format - * Note: Start and End times should be formatted as such: HH:mm + * @throws InvalidFormatException If the input does not match the expected format. */ public static void validateAddTaskInput(String input) throws InvalidFormatException { // Define the regex pattern for the expected format with case-insensitive flag - String regex = "(?i)^addtask\\s+/on\\s+(\\w+)\\s+/task\\s+(.+?)\\s+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})$"; + String regex = "(?i)^addtask\\s+/on\\s+(\\w+)\\s+/task\\s+(.+?)\\s" + + "+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})$"; if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid addTask format. " + @@ -34,11 +38,12 @@ public static void validateAddTaskInput(String input) throws InvalidFormatExcept } /** - * Validates correctly formatted deleteTask command. + * Validates correctly formatted deleteTask command. The expected format is + * "deletetask /on [day] /index [index]" format + * Note: index is the index of the task in the task list for the given day * * @param input String Input. - * @throws InvalidFormatException if input does not match "deleteTask /on [day] /index [index]" format - * Note: index is the index of the task in the task list for the given day + * @throws InvalidFormatException If the input does not match the expected format. */ public static void validateDeleteTaskInput(String input) throws InvalidFormatException { // Define the regex pattern for the expected format with case-insensitive flag @@ -51,46 +56,48 @@ public static void validateDeleteTaskInput(String input) throws InvalidFormatExc } /** - * Validates correctly formatted addUser command. + * Validates correctly formatted addUser command. The expected format is "adduser user" * * @param input String Input. - * @throws InvalidFormatException if input does not match "addUser " format + * @throws InvalidFormatException If the input does not match the expected format. */ public static void validateAddUserInput(String input) throws InvalidFormatException { // Define the regex pattern for the expected format with case-insensitive flag String regex = "(?i)^adduser\\s+\\w+$"; if (!input.matches(regex)) { - throw new InvalidFormatException("[ERROR] Invalid addUser format. Expected format: addUser "); + throw new InvalidFormatException("[ERROR] Invalid addUser format. " + + "Expected format: addUser "); } } /** - * Validates correctly formatted switch command. + * Validates correctly formatted switch command. The expected format is "switch user" * * @param input String Input. - * @throws InvalidFormatException if input does not match "switch " format + * @throws InvalidFormatException If the input does not match the expected format. */ public static void validateSwitchInput(String input) throws InvalidFormatException { // Define the regex pattern for the expected format with case-insensitive flag String regex = "(?i)^switch\\s+\\w+$"; if (!input.matches(regex)) { - throw new InvalidFormatException("[ERROR] Invalid switch format. Expected format: switch "); + throw new InvalidFormatException("[ERROR] Invalid switch format. " + + "Expected format: switch "); } } /** - * Validates correctly spelled user names that currently exist in the user database. + * Validates correctly spelled usernames that currently exist in the user database. * * @param input String Input. - * @throws InvalidUserException if input does not match any current user's name in the user database. + * @throws InvalidUserException If the input does not match any current user's name in the user database. */ - public static void validateUserInput(String input) throws InvalidUserException { - if (UserList.GetUsers().isEmpty()) { + public static void validateUserInput(String input, UserList userList) throws InvalidUserException { + if (userList.getUsers().isEmpty()) { throw new InvalidUserException("[ERROR] Current User List is empty. Please add users."); } - for (User u : UserList.GetUsers()) { + for (User u : userList.getUsers()) { if (u.getName().toLowerCase().equals(input)) { return; } @@ -102,13 +109,13 @@ public static void validateUserInput(String input) throws InvalidUserException { * Validates if the inputted string is an actual day. * * @param input String Input. - * @throws InvalidDayException if the input is not an actual day. + * @throws InvalidDayException If the input is not an actual day. */ public static void validateDay(String input) throws InvalidDayException { String[] validDays = new String[]{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"}; for (String day : validDays) { - if (day.equals(input.toLowerCase())) { + if (day.equalsIgnoreCase(input)) { return; } } @@ -119,11 +126,11 @@ public static void validateDay(String input) throws InvalidDayException { * Validates whether a Timetable exist or not. * * @param table inputted Timetable. - * @throws NullPointerException if input Timetable does not exist. + * @throws NullPointerException If the input Timetable does not exist. */ public static void validateTableExistence(Timetable table) throws NullPointerException { if (table == null) { throw new NullPointerException("Timetable object is null."); } } -} \ No newline at end of file +} diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 630a3d16e1..cfae00ba6f 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -6,24 +6,25 @@ import java.util.List; public class Parser { - public Parser() {} /** * Parses User Input and Identifies the command used. * * @param command The users text input. */ - public void parseCommand(String command) { - if (command.toLowerCase().equals("list")) { + public void parseCommand(String command, UserList userList) { + if (command.equalsIgnoreCase("list")) { UI.printListingUsers(); - UserList.ListAll(); - } else if (command.toLowerCase().equals("bye")) { + userList.listAll(); + } else if (command.equalsIgnoreCase("help")) { + UI.printHelp(); + } else if (command.equalsIgnoreCase("bye")) { UI.printBye(); - Duke.setFinished(true); - } else if (command.toLowerCase().equals("current")) { - UI.printActiveUser(UserList.GetActiveUser().getName()); - } else if (command.toLowerCase().equals("view")) { - UserList.GetActiveUser().viewTimetable(); + Duke.setIsFinished(true); + } else if (command.equalsIgnoreCase("current")) { + UI.printActiveUser(userList.getActiveUser().getName()); + } else if (command.equalsIgnoreCase("view")) { + userList.getActiveUser().viewTimetable(); } else if (command.toLowerCase().startsWith("adduser")) { try { InputValidator.validateAddUserInput(command); @@ -31,7 +32,7 @@ public void parseCommand(String command) { String userName = parts[1]; User newUser = new User(userName); UI.printNewUser(newUser.getName()); - UserList.AddUser(newUser); + userList.addUser(newUser); } catch (InvalidFormatException e) { System.out.println(e.getMessage()); } @@ -40,8 +41,8 @@ public void parseCommand(String command) { InputValidator.validateSwitchInput(command); String[] parts = command.split("\\s+"); String userName = parts[1]; - UserList.SetActiveUser(UserList.FindUser(userName)); - UI.printActiveUser(UserList.GetActiveUser().getName()); + userList.setActiveUser(userList.findUser(userName)); + UI.printActiveUser(userList.getActiveUser().getName()); } catch (InvalidFormatException e) { System.out.println(e.getMessage()); } @@ -56,7 +57,8 @@ public void parseCommand(String command) { String endTime = parts[wordList.indexOf("/to") + 1]; InputValidator.validateDay(day); Task task = new Task(description, day, startTime, endTime); - UserList.GetActiveUser().getTimetable().addUserTask(day, task); + userList.getActiveUser().getTimetable().addUserTask(day, task); + UI.printAddTask(task); } catch (InvalidFormatException | InvalidDayException e) { System.out.println(e.getMessage()); } @@ -67,7 +69,7 @@ public void parseCommand(String command) { String day = parts[2]; int index = Integer.parseInt(parts[4]); InputValidator.validateDay(day); - UserList.GetActiveUser().getTimetable().deleteUserTask(day, index); + userList.getActiveUser().getTimetable().deleteUserTask(day, index); } catch (InvalidFormatException | InvalidDayException e) { System.out.println(e.getMessage()); } @@ -77,9 +79,10 @@ public void parseCommand(String command) { String[] parts = command.split("\\s+"); String user1 = parts[1]; String user2 = parts[2]; - InputValidator.validateUserInput(user1); - InputValidator.validateUserInput(user2); - Timetable.compareTimetable(UserList.FindUser(user1).getTimetable(), UserList.FindUser(user2).getTimetable()); + InputValidator.validateUserInput(user1, userList); + InputValidator.validateUserInput(user2, userList); + Timetable.compareTimetable(userList.findUser(user1).getTimetable(), + userList.findUser(user2).getTimetable()); } catch (InvalidFormatException | InvalidUserException | NullPointerException e) { System.out.println(e.getMessage()); diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index 0f1bb168e0..a79418e08b 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -1,4 +1,5 @@ package seedu.duke; + import java.time.LocalTime; public class Task { @@ -7,54 +8,33 @@ public class Task { protected LocalTime startTime; protected LocalTime endTime; - public String getDescription() { - return description; - } - - public void setDescription(String description) { + public Task(String description, String day, String from, String to) { this.description = description; - } - - public String getDay() { - return day; - } - - public void setDay(String day) { this.day = day; + String fromHour = from.split(":")[0]; + String fromMinute = from.split(":")[1]; + String toHour = to.split(":")[0]; + String toMinute = to.split(":")[1]; + String formattedFrom = formatDates(fromHour) + ":" + formatDates(fromMinute); + String formattedTo = formatDates(toHour) + ":" + formatDates(toMinute); + this.startTime = LocalTime.parse(formattedFrom); + this.endTime = LocalTime.parse(formattedTo); } public LocalTime getStartTime() { return startTime; } - public void setStartTime(LocalTime startTime) { - this.startTime = startTime; - } public LocalTime getEndTime() { return endTime; } - public void setEndTime(LocalTime endTime) { - this.endTime = endTime; - } - - public Task(String description, String day, String from, String to){ - this.description = description; - this.day = day; - String fromHour = from.split(":")[0]; - String fromMinute = from.split(":")[1]; - String toHour = to.split(":")[0]; - String toMinute = to.split(":")[1]; - String formattedFrom = formatDates(fromHour) + ":" + formatDates(fromMinute); - String formattedTo = formatDates(toHour) + ":" + formatDates(toMinute); - this.startTime = LocalTime.parse(formattedFrom); - this.endTime = LocalTime.parse(formattedTo); - } private String formatDates(String time) { return time.length() == 1 ? "0" + time : time; } + @Override public String toString() { return description + " (" + day + " from " + startTime + " to " + endTime + ")"; diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 949170fdf3..2d3d8ba685 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -1,4 +1,5 @@ package seedu.duke; + import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -10,13 +11,15 @@ * This class represents the Timetable object consisting of Arraylist of Tasks for each day of the week. */ public class Timetable { + + protected static final String[] DAYS = new String[] + {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; private Map> weeklyTasks; // Map to store tasks for each day - protected static final String[] days = new String[]{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; public Timetable() { weeklyTasks = new HashMap<>(); //Initialize the map with empty lists for each day - for (String day: days) { + for (String day : DAYS) { weeklyTasks.put(day, new ArrayList<>()); } } @@ -29,21 +32,20 @@ public Map> getWeeklyTasks() { * Adds task on dayOfWeek at an index * * @param dayOfWeek first Timetable. - * @param task task to add. + * @param task task to add. */ - public void addUserTask(String dayOfWeek, Task task){ + public void addUserTask(String dayOfWeek, Task task) { String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); weeklyTasks.get(capitalizedDay).add(task); - System.out.println("Added: " + task); } /** * Deletes task on dayOfWeek at an index * * @param dayOfWeek first Timetable. - * @param index index of task within task list + * @param index index of task within task list */ - public void deleteUserTask(String dayOfWeek, int index){ + public void deleteUserTask(String dayOfWeek, int index) { String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); //check if index is a valid number within a day's tasklist if (index >= 0 && index < weeklyTasks.get(capitalizedDay).size()) { @@ -52,8 +54,7 @@ public void deleteUserTask(String dayOfWeek, int index){ System.out.println("Task " + taskDeleted.description + " is deleted from " + dayOfWeek); System.out.println("New task list for " + capitalizedDay + ":"); printTasksOfTheDay(dayOfWeek); - } - else { + } else { System.out.println("Invalid task index. Please try again."); } } @@ -63,23 +64,24 @@ public void deleteUserTask(String dayOfWeek, int index){ * * @param table1 first Timetable. * @param table2 second Timetable - * - * Prints the overlapping free time for each day in the format: - * ---------------------- - * Shared Free Time on [day] - * HH:mm - HH:mm: Overlapping Free Time + *

+ * Prints the overlapping free time for each day in the format: + * ---------------------- + * Shared Free Time on [day] + * HH:mm - HH:mm: Overlapping Free Time */ - public static void compareTimetable(Timetable table1, Timetable table2){ + public static void compareTimetable(Timetable table1, Timetable table2) { try { InputValidator.validateTableExistence(table1); InputValidator.validateTableExistence(table2); - for (String day : Timetable.days) { + for (String day : Timetable.DAYS) { System.out.println("----------------------\n" + "Shared Free Time on " + day + ":"); // Merge tasks from both timetables and sort them by start time - ArrayList mergedTasks = mergeAndSortTasks(table1.getWeeklyTasks().get(day), table2.getWeeklyTasks().get(day)); + ArrayList mergedTasks = mergeAndSortTasks(table1.getWeeklyTasks().get(day), + table2.getWeeklyTasks().get(day)); // Calculate overlapping free time intervals then print them - FindOverlappingFreeTime(mergedTasks, day); + findOverlappingFreeTime(mergedTasks, day); } } catch (NullPointerException e) { System.out.println(e.getMessage()); @@ -93,7 +95,7 @@ private static ArrayList mergeAndSortTasks(ArrayList taskList1, Arra return mergedTasks; } - private static void FindOverlappingFreeTime(ArrayList tasks, String day) { + private static void findOverlappingFreeTime(ArrayList tasks, String day) { if (!tasks.isEmpty()) { LocalTime previousEndTime = LocalTime.MIN; for (Task task : tasks) { @@ -104,7 +106,8 @@ private static void FindOverlappingFreeTime(ArrayList tasks, String day) { } if (previousEndTime.isBefore(LocalTime.MAX)) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm"); - System.out.println(previousEndTime + " - " + LocalTime.MAX.format(formatter) + ": Overlapping Free Time"); + System.out.println(previousEndTime + " - " + LocalTime.MAX.format(formatter) + + ": Overlapping Free Time"); } } else { System.out.println("** Whole day is free on " + day); diff --git a/src/main/java/seedu/duke/User.java b/src/main/java/seedu/duke/User.java index 372d66ec5d..3a7c5a5579 100644 --- a/src/main/java/seedu/duke/User.java +++ b/src/main/java/seedu/duke/User.java @@ -1,4 +1,5 @@ package seedu.duke; + public class User { private Timetable timetable; private final String name; @@ -7,14 +8,17 @@ public User(String name) { this.name = name; this.timetable = new Timetable(); } + public String getName() { return name; } + public void viewTimetable() { - for (String day : Timetable.days) { + for (String day : Timetable.DAYS) { timetable.printTasksOfTheDay(day); } } + public Timetable getTimetable() { return timetable; } diff --git a/src/main/java/seedu/duke/UserList.java b/src/main/java/seedu/duke/UserList.java index 6a24b8a64a..d595b3c951 100644 --- a/src/main/java/seedu/duke/UserList.java +++ b/src/main/java/seedu/duke/UserList.java @@ -5,45 +5,50 @@ import java.util.ArrayList; public class UserList { - private static ArrayList allUsers; - private static User activeUser; + private ArrayList allUsers; + private User activeUser; public UserList() { allUsers = new ArrayList<>(); } - public static User GetActiveUser() { + public User getActiveUser() { return activeUser; } - public static void SetActiveUser(User user) { + public void setActiveUser(User user) { if (user != null) { - UserList.activeUser = user; + activeUser = user; } else { System.out.println("User does not exist!"); } } - public static void AddUser(User user) { + public void addUser(User user) { allUsers.add(user); if (allUsers.size() == 1) { - UserList.activeUser = allUsers.get(0); //If this was the first user added, set them as the current user + activeUser = allUsers.get(0); //If this was the first user added, set them as the current user UI.printActiveUser(user.getName()); } } - public static void ListAll() { + public void listAll() { for (User user : allUsers) { System.out.println(user.getName()); } } - public static ArrayList GetUsers() { + + public ArrayList getUsers() { return allUsers; } - public static User FindUser(String name) { + public int getListLength() { + return allUsers.size(); + } + + public User findUser(String name) { for (User u : allUsers) { - if (name.toLowerCase().equals(u.getName().toLowerCase())) { + if (name.equalsIgnoreCase(u.getName())) { return u; } } diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index eedeacae16..74e79e4ab4 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -1,27 +1,45 @@ package seedu.duke.ui; +import seedu.duke.Task; + public class UI { public static void printGreeting() { System.out.println("Timetable comparison app opened. "); } + public static void printBye() { System.out.println("Bye. "); } + public static void printListingUsers() { System.out.println("The current users are: "); } + public static void printNewUser(String name) { System.out.println("New user added: " + name); } + public static void printActiveUser(String description) { System.out.println("The active user is: " + description); } + public static void printInvalidCommand() { System.out.println("Invalid command. "); } - public static void printAddTask(String description) { - System.out.println("The following task is added: "); - System.out.println(description); + public static void printAddTask(Task task) { + System.out.println("The following task is added: " + task); + } + + public static void printHelp() { + System.out.println("List of available commands: \n" + + "adduser: add new user \n" + + "switch : switch to user \n" + + "list: list all users \n" + + "bye: exit the app \n" + + "current: view current user \n" + + "addtask /on /from /to : add task \n" + + "delete: delete task \n" + + "compare : compare timetables "); } } diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index 6035d9dd22..5ed45507ea 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -34,11 +34,11 @@ public void testInvalidCommand() { public void testAddUser() { UserList userList = new UserList(); User user = new User("Test User"); - userList.AddUser(user); + userList.addUser(user); // Verify that the user is added to the list assertEquals(1, userList.getListLength()); - assertEquals(user, userList.GetActiveUser()); - assertTrue(userList.GetUsers().contains(user)); + assertEquals(user, userList.getActiveUser()); + assertTrue(userList.getUsers().contains(user)); } } diff --git a/src/test/java/seedu/duke/TimetableTest.java b/src/test/java/seedu/duke/TimetableTest.java index 69f89f9f73..1dd96a3ffe 100644 --- a/src/test/java/seedu/duke/TimetableTest.java +++ b/src/test/java/seedu/duke/TimetableTest.java @@ -3,8 +3,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import java.sql.Time; - class TimetableTest { @Test public void testAddUserTask() { diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index fd31a3aa5b..a04860ca1d 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,2 +1,49 @@ Timetable comparison app opened. +New user added: simon +The active user is: simon +The current users are: +simon +The following task is added: lecture (Monday from 09:00 to 11:00) +Monday: +lecture (Monday from 09:00 to 11:00) +NO TASK FOR Tuesday +NO TASK FOR Wednesday +NO TASK FOR Thursday +NO TASK FOR Friday +NO TASK FOR Saturday +NO TASK FOR Sunday +New user added: tim +The active user is: tim +[ERROR] Invalid day. Please enter a day from Monday - Sunday. +The following task is added: lecture (Monday from 09:00 to 11:00) +Monday: +lecture (Monday from 09:00 to 11:00) +NO TASK FOR Tuesday +NO TASK FOR Wednesday +NO TASK FOR Thursday +NO TASK FOR Friday +NO TASK FOR Saturday +NO TASK FOR Sunday +---------------------- +Shared Free Time on Monday: +00:00 - 09:00: Overlapping Free Time +11:00 - 23:59: Overlapping Free Time +---------------------- +Shared Free Time on Tuesday: +** Whole day is free on Tuesday +---------------------- +Shared Free Time on Wednesday: +** Whole day is free on Wednesday +---------------------- +Shared Free Time on Thursday: +** Whole day is free on Thursday +---------------------- +Shared Free Time on Friday: +** Whole day is free on Friday +---------------------- +Shared Free Time on Saturday: +** Whole day is free on Saturday +---------------------- +Shared Free Time on Sunday: +** Whole day is free on Sunday Bye. diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index 0abaeaa993..c0e9ab049a 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1 +1,11 @@ -bye \ No newline at end of file +adduser simon +list +addtask /on Monday /task lecture /from 9:00 /to 11:00 +view +adduser tim +switch tim +addtask /on Eightday /task lecture /from 9:00 /to 11:00 +addtask /on Monday /task lecture /from 9:00 /to 11:00 +view +compare simon tim +bye From 90bde4e8b3229166efbeeb5a8f3f6f39e44fccdd Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Wed, 20 Mar 2024 22:02:34 +0800 Subject: [PATCH 035/162] add test addTask --- src/test/java/seedu/duke/DukeTest.java | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index 5ed45507ea..bd692f8f40 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -8,27 +8,23 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.PrintStream; +import java.time.LocalTime; class DukeTest { @Test public void sampleTest() { assertTrue(true); } - @Test - public void testInvalidCommand() { - // Arrange - ByteArrayInputStream in = new ByteArrayInputStream("invalid\r\nbye\r\n".getBytes()); - System.setIn(in); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - System.setOut(new PrintStream(out)); - String expectedOutput = "Timetable comparison app opened. \r\nInvalid command. \r\nBye. \r\n"; - - // Act - Duke.main(new String[0]); - // Assert - assertEquals(expectedOutput, out.toString()); + @Test + public void testAddTask() { + UserList userlist = new UserList(); + User user = new User("Test User"); + userlist.addUser(user); + Task task = new Task("Lecture", "Monday", "1:00", "2:00"); + user.getTimetable().addUserTask("Monday", task); + assertEquals("Lecture", task.description); + assertEquals(LocalTime.parse("01:00"), task.startTime); } @Test public void testAddUser() { From e239cb19ff47b3fda54fe85a14e9475b79433251 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Wed, 20 Mar 2024 22:09:37 +0800 Subject: [PATCH 036/162] Clean up code --- src/test/java/seedu/duke/DukeTest.java | 4 ---- src/test/java/seedu/duke/TimetableTest.java | 18 ------------------ 2 files changed, 22 deletions(-) diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index bd692f8f40..bf5f60c475 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -4,10 +4,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; import java.time.LocalTime; class DukeTest { diff --git a/src/test/java/seedu/duke/TimetableTest.java b/src/test/java/seedu/duke/TimetableTest.java index 1dd96a3ffe..c97479dcd0 100644 --- a/src/test/java/seedu/duke/TimetableTest.java +++ b/src/test/java/seedu/duke/TimetableTest.java @@ -26,22 +26,4 @@ public void testCompareTimetables() { Timetable.compareTimetable(timetable1, timetable2); } - @Test - public void testDeleteUserTask() { - Timetable timetable = new Timetable(); - Task task1 = new Task("Study", "2024-03-18", "09:00", "11:00"); - Task task2 = new Task("Exercise", "2024-03-18", "15:00", "16:30"); - - // Add tasks to the timetable - timetable.addUserTask("tuesday", task1); - timetable.addUserTask("tuesday", task2); - - // Delete the first task - timetable.deleteUserTask("tuesday", 0); - - // Check if the task is deleted - assertEquals(1, timetable.getWeeklyTasks().get("tuesday").size()); - assertEquals(task2, timetable.getWeeklyTasks().get("tuesday").get(0)); - - } } From c5b811af59cd276ad85da004a142e7f632ebbb57 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Wed, 20 Mar 2024 23:33:20 +0800 Subject: [PATCH 037/162] Jar --- META-INF/MANIFEST.MF | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 META-INF/MANIFEST.MF diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..19e86fe56e --- /dev/null +++ b/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: seedu.duke.Duke + From 95f656664ee38e0ab330cf23d6430eb3206ba809 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Wed, 20 Mar 2024 23:38:23 +0800 Subject: [PATCH 038/162] edit for jar --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d3cf87934b..6582893042 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Prerequisites: JDK 11 (use the exact version), update Intellij to the most recen | _ \ _ _| | _____ | | | | | | | |/ / _ \ | |_| | |_| | < __/ - |____/ \__,_|_|\_\___| + |____/ \__,_|_|\_\___ What is your name? ``` From 3623593fb71b861b127d693064f79be9d620289a Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Thu, 21 Mar 2024 15:25:23 +0800 Subject: [PATCH 039/162] Add some java doc and add index of tasks when displaying timetable --- src/main/java/seedu/duke/Task.java | 9 +++++++ src/main/java/seedu/duke/Timetable.java | 31 +++++++++++++++---------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index 0f1bb168e0..e0d3a85b40 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -39,6 +39,15 @@ public void setEndTime(LocalTime endTime) { this.endTime = endTime; } + /** + * Represents the constructor for Task class that takes in parameters inluding the description of the task, + * the day of the task, the starting time and the ending time of the task. + * + * @param description description of the task. + * @param day day of the task. + * @param from starting time of the task. + * @param to ending time of the task. + */ public Task(String description, String day, String from, String to){ this.description = description; this.day = day; diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 949170fdf3..ac108b3d15 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -10,7 +10,7 @@ * This class represents the Timetable object consisting of Arraylist of Tasks for each day of the week. */ public class Timetable { - private Map> weeklyTasks; // Map to store tasks for each day + private final Map> weeklyTasks; // Map to store tasks for each day protected static final String[] days = new String[]{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; public Timetable() { @@ -25,6 +25,23 @@ public Map> getWeeklyTasks() { return weeklyTasks; } + /** + * Prints tasks of the day specified. + * @param day day of the week the task is on. + */ + public void printTasksOfTheDay(String day) { + String capitalizedDay = day.substring(0, 1).toUpperCase() + day.substring(1); + if (weeklyTasks.get(capitalizedDay).isEmpty()) { + System.out.println("NO TASK FOR " + day); + return; + } + System.out.println(capitalizedDay + ":"); + int count = 1; + for (Task task : weeklyTasks.get(capitalizedDay)) { + System.out.println(count + ". " + task.toString()); + count++; + } + } /** * Adds task on dayOfWeek at an index * @@ -111,15 +128,5 @@ private static void FindOverlappingFreeTime(ArrayList tasks, String day) { } } - public void printTasksOfTheDay(String day) { - String capitalizedDay = day.substring(0, 1).toUpperCase() + day.substring(1); - if (weeklyTasks.get(capitalizedDay).isEmpty()) { - System.out.println("NO TASK FOR " + day); - return; - } - System.out.println(capitalizedDay + ":"); - for (Task task : weeklyTasks.get(capitalizedDay)) { - System.out.println(task.toString()); - } - } + } From 266719dedd67f49d94067071ce415da044f81471 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Thu, 21 Mar 2024 20:29:35 +0800 Subject: [PATCH 040/162] Add flexibility to the task --- src/main/java/seedu/duke/Duke.java | 2 ++ src/main/java/seedu/duke/InputValidator.java | 4 ++-- src/main/java/seedu/duke/Parser.java | 6 +++++- src/main/java/seedu/duke/Task.java | 7 ++++--- src/main/java/seedu/duke/Timetable.java | 2 ++ src/test/java/seedu/duke/DukeTest.java | 2 +- src/test/java/seedu/duke/TimetableTest.java | 6 +++--- 7 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 811b4a97a9..0a58115a86 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -27,5 +27,7 @@ public static void main(String[] args) { } } + //assert false: "dummy assertion set to fail"; } + } diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 49bc488ba3..6cc513b6bc 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -29,11 +29,11 @@ public static void validateCompareInput(String input) throws InvalidFormatExcept public static void validateAddTaskInput(String input) throws InvalidFormatException { // Define the regex pattern for the expected format with case-insensitive flag String regex = "(?i)^addtask\\s+/on\\s+(\\w+)\\s+/task\\s+(.+?)\\s" + - "+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})$"; + "+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})(\\s+/flexibility\\s+[fc])$"; if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid addTask format. " + - "Expected format: addTask /on [day] /task [description] /from [start time] /to [start time]"); + "Expected format: addTask /on [day] /task [description] /from [start time] /to [end time] /flexibility [f/c]"); } } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index cfae00ba6f..f102864cd1 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -55,8 +55,12 @@ public void parseCommand(String command, UserList userList) { String description = parseDescription(wordList); String startTime = parts[wordList.indexOf("/from") + 1]; String endTime = parts[wordList.indexOf("/to") + 1]; + String flexibility = ""; + if(wordList.contains("/flexibility")){ + flexibility = parts[wordList.indexOf("flexibility") + 1]; + } InputValidator.validateDay(day); - Task task = new Task(description, day, startTime, endTime); + Task task = new Task(description, day, startTime, endTime, flexibility); userList.getActiveUser().getTimetable().addUserTask(day, task); UI.printAddTask(task); } catch (InvalidFormatException | InvalidDayException e) { diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index a79418e08b..f45ce26d60 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -7,8 +7,9 @@ public class Task { protected String day; protected LocalTime startTime; protected LocalTime endTime; + protected String flexibility; - public Task(String description, String day, String from, String to) { + public Task(String description, String day, String from, String to, String flexibility) { this.description = description; this.day = day; String fromHour = from.split(":")[0]; @@ -19,8 +20,8 @@ public Task(String description, String day, String from, String to) { String formattedTo = formatDates(toHour) + ":" + formatDates(toMinute); this.startTime = LocalTime.parse(formattedFrom); this.endTime = LocalTime.parse(formattedTo); + this.flexibility = flexibility; } - public LocalTime getStartTime() { return startTime; } @@ -37,6 +38,6 @@ private String formatDates(String time) { @Override public String toString() { - return description + " (" + day + " from " + startTime + " to " + endTime + ")"; + return description + " (" + day + " from " + startTime + " to " + endTime + ")" + "flexibility: " + flexibility; } } diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 2d3d8ba685..76a6b272b2 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -59,6 +59,8 @@ public void deleteUserTask(String dayOfWeek, int index) { } } + + /** * Compares and prints overlapping free time between two Timetables. * diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index bf5f60c475..14f6b8864e 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -17,7 +17,7 @@ public void testAddTask() { UserList userlist = new UserList(); User user = new User("Test User"); userlist.addUser(user); - Task task = new Task("Lecture", "Monday", "1:00", "2:00"); + Task task = new Task("Lecture", "Monday", "1:00", "2:00", "f"); user.getTimetable().addUserTask("Monday", task); assertEquals("Lecture", task.description); assertEquals(LocalTime.parse("01:00"), task.startTime); diff --git a/src/test/java/seedu/duke/TimetableTest.java b/src/test/java/seedu/duke/TimetableTest.java index c97479dcd0..7ba6b6f0f5 100644 --- a/src/test/java/seedu/duke/TimetableTest.java +++ b/src/test/java/seedu/duke/TimetableTest.java @@ -7,7 +7,7 @@ class TimetableTest { @Test public void testAddUserTask() { Timetable timetable = new Timetable(); - Task task = new Task("Study","2024-03-18", "09:00", "11:00"); + Task task = new Task("Study","2024-03-18", "09:00", "11:00","f"); timetable.addUserTask("Tuesday", task); @@ -19,8 +19,8 @@ public void testAddUserTask() { public void testCompareTimetables() { Timetable timetable1 = new Timetable(); Timetable timetable2 = new Timetable(); - Task task1 = new Task("Study","2024-03-18", "09:00", "11:00"); - Task task2 = new Task("Study","2024-03-18", "07:00", "10:00"); + Task task1 = new Task("Study","2024-03-18", "09:00", "11:00","f"); + Task task2 = new Task("Study","2024-03-18", "07:00", "10:00","f"); timetable1.addUserTask("Monday", task1); timetable2.addUserTask("Monday", task2); From 7b86a6674f43af82ea71a627b72df315bc039e30 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Thu, 21 Mar 2024 20:40:08 +0800 Subject: [PATCH 041/162] Solve line too long problem --- src/main/java/seedu/duke/InputValidator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 6cc513b6bc..0d1b40c76e 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -33,7 +33,8 @@ public static void validateAddTaskInput(String input) throws InvalidFormatExcept if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid addTask format. " + - "Expected format: addTask /on [day] /task [description] /from [start time] /to [end time] /flexibility [f/c]"); + "Expected format: addTask /on [day] /task [description] /from [start time] /to [end time] " + + "/flexibility [f/c]"); } } From 798aa3470b2c10db4c2264bea438d38dd486e182 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Thu, 21 Mar 2024 21:01:49 +0800 Subject: [PATCH 042/162] change timetable add task method according to changed parameter in task class --- src/main/java/seedu/duke/InputValidator.java | 4 ++-- src/main/java/seedu/duke/Parser.java | 7 ++----- src/main/java/seedu/duke/Task.java | 11 +++++++---- src/main/java/seedu/duke/Timetable.java | 15 ++++++++++++--- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 0d1b40c76e..3ca9cc901f 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -29,12 +29,12 @@ public static void validateCompareInput(String input) throws InvalidFormatExcept public static void validateAddTaskInput(String input) throws InvalidFormatException { // Define the regex pattern for the expected format with case-insensitive flag String regex = "(?i)^addtask\\s+/on\\s+(\\w+)\\s+/task\\s+(.+?)\\s" + - "+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})(\\s+/flexibility\\s+[fc])$"; + "+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})(\\s+/type\\s+[fc])$"; if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid addTask format. " + "Expected format: addTask /on [day] /task [description] /from [start time] /to [end time] " + - "/flexibility [f/c]"); + "/type [f/c]"); } } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index f102864cd1..3ac2531cb4 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -55,12 +55,9 @@ public void parseCommand(String command, UserList userList) { String description = parseDescription(wordList); String startTime = parts[wordList.indexOf("/from") + 1]; String endTime = parts[wordList.indexOf("/to") + 1]; - String flexibility = ""; - if(wordList.contains("/flexibility")){ - flexibility = parts[wordList.indexOf("flexibility") + 1]; - } + String type = parts[wordList.indexOf("/type") + 1]; InputValidator.validateDay(day); - Task task = new Task(description, day, startTime, endTime, flexibility); + Task task = new Task(description, day, startTime, endTime, type); userList.getActiveUser().getTimetable().addUserTask(day, task); UI.printAddTask(task); } catch (InvalidFormatException | InvalidDayException e) { diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index f45ce26d60..466ce97670 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -7,9 +7,9 @@ public class Task { protected String day; protected LocalTime startTime; protected LocalTime endTime; - protected String flexibility; + protected String type; - public Task(String description, String day, String from, String to, String flexibility) { + public Task(String description, String day, String from, String to, String type) { this.description = description; this.day = day; String fromHour = from.split(":")[0]; @@ -20,7 +20,7 @@ public Task(String description, String day, String from, String to, String flexi String formattedTo = formatDates(toHour) + ":" + formatDates(toMinute); this.startTime = LocalTime.parse(formattedFrom); this.endTime = LocalTime.parse(formattedTo); - this.flexibility = flexibility; + this.type = type; } public LocalTime getStartTime() { return startTime; @@ -30,6 +30,9 @@ public LocalTime getStartTime() { public LocalTime getEndTime() { return endTime; } + public String getType(){ + return type; + } private String formatDates(String time) { @@ -38,6 +41,6 @@ private String formatDates(String time) { @Override public String toString() { - return description + " (" + day + " from " + startTime + " to " + endTime + ")" + "flexibility: " + flexibility; + return description + " (" + day + " from " + startTime + " to " + endTime + ")" + "flexibility: " + type; } } diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 76a6b272b2..808fd507c0 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -101,10 +101,19 @@ private static void findOverlappingFreeTime(ArrayList tasks, String day) { if (!tasks.isEmpty()) { LocalTime previousEndTime = LocalTime.MIN; for (Task task : tasks) { - if (task.getStartTime().isAfter(previousEndTime)) { - System.out.println(previousEndTime + " - " + task.getStartTime() + ": Overlapping Free Time"); + if (task.getType().equalsIgnoreCase("C")) { + if (task.getStartTime().isAfter(previousEndTime)) { + System.out.println(previousEndTime + " - " + task.getStartTime() + ": Compulsory Task"); + } + System.out.println(task.getStartTime() + " - " + task.getEndTime() + ": Compulsory Task"); + previousEndTime = task.getEndTime(); + } else { // Flexible Task + if (task.getStartTime().isAfter(previousEndTime)) { + System.out.println(previousEndTime + " - " + task.getStartTime() + ": Flexible Task"); + } + System.out.println(task.getStartTime() + " - " + task.getEndTime() + ": Flexible Task"); + previousEndTime = task.getEndTime(); } - previousEndTime = task.getEndTime(); } if (previousEndTime.isBefore(LocalTime.MAX)) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm"); From f2ce7cf3a09f5781ffe2737e186d8ff386cd81e8 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Thu, 21 Mar 2024 22:59:22 +0800 Subject: [PATCH 043/162] Add method to change timing of flexible task --- src/main/java/seedu/duke/InputValidator.java | 14 ++++ src/main/java/seedu/duke/Parser.java | 82 +++++++++++++------- src/main/java/seedu/duke/Task.java | 3 + src/main/java/seedu/duke/Timetable.java | 29 +++---- 4 files changed, 88 insertions(+), 40 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 3ca9cc901f..c44a4aa25c 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -134,4 +134,18 @@ public static void validateTableExistence(Timetable table) throws NullPointerExc throw new NullPointerException("Timetable object is null."); } } + + public static void validateChangeTaskTiming(String input) throws InvalidFormatException{ + String prefix = "(?i)^changeTaskTiming\\s+/on\\s+"; + String dayPattern = "(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)"; + String indexPattern = "\\d+"; + String startPattern = "\\d{1,2}:\\d{2}"; + String endPattern = "\\d{1,2}:\\d{2}"; + String suffix = "$"; + String regex = prefix + dayPattern + "\\s+/index\\s+" + indexPattern + "\\s+/start\\s+" + startPattern + "\\s+/end\\s+" + endPattern + suffix; + if (!input.matches(regex)) { + throw new InvalidFormatException("[ERROR] Invalid changeTaskTiming format. " + + "Expected format: changeTaskTiming /on [day] /index [index] /start [new start time] /end [new end time]"); + } + } } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 3ac2531cb4..5bf1ae2238 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -2,6 +2,7 @@ import seedu.duke.ui.UI; +import java.time.LocalTime; import java.util.Arrays; import java.util.List; @@ -12,7 +13,7 @@ public class Parser { * * @param command The users text input. */ - public void parseCommand(String command, UserList userList) { + public void parseCommand(String command, UserList userList) throws InvalidFormatException { if (command.equalsIgnoreCase("list")) { UI.printListingUsers(); userList.listAll(); @@ -47,33 +48,11 @@ public void parseCommand(String command, UserList userList) { System.out.println(e.getMessage()); } } else if (command.toLowerCase().startsWith("addtask")) { - try { - InputValidator.validateAddTaskInput(command); - String[] parts = command.split("\\s+"); - List wordList = Arrays.asList(parts); - String day = parts[2]; - String description = parseDescription(wordList); - String startTime = parts[wordList.indexOf("/from") + 1]; - String endTime = parts[wordList.indexOf("/to") + 1]; - String type = parts[wordList.indexOf("/type") + 1]; - InputValidator.validateDay(day); - Task task = new Task(description, day, startTime, endTime, type); - userList.getActiveUser().getTimetable().addUserTask(day, task); - UI.printAddTask(task); - } catch (InvalidFormatException | InvalidDayException e) { - System.out.println(e.getMessage()); - } + addTask(command, userList); } else if (command.toLowerCase().startsWith("deletetask")) { - try { - InputValidator.validateDeleteTaskInput(command); - String[] parts = command.split("\\s+"); - String day = parts[2]; - int index = Integer.parseInt(parts[4]); - InputValidator.validateDay(day); - userList.getActiveUser().getTimetable().deleteUserTask(day, index); - } catch (InvalidFormatException | InvalidDayException e) { - System.out.println(e.getMessage()); - } + deleteTask(command, userList); + } else if(command.toLowerCase().startsWith("changetasktiming")){ + changeTaskTiming(command, userList); } else if (command.toLowerCase().startsWith("compare")) { try { InputValidator.validateCompareInput(command); @@ -93,6 +72,55 @@ public void parseCommand(String command, UserList userList) { } } + private static void deleteTask(String command, UserList userList) { + try { + InputValidator.validateDeleteTaskInput(command); + String[] parts = command.split("\\s+"); + String day = parts[2]; + int index = Integer.parseInt(parts[4]); + InputValidator.validateDay(day); + userList.getActiveUser().getTimetable().deleteUserTask(day, index); + } catch (InvalidFormatException | InvalidDayException e) { + System.out.println(e.getMessage()); + } + } + + private void addTask(String command, UserList userList) { + try { + InputValidator.validateAddTaskInput(command); + String[] parts = command.split("\\s+"); + List wordList = Arrays.asList(parts); + String day = parts[2]; + String description = parseDescription(wordList); + String startTime = parts[wordList.indexOf("/from") + 1]; + String endTime = parts[wordList.indexOf("/to") + 1]; + String type = parts[wordList.indexOf("/type") + 1]; + InputValidator.validateDay(day); + Task task = new Task(description, day, startTime, endTime, type); + userList.getActiveUser().getTimetable().addUserTask(day, task); + UI.printAddTask(task); + } catch (InvalidFormatException | InvalidDayException e) { + System.out.println(e.getMessage()); + } + } + + private static void changeTaskTiming(String command, UserList userList) throws InvalidFormatException { + try { + InputValidator.validateChangeTaskTiming(command); + String[] parts = command.split("\\s+"); + List wordList = Arrays.asList(parts); + String day = parts[2]; + int index = Integer.parseInt(parts[wordList.indexOf("/index") + 1]); + LocalTime newStartTime = LocalTime.parse(parts[wordList.indexOf("/start") + 1]); + LocalTime newEndTime = LocalTime.parse(parts[wordList.indexOf("/end") + 1]); + InputValidator.validateDay(day); + userList.getActiveUser().getTimetable().changeFlexibleTaskTiming(day, index - 1, newStartTime, newEndTime); + System.out.println("Flexible task timing changed successfully."); + } catch (InvalidDayException e) { + throw new RuntimeException(e); + } + } + private String parseDescription(List words) { int startIndex = words.indexOf("/task") + 1; int endIndex = words.indexOf("/from") - 1; diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index 3b64f56c2c..648a7cfb61 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -37,6 +37,9 @@ public String getType(){ public void setEndTime(LocalTime endTime) { this.endTime = endTime; } + public void setStartTime(LocalTime startTime){ + this.startTime = startTime; + } /** * Represents the constructor for Task class that takes in parameters inluding the description of the task, diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 16e2fe1d93..f2308b5f81 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -75,7 +75,19 @@ public void deleteUserTask(String dayOfWeek, int index) { } } - + public void changeFlexibleTaskTiming(String dayOfWeek, int index, LocalTime newStartTime, LocalTime newEndTime){ + String capitalizedDay = dayOfWeek.substring(0,1).toUpperCase() + dayOfWeek.substring(1); + ArrayList tasks = weeklyTasks.get(capitalizedDay); + if(index < 0 || index >= tasks.size()){ + throw new IndexOutOfBoundsException("Invalid index"); + } + Task task = tasks.get(index); + if(!task.getType().equals("f")){ + throw new IllegalArgumentException("Task on " +dayOfWeek +"at index " + index +" is not flexible."); + } + task.setStartTime(newStartTime); + task.setEndTime(newEndTime); + } /** * Compares and prints overlapping free time between two Timetables. @@ -117,19 +129,10 @@ private static void findOverlappingFreeTime(ArrayList tasks, String day) { if (!tasks.isEmpty()) { LocalTime previousEndTime = LocalTime.MIN; for (Task task : tasks) { - if (task.getType().equalsIgnoreCase("C")) { - if (task.getStartTime().isAfter(previousEndTime)) { - System.out.println(previousEndTime + " - " + task.getStartTime() + ": Compulsory Task"); - } - System.out.println(task.getStartTime() + " - " + task.getEndTime() + ": Compulsory Task"); - previousEndTime = task.getEndTime(); - } else { // Flexible Task - if (task.getStartTime().isAfter(previousEndTime)) { - System.out.println(previousEndTime + " - " + task.getStartTime() + ": Flexible Task"); - } - System.out.println(task.getStartTime() + " - " + task.getEndTime() + ": Flexible Task"); - previousEndTime = task.getEndTime(); + if (task.getStartTime().isAfter(previousEndTime)) { + System.out.println(previousEndTime + " - " + task.getStartTime() + ": Overlapping Free Time"); } + previousEndTime = task.getEndTime(); } if (previousEndTime.isBefore(LocalTime.MAX)) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm"); From b68068127c4e9df16d916975bf99143ad7e24b31 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Fri, 22 Mar 2024 00:47:55 +0800 Subject: [PATCH 044/162] Add method of change type of tasks --- src/main/java/seedu/duke/InputValidator.java | 17 +++++++++++++++-- src/main/java/seedu/duke/Parser.java | 18 ++++++++++++++++-- src/main/java/seedu/duke/Task.java | 5 ++++- src/main/java/seedu/duke/Timetable.java | 13 +++++++++++-- 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index c44a4aa25c..0ddba938f4 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -142,10 +142,23 @@ public static void validateChangeTaskTiming(String input) throws InvalidFormatEx String startPattern = "\\d{1,2}:\\d{2}"; String endPattern = "\\d{1,2}:\\d{2}"; String suffix = "$"; - String regex = prefix + dayPattern + "\\s+/index\\s+" + indexPattern + "\\s+/start\\s+" + startPattern + "\\s+/end\\s+" + endPattern + suffix; + String regex = prefix + dayPattern + "\\s+/index\\s+" + indexPattern + "\\s+/from\\s+" + startPattern + "\\s+/to\\s+" + endPattern + suffix; if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid changeTaskTiming format. " + - "Expected format: changeTaskTiming /on [day] /index [index] /start [new start time] /end [new end time]"); + "Expected format: changeTaskTiming /on [day] /index [index] /from [new start time] /to [new end time]"); } } + public static void validateChangeTaskType(String input) throws InvalidFormatException { + String prefix = "(?i)^changeTaskType\\s+/on\\s+"; + String dayPattern = "(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)"; + String indexPattern = "\\d+"; + String typePattern = "[fc]"; // Assuming task types can be 'f' for flexible and 'c' for compulsory + String suffix = "$"; + String regex = prefix + dayPattern + "\\s+/index\\s+" + indexPattern + "\\s+/type\\s+" + typePattern + suffix; + if (!input.matches(regex)) { + throw new InvalidFormatException("[ERROR] Invalid changeTaskType format. " + + "Expected format: changeTaskType /on [day] /index [index] /type [f/c]"); + } + } + } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 5bf1ae2238..e499737382 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -53,6 +53,20 @@ public void parseCommand(String command, UserList userList) throws InvalidFormat deleteTask(command, userList); } else if(command.toLowerCase().startsWith("changetasktiming")){ changeTaskTiming(command, userList); + } else if(command.toLowerCase().startsWith("changetasktype")){ + try { + InputValidator.validateChangeTaskType(command); + String[] parts = command.split("\\s+"); + List wordList = Arrays.asList(parts); + String day = wordList.get(2); + int index = Integer.parseInt(wordList.get(wordList.indexOf("/index") + 1)); + String newType = wordList.get(wordList.indexOf("/type") + 1); + InputValidator.validateDay(day); + userList.getActiveUser().getTimetable().changeTaskType(day, index - 1, newType); + System.out.println("Task type changed successfully."); + } catch (InvalidDayException | IndexOutOfBoundsException | NumberFormatException e) { + throw new RuntimeException(e); + } } else if (command.toLowerCase().startsWith("compare")) { try { InputValidator.validateCompareInput(command); @@ -111,8 +125,8 @@ private static void changeTaskTiming(String command, UserList userList) throws I List wordList = Arrays.asList(parts); String day = parts[2]; int index = Integer.parseInt(parts[wordList.indexOf("/index") + 1]); - LocalTime newStartTime = LocalTime.parse(parts[wordList.indexOf("/start") + 1]); - LocalTime newEndTime = LocalTime.parse(parts[wordList.indexOf("/end") + 1]); + LocalTime newStartTime = LocalTime.parse(parts[wordList.indexOf("/from") + 1]); + LocalTime newEndTime = LocalTime.parse(parts[wordList.indexOf("/to") + 1]); InputValidator.validateDay(day); userList.getActiveUser().getTimetable().changeFlexibleTaskTiming(day, index - 1, newStartTime, newEndTime); System.out.println("Flexible task timing changed successfully."); diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index 648a7cfb61..03ffd1b096 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -41,6 +41,9 @@ public void setStartTime(LocalTime startTime){ this.startTime = startTime; } + public void setType(String type){ + this.type = type; + } /** * Represents the constructor for Task class that takes in parameters inluding the description of the task, * the day of the task, the starting time and the ending time of the task. @@ -69,6 +72,6 @@ private String formatDates(String time) { @Override public String toString() { - return description + " (" + day + " from " + startTime + " to " + endTime + ")" + "flexibility: " + type; + return description + " (" + day + " from " + startTime + " to " + endTime + ")" + "type: " + type; } } diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index f2308b5f81..7ecb599ba2 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -83,12 +83,20 @@ public void changeFlexibleTaskTiming(String dayOfWeek, int index, LocalTime newS } Task task = tasks.get(index); if(!task.getType().equals("f")){ - throw new IllegalArgumentException("Task on " +dayOfWeek +"at index " + index +" is not flexible."); + throw new IllegalArgumentException("Task on " +dayOfWeek +" at index " + index +" is not flexible."); } task.setStartTime(newStartTime); task.setEndTime(newEndTime); } - + public void changeTaskType(String dayOfWeek, int index, String newType){ + String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); + ArrayList tasks = weeklyTasks.get(capitalizedDay); + if(index < 0 || index >= tasks.size()){ + throw new IndexOutOfBoundsException("Invalid index"); + } + Task task = tasks.get(index); + task.setType(newType); + } /** * Compares and prints overlapping free time between two Timetables. * @@ -145,4 +153,5 @@ private static void findOverlappingFreeTime(ArrayList tasks, String day) { } + } From 6cd21e10d93a449ba7c0cf01e165f06455eb00fd Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Fri, 22 Mar 2024 01:00:44 +0800 Subject: [PATCH 045/162] Add addTaskForAll function to add a confirmed event to all users' timetable --- src/main/java/seedu/duke/InputValidator.java | 11 +++++ src/main/java/seedu/duke/Parser.java | 41 +++++++++++++------ src/main/java/seedu/duke/Task.java | 42 +++++++------------- src/main/java/seedu/duke/ui/UI.java | 4 ++ 4 files changed, 59 insertions(+), 39 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index c44a4aa25c..6019671aba 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -148,4 +148,15 @@ public static void validateChangeTaskTiming(String input) throws InvalidFormatEx "Expected format: changeTaskTiming /on [day] /index [index] /start [new start time] /end [new end time]"); } } + + public static void validateAddTaskForAll(String input) throws InvalidFormatException { + String regex = "(?i)^addforall\\s+/on\\s+(\\w+)\\s+/task\\s+(.+?)\\s" + + "+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})$"; + + if (!input.matches(regex)) { + throw new InvalidFormatException("[ERROR] Invalid addTask format. " + + "Expected format: addforall /on [day] /task [description] /from [start time] /to [end time] " + + "/type [f/c]"); + } + } } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 5bf1ae2238..cec5979f8b 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -8,12 +8,14 @@ public class Parser { + protected static final String[] DAYS = new String[] + {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; /** * Parses User Input and Identifies the command used. * * @param command The users text input. */ - public void parseCommand(String command, UserList userList) throws InvalidFormatException { + public void parseCommand(String command, UserList userList) throws InvalidFormatException, InvalidDayException { if (command.equalsIgnoreCase("list")) { UI.printListingUsers(); userList.listAll(); @@ -67,6 +69,8 @@ public void parseCommand(String command, UserList userList) throws InvalidFormat } catch (InvalidFormatException | InvalidUserException | NullPointerException e) { System.out.println(e.getMessage()); } + } else if (command.toLowerCase().startsWith("addforall")) { + addTaskForAll(command, userList); } else { UI.printInvalidCommand(); } @@ -88,22 +92,26 @@ private static void deleteTask(String command, UserList userList) { private void addTask(String command, UserList userList) { try { InputValidator.validateAddTaskInput(command); - String[] parts = command.split("\\s+"); - List wordList = Arrays.asList(parts); - String day = parts[2]; - String description = parseDescription(wordList); - String startTime = parts[wordList.indexOf("/from") + 1]; - String endTime = parts[wordList.indexOf("/to") + 1]; - String type = parts[wordList.indexOf("/type") + 1]; - InputValidator.validateDay(day); - Task task = new Task(description, day, startTime, endTime, type); - userList.getActiveUser().getTimetable().addUserTask(day, task); + Task task = parseTask(command); + userList.getActiveUser().getTimetable().addUserTask(task.day, task); UI.printAddTask(task); } catch (InvalidFormatException | InvalidDayException e) { System.out.println(e.getMessage()); } } + public static Task parseTask(String command) throws InvalidDayException { + String[] parts = command.split("\\s+"); + List wordList = Arrays.asList(parts); + String day = parts[2]; + String description = parseDescription(wordList); + String startTime = parts[wordList.indexOf("/from") + 1]; + String endTime = parts[wordList.indexOf("/to") + 1]; + + String type = parts[wordList.indexOf("/type") + 1]; + InputValidator.validateDay(day); + return new Task(description, day, startTime, endTime, type); + } private static void changeTaskTiming(String command, UserList userList) throws InvalidFormatException { try { InputValidator.validateChangeTaskTiming(command); @@ -121,7 +129,7 @@ private static void changeTaskTiming(String command, UserList userList) throws I } } - private String parseDescription(List words) { + private static String parseDescription(List words) { int startIndex = words.indexOf("/task") + 1; int endIndex = words.indexOf("/from") - 1; StringBuilder description = new StringBuilder(); @@ -133,4 +141,13 @@ private String parseDescription(List words) { } return description.toString(); } + + private static void addTaskForAll(String command, UserList userList) throws InvalidFormatException, InvalidDayException { + InputValidator.validateAddTaskForAll(command); + Task task = parseTask(command); + for (User user : userList.getUsers()) { + user.getTimetable().addUserTask(task.day, task); + } + UI.printAddForAll(task); + } } diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index 648a7cfb61..ac6cfede52 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -9,6 +9,20 @@ public class Task { protected LocalTime endTime; protected String type; + + public LocalTime getStartTime() { + return startTime; + } + + /** + * Represents the constructor for Task class that takes in parameters inluding the description of the task, + * the day of the task, the starting time and the ending time of the task. + * + * @param description description of the task. + * @param day day of the task. + * @param from starting time of the task. + * @param to ending time of the task. + */ public Task(String description, String day, String from, String to, String type) { this.description = description; this.day = day; @@ -22,10 +36,6 @@ public Task(String description, String day, String from, String to, String type) this.endTime = LocalTime.parse(formattedTo); this.type = type; } - public LocalTime getStartTime() { - return startTime; - } - public LocalTime getEndTime() { return endTime; @@ -41,34 +51,12 @@ public void setStartTime(LocalTime startTime){ this.startTime = startTime; } - /** - * Represents the constructor for Task class that takes in parameters inluding the description of the task, - * the day of the task, the starting time and the ending time of the task. - * - * @param description description of the task. - * @param day day of the task. - * @param from starting time of the task. - * @param to ending time of the task. - */ - public Task(String description, String day, String from, String to){ - this.description = description; - this.day = day; - String fromHour = from.split(":")[0]; - String fromMinute = from.split(":")[1]; - String toHour = to.split(":")[0]; - String toMinute = to.split(":")[1]; - String formattedFrom = formatDates(fromHour) + ":" + formatDates(fromMinute); - String formattedTo = formatDates(toHour) + ":" + formatDates(toMinute); - this.startTime = LocalTime.parse(formattedFrom); - this.endTime = LocalTime.parse(formattedTo); - } - private String formatDates(String time) { return time.length() == 1 ? "0" + time : time; } @Override public String toString() { - return description + " (" + day + " from " + startTime + " to " + endTime + ")" + "flexibility: " + type; + return description + " (" + day + " from " + startTime + " to " + endTime + ")" + " flexibility: " + type; } } diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index 74e79e4ab4..397aad17e2 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -42,4 +42,8 @@ public static void printHelp() { "delete: delete task \n" + "compare : compare timetables "); } + + public static void printAddForAll(Task task) { + System.out.println("The following task is added for all users: " + task.toString()); + } } From 81a7ce2d50acb3fccb97f99e93e990841939ac0f Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Fri, 22 Mar 2024 01:24:46 +0800 Subject: [PATCH 046/162] Add show confirmed events method --- src/main/java/seedu/duke/Parser.java | 24 ++++++++++++++++++++++-- src/main/java/seedu/duke/Task.java | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 5647d1812b..901f10abff 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -85,7 +85,10 @@ public void parseCommand(String command, UserList userList) throws InvalidFormat } } else if (command.toLowerCase().startsWith("addforall")) { addTaskForAll(command, userList); - } else { + } else if (command.toLowerCase().startsWith("viewcommonevents")) { + printConfirmedEvent(userList); + } + else { UI.printInvalidCommand(); } } @@ -122,7 +125,13 @@ public static Task parseTask(String command) throws InvalidDayException { String startTime = parts[wordList.indexOf("/from") + 1]; String endTime = parts[wordList.indexOf("/to") + 1]; - String type = parts[wordList.indexOf("/type") + 1]; + String type; + if (wordList.contains("/type")) { + type = parts[wordList.indexOf("/type") + 1]; + } else { + type = "common"; + } + InputValidator.validateDay(day); return new Task(description, day, startTime, endTime, type); } @@ -164,4 +173,15 @@ private static void addTaskForAll(String command, UserList userList) throws Inva } UI.printAddForAll(task); } + + private static void printConfirmedEvent(UserList userList) { + int taskCount = 1; + for (String day : DAYS) { + for (Task task : userList.getActiveUser().getTimetable().getWeeklyTasks().get(day)) { + if (task.type.equals("common")) { + System.out.println(taskCount + ". " + task); + } + } + } + } } diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index cdb4545fe2..aeca9adf3c 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -83,6 +83,6 @@ private String formatDates(String time) { @Override public String toString() { - return description + " (" + day + " from " + startTime + " to " + endTime + ")" + "type: " + type; + return description + " (" + day + " from " + startTime + " to " + endTime + ")" + " type: " + type; } } From ecac00fd5f58f4701ddaae4ffdeb6778010c43b1 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Fri, 22 Mar 2024 01:36:19 +0800 Subject: [PATCH 047/162] Remove redundant function --- src/main/java/seedu/duke/Task.java | 31 ++++-------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index aeca9adf3c..448034ebbf 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -9,11 +9,6 @@ public class Task { protected LocalTime endTime; protected String type; - - public LocalTime getStartTime() { - return startTime; - } - /** * Represents the constructor for Task class that takes in parameters inluding the description of the task, * the day of the task, the starting time and the ending time of the task. @@ -37,6 +32,10 @@ public Task(String description, String day, String from, String to, String type) this.type = type; } + public LocalTime getStartTime() { + return startTime; + } + public LocalTime getEndTime() { return endTime; } @@ -54,28 +53,6 @@ public void setStartTime(LocalTime startTime){ public void setType(String type){ this.type = type; } - - /** - * Represents the constructor for Task class that takes in parameters inluding the description of the task, - * the day of the task, the starting time and the ending time of the task. - * - * @param description description of the task. - * @param day day of the task. - * @param from starting time of the task. - * @param to ending time of the task. - */ - public Task(String description, String day, String from, String to){ - this.description = description; - this.day = day; - String fromHour = from.split(":")[0]; - String fromMinute = from.split(":")[1]; - String toHour = to.split(":")[0]; - String toMinute = to.split(":")[1]; - String formattedFrom = formatDates(fromHour) + ":" + formatDates(fromMinute); - String formattedTo = formatDates(toHour) + ":" + formatDates(toMinute); - this.startTime = LocalTime.parse(formattedFrom); - this.endTime = LocalTime.parse(formattedTo); - } private String formatDates(String time) { return time.length() == 1 ? "0" + time : time; From d4d2ecd6ac24d32ad5a6b6dbaf5be216dd044cb4 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Fri, 22 Mar 2024 12:14:49 +0800 Subject: [PATCH 048/162] Add assertions --- src/main/java/seedu/duke/Parser.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 901f10abff..45481ad075 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -168,6 +168,7 @@ private static String parseDescription(List words) { private static void addTaskForAll(String command, UserList userList) throws InvalidFormatException, InvalidDayException { InputValidator.validateAddTaskForAll(command); Task task = parseTask(command); + assert !userList.getUsers().isEmpty() : "There is no user added."; for (User user : userList.getUsers()) { user.getTimetable().addUserTask(task.day, task); } @@ -175,6 +176,7 @@ private static void addTaskForAll(String command, UserList userList) throws Inva } private static void printConfirmedEvent(UserList userList) { + assert !userList.getUsers().isEmpty() : "There is no user added."; int taskCount = 1; for (String day : DAYS) { for (Task task : userList.getActiveUser().getTimetable().getWeeklyTasks().get(day)) { From fe556145c666d147d2888a661714aaf1c61a9672 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Fri, 22 Mar 2024 22:00:51 +0800 Subject: [PATCH 049/162] Add addRepeatTask function --- src/main/java/seedu/duke/InputValidator.java | 8 +++ src/main/java/seedu/duke/Parser.java | 61 +++++++++++++++----- src/main/java/seedu/duke/Timetable.java | 2 +- 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index a957ee77f5..795a048698 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -172,4 +172,12 @@ public static void validateChangeTaskType(String input) throws InvalidFormatExce "Expected format: changeTaskType /on [day] /index [index] /type [f/c]"); } } + public static void validateAddRepeatTask(String input) throws InvalidFormatException{ + String regex = "(?i)^addrepeattask\\s+/task\\s+(.+?)\\s+/on\\s+(\\w+(\\s+\\w+)*)\\s+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})\\s+/type\\s+([fc])$"; + + if (!input.matches(regex)) { + throw new InvalidFormatException("[ERROR] Invalid addRepeatTask format. " + + "Expected format: addRepeatTask /task [description] /on [day(s)] /from [start time] /to [end time] /type [f/c]"); + } + } } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 45481ad075..4ddb0d19ec 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -56,19 +56,9 @@ public void parseCommand(String command, UserList userList) throws InvalidFormat } else if(command.toLowerCase().startsWith("changetasktiming")){ changeTaskTiming(command, userList); } else if(command.toLowerCase().startsWith("changetasktype")){ - try { - InputValidator.validateChangeTaskType(command); - String[] parts = command.split("\\s+"); - List wordList = Arrays.asList(parts); - String day = wordList.get(2); - int index = Integer.parseInt(wordList.get(wordList.indexOf("/index") + 1)); - String newType = wordList.get(wordList.indexOf("/type") + 1); - InputValidator.validateDay(day); - userList.getActiveUser().getTimetable().changeTaskType(day, index - 1, newType); - System.out.println("Task type changed successfully."); - } catch (InvalidDayException | IndexOutOfBoundsException | NumberFormatException e) { - throw new RuntimeException(e); - } + changeTaskType(command, userList); + } else if(command.toLowerCase().startsWith("addrepeattask")){ + addRepeatTask(command, userList); } else if (command.toLowerCase().startsWith("compare")) { try { InputValidator.validateCompareInput(command); @@ -93,6 +83,22 @@ public void parseCommand(String command, UserList userList) throws InvalidFormat } } + private static void changeTaskType(String command, UserList userList) throws InvalidFormatException { + try { + InputValidator.validateChangeTaskType(command); + String[] parts = command.split("\\s+"); + List wordList = Arrays.asList(parts); + String day = wordList.get(2); + int index = Integer.parseInt(wordList.get(wordList.indexOf("/index") + 1)); + String newType = wordList.get(wordList.indexOf("/type") + 1); + InputValidator.validateDay(day); + userList.getActiveUser().getTimetable().changeTaskType(day, index - 1, newType); + System.out.println("Task type changed successfully."); + } catch (InvalidDayException | IndexOutOfBoundsException | NumberFormatException e) { + throw new RuntimeException(e); + } + } + private static void deleteTask(String command, UserList userList) { try { InputValidator.validateDeleteTaskInput(command); @@ -152,6 +158,35 @@ private static void changeTaskTiming(String command, UserList userList) throws I } } + private static void addRepeatTask(String command, UserList userList){ + try { + InputValidator.validateAddRepeatTask(command); + String[] parts = command.split("\\s+"); + List wordlist = Arrays.asList(parts); + int taskIndex = wordlist.indexOf("/task"); + if (taskIndex == -1 || taskIndex + 1 >= wordlist.size()) { + throw new InvalidFormatException(("Please enter a task name!")); + } + String description = wordlist.get(taskIndex + 1); + int daysIndex = wordlist.indexOf("/on") + 1; + int endDaysIndex = wordlist.indexOf("/from") ; + String[] days = Arrays.copyOfRange(parts, daysIndex, endDaysIndex ); + if (days.length < 2){ + throw new InvalidFormatException("Please enter at least 2 days, or you want to use addtask command!"); + } + String startTime = parts[wordlist.indexOf("/from") + 1]; + String endTime = parts[wordlist.indexOf("/to") + 1]; + String type = parts[wordlist.indexOf("/type") + 1]; + for (String day : days) { + Task task = new Task(description, day, startTime, endTime, type); + userList.getActiveUser().getTimetable().addUserTask(day, task); + } + System.out.println("Repeated task added successfully!"); + } catch (InvalidFormatException e) { + System.out.println("Please enter at least 2 days, or you want to use addtask command!"); + } + } + private static String parseDescription(List words) { int startIndex = words.indexOf("/task") + 1; int endIndex = words.indexOf("/from") - 1; diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 7ecb599ba2..ff92e6fd9d 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -83,7 +83,7 @@ public void changeFlexibleTaskTiming(String dayOfWeek, int index, LocalTime newS } Task task = tasks.get(index); if(!task.getType().equals("f")){ - throw new IllegalArgumentException("Task on " +dayOfWeek +" at index " + index +" is not flexible."); + throw new IllegalArgumentException("Task on " +dayOfWeek +" at index " + (index + 1) +" is not flexible, timings cannot be changed."); } task.setStartTime(newStartTime); task.setEndTime(newEndTime); From 8d3f1436b09dab8ad4153612fefc951f35ae4f3a Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Sat, 23 Mar 2024 19:19:13 +0800 Subject: [PATCH 050/162] Add compare all --- src/main/java/seedu/duke/Parser.java | 8 +++- src/main/java/seedu/duke/Timetable.java | 55 ++++++++++++++----------- src/main/java/seedu/duke/ui/UI.java | 39 +++++++++++++++--- text-ui-test/input.txt | 8 ++-- 4 files changed, 74 insertions(+), 36 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 45481ad075..45c5cdbab1 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -69,6 +69,9 @@ public void parseCommand(String command, UserList userList) throws InvalidFormat } catch (InvalidDayException | IndexOutOfBoundsException | NumberFormatException e) { throw new RuntimeException(e); } + } else if (command.toLowerCase().startsWith("compareall")) { + UI.printComparingAll(); + UI.printSharedTime(Timetable.compareAllTimetables(userList)); } else if (command.toLowerCase().startsWith("compare")) { try { InputValidator.validateCompareInput(command); @@ -77,12 +80,13 @@ public void parseCommand(String command, UserList userList) throws InvalidFormat String user2 = parts[2]; InputValidator.validateUserInput(user1, userList); InputValidator.validateUserInput(user2, userList); - Timetable.compareTimetable(userList.findUser(user1).getTimetable(), - userList.findUser(user2).getTimetable()); + UI.printSharedTime(Timetable.compareTimetable(userList.findUser(user1).getTimetable(), + userList.findUser(user2).getTimetable())); } catch (InvalidFormatException | InvalidUserException | NullPointerException e) { System.out.println(e.getMessage()); } + } else if (command.toLowerCase().startsWith("addforall")) { addTaskForAll(command, userList); } else if (command.toLowerCase().startsWith("viewcommonevents")) { diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 7ecb599ba2..faaf2c78f7 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -11,8 +11,8 @@ * This class represents the Timetable object consisting of Arraylist of Tasks for each day of the week. */ public class Timetable { - protected static final String[] DAYS = new String[] - {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; + public static final String[] DAYS = new String[] + {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; private Map> weeklyTasks; // Map to store tasks for each day public Timetable() { @@ -29,6 +29,7 @@ public Map> getWeeklyTasks() { /** * Prints tasks of the day specified. + * * @param day day of the week the task is on. */ public void printTasksOfTheDay(String day) { @@ -44,6 +45,7 @@ public void printTasksOfTheDay(String day) { count++; } } + /** * Adds task on dayOfWeek at an index * @@ -75,55 +77,61 @@ public void deleteUserTask(String dayOfWeek, int index) { } } - public void changeFlexibleTaskTiming(String dayOfWeek, int index, LocalTime newStartTime, LocalTime newEndTime){ - String capitalizedDay = dayOfWeek.substring(0,1).toUpperCase() + dayOfWeek.substring(1); + public void changeFlexibleTaskTiming(String dayOfWeek, int index, LocalTime newStartTime, LocalTime newEndTime) { + String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); ArrayList tasks = weeklyTasks.get(capitalizedDay); - if(index < 0 || index >= tasks.size()){ + if (index < 0 || index >= tasks.size()) { throw new IndexOutOfBoundsException("Invalid index"); } Task task = tasks.get(index); - if(!task.getType().equals("f")){ - throw new IllegalArgumentException("Task on " +dayOfWeek +" at index " + index +" is not flexible."); + if (!task.getType().equals("f")) { + throw new IllegalArgumentException("Task on " + dayOfWeek + " at index " + index + " is not flexible."); } task.setStartTime(newStartTime); task.setEndTime(newEndTime); } - public void changeTaskType(String dayOfWeek, int index, String newType){ + + public void changeTaskType(String dayOfWeek, int index, String newType) { String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); ArrayList tasks = weeklyTasks.get(capitalizedDay); - if(index < 0 || index >= tasks.size()){ + if (index < 0 || index >= tasks.size()) { throw new IndexOutOfBoundsException("Invalid index"); } Task task = tasks.get(index); task.setType(newType); } + /** * Compares and prints overlapping free time between two Timetables. * * @param table1 first Timetable. * @param table2 second Timetable - *

- * Prints the overlapping free time for each day in the format: - * ---------------------- - * Shared Free Time on [day] - * HH:mm - HH:mm: Overlapping Free Time + * @return Returns a merged timetable comprising both input timetables. */ - public static void compareTimetable(Timetable table1, Timetable table2) { + public static Timetable compareTimetable(Timetable table1, Timetable table2) { + Timetable mergedTimetable = new Timetable(); + if (table1.equals(table2)) { + return table1; + } try { InputValidator.validateTableExistence(table1); InputValidator.validateTableExistence(table2); for (String day : Timetable.DAYS) { - System.out.println("----------------------\n" + - "Shared Free Time on " + day + ":"); - // Merge tasks from both timetables and sort them by start time - ArrayList mergedTasks = mergeAndSortTasks(table1.getWeeklyTasks().get(day), - table2.getWeeklyTasks().get(day)); - // Calculate overlapping free time intervals then print them - findOverlappingFreeTime(mergedTasks, day); + mergedTimetable.weeklyTasks.replace(day, mergeAndSortTasks(table1.getWeeklyTasks().get(day), + table2.getWeeklyTasks().get(day))); } } catch (NullPointerException e) { System.out.println(e.getMessage()); } + return mergedTimetable; + } + + public static Timetable compareAllTimetables(UserList userList) { + Timetable mergedTimetable = new Timetable(); + for (User user : userList.getUsers()) { + mergedTimetable = compareTimetable(mergedTimetable, user.getTimetable()); + } + return mergedTimetable; } private static ArrayList mergeAndSortTasks(ArrayList taskList1, ArrayList taskList2) { @@ -133,7 +141,7 @@ private static ArrayList mergeAndSortTasks(ArrayList taskList1, Arra return mergedTasks; } - private static void findOverlappingFreeTime(ArrayList tasks, String day) { + public static void findOverlappingFreeTime(ArrayList tasks, String day) { if (!tasks.isEmpty()) { LocalTime previousEndTime = LocalTime.MIN; for (Task task : tasks) { @@ -153,5 +161,4 @@ private static void findOverlappingFreeTime(ArrayList tasks, String day) { } - } diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index 397aad17e2..6613714f57 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -1,6 +1,9 @@ package seedu.duke.ui; import seedu.duke.Task; +import seedu.duke.Timetable; + +import static seedu.duke.Timetable.findOverlappingFreeTime; public class UI { public static void printGreeting() { @@ -33,17 +36,43 @@ public static void printAddTask(Task task) { public static void printHelp() { System.out.println("List of available commands: \n" + - "adduser: add new user \n" + - "switch : switch to user \n" + + //"\n" + "list: list all users \n" + "bye: exit the app \n" + "current: view current user \n" + - "addtask /on /from /to : add task \n" + - "delete: delete task \n" + - "compare : compare timetables "); + "view: view timetable of current user \n" + + "adduser: add new user \n" + + "switch : switch to user \n" + + "addtask /on /from /to : add task for current user\n" + + "deletetask: delete task \n" + + "changetasktiming: \n" + + "changetasktype : change the type of a task (flexible/confirmed)\n" + + "compareall: compare timetables of all users \n" + + "compare : compare timetables of specified users \n" + + "addforall /on /from /to : add task for all users\n" + + "viewcommonevents: view common events \n"); } public static void printAddForAll(Task task) { System.out.println("The following task is added for all users: " + task.toString()); } + + /** + *

+ * Prints the overlapping free time for each day in the format: + * ---------------------- + * Shared Free Time on [day] + * HH:mm - HH:mm: Overlapping Free Time + */ + public static void printSharedTime(Timetable merged) { + for (String day : Timetable.DAYS) { + System.out.println("Shared free time on " + day + ":"); + findOverlappingFreeTime(merged.getWeeklyTasks().get(day), day); + + } + } + + public static void printComparingAll() { + System.out.println("Comparing all timetables: "); + } } diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index c0e9ab049a..e38cfc6f9f 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1,11 +1,9 @@ adduser simon -list -addtask /on Monday /task lecture /from 9:00 /to 11:00 -view +addtask /on Monday /task lecture /from 9:00 /to 11:00 /type f adduser tim switch tim -addtask /on Eightday /task lecture /from 9:00 /to 11:00 -addtask /on Monday /task lecture /from 9:00 /to 11:00 +addtask /on Monday /task lecture /from 9:00 /to 11:00 /type f view compare simon tim +addtask /on Eightday /task lecture /from 9:00 /to 11:00 /type f bye From 643204ff99d9351cec46fd17db306edd6d567324 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Sat, 23 Mar 2024 20:48:13 +0800 Subject: [PATCH 051/162] Add Junit test to timetable class and inputInvalidator test --- .../java/seedu/duke/InputValidatorTest.java | 71 +++++++++++++++++++ src/test/java/seedu/duke/TimetableTest.java | 61 ++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 src/test/java/seedu/duke/InputValidatorTest.java diff --git a/src/test/java/seedu/duke/InputValidatorTest.java b/src/test/java/seedu/duke/InputValidatorTest.java new file mode 100644 index 0000000000..e9e56e55cd --- /dev/null +++ b/src/test/java/seedu/duke/InputValidatorTest.java @@ -0,0 +1,71 @@ +package seedu.duke; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class InputValidatorTest { + @Test + public void testValidChangeTaskTimingFormat() { + String validInput = "changeTaskTiming /on monday /index 1 /from 09:00 /to 10:00"; + try { + InputValidator.validateChangeTaskTiming(validInput); + } catch (InvalidFormatException e) { + fail("Unexpected exception: " + e.getMessage()); + } + } + + @Test + public void testInvalidChangeTaskTimingFormat() { + String invalidInput = "changeTaskTiming /on monday /index 1 /from 09:00"; + try { + InputValidator.validateChangeTaskTiming(invalidInput); + fail("Expected InvalidFormatException"); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid changeTaskTiming format. Expected format: " + + "changeTaskTiming /on [day] /index [index] /from [new start time] /to [new end time]", e.getMessage()); + } + } + @Test + public void testValidChangeTaskTypeFormat() { + String validInput = "changetasktype /on Monday /index 1 /type f"; + try { + InputValidator.validateChangeTaskType(validInput); + } catch (InvalidFormatException e) { + fail("Unexpected exception: " + e.getMessage()); + } + } + + @Test + public void testInvalidChangeTaskTypeFormat() { + String invalidInput = "changetasktype /on Monday /index 1 /type a"; + try { + InputValidator.validateChangeTaskType(invalidInput); + fail("Expected InvalidFormatException"); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid changeTaskType format. Expected format: " + + "changeTaskType /on [day] /index [index] /type [f/c]", e.getMessage()); + } + } + @Test + public void testValidAddRepeatTaskFormat() { + String validInput = "addRepeatTask /task lec /on monday tuesday /from 08:00 /to 10:00 /type f"; + try { + InputValidator.validateAddRepeatTask(validInput); + } catch (InvalidFormatException e) { + fail("Unexpected exception: " + e.getMessage()); + } + } + + @Test + public void testInvalidAddRepeatTaskFormat() { + String invalidInput = "addRepeatTask /task lec /from 08:00 /to 10:00 /type f"; + try { + InputValidator.validateAddRepeatTask(invalidInput); + fail("Expected InvalidFormatException"); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid addRepeatTask format. Expected format: " + + "addRepeatTask /task [description] /on [day(s)] /from [start time] /to [end time] /type [f/c]", e.getMessage()); + } + } + +} \ No newline at end of file diff --git a/src/test/java/seedu/duke/TimetableTest.java b/src/test/java/seedu/duke/TimetableTest.java index 7ba6b6f0f5..218be2e572 100644 --- a/src/test/java/seedu/duke/TimetableTest.java +++ b/src/test/java/seedu/duke/TimetableTest.java @@ -1,8 +1,12 @@ package seedu.duke; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + import org.junit.jupiter.api.Test; +import java.time.LocalTime; + class TimetableTest { @Test public void testAddUserTask() { @@ -26,4 +30,61 @@ public void testCompareTimetables() { Timetable.compareTimetable(timetable1, timetable2); } + @Test + public void testChangeFlexibleTaskTiming_CorrectInput() { + Timetable timetable = new Timetable(); + Task flexibleTask = new Task("lec", "monday", "09:00", "11:00", "f"); + timetable.addUserTask("monday", flexibleTask); + try { + timetable.changeFlexibleTaskTiming("monday", 0, LocalTime.of(11, 0), + LocalTime.of(12, 0)); + } catch (Exception e) { + fail("Unexpected exception: " + e.getMessage()); + } + } + @Test + public void testChangeFlexibleTaskTiming_InvalidIndex(){ + Timetable timetable = new Timetable(); + try{ + timetable.changeFlexibleTaskTiming("monday", 0, LocalTime.of(11, 0), + LocalTime.of(12, 0)); + fail("Expected IndexOutOfBoundsException"); + } catch(IndexOutOfBoundsException e){ + assertEquals("Invalid index", e.getMessage()); + } + } + @Test + public void testChangeFlexibleTaskTiming_NonFlexibleTask() { + Timetable timetable = new Timetable(); + Task nonFlexibleTask = new Task("lec", "monday", "09:00", "11:00", "c"); + timetable.addUserTask("monday", nonFlexibleTask); + try { + timetable.changeFlexibleTaskTiming("monday", 0, LocalTime.of(11, 0), LocalTime.of(12, 0)); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + assertEquals("Task on monday at index 1 is not flexible, " + + "timings cannot be changed.", e.getMessage()); + } + } + @Test + public void testChangeTaskType_ValidInput() { + Timetable timetable = new Timetable(); + Task task = new Task("lec", "monday", "09:00", "11:00", "f"); + timetable.addUserTask("monday", task); + try { + timetable.changeTaskType("monday", 0, "c"); + } catch (Exception e) { + fail("Unexpected exception: " + e.getMessage()); + } + } + @Test + public void testChangeTaskType_InvalidIndex() { + Timetable timetable = new Timetable(); + try { + timetable.changeTaskType("monday", 0, "c"); + fail("Expected IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + assertEquals("Invalid index", e.getMessage()); + } + } } From f6158d463d5b9a99d740f12049c312a7a7c0ddd4 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Sat, 23 Mar 2024 22:27:48 +0800 Subject: [PATCH 052/162] Add assert into te changeFlexibleTaskTiming --- src/main/java/seedu/duke/Parser.java | 15 +-------------- src/main/java/seedu/duke/Timetable.java | 3 +++ 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 659a2d2fbe..012eee24f3 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -55,23 +55,10 @@ public void parseCommand(String command, UserList userList) throws InvalidFormat deleteTask(command, userList); } else if(command.toLowerCase().startsWith("changetasktiming")){ changeTaskTiming(command, userList); - changeTaskType(command, userList); } else if(command.toLowerCase().startsWith("addrepeattask")){ addRepeatTask(command, userList); } else if(command.toLowerCase().startsWith("changetasktype")){ - try { - InputValidator.validateChangeTaskType(command); - String[] parts = command.split("\\s+"); - List wordList = Arrays.asList(parts); - String day = wordList.get(2); - int index = Integer.parseInt(wordList.get(wordList.indexOf("/index") + 1)); - String newType = wordList.get(wordList.indexOf("/type") + 1); - InputValidator.validateDay(day); - userList.getActiveUser().getTimetable().changeTaskType(day, index - 1, newType); - System.out.println("Task type changed successfully."); - } catch (InvalidDayException | IndexOutOfBoundsException | NumberFormatException e) { - throw new RuntimeException(e); - } + changeTaskType(command, userList); } else if (command.toLowerCase().startsWith("compareall")) { UI.printComparingAll(); UI.printSharedTime(Timetable.compareAllTimetables(userList)); diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 91c6e5a394..6cd72af423 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -78,6 +78,9 @@ public void deleteUserTask(String dayOfWeek, int index) { } public void changeFlexibleTaskTiming(String dayOfWeek, int index, LocalTime newStartTime, LocalTime newEndTime) { + assert dayOfWeek != null : "Day of week cannot be null"; + assert newStartTime != null : "New start time cannot be null"; + assert newEndTime != null : "New end time cannot be null"; String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); ArrayList tasks = weeklyTasks.get(capitalizedDay); if (index < 0 || index >= tasks.size()) { From aa88c0fb31705eecd7a53b2dfb88d852aa5ad832 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Sun, 24 Mar 2024 18:26:00 +0800 Subject: [PATCH 053/162] Add Storage class and functions --- src/main/java/seedu/duke/Duke.java | 5 +- src/main/java/seedu/duke/Parser.java | 3 + src/main/java/seedu/duke/Storage.java | 174 ++++++++++++++++++++++++++ src/main/java/seedu/duke/Task.java | 5 +- src/main/java/seedu/duke/User.java | 7 ++ src/main/java/seedu/duke/ui/UI.java | 4 + 6 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 src/main/java/seedu/duke/Storage.java diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 0a58115a86..990d662970 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -2,6 +2,7 @@ import seedu.duke.ui.UI; +import java.io.FileNotFoundException; import java.util.Scanner; public class Duke { @@ -12,9 +13,11 @@ public static void setIsFinished(boolean b) { isFinished = b; } - public static void main(String[] args) { + public static void main(String[] args) throws FileNotFoundException { UI.printGreeting(); UserList userList = new UserList(); + Storage.createFolder(); + Storage.addExistingUsers(userList); while (!isFinished) { try { diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 45481ad075..ba2b0945d1 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -36,6 +36,7 @@ public void parseCommand(String command, UserList userList) throws InvalidFormat User newUser = new User(userName); UI.printNewUser(newUser.getName()); userList.addUser(newUser); + Storage.addUserInFolder(); } catch (InvalidFormatException e) { System.out.println(e.getMessage()); } @@ -51,6 +52,8 @@ public void parseCommand(String command, UserList userList) throws InvalidFormat } } else if (command.toLowerCase().startsWith("addtask")) { addTask(command, userList); + User currentUser = userList.getActiveUser(); + currentUser.getStorage().writeTaskInFile(currentUser); } else if (command.toLowerCase().startsWith("deletetask")) { deleteTask(command, userList); } else if(command.toLowerCase().startsWith("changetasktiming")){ diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java new file mode 100644 index 0000000000..987697dae9 --- /dev/null +++ b/src/main/java/seedu/duke/Storage.java @@ -0,0 +1,174 @@ +package seedu.duke; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Scanner; + +import static seedu.duke.Parser.DAYS; + +/** + * Represents a storage manager that deals with loading tasks from the file and saving tasks in the file. + */ +public class Storage { + public static String filePath; + + private static final String boxOutline = "+---------+\n"; + + private static final String boxOutlineForWednesday = "+-------------+\n"; + private static final String boxOutlineForFriday = "+------+\n"; + private static final String lineSeparator = ".................................................................................................\n"; + + public Storage(String filePath) { + Storage.filePath = filePath; + } + + public static void createFolder() { + String folderPath = "data"; + File folder = new File(folderPath); + + if (!folder.exists()) { + boolean folderCreated = folder.mkdirs(); + if (folderCreated) { + System.out.println("Folder created successfully."); + } else { + System.out.println("Failed to create folder."); + } + } else { + System.out.println("Folder already exists."); + } + } + + public static void addExistingUsers(UserList userList) throws FileNotFoundException { + String directoryPath = "data"; + File directory = new File(directoryPath); + + File[] files = directory.listFiles(); + if (files != null) { + for (File file : files) { + if (file != null) { + String fileName = file.getName(); + int indexOfDot = fileName.indexOf("."); + String userName = fileName.substring(0, indexOfDot); + User user = new User(userName); + userList.addUser(user); + loadData(user); + } + } + } else { + System.out.println("Directory is empty."); + } + + } + + public static void loadData(User user) throws FileNotFoundException { + File f = new File(filePath); + String day = ""; + Scanner s = new Scanner(f); + while (s.hasNext()) { + String line = s.nextLine(); + // ignore lines for formatting and weeks that have no tasks + if (line.startsWith("+") || line.startsWith(".") || line.isEmpty() || line.equals("No task :)")) { + continue; + } + if (line.startsWith("|")) { + day = line.substring(1, line.length() - 1).trim(); + continue; + } + user.getTimetable().getWeeklyTasks().get(day).add(extractTaskInfo(line, day)); + } + } + public static void addUserInFolder() { + File f = new File(filePath); + String day = ""; + try { + if (f.createNewFile()) { + System.out.println("File created: " + f.getName()); + String fileName = f.getName(); + int indexOfDot = fileName.indexOf("."); + String userName = fileName.substring(0, indexOfDot); + writeToFile(filePath, "Username: " + userName, true); + } + } catch (IOException e) { + System.out.println("Something went wrong: " + e.getMessage()); + } + } + + /** + * Extracts task information from the local text file. + * + * @param line the current line in the file. + * @param day the day of the week. + * @return a Task object represented by this line. + */ + public static Task extractTaskInfo(String line, String day) { + int indexOfDash = line.indexOf("-"); + String startTime = line.substring(3, indexOfDash).trim(); + String endTime = line.substring(indexOfDash + 2, 16).trim(); + int indexOfType = line.indexOf("(type:"); + String description = line.substring(18, indexOfType).trim(); + String type = line.substring(indexOfType + 7, indexOfType + 8); + return new Task(description, day, startTime, endTime, type); + } + + /** + * Writes the text to data file + * + * @param filePath a relative path giving the location of the data file, relative to the current working directory. + * @param textToAdd text to write to the file. + * @param isAppend whether to append the text or overwrite the whole file. + * @throws IOException If there is something wrong. + */ + public static void writeToFile(String filePath, String textToAdd, boolean isAppend) throws IOException{ + FileWriter fw = new FileWriter(filePath, isAppend); + fw.write(textToAdd); + fw.close(); + } + + /** + * Adds task in file. + * @param user the user that the timetable belongs to. + */ + + public void writeTaskInFile(User user) { + Timetable timetable = user.getTimetable(); + + try (FileWriter writer = new FileWriter(filePath)) { + for (String day : DAYS) { + String outline; + switch (day) { + case ("Wednesday"): + outline = boxOutlineForWednesday; + break; + case ("Friday"): + outline = boxOutlineForFriday; + break; + default: + outline = boxOutline; + break; + } + writeToFile(filePath, outline, true); + writeToFile(filePath, "| " + day + " |" + "\n", true); + writeToFile(filePath, outline, true); + + if (timetable.getWeeklyTasks().get(day).isEmpty()) { + writeToFile(filePath, "No task :)\n", true); + writer.write("No task :)\n"); + } else { + int taskCount = 1; + for (Task task : timetable.getWeeklyTasks().get(day)) { + writer.write(taskCount + ". " + task.getStartTime() + " - " + task.getEndTime() + ": " + task.getDescription() + " (type: " + task.getType() + ")" + "\n"); + taskCount += 1; + } + } + writer.write(lineSeparator); + writer.write("\n"); + } + + System.out.println("Timetable has been written to " + filePath); + } catch (IOException e) { + System.err.println("Error writing to file: " + e.getMessage()); + } + } +} diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index 448034ebbf..85241ca587 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -10,7 +10,7 @@ public class Task { protected String type; /** - * Represents the constructor for Task class that takes in parameters inluding the description of the task, + * Represents the constructor for Task class that takes in parameters including the description of the task, * the day of the task, the starting time and the ending time of the task. * * @param description description of the task. @@ -58,6 +58,9 @@ private String formatDates(String time) { return time.length() == 1 ? "0" + time : time; } + public String getDescription() { + return description; + } @Override public String toString() { return description + " (" + day + " from " + startTime + " to " + endTime + ")" + " type: " + type; diff --git a/src/main/java/seedu/duke/User.java b/src/main/java/seedu/duke/User.java index 3a7c5a5579..5b0d1e1fba 100644 --- a/src/main/java/seedu/duke/User.java +++ b/src/main/java/seedu/duke/User.java @@ -4,9 +4,16 @@ public class User { private Timetable timetable; private final String name; + private Storage storage; + public User(String name) { this.name = name; this.timetable = new Timetable(); + this.storage = new Storage("data/" + name + ".txt"); + } + + public Storage getStorage() { + return storage; } public String getName() { diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index 397aad17e2..d4c05df61a 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -46,4 +46,8 @@ public static void printHelp() { public static void printAddForAll(Task task) { System.out.println("The following task is added for all users: " + task.toString()); } + + public static void printLine() { + System.out.println("____________________________________________________________"); + } } From 8b955ac155bb3e2436686b27edde9adf10d9b7ab Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Tue, 26 Mar 2024 10:00:14 +0800 Subject: [PATCH 054/162] Clean up code --- src/main/java/seedu/duke/InputValidator.java | 16 +++++++--- src/main/java/seedu/duke/Parser.java | 30 +++++++++++-------- src/main/java/seedu/duke/Storage.java | 16 ++++++---- src/main/java/seedu/duke/Timetable.java | 22 +++++++------- .../{ => exceptions}/InvalidDayException.java | 2 +- .../InvalidFormatException.java | 2 +- .../InvalidUserException.java | 2 +- src/main/java/seedu/duke/ui/UI.java | 1 + .../java/seedu/duke/InputValidatorTest.java | 2 ++ 9 files changed, 57 insertions(+), 36 deletions(-) rename src/main/java/seedu/duke/{ => exceptions}/InvalidDayException.java (81%) rename src/main/java/seedu/duke/{ => exceptions}/InvalidFormatException.java (87%) rename src/main/java/seedu/duke/{ => exceptions}/InvalidUserException.java (87%) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 795a048698..d59be1e2dd 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -1,5 +1,9 @@ package seedu.duke; +import seedu.duke.exceptions.InvalidDayException; +import seedu.duke.exceptions.InvalidFormatException; +import seedu.duke.exceptions.InvalidUserException; + public class InputValidator { /** * Validates correctly formatted compare command. The expected format is @@ -142,10 +146,12 @@ public static void validateChangeTaskTiming(String input) throws InvalidFormatEx String startPattern = "\\d{1,2}:\\d{2}"; String endPattern = "\\d{1,2}:\\d{2}"; String suffix = "$"; - String regex = prefix + dayPattern + "\\s+/index\\s+" + indexPattern + "\\s+/from\\s+" + startPattern + "\\s+/to\\s+" + endPattern + suffix; + String regex = prefix + dayPattern + "\\s+/index\\s+" + indexPattern + "\\s+/from\\s+" + + startPattern + "\\s+/to\\s+" + endPattern + suffix; if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid changeTaskTiming format. " + - "Expected format: changeTaskTiming /on [day] /index [index] /from [new start time] /to [new end time]"); + "Expected format: changeTaskTiming /on [day] /index [index] /from [new start time] " + + "/to [new end time]"); } } @@ -173,11 +179,13 @@ public static void validateChangeTaskType(String input) throws InvalidFormatExce } } public static void validateAddRepeatTask(String input) throws InvalidFormatException{ - String regex = "(?i)^addrepeattask\\s+/task\\s+(.+?)\\s+/on\\s+(\\w+(\\s+\\w+)*)\\s+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})\\s+/type\\s+([fc])$"; + String regex = "(?i)^addrepeattask\\s+/task\\s+(.+?)\\s+/on\\s+(\\w+(\\s+\\w+)*)\\s+" + + "/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})\\s+/type\\s+([fc])$"; if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid addRepeatTask format. " + - "Expected format: addRepeatTask /task [description] /on [day(s)] /from [start time] /to [end time] /type [f/c]"); + "Expected format: addRepeatTask /task [description] /on [day(s)] /from [start time] " + + "/to [end time] /type [f/c]"); } } } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index cd54789bfd..c6f466fc01 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -1,5 +1,8 @@ package seedu.duke; +import seedu.duke.exceptions.InvalidDayException; +import seedu.duke.exceptions.InvalidFormatException; +import seedu.duke.exceptions.InvalidUserException; import seedu.duke.ui.UI; import java.time.LocalTime; @@ -9,7 +12,8 @@ public class Parser { protected static final String[] DAYS = new String[] - {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; + {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; + /** * Parses User Input and Identifies the command used. * @@ -56,11 +60,11 @@ public void parseCommand(String command, UserList userList) throws InvalidFormat currentUser.getStorage().writeTaskInFile(currentUser); } else if (command.toLowerCase().startsWith("deletetask")) { deleteTask(command, userList); - } else if(command.toLowerCase().startsWith("changetasktiming")){ + } else if (command.toLowerCase().startsWith("changetasktiming")) { changeTaskTiming(command, userList); - } else if(command.toLowerCase().startsWith("addrepeattask")){ + } else if (command.toLowerCase().startsWith("addrepeattask")) { addRepeatTask(command, userList); - } else if(command.toLowerCase().startsWith("changetasktype")){ + } else if (command.toLowerCase().startsWith("changetasktype")) { changeTaskType(command, userList); } else if (command.toLowerCase().startsWith("compareall")) { UI.printComparingAll(); @@ -84,8 +88,7 @@ public void parseCommand(String command, UserList userList) throws InvalidFormat addTaskForAll(command, userList); } else if (command.toLowerCase().startsWith("viewcommonevents")) { printConfirmedEvent(userList); - } - else { + } else { UI.printInvalidCommand(); } } @@ -148,6 +151,7 @@ public static Task parseTask(String command) throws InvalidDayException { InputValidator.validateDay(day); return new Task(description, day, startTime, endTime, type); } + private static void changeTaskTiming(String command, UserList userList) throws InvalidFormatException { try { InputValidator.validateChangeTaskTiming(command); @@ -158,14 +162,15 @@ private static void changeTaskTiming(String command, UserList userList) throws I LocalTime newStartTime = LocalTime.parse(parts[wordList.indexOf("/from") + 1]); LocalTime newEndTime = LocalTime.parse(parts[wordList.indexOf("/to") + 1]); InputValidator.validateDay(day); - userList.getActiveUser().getTimetable().changeFlexibleTaskTiming(day, index - 1, newStartTime, newEndTime); + userList.getActiveUser().getTimetable().changeFlexibleTaskTiming(day, + index - 1, newStartTime, newEndTime); System.out.println("Flexible task timing changed successfully."); } catch (InvalidDayException e) { throw new RuntimeException(e); } } - private static void addRepeatTask(String command, UserList userList){ + private static void addRepeatTask(String command, UserList userList) { try { InputValidator.validateAddRepeatTask(command); String[] parts = command.split("\\s+"); @@ -176,9 +181,9 @@ private static void addRepeatTask(String command, UserList userList){ } String description = wordlist.get(taskIndex + 1); int daysIndex = wordlist.indexOf("/on") + 1; - int endDaysIndex = wordlist.indexOf("/from") ; - String[] days = Arrays.copyOfRange(parts, daysIndex, endDaysIndex ); - if (days.length < 2){ + int endDaysIndex = wordlist.indexOf("/from"); + String[] days = Arrays.copyOfRange(parts, daysIndex, endDaysIndex); + if (days.length < 2) { throw new InvalidFormatException("Please enter at least 2 days, or you want to use addtask command!"); } String startTime = parts[wordlist.indexOf("/from") + 1]; @@ -207,7 +212,8 @@ private static String parseDescription(List words) { return description.toString(); } - private static void addTaskForAll(String command, UserList userList) throws InvalidFormatException, InvalidDayException { + private static void addTaskForAll(String command, UserList userList) + throws InvalidFormatException, InvalidDayException { InputValidator.validateAddTaskForAll(command); Task task = parseTask(command); assert !userList.getUsers().isEmpty() : "There is no user added."; diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 987697dae9..93e7ebe0fb 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -18,7 +18,8 @@ public class Storage { private static final String boxOutlineForWednesday = "+-------------+\n"; private static final String boxOutlineForFriday = "+------+\n"; - private static final String lineSeparator = ".................................................................................................\n"; + private static final String lineSeparator = + ".................................................................................................\n"; public Storage(String filePath) { Storage.filePath = filePath; @@ -79,6 +80,7 @@ public static void loadData(User user) throws FileNotFoundException { user.getTimetable().getWeeklyTasks().get(day).add(extractTaskInfo(line, day)); } } + public static void addUserInFolder() { File f = new File(filePath); String day = ""; @@ -99,7 +101,7 @@ public static void addUserInFolder() { * Extracts task information from the local text file. * * @param line the current line in the file. - * @param day the day of the week. + * @param day the day of the week. * @return a Task object represented by this line. */ public static Task extractTaskInfo(String line, String day) { @@ -115,12 +117,12 @@ public static Task extractTaskInfo(String line, String day) { /** * Writes the text to data file * - * @param filePath a relative path giving the location of the data file, relative to the current working directory. + * @param filePath a relative path giving the location of the data file, relative to the current working directory. * @param textToAdd text to write to the file. - * @param isAppend whether to append the text or overwrite the whole file. + * @param isAppend whether to append the text or overwrite the whole file. * @throws IOException If there is something wrong. */ - public static void writeToFile(String filePath, String textToAdd, boolean isAppend) throws IOException{ + public static void writeToFile(String filePath, String textToAdd, boolean isAppend) throws IOException { FileWriter fw = new FileWriter(filePath, isAppend); fw.write(textToAdd); fw.close(); @@ -128,6 +130,7 @@ public static void writeToFile(String filePath, String textToAdd, boolean isAppe /** * Adds task in file. + * * @param user the user that the timetable belongs to. */ @@ -158,7 +161,8 @@ public void writeTaskInFile(User user) { } else { int taskCount = 1; for (Task task : timetable.getWeeklyTasks().get(day)) { - writer.write(taskCount + ". " + task.getStartTime() + " - " + task.getEndTime() + ": " + task.getDescription() + " (type: " + task.getType() + ")" + "\n"); + writer.write(taskCount + ". " + task.getStartTime() + " - " + task.getEndTime() + + ": " + task.getDescription() + " (type: " + task.getType() + ")" + "\n"); taskCount += 1; } } diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 6cd72af423..ccc509ad7d 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -12,7 +12,7 @@ */ public class Timetable { public static final String[] DAYS = new String[] - {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; + {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; private Map> weeklyTasks; // Map to store tasks for each day public Timetable() { @@ -81,27 +81,27 @@ public void changeFlexibleTaskTiming(String dayOfWeek, int index, LocalTime newS assert dayOfWeek != null : "Day of week cannot be null"; assert newStartTime != null : "New start time cannot be null"; assert newEndTime != null : "New end time cannot be null"; - String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); - ArrayList tasks = weeklyTasks.get(capitalizedDay); - if (index < 0 || index >= tasks.size()) { - throw new IndexOutOfBoundsException("Invalid index"); - } - Task task = tasks.get(index); - if(!task.getType().equals("f")){ - throw new IllegalArgumentException("Task on " +dayOfWeek +" at index " + (index + 1) +" is not flexible, timings cannot be changed."); + Task task = readDay(dayOfWeek, index); + if (!task.getType().equals("f")) { + throw new IllegalArgumentException("Task on " + dayOfWeek + " at index " + + (index + 1) + " is not flexible, timings cannot be changed."); } task.setStartTime(newStartTime); task.setEndTime(newEndTime); } public void changeTaskType(String dayOfWeek, int index, String newType) { + Task task = readDay(dayOfWeek, index); + task.setType(newType); + } + + private Task readDay(String dayOfWeek, int index) { String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); ArrayList tasks = weeklyTasks.get(capitalizedDay); if (index < 0 || index >= tasks.size()) { throw new IndexOutOfBoundsException("Invalid index"); } - Task task = tasks.get(index); - task.setType(newType); + return tasks.get(index); } /** diff --git a/src/main/java/seedu/duke/InvalidDayException.java b/src/main/java/seedu/duke/exceptions/InvalidDayException.java similarity index 81% rename from src/main/java/seedu/duke/InvalidDayException.java rename to src/main/java/seedu/duke/exceptions/InvalidDayException.java index 99dfff6a7b..b5e41a24dc 100644 --- a/src/main/java/seedu/duke/InvalidDayException.java +++ b/src/main/java/seedu/duke/exceptions/InvalidDayException.java @@ -1,4 +1,4 @@ -package seedu.duke; +package seedu.duke.exceptions; public class InvalidDayException extends Exception { public InvalidDayException(String message) { diff --git a/src/main/java/seedu/duke/InvalidFormatException.java b/src/main/java/seedu/duke/exceptions/InvalidFormatException.java similarity index 87% rename from src/main/java/seedu/duke/InvalidFormatException.java rename to src/main/java/seedu/duke/exceptions/InvalidFormatException.java index db2ba7fbff..c01762e054 100644 --- a/src/main/java/seedu/duke/InvalidFormatException.java +++ b/src/main/java/seedu/duke/exceptions/InvalidFormatException.java @@ -1,4 +1,4 @@ -package seedu.duke; +package seedu.duke.exceptions; /** * This class represents Expections expected from the InputValidator class. diff --git a/src/main/java/seedu/duke/InvalidUserException.java b/src/main/java/seedu/duke/exceptions/InvalidUserException.java similarity index 87% rename from src/main/java/seedu/duke/InvalidUserException.java rename to src/main/java/seedu/duke/exceptions/InvalidUserException.java index bd836c0681..7539be9c61 100644 --- a/src/main/java/seedu/duke/InvalidUserException.java +++ b/src/main/java/seedu/duke/exceptions/InvalidUserException.java @@ -1,4 +1,4 @@ -package seedu.duke; +package seedu.duke.exceptions; /** * This class represents user Expections expected from the InputValidator class. diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index d40052d17f..61f8788501 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -60,6 +60,7 @@ public static void printAddForAll(Task task) { public static void printLine() { System.out.println("____________________________________________________________"); + } /** *

diff --git a/src/test/java/seedu/duke/InputValidatorTest.java b/src/test/java/seedu/duke/InputValidatorTest.java index e9e56e55cd..185e76437a 100644 --- a/src/test/java/seedu/duke/InputValidatorTest.java +++ b/src/test/java/seedu/duke/InputValidatorTest.java @@ -1,6 +1,8 @@ package seedu.duke; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; +import seedu.duke.exceptions.InvalidFormatException; + import static org.junit.jupiter.api.Assertions.*; class InputValidatorTest { From 4f78376aa74da4b75c219c79b7342c52b01bf606 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Tue, 26 Mar 2024 20:49:44 +0800 Subject: [PATCH 055/162] Add parser tests --- src/main/java/seedu/duke/InputValidator.java | 2 +- src/main/java/seedu/duke/Parser.java | 37 +++--- src/main/java/seedu/duke/UserList.java | 6 +- src/test/java/seedu/duke/ParserTest.java | 120 +++++++++++++++++++ 4 files changed, 140 insertions(+), 25 deletions(-) create mode 100644 src/test/java/seedu/duke/ParserTest.java diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index d59be1e2dd..63cb694240 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -72,7 +72,7 @@ public static void validateAddUserInput(String input) throws InvalidFormatExcept if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid addUser format. " + - "Expected format: addUser "); + "Expected format: adduser "); } } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index c6f466fc01..469bf3bb66 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -19,7 +19,8 @@ public class Parser { * * @param command The users text input. */ - public void parseCommand(String command, UserList userList) throws InvalidFormatException, InvalidDayException { + public static void parseCommand(String command, UserList userList) throws + InvalidFormatException, InvalidDayException, InvalidUserException { if (command.equalsIgnoreCase("list")) { UI.printListingUsers(); userList.listAll(); @@ -33,27 +34,19 @@ public void parseCommand(String command, UserList userList) throws InvalidFormat } else if (command.equalsIgnoreCase("view")) { userList.getActiveUser().viewTimetable(); } else if (command.toLowerCase().startsWith("adduser")) { - try { - InputValidator.validateAddUserInput(command); - String[] parts = command.split("\\s+"); - String userName = parts[1]; - User newUser = new User(userName); - UI.printNewUser(newUser.getName()); - userList.addUser(newUser); - Storage.addUserInFolder(); - } catch (InvalidFormatException e) { - System.out.println(e.getMessage()); - } + InputValidator.validateAddUserInput(command); + String[] parts = command.split("\\s+"); + String userName = parts[1]; + User newUser = new User(userName); + UI.printNewUser(newUser.getName()); + userList.addUser(newUser); + Storage.addUserInFolder(); } else if (command.toLowerCase().startsWith("switch")) { - try { - InputValidator.validateSwitchInput(command); - String[] parts = command.split("\\s+"); - String userName = parts[1]; - userList.setActiveUser(userList.findUser(userName)); - UI.printActiveUser(userList.getActiveUser().getName()); - } catch (InvalidFormatException e) { - System.out.println(e.getMessage()); - } + InputValidator.validateSwitchInput(command); + String[] parts = command.split("\\s+"); + String userName = parts[1]; + userList.setActiveUser(userList.findUser(userName)); + UI.printActiveUser(userList.getActiveUser().getName()); } else if (command.toLowerCase().startsWith("addtask")) { addTask(command, userList); User currentUser = userList.getActiveUser(); @@ -122,7 +115,7 @@ private static void deleteTask(String command, UserList userList) { } } - private void addTask(String command, UserList userList) { + private static void addTask(String command, UserList userList) { try { InputValidator.validateAddTaskInput(command); Task task = parseTask(command); diff --git a/src/main/java/seedu/duke/UserList.java b/src/main/java/seedu/duke/UserList.java index d595b3c951..3cd3b78156 100644 --- a/src/main/java/seedu/duke/UserList.java +++ b/src/main/java/seedu/duke/UserList.java @@ -1,5 +1,6 @@ package seedu.duke; +import seedu.duke.exceptions.InvalidUserException; import seedu.duke.ui.UI; import java.util.ArrayList; @@ -16,11 +17,12 @@ public User getActiveUser() { return activeUser; } - public void setActiveUser(User user) { + public void setActiveUser(User user) throws InvalidUserException { if (user != null) { activeUser = user; } else { - System.out.println("User does not exist!"); + throw new InvalidUserException("User does not exist!"); + //System.out.println("User does not exist!"); } } diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java new file mode 100644 index 0000000000..93347582f8 --- /dev/null +++ b/src/test/java/seedu/duke/ParserTest.java @@ -0,0 +1,120 @@ +package seedu.duke; + +import org.junit.jupiter.api.Test; +import seedu.duke.exceptions.InvalidDayException; +import seedu.duke.exceptions.InvalidFormatException; +import seedu.duke.exceptions.InvalidUserException; + +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +class ParserTest { + UserList userlist = new UserList(); + + @Test + public void sampleTest() { + assertTrue(true); + } + + @Test + public void adduserCommandTest() throws InvalidDayException, InvalidFormatException, InvalidUserException { + Parser.parseCommand("addUser User1", userlist); + + assertEquals(1, userlist.getListLength()); + assertEquals("User1", userlist.getActiveUser().getName()); + + Parser.parseCommand("addUser User2", userlist); + Parser.parseCommand("addUser User3", userlist); + Parser.parseCommand("addUser User4", userlist); + + assertEquals(4, userlist.getListLength()); + } + + @Test + public void invalidAdduserCommandTest() { + try { + Parser.parseCommand("addUser", userlist); + fail(); + } catch (Exception e) { + assertEquals("[ERROR] Invalid addUser format. Expected format: adduser ", + e.getMessage()); + } + } + + @Test + public void switchCommandTest() throws InvalidDayException, InvalidFormatException, InvalidUserException { + User user1 = new User("User1"); + User user2 = new User("User2"); + userlist.addUser(user1); + userlist.addUser(user2); + Parser.parseCommand("switch User2", userlist); + + assertEquals(2, userlist.getListLength()); + assertEquals("User2", userlist.getActiveUser().getName()); + } + + @Test + public void invalidSwitchCommandTest() { + User user1 = new User("User1"); + User user2 = new User("User2"); + userlist.addUser(user1); + userlist.addUser(user2); + + try { + Parser.parseCommand("switch", userlist); + fail(); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid switch format. Expected format: switch ", + e.getMessage()); + } catch (Exception e) { + fail(); + } + + try { + Parser.parseCommand("switch noUser", userlist); + fail(); + } catch (InvalidUserException e) { + assertEquals("User does not exist!", e.getMessage()); + } catch (Exception e) { + fail(); + } + } + + @Test + public void addTaskCommandTest() throws InvalidDayException, InvalidUserException, InvalidFormatException { + User user1 = new User("User1"); + userlist.addUser(user1); + + Parser.parseCommand("addtask /on Monday /task test1 /from 9:00 /to 11:00 /type f", userlist); + Parser.parseCommand("addtask /on Monday /task test2 /from 13:00 /to 15:00 /type f", userlist); + ArrayList testTasks = user1.getTimetable().getWeeklyTasks().get("Monday"); + + assertEquals("test1", testTasks.get(0).getDescription()); + assertEquals("09:00", testTasks.get(0).getStartTime().toString()); + assertEquals("11:00", testTasks.get(0).getEndTime().toString()); + + assertEquals("test2", testTasks.get(1).getDescription()); + assertEquals("13:00", testTasks.get(1).getStartTime().toString()); + assertEquals("15:00", testTasks.get(1).getEndTime().toString()); + } + + @Test + public void invalidAddTaskCommandTest() { + + String expectedErrorMessage = "[ERROR] Invalid addTask format. Expected format: addTask /on [day]" + + " /task [description] /from [start time] /to [end time] /type [f/c]"; + try { + Parser.parseCommand("addtask", userlist); + fail(); + } catch (InvalidFormatException | InvalidDayException e) { + assertEquals(expectedErrorMessage, e.getMessage()); + } catch (Exception e) { + assertNull(e.getMessage()); + } + + } +} From 80f87d83d3408f0b293986b933d31ff706f9c249 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Thu, 28 Mar 2024 12:41:43 +0800 Subject: [PATCH 056/162] edit developer guide on changeTaskTiming in parse class with uml diagram --- docs/DeveloperGuide.md | 13 +++++++++++++ docs/diagram/changeTaskTimingClassDiagram.png | Bin 0 -> 77678 bytes .../changeTaskTiming_Sequence_Diagram.png | Bin 0 -> 55991 bytes 3 files changed, 13 insertions(+) create mode 100644 docs/diagram/changeTaskTimingClassDiagram.png create mode 100644 docs/diagram/changeTaskTiming_Sequence_Diagram.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 0c327c7154..81a4b586f3 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -38,3 +38,16 @@ ## Instructions for manual testing {Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing} + +## Parser Component + +Here is a partial class diagram for the method changeTaskTiming method in Parser Class. +![changeTaskTimingClassDiagram.png](diagram%2FchangeTaskTimingClassDiagram.png) +The following sequence diagram of changeTaskTiming shows the interactions with other objects. +![changeTaskTiming_Sequence_Diagram.png](diagram%2FchangeTaskTiming_Sequence_Diagram.png) +Here is how this method works: +1. The Parser calls the changeTaskTiming method with a command and the UserList. It calls InputValidator. +2. The InputValidator validates the command, ensuring that it meets the required format in days and index. +3. If validation is successful, the User calls the timetable and calls its changeFlexibleTaskTiming method with the specified parameters. +4. The Timetable updates the timing of the flexible task. +5. If successful, the InputValidator sends a success message back to the Parser. Otherwise, it throws a RuntimeException. diff --git a/docs/diagram/changeTaskTimingClassDiagram.png b/docs/diagram/changeTaskTimingClassDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..8e824747ee780fece46fb61ca6e0ba332a5b5495 GIT binary patch literal 77678 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

x5k@SKso|B%l}#qU10D8$1yaH#Xd+i-oh zV3S?uk_qV%XXULgy}bPF%HNy9X=rvL;v}Wyz!j(OHv3y2lEjsC2akMkwL_A%hOpSk zr~gMhiwQkGl{$61)T^%1`JmZ!+_?{`?%2pjq)2)62=qF|na~6MYQG0OTGr}D(Nlud zq;D`6#A5sC9*x1vFRxBd|CtW?4O}dpot?EoCol3K>ZcXF*{v>Ih>Y<5pycNK7_hTe z7Pg+yf!u>9w`EI8(C?SDSrwb5M;RADGxC{qJml977-hx1P(4%PPj^PVt<#{kL&~aH zHq)=9M1FW9tcr5E7SH1w)&9KuG&HmoE0T-Vpc`Xd?4av}N!PAiO3*}zZGc*(#Yrm> z>O$;J-4!s-^$BbW^4U{%@^a+grHFlr|X?~>{$TIo@MK@DNq^OqIUimC*!GC z(wy9p0(F_eEYq(fK$|W5)j7p|3YEic{&cxLg;HfCIm3Nb?rq~2r_am|ecm%4(3k3a zG^;pUAfJkadIPEHah)O|mJvxBU2Tj3BdB{bw1w~6-2TQpU=nSLzo!sK6q-$J7EFG( zm$O5MB15sai#XKP(h^c~lE&Gp-%R=N;i%tCgQoCsBRN%fa5&m4#!s~iWcVil73ho5IM?yEY8~xbs9Fp9op`-?L-;>k(_&I;k zZQCE!^B6_njw3LEp`Q3rW}+n_xsUbW)|JX*J%vNJ!~e9|MK^@`KUY6Epn{336^GW| zn&X1`F+=bd`5toH$n9|W9FL)c!z4P5NMP;A_F%U$tb{}u9qpo}>-Xq+QhRmp;RB_z zNA!rQLa;Ek;$+kzeNmrByE*I_jOPimdv8)wFvDE^vXr5HcP*Om?)z38ThhL0ktUDY zubrEuR1SE~V87nnUb)5;M<4vfoDgH%a}h!O{ZJT;>e%9H%IWs7SKm zoCwubzsr}N08J`=q;4c@C}1y*%%Zl~Y-n(uz}zBE9yDj(y*G-ul2Z9bJKX3Ex0Zyt z5&4S%VhZ)Q&e!xu8XZk`xE3wAektjB#q&OFPewk5K71bsDV=xx@bce6BmCX7vsp)3 zlaxqKtYqzCCL@Q}QAd)p-dh0XL3v_d8z)u%^Ht2;ZHO!UoJp%7Vm8MxtUri zM&RD(t3Sqf($Rf~wr8y&Y*2;F%WmNiIqG-C(cUpoUEW;&;;8TN`eBeqlz{PPVWpqB zA=Fc5amWDdE<_US*g^tmsK5V!)4<_8N*?tFK_PMRz<>aT+y-xO+jSh^8(>TMc!oC3ESoi{}gD+=f?}al$BQQ?v03T|9JJi#Pqv*p2CNIEadI% z`X631K=cTUltk%(rWpll5&$A>#RE$iWSZKz$t!GXww z(1>5|xo>3i6Ur_Rq3eYRH*|{hEj1fRc`Xl-V%@68|D&0ga0TUeV&`r2w2#k||D7QD zM-=`uKw4A0y>K(-RYf<3&)Rml_m+2Z=&xW7G~2mL!tqU4S4@E8Rb~|7)DA_fDGxOW zcD%lp9~v5(XeSu9?_`8#d=2?i`p#Qzw$5N|9b#O)GEbS{ce(me9PPI1U}ou+k)Ett zMRHGvbN#6VW54xxo#7jChblor#nfs3G*onmxlyt?RywgWnY8JS4SRh~LD|3j$NB9m zY0_1!dPefGr}Auf`pZMa8t#~?D_J{2tU`XqTd{D+e1|h%sqA5QFc*6E&qx*;8yCtA zBP{*=^^4j=zhZk9?eB5T>;UU0_MS(gRsS@t+g-YZv9(kJ%bn--X&K#{ny6;>R}B4_ z#3uNy5=%DWa~s;(t3Fcwelnfi-H^(o_b#UgTCX5G9dt~ZgENQ&1054Ftp%Qn)b%62 zY{{1~$x&@7kgt`4TNu!ifo^?WJE9ZJk#KsEm-l%x3DN=XHJd<+{C9*y-k5TZJ4CT~ z1RE+Z?7AZYb@$X>r>k*0E@7y~-=1F(xUoq zuPT$UOU7Ry4TCeYq3G_P#-ngqO;XGw|1D^nGbLWN@9in$xa6p3p--tq<^Yu)YoIjI zxgtudB}r$igq@2T?|mQH-Y%)V>Yv^N3MZ)UQp!-*NxOV4ui~AYnVG@AFmjzO8@kK8 zV*~4CotwYGb(%*?-c%K9RU-xW*}v886`A+p7TgU#1tAYz+ZgXDjwX|RnI;L=7?J3b z#xNM%Imu||MhmIZ3U85zIa9p#ZuIo1SM~<93eTF&KXjqJbi~R7rSxKC2KFr#j1EO5%kvn*}P|!{%OTdKV{5Q`0dsD-NjVgB*I6?GcN%~3j zLuRTWJtY9-N5rWu>bO+H`f4R744SBk&m0x8%`hf-N^LtnImOR2fMEa$TU3g5?c9Bn zrLf%Pnu%gU6N8qS6Dc zuKc6ktJO>juk1UK&A#>S4fstw+s!i$Bj!4g8^4=rMS$S_jDwjoOEpx@q~=4N%07bt zKKYV64QbOMM*J6`G!PcwfYEy3e{d})8~#ommBj@qIB%$C_AgjHwYQ1gq_R%q{ zib6>=u_yc*Z@b8s_vw-U)N4LimBb(meuAdP;d%+A$C`0p;o=De@2^<>j1^4+h1^NM z>_vo{*6;wfyI5ISbHjPAC%fr%+%w3;yl6>Ha$uR6g+<_%Ps@eNxSU}7n&d;GPcgTAlH*P*MeMc*?LnmklLE2!$0sg< zbikGHBJE2wTmXGe>CDuq@C={LJDwF`!1X>Q+W>wr-yj3|h@}8QLe!5aSx%Ky=4oS?aq)% zg9?M&_fc)PTH`jE%TtNq%K_1RIhAr(%H=CYJ^|QGW(iQ zz*SUKL=-pI%ozp!fzu;GLS`VXY#as4ZjzHRFSh>1?N+VuSC!M>fDiRtVqzl5FN9x8 z0vwROv@S%YTSBI9tEniyZMA{hUi9+`^F_53T5asV7g{vY@8gw5-@jj9j@SEbXsCSc zLC*FIic*e!6q~uA*oh){U}B=Nm+Wg`{Tppvz0{6e*3r85M%b-ew_r0Mg?}U@)~;Pk zcv{=7I#NlP7&pXNI5>EG>pGY>F>3|oI)q+gIsMGpeBG<>M!_WTD3NT$Q~zig@kq9@lpDjJ02k#&Dv20(PS=1?L&o7-G3Sr>qzij@$qrTfp|il zJyHF9Q=%eP6h5=M*5|Fet}IytcwIS=RpZ(fsGi|o>p7oRpglZNg9SdgtdKFSw2f;7 zsIIB1dM1hRq!~ynfOzG;wcmE4Al*E-diClKs$B*Ejl{y3b8~WQvF>((|GU=d)2HDA zY-(bHo7efWYyucCP4eUMjY^;J+hP8#el4N$DK;oAKfav99xiq&SlHOeUs}2I4vzW~ z`&3v0tF2ALyg;73B(lP}>I~N92>KM7L3#J3>JMMGL2wWgSYo@o0vqYCgCPcCWCJTs z7*AJy_>v9XFs$x8Yc`?Uycs)kuKh<1dDy5yaWRjMjXjAKLe}vI8@uMhp6Yy1E#$Yz z4qJjjk~johQN)7>X=~FY3wcIDf2Eai7vwnJVRcckdo}x59EkHITqBI6@-*i`BI?`X zOraGNRN(0jbJrlS&!8ndH?jUS%w^Jl*W}6A_`CF_Wf-f}=lQ=ge5*o6dV#No862WR z<%njXQY=3tR3MfEe+fhy>rby1G4ur9bG&BX%GN|(OIH?ocQ@$4-YLGamKz{r{x4VX?2KF zX6r;_F!785KMTr_fq^s=N5jPN7J9&>g#~IN3dCM)S63HK{5;CZ`e%=%qbLy?={39lJQ_`D6oZ(opfM)I z5k7qJg~f-Mb(@d>=Nj-;;CEZAOzqv))&{;0d^oo35Mmb=&T(|({rNm`aG#V^%oh5I z_CCzPnDHD=oag{kXKtdK>guhT7R>Iz*B-|S$J{V^-U`tZ7MDU9>ouUd9uphe8a$id zcj655b^8HI8yJQHfT7f&pa@HLzMxD&*oCfHy_!&pGp(C5#L^U0(wQ5!ckM;g?|ywv z{G|4YCMr0DreoNE|C8{Xz&q<;2vQ4^Se~idkI@4H4}v6^=TmUfKek~in2ixgg5y@ zlD9SnikTVEN5z!Ks{U3{mt{L-M=yxtvOFG0OajmSjKZFn~KZ^_`Im=k+IyYRYKNR{1kCGBBVSIk+Tj zAh3IPDe6gtT2L;b_tiHj6>ED#^FcoI>k?>F;P<@yu&j0=kgMObxx)DJ(i#dL4V8EI zwAOy>E$M|9Cla9d_!U-gP9KWi@c)cZ<%(c)x69QMa~LVK+O-TQxtJIks|>t;II>k@ z+iJSxUYy7UP4I>vkOQs;Ab}jPY+}bW5s2qqkLtwdcnksZD+@{BX+Zzp>!+FG*!VL} z6Co*)^2$moK6t<;CtXnH(b3}zzjH?gOc!1e^Re%}@V&xHd8cJDHc^Yw(jA#<&Bi1V zoAqUA!r#A#^2_T5r^hV_1}>mAppM+UQ@9+O8bun@D27mKQg!x5wI!l~lzD|`8dd{B znCZlm*3NTlE|#Ozg8|#Y!qWKPZw35wm~`Gt+(w~bBz5)tt%rliSYfx+Q8JqYSO2l`0*8K3M&SMBU;!PMC8{^1kPsx5VxBx9JC_{gPj&5K4PKZ!V z!ZjIj1KN?<8o$E;B{hRq&H1$DrtT9bW1B-XG_-+ISidzG<(}hDuSA%^3uu4oVk7m0$OIedyH|&) z-1!L=74@W9@Nack)x3;rt$3fmFZ$?&>Rz=1V&OTUzm@$wCQKKFG>uG0(0((UJTM_f z*Y`Vx*UVASvM0#7FBM?D4q^xWlWyh5#oEp4Uz(J-f2^qBx)y3u?Nmp+R#ZihrQxj# zZ)nCsu^gfe%8>p0_seL{iad0iM5cswIbb`4KYR^XATGh71RjKSV(+;`sqiMQfs=}w zjc@*t0mbIm*js=w7Al>k!9aN&7jy7u5wk6b!lLFEJ{6pS-Hr~Hq4+>itG9zuzSG3x zz!<(!I15ybr#%+LH(27GE>OvWg?~KS3V7H2r2j5Ik z&>kNPg)9rg_)xH3|((PCx~GEXkM5o1Mgj0=R@(8@C`xXijJfN z6xoy9iJA9~FiwrZ$*vm|rSb5>h`|W-U)j%}^Rtvx)j3%>`{@{{n($sv=8Vwkd^o$6 z@#8$61Bx6%bgYpk*9*M~qH+|r?x6g@|2h`WB_A}(tL=S_PZEz@G+A6&02!OXJAv;W zAVwH;K5Qv3SRe#8TSh-z+WMdxF z#WnL8acEvzx>Jx}2?emw8f?Tp><_i#Y`!*xj{xcbA)QM-woK}C#wu$NoCy(SJMNa% zy?uM=a_AAbrSnQF+USwR32~qK)9FEsi59bq2@Y;X zOE$GCRfy14w4_pV-*>K3hoLKSw=KjKglf!2j$5qhPAxZ8m{ z4k#6wS+-LH=o1WkmqJMqr=PgyFb@?NDer**pbQ%15ZGcdnR~F~Nl4k-x9C8P)~aYP zP7_A+YfeDcF2VihMwO?<3xvB%g4}D2S#al2!8ZrP-As>3-I?Z||J}PJC#NrP8pC(* z;9WKIZL~QF+GD6nY>zYx*>#D&>>;#|h<+k-@%xwUrX^VGfN5vh2YPdqs08(cS-%4X z6KsI*RcU`NMUlcg+b?&+-`CeXT`?a5@eYK4+QKwWCuRtkH1|V`8R9rmgK_;7q+y&` z=g;-eUc5+7^2_8GMsq~H%;7X%jZg*!cLw&9D}em-vMjqxJjnQjolnXj+=V@P zwL!kT)uOZb%C#N~G^ZhF+n7gT8XgpcY|Gx|gqsS6SuZ{w99JAHEjy4wFh0ZX^d3@` zp_b;EGY`|#$FO@pR2+BeFrj66CFD1b;LC4Wia>-S#vseYH*ldGW79Eo@XFyT9DGbg zty$*$?Bam;MFGk{UmY#u0Ase)1WI+$5HWFaGZ`>${Ln3(6~=O+l6D?z3T5L7pv0z0w-WU_&AA$8lD1|N3Fht|nI@7((pBrc(2 z>5EaQyZqxyL_}_lm~v%mRans{Cvzzeb&((!hUHh(+-SRiCT>+J79>1sFxn71Q||NX zqxvtL=CBupzmU`eS+!09{|czT+@1`)p@l>R&;qog1>gmFSx+9OlTnxd192#wT0(^X z^yw2)6|SiH7<&=&q&hro{TUL`y|%`e-MMA_9UloP4k%k)S=kxT)_XSFKIk(oBqbx~ zAaCJ;pC6mK^=U7l)w$_uD@cm4$_cnK`|`^~{6pyAT1)$$99t%8Z5qaK$H( zy#IcPEJ9!cH4Xw#nXINL9BSpSUA>yq>^TRmAgr`*p{Z_ui68>@T7q&eJ{B4I9;M$( zpxvt4qw4DS@vQOxVm0n@lSyu1w%~pl#PJ{7e<~_7HZ1V0h?CfvezYh=TK&oo$A%HHT7vrVd z10F1JjxX&`*;vN~tV%s8QCOe-19MQts2)9v`s6K!s9=M1N(G^T5Ch3q%(xGgg9MTz z?g8KTX}Tb+@gNRB87SALJ>bVRV`HZ7)iWaiDst_hLG^tnThSa~S41|DW{H9v@GEL2 z2xLmSPO!L7nN)+{ora8w7P?YWw{bw=cP>3@viky}f${V6{?XA!moH14Tras1vSwho zGcU6sAFFuTnpQuge%c8exGrb1jd{n8 z(XU@si;9r*Ff@mFY87j{O;{=}cGwoNTGLLct%;er5H0!#%L?+sal-!{dE0_O+D@)# zT7Y2yF4|jV`Rz>05S!F?jYx6421R{*y4SAIfU=CmEH&0{Rm>vp1drd;%uLI0ua)jL z=3ToQxCqlIz#At}g5h!DB6dDbd<#7F1EL(h4y1OUy9Aknb+T*fp9i2Aha(mn9qoPV z*6H!^3%S41rqPj5q?_XF*Y1f?wV>D=-2r$CsOc;^N-M_feF~L$(vajDz)p%;Ajb;w z!2;(8=&>7^9ec2c?U&APJ(58 zitHAqb_U=AN`Ma_WrCXlh5dCS`lhqMxujZ%=XK$k3;S7s;1FK@`<<2a^uhq(18Q{I z-nG=)&}}H=vC>mhV+FzCq5)pAuHpZIi~!M2WPW(3KXdtcFQfyC zA5EH*U=|Dy!Q%?0)fh5qMV^=E9L^;Y5Os!B>_z^8eygZ$i$J|v?~zE9vNP7*Zmu|UY%b6gz- z&3jx7*j{}@q_($5(-4Ku>m#In?bcHz4K`F(o`=R&L9&7UmulJBRf(et15{*ZbYsZj zxCF1=7DF;yaY)G0PZkKKIiZvTgh(9VDa3fGTZBF~G-P7lh8nW|9gB;Jg2Ii)y?1bv zfzG@e888nV(LH~DFPBhQ{*IkH{aIyyqMD&xYB=$+)2k=+A#bSs)$cqfQx1GI+SSk; z!Xk6o5di>C6nr2iKueb|FQD%1yp-T8XRo8-hX0n5;GUD4dk@Xin5gcF{Cl?vJ%q8b zI%Tqcx%d_e9_UsrF>VgCdUdpY5*=KgW+vfKjcfBO!SCp)^id_$0enn}(7b<+ve6_+ zcnEpARSPTB<3#)GNjThnDj*m76hjndi@$%zlg6W(nwLnV7};xixAXl=Sq-=Nf8sI4 zfX5KfmX!pCFh}yd#YV?j0TP=7NCIqoKb`x?*!b6>otZ1RN>*0@3ZNsB0$~6dmC!`6 zONlDWKgI=O3e7I5w)gMnu!d?IcW+OQg=oH2>t6J9S@-rRN4!ChwE^1I{wS29sSJ(yO6vN(a`wWC9g{AJCcVM8#Kxqh|TK+X(+t3}dF zP7V&QAB|XPOc)d&=A7U1qu>M7q)^@$02c^*DPWXyOIRxJ$f;xYcBUO(&CSgW3=E>S z7W{1?_g@HR1mtOH9!a{y^r0IOzOz$fh5RjU{Rz4%GFc;@v+~KYdhrUu9clM{R`01; zz2V0;|A$dNl-lJ=v>W*NDsOXb6W}?~l(>$v+fZ@5)boskwrGb|c2i^4j#=_jhr^GO z`iW1w9EonF(){W*{mGw|)2SR;i|@Y-8>o*KK|+R4hP4;# z<`M1crx*B+AdeqCS}iZL{!Cw-7rW2aM5lw6c<795Yz`I{l&v&Ik5}Di^C30r3yr}6 zusozwIcP$vS1pA@HWRWUh-;$i(yZ5}$r zHH?|A&v~e*#Be~w+XiGhREIeVyIN#eZWf@)TWbwvVz?^+-xb<~tskgHa*pZK92#vw z3sWW;9vrO5@T7d})yFwRLd2di+c?Ww#q!nu>HQ=K5k;LR6di^qo%P-kN_poSPm;rm zIIG9p! z%#8Ds4~wxJ^<6U)(P_c=@5|uKdSp9qT}w+Xnzc?9{@vl>??G-(n^g5E9vn6a8tNq<1$1D)WsFaEPUL(L-k>ln5HA0bb% z_}p~e;>oUbqw;+pEXRM$&AGU^AkYaL8C>aL^TB|=%ogH8uOY;FHLJF^7L=CvumDnM zIHz|WXO9pr{;e#^9CiPRdLxbf9Mg$N^cgqn!-X&;L+j^lvDQdyOF#i#0hkp~%EV69 z_aU5JG#*Dk^r`IOfXuFR~(jeJNInDlUss5 zagB);#B#Uzy+Yv{MCnsr4V9sQfJ;~`B$13^)n;!mXmlt9d;>-H+Q!Dc)LZvWBgrA! zq9B7Z*hhf>RaM-(clTprbxw9oA66`&DhqsFznFJjKlYh-Vcq4NpeMV}XC=e@@toC48t`u082aJxnzCwG0h)A4hZ*M$HDoFVB8J8A$dQqw{Zripxp5gvJqvH&O zL+}GFqMH{`$US`Z>QA62)h25dx0Wgl@;QS_D*~hh>A!UCp@`iN`$k4mO88Ss$Sc>- zA|L@IPf9C&UoA0>?G1S>(WCUj5;4j~(-Agf2z?D85A6WaXLg>Mb{7eV8BV}vWQn%6 zT+p#Ff15=?u1{uh~ymeL{80 zA*ho)!$zPm#wE|rs)T!tGdAz*J9K*CHVqpzq?8mf$;|jtqgtkmc@6>|Ced&x&e_y_ z5EyhrW8Xs~os(b*{}Dwa_r*qbBzoXbKktK1AVT-4#b;i~wB>)$-Z z4kcyVQRx%S#a{b(cqlk%ckR+(U~d`3;13;Jl-%{Jh#d-i0NzaU?c<7NzEh*m_fmRr zR6~P{dh03-{xDee`uCk20(XRrJAs)#GuuNRN_T`Uq}AZUtJTQ<_)*qSiKOv*ZxglU zLwENzh?!nsv@uAo&}yTuW+V4^m8{v2@8rlv>*G1Jv%H-hL!(~ncu(j?O(*8ArTWD{OUSnsm#nw%m?nRZgoBV zpae$)L@F;Y%r(dunEKhS?#7Kh+f#OK+@NLkM#7l0Q>D zlqArp>go-fHs$8z%zXcDl4}`kaArew5;|RMcjHsM!!`MVqlX4*0^a7B&@Bb}`rc&O zCFBit2KLpVNEPrj_ns>Yg@7+j2nI@ZHTLUr|(+ zj$p!YQ{d2dh8+ecd;uHn+LV%+`P)<;m~EPO7*Z3q!r>8?LlI1iXet4n4%FwEjG}*i z`g9Uz(wBbyu*-=*{R-h6HyIxkEe1#3*8ZBt#tBfx{=SyEc*I*wTe~|ucgefoM^sQi zT*vaxvCp-h$XYNcLCk;xdXR-r{4B`B@W1iA3VTH)NjR5;B_td-7+7V30j3?+lW;a? zhVkxD_M#8TfA$R4nBobeo*9f4}l3BufGW7EG%Cp3Jmf_~ljNnBio3 zX3+$FZ2}O7mOQwS^dKX{7W^KJ_J}!4-Bu$Y79lY)R6pLdv}|)LL#)Qn`3dd#oKGcm z^z@R_(u1yx3g`Y~J?PT}G8 z8Cs<+(DN%T)4LOBrPyJqR-+DMGn^>eZQBO=`kLS(2fPh03+tFT?zg?YgJ00@)V7cW zJ6|gXw|Gs%T1rYx5MJcSS6sxo@p*!jhJ?UXmv+;*v@Vb@kV9kyU$yeb5!jKvVO;{sd~WAMefO2c5ip(J=q(S`Y(L=##ntc(ZQ9~#7gyIi zopIG+{NV760s}!7!{|*RVz-piN!8DTs50S6(#LgL+Xn9}wjg zxhM!B>*8EA*4OL(+L4W7ho9~)aIzrE_g>C47J&x;r?xMF#(MACCbJ@QGGrz#TLoI_1Xy|NHHI?d!Vs-c8?;qscpiKM2wX(?{7Jba~T@*Nvjo)R8;`;^%LhBs#_` zTI7hYl(3!T>l7%Ew`x*J@iQ@apy3M*&rz>gz;=`(N8|A{X~Rq7QWu*qDj4+w;h?#> z8F&`$uyw7il32+IS_X;ni_$CEq+9xmh(cK7Lk}@)B^3K;G;-g2;<${@c-z+FfVuEEV%ex`^?irO3E4!5I%z|DYr#FPU1fG6h<;(L&w_|lzj=~VQS_}t;~Dp% z@hR9(ibvycHSz!_0J&R$sh+cxbSGV3Lb{EB3XaIox`7s}BO%y>;w~&Kg!AAFLN91q zvf1omXhGBw-i!&NhLz4f^nZieg~quF8?>dQbgH_<#B-*%eO5WKwVAwOMoCE)pj?Bx zu~@jABL|ZgV77x%L|jg87KJG;u_$(iQ|>Q{(a`pcT%|&dMn$K)J;VS6ys%N0qv(O-n#y zq9F^>2^%+q1Hg5qUq3qr-!7*{m@W`{oJPjxJl{U$Fh<( z-0X_QE<=!Pgn~t2pH?}dU-j~5spWHDZ1-b}khPig$MF5t#WQVPT@rFkOrL6CqCitk zJEnr{9sE@y;2N28&_eqZRUIf41z#rH#7C%|z&0H?Z~!UM))OJ*o^DDhGSNazEQy0f zUtbqrkSc5^QW&*cKra`3@S1rYT|Wqa|ICEVyI~pSYL2s+c~1p zjeVgbOF8vwIk7KOMvVQ5-*<>4_9!h+YA8^cVqg4ySONwI2f;9d=70X&6^t3yOZL3~ zxR-^M<%qs6HneRnK7c|1Z%pL*+5~zSLU&PzYp#CjxDHX~rLi2lCkL<=Mi+~2EYn5}bm&kM zk_Ze$5J52)d^gB;TsVZFD}F2-!aSNSk+i82#|=I2%Ql?cx)})ou`3lefU2r0WNNIb z289evW-xFxBHVvFZ<$=IXE?@z@A|JZZMa`$1TF!L&_#&{V<3+74nQH8I|^~u5P@-V z^#Xr%@M$bKX?8+eNLB`8(Js-=l1+=zlAUOMD7b$gb2$3eE{V{5w3lHmH!*MZAzh~^cFtBqHKF$){qb1vQrPcSVEM?n{#*Bu zt0d70aiAgKJhCwA^QncGRx|BLftHwZ1P-7!6ZZpA!V@VROi@Uqyt#$tjJ_M^OiC}P z*N4t8Xb%}$Jo|}^{s?~)>Rqs6&1N(XcfFDcqhfyIs==l(HQ44xdpuOZ^FNeWyesi}MfrlY*nbc7gozF1UA65vVlRL z`t$e^Dr(xEx;kM+#f96mm(q9a2y)uQ%q6Z`s)&$zthUwE4ObRt%pe<0)?B}#O&m4` zlyGH^!Xd&xuw1MdJoyAg6vEFckcbf7Gb1w{RMAkiB_DXf>Rg)amFo!rdclkpYu=QP zoCEb02T1nw#}6^rBfOsE>4~?{_ye9I^}5Xo49Q?Td(h%W7TepjAwn{ynK(sWI*%14 zGfOxtJEf%T``D;HU(?6?p2iXsoOCS6!4!;9hxSy=4!F8D*3+Hd?Rx?N4~*q?ZsI7i2|qtS7Q+h8$Nykiy$4PKnnbZEc_jiSv$d1Wks?w; z`+(&k^!-4>go;h^yy3}e;zMcx5In~r&|X%d^tD(hNnzv)vI}_)!rMI4D`cT1=w-GY zgzBjrIWaLYU|Xm$aG#K~E+(>J-0T@J--LjVcX{Ls-D`OVGE zZBnr23j5@AFIsn$Q6mK)xZSND*QBlk@E^F#Qt9UA2B#QM0~QVqqm)0Mr@8&bXxAG- z!2{HPBdzj917s8x?L02YIhbR{h+j@vL_}y?a1!YI58u9xV!{AI=(R+jHu5i#md5nJ z8~Ed&+U6mgVSu&Qf2=v6`0!K$VMgmWJOgMUCZ@iw<1Jj=G$ z3g@DtK%t-8XR1X~?ae$Gy}XWgA{{Ofo}-3_>K6xIJPTY0g@IzpXbJg%b`Oo~U1$a- z0d$%CXyeK8Xys9Gp|-*VZ?}^t`_eV2&>*?85>WbZWJ3?P4<{zdeRRgd6f8lN{CQs* zcZ?L}ysU2(bvFVU)R1NAByp%Mf|0=A>O+*nAyecbQ6*h0f$B0)X1s7b%kodAP%#EY zin)?eGKGGjF!^pA|LZ^iaOrnAYg_DyvC>fAZuViEKZc;HbBQFr2P|G+{T5g&S1T+j zEIbCeChk0JO3M=uwHXKb+BVO4w0Bvj-$pPaL;8VuRy=zcA^{U=nnzHC!#Q^n3vU*3 z^~<~zYQBvrfplg3!Egi)Ff2~5tpr@94b6Jzp)|!suh6%13O!1&Uc^crZm1lMWj{)H&4cpe~H|g8LDTTj-<)=Xf%`~SiU-b6Qu-c(SkXKZ^>$rc$ zFCmiV%9SfM4Q$UgOPFK08>0s8*-Cr`Og30UfXuy$c}7BuH74%%_PgQGtY69r-gYec zgJGRxwJ*61<1h|bdfRgT2w$2u%J1EKy9W2re*2 zhw>Jj%f3|Ak7#hJ1{}4r)o~y2$@u>t?*DB<55TSvce^sAHcW7ZTt`!&gyF7?an;gl z1!Vh(#KW7b2#O)hlsP4TBb+R)*SIz%uyjBYZIKSiTAsbLO7Nvr6e!jn!GhPeqGjD% ziZbxrwI}XOO#B2-8zz{+1V(d+W{o^5bME>e0xG#p3E^1q$rLa#>Wzb6L#N3sor9yg zk~cgkIVOaZH)7ip(~2)GPfDn$R4q^3FjR1V&Ak>9_@KP}%gEDTsFI}opIqpG(Y{5R zXiwk;7JR2z2yVFL`SYW~v%+Fx2g~jqP7h_-kRTxJl_%YUtc!3O5gv~A6&TBZEiOXE z5>-*TwH)>eZ&%)RKsUn>L$-TI@JM{|Cf;uoT;K5V8(d<>88^a+b0i}i0DgWjC0K7& z1twM6x|*+P9;oN!e(IheLNg!ruH%(4Q=m3lUu?Wa1Nv2r&Vt)elb-kYkFc``THo}@ zQx!S6UO1Th`g|Z%zcqr(;3Q(S5%YxA$BtWv-Fb6K$yY}QW$hA@l8g;rY2J%+ivCRg z?Cs#JxnR2x{g)3dlQJsaL(V&UeYPu+_tGv;JiFrH?#|pv7n6TN)X9>SIOVkGgCJ>I z1LQx6OW5eoPZJvF1g;3wLeA*-LhChlC){@snIaW2Ce$%fcJ%bD-Ymo>lg3Iet}Wv0 z=N^0`sx`;zb1~{9N6K)@SXx>&Md-E+-7vyX@@mR!n=-?WB(T)cPDC8xlhH2A$~pi7dB>#xgH%Dt|}|{F8#?Q@YHFpD1UQ-&eLM{wF5k7rc=M9sZ>tuztXE_ zzef8n-~av*4nAj0z<_jx%!nmo{_~&SO-+%Td4K{zRYQAFRa3KW%&yB-sd(r*8f%uR zzhKDd+fvcWEXi$lg`3pvB!)-!&X8gJ=6X(z@Eai5bj&2^B1|c`YOQZ%?y-c@p zM!TswBzG}Jg^cPeVtE$hQLI#~bUk*=!7WrVS6scEBfBc!vD8+izUpKiP7O4CpmVzr zO+)QxS<*!Q+ehtHJ*nv+#`xo%6%l)dBAPfwXoYz)8~LcO(eZ2@ESH=*@$!TOzl7R3 zOJAEeIj#0jR_N%6dNbSBMT{7Koc?ke$2LVz=<&famPj_uq4X7&NRgXFhVjR)Kiyql z9dnD!J0{r|ajw=sMX!~XpNIS?ok(0bNZWGu6oxg1owni|`st@@uK4uWmlF!yqSFSV zpW8{lhWk4>Z$C2ABe(XRGUe>i6xBWw?PNq@svd1|c&U|BCMt{3$!jW8E5X@P!)6D+ z)eu`hF?(i*Uy-y}p47OD66=9ziP(&c#zJ-(ytjRZ9+vUzRl}Xbf0H`%nF~Vb-QDd= z0?w^G7UBKH{EbdypPW0b5!0IG-pXk#cyVXS>zVv~prUC|`oV^HKtoRe7S1Ub#vTqD zbFKWo0`qu%Gj9u=uwflirkz!WAazZ+k=d{G6{U%0eW#6?wdg`^LFnJO`>0DgQEKCh z%HW#mv{$9&_cFBKJ=KjQg%z+9O@|#<47DMVr zWMNFdhR7o!RbunElD2OQ#J1YHT-ZdJ`?&V+t7qtYc*so9MU%b| zBt-v{{FgB<{4(xFWh|2Z43P}pFUG!wb5(4YSSn$E8SGRH+=qe=45H&HZKeb#2V0)O zxEU?CNS8umznx_@O7y4C((|4jpXR%tE;UXtZ0L?_8=!*=+{wcOQdK3AF%nhCx~`6n zx36y)wRyR4`{~@%q05!eva&*#4*8)1JzZSM7#8fVO>c58`m?c6_ZZi~Xk~ig&3(LP z&9Sl3*8{~gA6$Fnwb4TARA+m?w_U|fN4oD0xl-VZbt{@IzpO4#6#*(-gkF;y|i0#_R!UWITC1J1?SR*CMH5Y{H!)K=$T z1g^~q3>lCXi@Qw3%V5>})o*4EsMOWfwRuFxq1SL{Zkw!aXjoW33~hXVu*L1LuGZb7 z=_8$JfXgmV&Crv>9gQI)n6C2@BLFXu36=3Rxbpz_$WkpT6USKAkNRsWi|cehW&&HQ!b#gYO+Tc`B_ z!>Oa~Hx&A`j9R^=Q^zd|W7jpFX7SnvvpLks7xKT^TOyYC2VdL{O1|(qRqu zi+LTnMyA=4zK)h*(cGzZ7KjV^r&fD0K=^Ln15oZkq*vxw7=}_GDWz zFUZk2n8?V2BeW^Rcfp66mg&4gY~T&ZX0n^IlLQXNvozv9;*P(H{Vgii)&j}5rDnJ^NC8IMz-~{ar zbmM3ZvC{`aTK7>+w7Khu3K_mnx(W4rs~~!PXwEkGBG)nzH8}`PbU}?2-cW z(Gvl;1pDgR&14Q%+rQ(r*1yJ*PE3)F$v4%ZvB=Ej$>$i^C?m@pe2#u`In4A|ypFUEl=-%r$mvWlu zg!X`+{;NX~{H4lkonJ%!G%A{|95Z3D{eT(19H$O{-Yr8?Kvjj7TSlvh4cepr-}Vza zVxO^Ok&BOPz~R=yn$X?x?tv&4QMUW2wvYA2NGVjNe^zft-%Ic(xO3?VbegCgx4oec zOH1S59nYNBtq)c|F`X3aGq-rRZoR3z1mw|wr$Q!%)i z^!WUywF5WT5?gpUvl}ZI>@3;?`iX z+esmr@21#0jcn?24R|<}74q`rv%g-+_hbz@>KCw^*}ALPfV?}kr{5{PUTx_;J3(&~ zi}#IB?b-^)cZAcKWG|Vp-fl|vaI7vcYIR@g3S6Ul7_a@pWaw64M%2)o#@w^jBZWeD z03~MCpL&&>94}S7STN_DrvLPHi(ki&3Q6ycqxY_ojX@t(_U=XJd{JD`P+z&L*<JBm`7&FmG?mlr|+i#LaiEq+x46q@~7c!?C5{1Gi-y`b4UtcNcVgNy7njQS)bYjACoFJ@k-gsJEK z^t7&7xDQHjs|ZP%YCYMC#sKpJX&g(j*|c4Yy$twbwrpD-Gn%eFg*1VH24&R- z_Py~%t7xvn;7s+*!1c9fE3+HF?@%m$1p>9(1aTk{Q;ko5wx!h-T-dcGO}<-hRgn64 zc<=3?GvO@=S-nDRc4NQ3Ju@(Q8z6}+!opx=Vk@om!sXocBkbubP7MhHX>X^74AfQ= z&L#p^31V@FgvSVWzz9_~#E_o04)q5W;?H zZoCpAxH&5PcP6;6>TL4flbLCE$DRT0H(SjzL}e)#p=UpP&MPmisKT{n z`=1oh9HDEYX4~bza@F%|#|f1i7gCBnzTEqvdh6NuEoWJ7@AGE-$iA@H`95>@o3d>a z-2M#wmep&^uFIL%0Hlx$*dbFvHcjsZw{35hZad;!Gk8f~pE>ja3McHEhd$zOB3>nV zQ`!3iwxk6$I{cMTcd1mMon?B;49N&RjE2rRaD!0oy=@+$P0l^%jTl!w&sN7~v&ay6 zfn3H#4_ACpr+G3;bdT(Hz~W z_fcwTPi?{35A9n!13KkLOQ4}Tin#rL+Ke0Ku5vdI{2h+xEhm0HijA77#t4r=$Qa+Be6az`3Vm3mu`K-b=c8eO{(J zfak?Yf#jV_kHf@w?~X5G6`v-@ZEKIgIHNyN`_%MvoAn0E-tX@{cm|8ir|c`L)Alc) z%bhc~`ncoEFl#__b{TH8*V^5bsNLrw8rf_S5fPb8g#wHMo^9YXOP-Rzeocw=6DB5o z;M}3&pTvrhLiG{|5eRCR&t?BLTfUhbV?61B9(|atNnrO0ZY7m`Qc_Z%lfp3t3kyTG zo%jor2v%Dsz>&d-#hk%z_Zqw*_Qf8VIPjdMz_u#`?PT1FdJ|Bhe`3mjiF#HAb4l_N zH$~^wgTp%yZoF1{gC(ADg~suwhlDbXdeE%B@ZFV9h~wg-qL@yhuIi`r$+o;+PYhDT zr;lmf>c7Ay`S9~p>ltpAgEkzND9lIie|xDnpt){Ob*iwCdZZlU3QO`)f5(R_@+Oi` z%<4zICdh%@@VxGKECr>?quht;b<>gsAX`i_7R(he-c|Z+#$}k(TWyG=ipUb3ORw^4KMc>}vA>-00{cuA+lETCZqfG5J zp|`(ZUWNfdYC@$v86|}QV zx;7-Ncm>8I4xdgXS5!;^b|6TqMqz0<&yn9jYt^emd#np+m)n8!bQK7J#3vN2Ycx}7TQ>qDxxE1vC zVAatKy!9aOHTR{++HNqv^O97|ASoyj$%gN`Hg|phv#IPy#0>Gi!6;&OBy&u@@jX_m zYs_b&$kmy=LLmqcD!TK&lP`P^BrSIdp8I?489f#uy|o+I-TWgON3p81vU{+GJ|>l1 z&VN&1Vi0`>(w{t~8eT`t1A+{sHg{gpy%Ui>C3%~Wm53oZ@_bOJWu-SIQWf+3lDdXT{=bQ{@DW|Yhr2)T~f(vC1FSC z$OHntZOH5a(O4%o2VOIWM??+3h0|Z|uyd6*YOQNX_Fa2Q^mVmN#K#)3{H6?YLcOw& z7#N&`wfE~=IWL#)()&_uo5fE*tMs=&HTyDcO8l_iWM3|O!r1<8*Z-aVP>zwJ5$j>* zR|(bMXi;*y-y>qrWsTtVxNyFfJuH!*UsoF2G^kS_EF=H)>AmEK+x`@X=P;3o#x^9F zJdo8h0=;omOAX^ptXluh{t&L@vx%LECE{NZRIF^jNuQ8BZZl%wzc5cEaijhwP9yEs zN@0@cKYR;3w$j9nc;TT;ZJVztWomJN4(zTJ4i9qLMW^welEqc7l5~{(0rED#0jY7j2v)cV?G*z!eh74^8>XLv=xHn#sS< zN-5Fy05b9?D`m83x58XQ=KmIM+Tgl09De`%+`OvXfbNKmtXoSkMgSyoT)ng?&h&4d z`MVh7t&o`Ozb;E#DxvrW30L}znihnn+!)yMYm`r#IN==o^G_B9kJHqyl9qUwH7G}M7Yql`N-U>`TbjrbvsDvWz0z*vU55NLezH zHH<9`Gxlv5%>3SiI_Gqp=Xt)@^}DX`b$y?IoO7O;&wM_g`@Y}r*LL3zFDaedxQ=rj z0)f~lfBwv61Y*?`0$|SH z>@sz5u(6jC7Phf8v~qB~VJURY`i2v}f)_5KZ>FZ{@bkYTR={;`hDNDDDn;8}Fw(Wx|xU{t>p>^w>QcGuO>iD}yVJ1zz7uoebP?Jd^oIEymKU-7VLeZ_xjn z8fjnG8Ih_jxB0fM54|*LQM_mW_9LI#nSBv&Klh#b_TXvY?i8=Y*smQjs&SX3PHc1F zCmyWq#Okiw`Bwi^=eZ);&(6nxpigDaZy7zAuoW2a+?Om77 z;nVAp{5ZuHS(frTnf<43c?Rd=V|)MNl_!k8theNn-UCVJ(l;)sLJ9-s%iH zp4VBs(X{?#M@tiazm7Z($NqL+xK8!;`W_=~L#vXtfvZ*sh$&AG-Pq2hry_7hAfMCv z#iz2JIoD6wcS>=vzE8dC-uyO4ar1V&F@NHV$4)^HTi^UKIL%kx`sh_q&E|%K+x%9) z&vQyAj0zD7u7CZ^@jmITOTTll$M`zj59THt|LjN~=2(em#%FzcpYnz9HIG~jyHCtE-;={fTfE#-jgM{LvQBYLZ4HkN!L0S@jWva$fkh5yTqRr{;m+!c^&^e=TXZ`0^*YF*`j5{-Bk3e`KttJROIQk&HU#3R$Sg7zIO8tD=GRUzGBeW03#`4(v;pPRXA+oKAn(`$)IRigo~LB zeikvg7|)p1h@y37ZEG0+fcSF8cRk~8$|`;##^0i?@3I+x5eiSc80!gf_~iec4?Ok# zX6~Z1_ubkK;$VOYfK0B2RWob`4%X zM!X#E@J&8ZCyPhK_zO9?aOfcp$AtJ=)?|#>wN1<=x^v$to;DBWKV(Lx(>=b_3c4E5 zsg20f!AGy%&w5@ildh_SoU9Yn$-Ftc0%3Dibl#W+A@R1iDkLZnDTXC&u4F-OS7Mm+*(W>%oFiFPNzw@JFwHi+kN8fbdE=4-TKNLIVYY~=IRq3whSvVHHD^6F}h&jmCp zxi(r+wK|?8TsUW^NnfM8>Rh~fqFS!hOlOG?yRd!&DJLgKNiAEQMRxj)luL|K7>~!a zA^mBn6~@Q#KpmlY|JH0{^Wy5>-VGgnHIXFOO`M|Vk$G@kWKHl0J8u8n1rn8)HsUii z*z#n@(Nhu+hxiNA5Qsyo2MQ1fi^F<2wRW-vrPcn4RU-@fYR6rng6XT=QuMj;u(NV} zB15NJ?{DJ9o-UlJvJU<9m|L3UyD5LV%TMY2O!om)j$O|M?r*JO87V6!hTGc-Nw|Ke zc^f)yUZ6yUs8KyVnsXaJY*piU&d{(^{y^9}vcODox~KM4_78#w4xGzqzcpS(r%?)# zyF0b}uQ#3cX?3hV-FbJ&sp|Flrr<63-snhtNu$1-B2w*PDvERJ)Ow9?W*R~{-CH~N z4Sjn5RAW2hN|YCY9dX6qu;hN68`Xd|7F0-|AFjRi`jbY%SYVj6^UD`6VqMRky+2#T zc!3cSr!rs`lnN9q(W81>J0qhRex7%5S^?(=AReX@sR-`BS$ z;qL17!ub=I8P7?WWBSURV=hzh!?XH`Rjb70@M#t#+m4MEHIv`dO{BxOx48}H!$eXK zgh}W#nLI3Kqsr}Y-mE2aaHDu@$E}M3x`*bq`sy_d5|wBf$?jF|cFu(HOA>E~wo5!q z5!)MDRfRW!+tg_%O${J)gL&>tINYjEv%Zs6plJE<|qb z`rXcYMy^9X#mti>MGx;La&%f+Np;KA#UC0eWUsrM_q8~%&XFP<(RerXOyj~6^0oD> zC^DAP`(Ef-7(=j+9QKef!S6(Cm^B59S+ow~k^)xIcf;bpID2sP5*>GXsQq38{6EpB zgRLC0?ruE6r{LV?LWBjcW*o&SjO*J&NSf{2U@|?@$s1m_ZKH*mW_|(t?yvVZauv)H zhNJ6gV*3eubPt8;54Gj%)Hf#T#6(KHBa^yfsjzeiyF2ev4Li;hH$1XAF3xSo!&tc_ z!z?SpTulnQc6I=6NU5+yDd0Re;>zNUQ-hQ|NBs;EbaRd+PKEg67M`FfT9FG)uQZ@R zp*cmMeOSv|=CfhPkzIq4?T7Qbd=It0{cvY(JXKX08D)P2Rc&TbytYF#*D2Bb%a<>8 zERNxNxlaB(NNu!wf@bH?0ID#T?=_D2)@Dm9&Y?d*eU@B6y4}~lNfnsQpl=F#ut5V-kugi{1tJ+<)we+mmpi3|2k9y? zKe^VK%CeW)=SzrqwdA{$l&{9EQo!g?iT!n?2)mBNJy0(;Lr zb_hG%F*o$`Itk-bEN7ETPRb3n3a;pJIG?R9z&CaGo2*n0try!nCl@899Lr0>5e*m0 zLT~?b_1VB{M7MODTw{s8Y3BtTc}%|ev0dW|gnE}A58|-62|jcax72%!#vv%fRBxuW z4w1yO?ei&ld2<8l)mAkTrBEyl+$ZbbH?y$xoPOcM>oNVlR*6i=rL@y&&h;1!X6UZR zRC@R%sXpFiymzoAOQSz@oLjrf9uqvWB5!smH%Q;rEado&w6wJS7hi3DC8lTdVKtWa z8ATgitnvXD3G_?Ze>{e|bHXTR_3G86+pRC2Pj{tM1gZRAK16O?w+)79&@XNOZJ z8x43RY&u}s+cjvJ%+C=~lnwj?cQH`ry)B~m&skbg)q-79WyfDv$8K?r!0}9-YP@S8 zPwCWdl5a(pkf5TE3b7#0s~a0fU*J+t(shA}egJdxRQ>q)cz&2Adyia-w6fpWg_Veb zYlCZ;5f8rf1Q{ef7y6vhs81feo_kREwrpWm{dN_7d4!jH0%6w*#Ix@O?z0~svbJPc zP|B4((%fgKpb~AG+oql?=d#72i+CeL?uEuy#1&o(@$(GyaRR%$bT#82G;g!9GyYy- zzO2jm>&188b^*$~-1UF@frnmfl=1`N)HX_iCxw7|WH|GI#bbJ;1R#XnM`=^d-FORO z$8{*96BS*GueyXETCYn8m-3rr7wKhvG&8d2;FO+s3WtkoD-7!s6n&;xP-p66X5LhD zOIDlI4=A;mXC)4!25xbx)BH@AH(M9KNC_y5E~3h(XnG#KCi~$Pi}3BM?c4qceI{O- z|Kstnb(?MvNkL#I3 z&HKaGU84xK*V@-@cCekoyS-#Al6St0@wFFAUyFjTJ@d=sPw^n36AE7)4Zrfmhy7&g z@VcAE*Uf$1+TAHGXE)WpPMf+MGorfY9b4O7e!FMls~eQ_egFEDE2c{N;0_5YTxPdT@>D8N5c>s(rcf>HNA_T3QQN8c$OR^WLUkmLFmPOJ?}|!dp-%99PZ)jGcnN%xF<|@UK+r% zm8W>lzGJm(Ufhq#R?<@(#<=n9K+)_xv&wwuii^$|S_r3zcKGDjDg-b+WeJLWw#}o$ z>&4ZNAt@tyr(*G2oh&tT3-`5&q?Gwo)|C0?@!w4hKg*kEUks&s6s|RK#-u8E9H3H( z=L`BsO293jGZ&WbxkPCX@3wemszS+q;tSTJ*fV&Jh64$D2RG)f45v*PL2s^Zrx(Z@ zWqQuGd`kArzgh7jWRB4N&8uerWzOBDXrq$*6<@ww)T7si>vM^b0yc5mshu*o^z}#T zXOEtpm$h-C(z6re)x209e3;I+1TAX$fvmp9Vcq(nP*QY=aj2_#Zmp610W?~B&Ym;52Oyq_fD4;>sC?^GB2;^ixR!hMu~Z^4 zytBVB%4v1x4L5Tut2RC7D!b(IqQHJOdbLTD>e{4Rl+MDr9uZPb_j74M>@l~g67wsA z%|`U@15XG}En!+(H(EvPC<((akc{#WwPSSu;XI@A&yRVKRv&K5NlAIqp0n%Pq|RNfu>5Y`UFN5Mv$OhPXszBH)B0StOsjQ<ot_s z$yN4mW(|WCC+9Tk;$3I=vdExcA0Lru#PvQ(J1kC zLmfj?PdwGIAL1`I(XlSZIKJyeX3V;0mCZugC{^P0#QPCsxYzml;r5vQc^>n*S#7Sl zR7vMe`~tzT%^HcWr;%zUm&euQ>3g3X?rY779~uWz+3HTQbleTgl6Ve9eTZGlLlz!e z&%}B!F`vtN?xl7Q*Kswh;MbWgmk(Vpd)j$OgNCl>b)R52ckFjE6x+ljGY}OdP)8#U zC94zI3#S9cENF3UitElsz?aiJLRFV`D_2hZ(&i$9q6V(?N>h4siVc@RN=s6irT$y~LgCn!9ZB*Jb#JDPWql*i7m~46L=LVOf z^Mc-F0ZW4GeIhC`207Agc&>lzQq^NK3^j9{KfmspQ}|bYOh!<*bf7Ay(`pY&ZV+A~ z(%#i|e7*2aqf0#cD{jt>#(XoUx0LvcdsMp2S`nlwCDS9m zO%(k(2Z1+>V%gg_0xE1>A87j$sRVMb3{Y3XQLU54h%rHLI-02>c?8`3pKXW$u8pwp!`D&Q83rX^yl+psV6{0|s95-C|ulbYSd-)Dtw5dX_3wJT-wXc=-*< z?IZ__?`i1UL`m?R+cA+5xq>XfJ{7NSI>0h*I6n~C@9w`SJWFkCEBtdcHG zD!7m4w`t!}Iwj?Hm}u*v0*YS|4s6g_oZBBXuGB_T)TplH#H{$xOs#Zd=T=+F%jVMd zx2GS|s@Ex_@)Iq9lDcC)Y9zfQ;P_3PK9&*im!TD$Qjt283VQ_%4Z zNr~?9wLF=}=1puaG^tuMYtIO{HtMCf-Mr=}^)8~TkUpv@;nHztC7I?69OuRSU;0J8 zO9Ji#wJzptTxX)zxN`Mw?ATOGi-Vq#G~R$KZah?Jl;!ZiWy@5DrGkPERaUG!uU6bY zoNVP(f=@TC8K<(m!FqmSpZ*YVhNM2*)WqefL*2L@`x3`VBshc#9g zd>R^?8~3z3#pqr7G+d!_Q>xN4gB`C9S`LP}7%NkfH}rM=e3>>yUgHzOr(&W1zsCpm zqwc5{W19Jg0*BQ+M()glhUO`Qoc~N^*$_W_2m~_KDfVB0<|Ue#3Im_zT8XCUdl$wg zpqSO<{0miMgcucq=6z3ZU5sWX1K~)meIwwQI4H2iAq zG44Z~UyI`^Nh&O~!%H&JsEwX|RFUeuzW0qTYtYn*elktYh)BQR#rrM>-saSh`_!-p zC189ct8o5@mPy!;{#vh=fs`6*3lsZ|D-Y{e%|{uQ*!$Awyo2~sFlDdq{i+nr8I?{n zzowVX^ffhDw1r-B>`jH9_~g8_OvR8)nlSl(Vra^Wwfa)Z1XWH{>0oOPnTbUv;DZ?2n{y@h%-@WhaGw;t-zeON8+#6Cj zU$%FB-OAa1WzU9mlebnA37d(Ax8rMEraSJ~7fxmHo3F-h)W2Z|)2L!1`~$zCGI#b^ zSYIJ6Blp}BePz^qI{`V+?aj)Z@Xwde$D8Xq=^D5)E=w2fI!PL&+pFGLvr#3>)H;7M zyuY^4zI2<$Kf5EkZv16nqUyDSLbT{{`nx*MSmW_tfxz}nTu$D#g#gn%r%MD5q^ij! zDhKXB&5cwOh%C7@nlH(z<%Tmh#8GTb#`(~x6p`$;BX@XPhiUez_+gWEK`KG_^)6;? zTDw8Qy41JcT&?nDeuUkuR(fyWrG=Jhn0zlrV$k~lrEv4muWC-8nI{V*@EkX$OhRQb zlP_FondTkB>8@0~F!2xN zn5Cgoo@evtqP%{tY*mv>`K}ODkidmJ^wH&2hq(hP^!VV*<2RZ?b?)~;-8zWO&#~H| z^V-|wE8jpIlSaYp$N|hjG94 zoCMzNPTDLs)>(q;q1W#BCOWXwi;9K*tmhF))n+jn8b;sVS%evIeDy?5GCEab(&}*{ zs((VGKh|~Iv17+VRpT^F0NctGD)Bna&u>GkIR%Hg<6Pb86whJD<`R4dkC*E=i{!8d zoTIwBdI&SCZ)kN1^7$kT)fd4GPr6nQswyPBHA+F8LfFVM4*{8iHQ;y~)n=~~mC{Up^0p}pO_rnBF)ZaCE_N~YD0@~zNN-~GA z_Cy}%!wZ#Rj1d}VWs~SAQXs~;U0_me&E7V1&--EUt-<-pWV#J)`&C~ymx`afdTwi3 z$f-MxPi(5qZ6!~#i^%dVi46z3*1ZT!l>YGuPn$Ab$1ijhE8n0$JH^d&%Vy~Q#z26P zGZqFRWB%3`Cn>23`(%w6)u}kd#{A_+gOx6-rX$qdrIQvTrH_;!E~*C?A`O7sWnsmi zhFAr6vdF12h`D0g6voxO{JROoq9#Hv*XjH7{d#2Dru;;{QU38oi9j`dA8qj_S@@F- z?g$&-y71+|j`2>pOPurTt{WQz82&Q9Hg&JiyX*)2stx)iw#7R+A}2Hk>PMVLD(&hg z;K#iBt4a$Fo$&R0b9Pa4EB}AI)XR6-C~D0U znY}*!7qynOnRV91Y&m71uEgku$;;$y8yn@ZbU~queIPwWGq7;} zMoDXqJrchBNOS4S8{x}u>vBM3*(&@up<_;DEIRv;dfxjhACl+KeTtcb;ht{DGTteB zs|i#ZA=;9@8HA>nxc&N(J!_85r@fN(K+PJn?N56h(6!S4 z(P|dN_KvF7m3a@mFBTq-e$rlDz;W-PWwgq>>}T$&J039o+qcg?TeKcGulP5uZ;vmV zc$)BbCflNaf40^#nvCe?wTEvaQV`a?+dJeoT&Efxb)WN?sycY_x(HwCYEF*zpzIcf zlIy{!A@S!&0MqLq2Cb-dV*KJ5=Gofw_{ zE*^R0S(WJjaAOPlC1THsC13T-z~$EW?+@O8vHfF^8yiHuB3yQ~2=V`36%^dv(EUGsEkI^=HXT~XW`RG7`1%~D&|Y}k=v zT*YZ^aahj9h;u~u`}gm-h@==C_VZeXV7lW?o7oAbIazjF?!3I#Z3#ZEf;SN-WJZ^nK&~+>Hg29GzKzFXg$n1!9zA*l z_D~*`6pvGh;!u{Ixt{AZ_^q}!+@+U;kZoR%1uMeD*toa58yth8{+YhWCr;#sDuR7u zk{-wwCugSyJ*lT<>?V-7L$8Nl_ihnog621 zeQMx4G1UI?tc`eQs2Oh!_fR3-!|_HK6PeHQ0~2CH@iLQ$>6_PC_T#V1pC16(tWegW z?`xjRxSD!27y9v0M^YWr+D$U^6SV@&HU6NsfU}X9l;kmx`Z=_HKN^`_NTbfrQgYp} z_OcUSPrFSGK=JYayw>6|SoV0PEbI26 zI!8WX;bbiK0vg1QK2ax9oqW$JY(zkKl3p(9Y!#g?c=q90e@-#O;=4VSLAmGRfzN)g z1{;~$>BB4KuXJ$at;iLz9q9Iax2(cDF)_JEZOmcJzvnt9Glm==CQT;Cjn&W1-6Fgy zJKw$Ov6R8H(9lqb2{i0P4IKIPT;5DJ&#U`ouUBJ`H(D|sc^VX&pa|@^yG(^!^KON| zkma%d{(d`;zB=c@W-)N!BO)S%^l;g%0-nl__-mgZ$5nvk9`@^&RHBq9PnsDMMHuTrQ)svBhp%pdCX^pjKGEa=kL)*T)5+nkX$=2gLB zwXZQl9fcV4A?m@&^Z8UW-G&nrelzPq4F(c;ak#dgXmQ54=wLyoq(tzp598Do|n1sId zR7M+Nl&y&3&d#2mA%>%1iGk7S2zFQhr=r7r zhYrQVh+whi-`>gFof3l?kvoJ_h_VOE$%(UY)ZaQmFIOE|v-gS2v6~}Th_Rdoc-HAN z_wL_iI3rVP^jH{U6LazPv1^|;h+#q6#uIiw#pRLqfFpMz|GE;fh|D`3yk=98qHGM- zvL#cou^!DWVe=-52`cmvxf7h5IRbZW+qMnl+cbkh52cqoUPZll`EshSX0NcYHPj-z zQyCVGNzeA4>m?F}wcnS`$kjq&GjQ#XB0W@-qJm#8ajt%P>)WCO0>Z+>Em_G@AxcFK zk*w~W_t;@2MUgR2iH03s1V_(OJ(kdBMR9_tMZ;mZZw!pVPH`(;DATWwUQ^Q(UxR7a zW3hB-WD-`pQjK(*dc-ZQKB>lUbY-phyfd~r^TsTgywcn&lRY~uNRov;$9w?#{EfKxeMjWW1= zIfDLi!RXuD^s)=%LG2e1k-Rz5k(kw{t)|w!G32nNIrIZZnsD}-*No5(|M9xXf%d{e z?2Eua$Kkg8?ChqQ8#eHR2;1#)zFgng{Q^t<*kOHUKxJeH9XxlqfV^-Sg&-kD?nICK z*W(11SeIMFV2Pb#=(htn&EnzX$OB`jqdUQvU(J z(i6|0{+Ig=_gNEsH}qqL3IGyY%GKWyEkLtfT6S9xom+tz{Ydaz4%S^SmrvNa8u5|U zS$H`}xO7vSm0R;Q{|(zIo>IEna}co$lkJxJJ7hLv;}^OjF8MGpk}(B2x9|%+J^VlY zn+hAh)pdizOOL0e-R$XkD$G}B0r7on=^k&;v33V+WL1wvLnLMaCJm0g=2Fn!Y<=Ka zVIjpKW2M`D`Mj7GKj8ui<1ae^{`E71FQo1Nor|fXc$t^MWhbIx@NC}2^o@KOypzE4 z{+Bze@c60Y+}16bH)dvL7=?XyxR4ITB-DNC`xBY52b;=GtQUv|{;xk2nZ5pz<*~)V6?i`W{(3|OWS49j^_(SHDl043ZrT}3cI0Wv=A3gV z_C6I`6Brn{k>l9M7ETR(AcvGgtZU5^mX*^xmKiYrE}bA+R&4CS zLx;#|l|n69*5OtIZTYjXq8;@Z)y+|kd%F9%a;8P25E426+5}VMPcx}Of)P|>MZo2_ z4K-(wZ?6|JZ7-Nt_N1!1YzRKUz42BA)SdVkQwWBvl>90m&K)ShbetX2%LW07SUCu}YC+$3OxcC&ed|J}rV* z{e1I(V%N1oAuw15{<@7TrvGhec*`g3Jt76zQ_{XSwxWaul|aINgLK)qZ{J8H(q|sG zFEiZNoN-Zy8g=cfAgjf~BNHp26nV>1ad2%Wxgk;7b)pY2Y_xKC5*I_}SH|{V`ixb9 z&ehQ$6R!R`z-oirOGsUMKwxhO18vr$@2wAXEBncM4e63UcHZgbF;^^Oje8z{2;?LN zR_&)Byfj|pP0E=Na~Kb;b?2*(t@~K-LY*W#Ltd-^l3_z1a^3bzh*7Nh<2M!3CX-pX zrQSuyrRfqhb#>=D?yz80<2V#wACnW`e{5^cX+RY_ojTGOkaSwl=tR*n^PW*KXRjXp zx^Lxk&2v{A`oBd5={dc|vTfToKjd6!@3R0)(_{h{0V1~IlRp7_ENLHIaWmJUf9or&{tM~GRcf-40zNFfPMkg00)JuEMt|rc zk&^ll<)^Bwtc-FR(5xE0vjN6aR-Q4QA8&qqu!U3vkuqQ3b%fXm)&ok61q2aQSy@`- zrH<2RTe_^%m9@J$CB!Bp`UdozM~E%|1hY&*{+#LN&Qbt^nmV&{ParmKe)UnRIO4}A z|JcOziY{JbS{zEA7 z3|M{enn|u#g4KxW5|bi$iPJ{!uo1_UDP{B5zP28SV|Lk-h{L(I<+El0Mc(@?8RvssK}7_jYuk8qwfkKYKs zfI&-%yNq3rIcl>Zcy^!IZe=x1&1^^`N1l5^DwK}ma-6usBHIVhiAewcLo!C@iZj8$ zwvj2uX()%7q@ST+b)vJAWa4$g zf5g6wr@U1um?aUmVppcXp+gE6E=+`8J-x6`?Ix|&z^^N>pzSQ8I86l;G>&Teq zL&-LYm75b;Dw}?s9wexP;g7l*E-qaRo0ko#vg-d5bO#~FtRDX1+&J=)g?~T;}AQU$A zAI^eG1chX^gH+dLo+npI`)!(5#1@s08W^M$PM6lDWj_La>&rn4ra9{p-KZOx{|?C z7Y$ne_I)oxx1cJZTCY|8b5oB*@R!^ytgIOHSA!9K-8GzJ$L1w=-q!nixlS}7M8v~O zGdBQgA$eO|%iNN7uD-I7fi4$+|3sLYM@za%_2`e!ZnBw^PvHmG6>$OrPFws9gcd}V z<>lo&K4 z*8s8^NcGkEHv1k^(h>I?A%9h1%LB45E}{R6`{40J9bXk>D*jdDTzXUn7~UVS>`P+^ zwSRf(eh<5m8jqtl)i!4SQi&HKuS?|%fV^)~|M{w}J^TIbczxRQkGJhF2hVU2VR44R ztQbqFY+)4s)2%H+SNNEJ`uq3q+IT}t!Y&vY^?dFO4rVvFW&7pTQKhx>!vNQ2rdq6X zbNTS@7?924$KBizCyKM(mV5n*r0vH~K2uz?_{cvJQZMVCb8^a@?eto~)R3SRDUhh0 zVMm+q6)%(oy6l|wF{e5bpMW18T!CQzF;senG1jU+{T4011mQY27S}yzj&m$NkiUrM zV{Ktt2|*C%$LaeUY9=Eh_7K}4;rj#xQ14pBUYB(gmlx2pUIqo_N+V8mEq|YrZFew# zEZrx^_QZb!ihor(BQJFGc+QOuXjdaCt!YM;c6N4)((LP1(h1rb<|7>+AZLJe|8RRX zUge1_)f805R-`jDGpG&N6<@+p?ctFO6I*>A3dT{>uWtemX^_s=t4>O`R3Hj>5z}Xjxs~{oBmF zApXFgk0I_e)<8)Fph!S{o?tD%h17K1VGZ#my>gZ^>-{nf0@?KUNCYG_WoRMWD3V` zkvR3)B02xlumF?kks*CZ1QN}EUuscYXAlpcW_?L9g^B~waT$NeQ#SCnEnzzB86{6q zfYvGt0%k4d%G%GM?983($0c=lcUuy0=mlLArOP2^UU!$7^`)@E5KkT{2ezmLH!Hsl zo1u#6P?%fZo25Gs>l5F$2z$;{9!knS)mVbTS3i_et02HW4(mgRB7H-*r2ULy)KRec zM1Gl$v8E^x8sGsFq8Ql20+O!kHio{a9TOuRWKVK*Y66uBcmT9W*bdMoThX2lO;cc_ zdSHnU%i3OlK*BqYUOfY9;7=u!6i02W>unk`^g)}Oho5(J;=#r3qeBk9wx%e?e%0fz zZ}D$1r7i0aDH=_f_;M9Q!&9rxEA}mnG&ewkq@*cPkhI9kwv-`4OM$x^VaF>!978aq z!oCY29tGFS13lKZnWiTp))PN@7ed%yc=%9-t$U4Y8IXIJ~)UmRB`j<3P3Dh zuXUF_16&a>{&n18li^*ljP^t7acNoG5LblhN}Y`NaT<4W)zd#*DmQ>c#EycUNf&_plVs5sEo@1cZhA(o2$)dB)$iGU9V=5q_+^pUQHwAC`!sNqd1ih2Y#?7pEF_R#|QmHr9kBg}V*q0QqWgL^)zYtP67XclYn~ z-s=!M&azYD>u;}!OJPwQ$TPYxhc4DqQ>%j|>@iQ3^t@>XO$rcl<(DrzMT{R|L1ERc zTTtv26cpSh`kn;^iMvf%&cy!G?j9OlsU8~}gCzcOi-wDQp#p;rQeT3_6smf@DF{0j z7?M%9x;{SS;NZY{)GCTI)9Ed+(JU9_X~2*{yBujcRym9jeAo#EZ(&0Hz2YrcU<>$# z(G#4Wq7*ky0Hh8DB+%AyR?McO2pzBPvRD8QN7-Gf z10&-~CNe-zU-B!PpK{eweHU~HXp81P_oK2&$9uqHo60=C)v*^eXvRGmw&s8Iudo9k z82bFV>ZMCI0QmX}@qN4h*+04Lu4xJR~+9f|9jWS*j8_{zXK(ZtPaQ|L$MtWoZul!b*RiO(2|}fBEY@UETA~fdwOapTd6x zRsS6=E!@`sggSnq$p3(0{_=V`{r>SLMYl7a0g)GzGGH+>`-A__wbPtU zx~L^@yJFYL<)Pxlp{l$4dBkuT|H{SFO*MLr0`+T}rNYscb)bDrf3XYAIbfZRl%rzi)D z%8O5dLG%9odmN6M`kBYx&k>(sW1QEgsohnrM(>gE5#SuD?5ls;w-jxvz0#-!yOw!4edO&2l0l z=@Ajd?H}ly5s1k0Mdo2;vq(!eMg~+fT+6!X48~gYFS)-l1T6OeJ_Vp;L?v6oIZ4N# zdd3dM2C41O7s0nmYsa6knsJq`t}gIVpe4Dh#wgYMYiVhL-GoM?pYK;(chR=Cwl?cV zOEmc}URbUw4Nv>`VOaP9a72C$I&9;phaROMobLd(3@#PM0R$WnYk)Rwx@h~;B7!y! z_i>{k;WdM>lZOX9|3KK-P?lThoTVGBel>$AEEfCj-Mh53Z-kq-1C${sa(?sj6NGVR zOZa>9d@bx0DHZle1^Nx02lJKrg6yxE++=S-^8KCLh-WXA`2HvAXtevVTRRy@gp!gH zm?d*FH>#KwWNXc5$Or@rES&Ckd&2K<_OGj9s1JTV#`ec2c3FI5l$0Y!3RfdU zCE?pIrXPn^EX!Ku!k*l)x3`zB;}kXBJR^ue_{Zb_R`=zgVI_#@_?W+j`3*=ThD3Ef z9t$HI2EA_+#b&8#5qrkR8TRd7*r06C<^#VD4+O9CrN zOr80>AK2KKkp^2u43zj+6cOp7PTi`|q`RrPK2TmW}uil^#w|Sn5y+)5D8$ zz@1-h4e?cz@eC_d&i-_2|&fA5M8Di8+ zX~-&Y1h+wIP#_Kz$|*@==#RMM-&PiIlPF@UmCiMTuMaBtW%Qip6Zv;|QDD$aOrnf?<9Hl_IxRZ?mDUk`1eP4HhI> zW)8LLii!$U<t)a#DoS;Nqo-kmzY|dJn0b&euo2pzi8x;C zI4`4dLc{zNMk!1Y=~ufJ@ieV?N>`DwNQZ~tCeGp%Pq8R!}EiNeuUsXj& zGg7D;l@H66wQNf1uZ!yiB%!&5?(2)_0x|7RCN_4_DM_Y z@TDrvLjSffuWe?WhXI3dS8qktxC0b*wf^~0J;W|8hE`%zX|L93~$q0x%LqU8iyA$_(GQcHk4Qfe>%#Sy6PelNXJ zdE3nws1gV9H9QdlFaouc;3_yn{l}|-SPc_bb(nbpE_m;?Ma9ipdMn4^Q8pbXVo(Ut zbqwtzn<({r|69|VcN|x?pNYW{CeA(KmTt&(whrufX$GJcd0ArHMg`ly5mo2hiqX0f z#gOBYf`7pVOz7jWTx1z^lM2s}>S~^2wp|||J=&mG*bf^stAeA*q=RVd?`b_zLHeXy zC&g{{DMj^8r>~X`lZv60)FHk;VBlcSYRBilk;0!<(lm0q+LKlrqs(hMS!lP6 z0|J6spLbzJC~&+96e{^2OO$D9K+>p!jaVt{{m+(W_M_dFD)&nkRn&*T6hP7bxi;$! zf_k_KV6jP(NBNVa#sP8V0Vft6((mep-T3(G>S`c?$F7$_e3=PVw~R9G@A;Ye9p|Ea zyX&MtCGy835w({skQIdR9d+?5f77S&iU>H}S%ngQTYe%LnOGbZkrp1KJRXMt+ zEsBy;?Xslk|7IclNwFE%o{mjOILyz_Joi6bd09gB(}n(ZyX>qCu>YF^0${1gYRPl> zKNHfIA)ya`#cckgF|c5ekAH>0#((@6WTgL#fAF_Aw%p?_>eZT`iFDRVh2$ywc%dr-&t5HKe-u z2*{cMd0T=HyfQ?W@}fjy6TWU?wwk_yhzBGG<%0Uihk^~A8K5R9ua?s!RJEEPgz!g(X7>J4dgGj_gYQ6c?22_!NfLJzP_Njt|b zYLgiT=Q2WAvpKPAL}sGs^xhz7Z^OmXx$%F zNP^yVzv_C-DP~@Lm$@=X7`lQNiWE1?yVA@3-!uqWv9w<@p|{$Q zE44p{SLS94oJb=OQdLm_1kW6fIf772as=a`Ex0Q+x%m(v(JU&GL^xh0mJI15X}j(R zSlC)2@qx|x_cnjvzu&+TTm_nL11DOc^7ZnJ~$@;Nej~V}s~wJ{;H5 z=sy%H0`W^wnz2x4U#?Qs{mHexfJDAKw)`}V%vSy-opAOt0(O&ist^RSLWfJ*8^b|T z6*nDCAqDv}L)wRzTuhEW0;^Tenc&DAo&7f+j#ELyQDnXS9MhW-1Iu$DGd4=xFKIFm z-ef>PKt;s`=W76dF6^blnO3o`T3WBM$q<0`fxv>KRckh+HvsI%;;bBqp^FB+C4_z} zvYLL!b~AauxXV+m4h}i012Hfz|YSW5(hvC+sylLxD0Xl)8Z0SQz2e!Nw1d8g={UiIme53 z5Pt6do%U`6lRJbe4oQy#Sr=epG2-=rsp4?7UL;WFIDkROa#tUm(*jqP`-^Mo3)Y=y zuSj@#Rn_3gGx*?Cf31%)$Yq(Z5LCjX)3W&aUjNmIg?c;bd4C>cvxVh?{QPkV2@}xJ6@7A-tKYDL=y&~hIlc{!0DDTv0$u&ZcGvvm^#8}E zam4@HIe*6k%RRw=??C@I0C93Pvc~4+~Qre*{0oBrjV>@WFkgGbg)ZSv2^hx*n*I{d% zn$k^_Ve>(#kGDJI&%+iGU5CD;d!Cy?4NGMk7=hEc(`Ft&7T z_vA%*F$C$c;TWsm-QLLT+NFa3B_*~(#If0BqOWFR!hw(t&kx-hK&)f`x6-gKkLgYy zB|VK7P_7>BI2r-=HaPGg!_qeSy7~&=>ReBUQ`TDj;Xuwykl{~Sd1*${E zEYyMRFmho)6G)#RstRYrb@%jCVUW^CO2Z^*?}<@- z$AUnNs;H~OhW2VmZ=gp%=`M)_OG^=So7-a-tB3c^)_-4t@Y->?oWVjMZ?SIudf0E) zR>b01vZyBfTDy!?QrzJz@K{0N0^_c_8n)9_B6&#_3;O?ZJ{!j2W&BvnrVKblV}XMG z{vQ7lB%0*efIukSZEe+^WW-@|u9o_4avUsci+*vP8kX}b$n*C~$A@7Y`Syv!q^~;@ zWLkIX1jizcoM98U{i{p+_Yw*g=-hGG%;ia^0gw~?i=X)04gTGf1Jl(S*dU19ge7uz$f~M3gON^;V*m$!YzkB+~zb1Zrv9#4;u- zsLJb`6c=37e`wS-R4kx?S1D|Hqqh=eV@SdU(_OHg$Xpge?)Ld0XF`yjB3c2PTy0Rpkdvst znTI4@1Ebm`)b@UE&zXd^hzEj8tSFIXkrhn_hJ_8@kZOBaX41{3p-%K7*LfWvfGu~y zqA@{BRZmY3j-_O97>LCZ;B3>!kf23@rw++x^-0j3W38~?u;@cXgF%Lp49V0mpNFPJ zmk8DIXCprS7<`rj^#$a&2GknQ^@yemOMQ~ev`7P?PbSrUf4c&RBA3mBb4>V=L^$~Z zBo?Qvoq#sq`tW>nB;H*VqZdkFUkdaBn?wl4-|B{Q9RO`~P5lu;#ee^rzes z1PAer$f1%BtqWzX(6J6)b3A6tj4dbsvD&n6y^KqvAx2Ne*iYdq3esZm=NAYfEBDPl8Vkn`t&bEP`dLu za%zsNa_jKkFksoZdHY;I|MsYlKVa^}CniQE7z3-1u!B$?8Wc@WPeaW7b_Jk;s>;g9m0(uGu94HH znZg)rW=zv10yuBsn>TM#Q=hGC*s08xaGeju!(|Z;q4&4XEZYmhTsH?+qzfAqZ&VF_9Ma1Ux+>^sqr`@1W)@`Xn1l78VCH82qbXUoAUW%mv` zlP=wmo$g?wSqBo5V!ACm5>|MfxB{kYmY7CIWKGEgBi`ve*7m5?G$ihE;*-pB#NE|} z*KuFfq`isK>R2b7f=NIv8N&s z;zQE^AA4^aPG#G+0k1|)N=b@BgN&sV%3P5wN(+%8jgq;9B4eW=2@91FMPv#Y6Agwe zjbxrmX+nk~vv0rFLMr$DJn#3uf4*(|{CKwQxnr&CInecuoN+iIbMRi+7) zFhqui=heNvy>H%V+Qmxyy!<5P)W3lZ4RVtu?)H z%KR-vstI;*Y{u6+F$yYQ0BBC1K0RDmsu_)`J$q`0#FEm{m>}q2v|vfipsK1W_-q;s)rzP@k_{xw3b_i5!YVb<1mj zs2)Eze#z-*E@MU3cdod(EcL@H$$6B!zW)6u&8UvFq>kqGAFrr<7Ve0`cD-lO5Bc`S%E6}cf}dn+S=tn$tlJ% z;=H_#U{OXsMuBp3vHPKzL-_|Inl%Fajc${DRI4CIJR4sPg#o`Q*Qw@2Y=P?HTb+<` z_TtnNp(Q=Jb!){ZCEG%H>1ww>+7qU6!30P6_R5q8Wsh6z$uFk9;2=$#Y%8+TO7Hj- zSq>RhXM)_!*ZTaaSL)TT6}?CL_N|rQ-KG+$N1f*lc(}LMzSn$jrge0bs;X*iR8(8v z!1qrtwGV40CMJSwz|x4b&%8D>B_cx6;iX@4J9I9Us4Wn(JZNZ*wYRrZ+dW>Lo-*@; z(J?|;;ZAN!#F1){VP$yy`1f!{PwH}?LlIWeWfSxS`lyDDm3X&LcDL=nQv)y%Xm=Eq z`zV}s`k@n3Ff=!BflNx_;O28c@o3KLx7nUVmQ84Xsd4Dch2bDC#JuIQ<_ za~%tIZ{*xyO5$OucyQ&Z`E$1JBR|#*5bU+!EQ#e3Rfj#|=Ez5N^Ome4yE8RX5Iun% zMfNKkId-i5^3pBp>grkv264|~;e@~C>K*<-e}78Sn+O$l@^XO~Yw<|4t42 zT^9>#)bVac6BW%4wQbvA!ZO1@xIlgL2Ai*%9McWs%6uwzd#hh6kla^UtgEFZ_|mEO zhjFHsbso$ZP#rB3Y%HG-o~`%c6@rCezayVDptS)mQl8R&K7&U}A8)9bzd!1}Lj#gg zFSzcod42Lx;z}$xnBK%wYeFJr(TKa_C!L&{DoYA$z@9w9$IBJ`CXNr8@hNCiQp?Zp zvbD9fv&(oOzWyYfgTDa2^6>EJcgm4@`^GVW^^tfGiw&UU7^PA_r<7-)r=sH5I zb|itBl|vaR`~&er#Gf)jGYu~#W{`|_Iz3dNZ>1Te5Z95#tWtJYQsq3gDjoIjOV|>( zr0n0koNx^wzFLOlVze_LC?MeD_a2DZ;d&M2piw@2_2-FGan6EC#Ie{xA(7lvD;_BD z(5%o9Hr~HP`XpglA8h%x!*n&b7guBsLA&?+dHBQDYE_$C=~dZW96Z9^ynfyjN%Dst zf8!M`6b`%<5kZMJb<_yld%Wk*hd-a4N3-8oAYeZfHlL+o908kqi3Cea#Z+xY-V(Y_ zqVUu@tDEML;QVaP6S;~tA}wRJ74eC_chCBv%LLKn?P_Y=8?8Pd=C`f3c>CMigj{(V z+t}N_il%3^Pi+j&Cl{{iv&g7ByKN|Bj=R5SsrjD|q zo#uL+PR|?v3L*2^A67H&mn45bH^;Ndp}OomZj{&u>iWc^T**z?JR5+41dOU<_+vk67%sS*VDKts_f}fLU^m@j2%&&DXAG@|^Ja^j=YXE=ge}&cob43J{|9(y=QqOw)`$r*XW)XBM`~cwt%hkK5*3QM{z5cv^>}o*{ zOuV-vPdZPb|60*s!ABte&#iRD?eAT1XL;U~HgU$+kzP@{#R9!2x)_0?Ir8vGpZSST zpYU)UN|%vqCt1%Y9>|!L{6WSdSH`SnFUdFHT=zZMJKpnKQVk&)@JALIo@5!*!c$0_{3ACjgrfsywlJ(xIf84n}tut zv3Gq$3i4zV6O)d<0f0F$PjcR)rzaGSV;q;Z0pJ^Euev5#h{)*@R?aX0!;F z2|7BJhO1T=TnCf?HO$|`l3kOhl1`riNr`w?Tj!L}1xdp%s-*aqs+E(5(@IU4o$e)k zbHGOlfZ)M{2Dlyi)3awMhrUd+`+m663Qc$zKwZpGcoRsa=H}{>)C9B? z8yUHk8c}U=Kd!Tbn3>RAX%w0w#`^i%4>X1&BJ!$a^Q|0fR=)-RkNV~#=2IYMiPS1J zWtl-ov*qC3a$UFYf~X*d^Y2HG{wevX}-3l`z+pn86 z1z%=6^mL%3LYA62b0)GV#YSXF3LE+MB!b21fKFDpZ?PH2d43ftr|0SBorC^KCB(b5 zx4(fs+-%96ELjWoqoAWuol4jiLev2vxYNgHi?BMQX?X}EEvIkaano|_-_f+3t%s48 z&#@kpma|?NKP_MJk7@Y>C0YT}yvD>11=-M6mKXnhT22e=VBeWFpmIX1%=7eib8~YjYg$swTY{Utsx~wQBZpl~u&74?lV(a{3@{7;`hM|ca&n8Ah~D}Pb=tEzx6kXtWZ zz50@G8WhQTlgJNFpdC_cPq_E&yjEKk zuvk}V*$k~DUv6)&BsCqakl_5q$EOD?a&=;tQ=Y@cm)F!Ht9@%Vw_r)d){6_5(#n!6 zMEAQ20>CpL_E(iP1(COIISh1`Yj#72iv-rp|Jlh{M#-Tm&|wh7s}k_a z<`mk=hR+Xr%XEP~q<8IJc4wJh4qS2-b!@LtsUP~EuI_>0SWq@yi2p*>w<*>_db_l> zHCCJdx-F8z9QqDLkg1q8frvb{;ZzS`v^Y5k1O^ICHh*__cR<@tIp`$x(4Gm3i+3U6 z3YP{?3jOocd-vR0?X1L|Ituwtb$&&IRE?5x;|7ncY>24ATwQb+`uV>kICTo4@UTUZ z4DT;93kw5uwXIh8#%dDjs*qu5Qmk~}<8w3T5QiXS;!g_;=lXXfrvp?+``A4yHZCq$ z!ZPHDYSbD`>FM#FS~%M>yXPa)DYvB3EpueZ#4fD-8W#JPl|ud3jiD zspLG)CJL>6H#Sg95&yS>~aemB5p2*ea3`nM9~>DLz(csDxrcO!vTS>%Lw zDw?Nm4f~-BLRztRBa@2ZKJh_9J0){gO6|hj7Q6}dw%LZV>9&9(=USj{S6bC7a1UVn{q#JTQU#-&3mu%XMgqgT1Iz|E95A|IZS1IBE7UT!U~i&nl=BC2l9&gGb$4VZkC?7m!EEaumw!TmpEi!9S)A-NM3wXG*Lj`{yjzyJ5?H{pvkTF5LJlls3FLSAl| zkg1PtZGPm?1sZ@f-)fhho3Rrujcq{h!2l5>7_)2#`Iu;v4kAVM3j?tuJv|+!RzWn& ztoD4WfQGI}aGrfU;bjF$Z`?PH%drJJLZq+u-b+iL$IQ%(10$u(I$vgri|zh@$c)YX z#$?8rPFHAPlkwu|x$gOa<=aVMbI7;_D&=d}uJt<&0qk=gXxdv|R_1ZU%&Zwn zGX9HFV~|Cr`!&it7}o?0v3-8j2`8PjscWV*CBEV8G`5_3H#0L6>F$^g{A^J>*KL7KV1Nyzy_gD}CvOniNm{h$o1ZUR`fo z3_q8y)_UizW*r>?&gPm74Tqb>AP#AxtqP+G4Ld~rga=(5Y`s5QMe5GRCM2kB-|k;P zW9@OseqZ3N@eX~lG9S0o{;?kl4nBFg!>$W@Uy75;6!K$OLMiZu&Dw}I5D2zOAMeD( z&s!A%i6`%h6>dq*cOkU0v9TE{f7$?(LbO3V`Sot!$g&VmNlAge;a+)a=lfAioc^S* zH$}7k2~;JTkEA)qbL&qk6kc)onS@dcS($`{gpACd!(y80C)>k?JvW=`MM}V$Gd+C+ zxlT|}(2SX%3E6fN2PY@)PnSlU$I3e3Bo|?T5o%#aU^tT3cm2m+JKH9AdRk;_s%Ld% z6#1vg8tT~DavXogYrVkk4P5EAih(ojADhvh&uQ))rFxKa?SZrWdM^(Yot<)r@a^hs zO*7nPS8Mk9=+{ajUE99GXp#{#JVi1_l9|-$jASO_mSPq~xp23x?zO1Ja!w9TPJ{7# z?xQU6rI&)8^C!F9s<~!v4pRQ|3>9<_Vy08W=b`&uS2ja&Es ziq4~-w+n8a@K$a~S$d-mIDK=<(kF~hb5qyVwSNM)Js1-V^@I)?d+X41{68^iv!Hw1 zrxL&%kytCM{GM3jL%W6(YXSM)`+m+d<}ZS>A?M{M&hDgM9L-TaL!G9&*^5CiQ&~f0RrCpB> z&;i}VsqhYyH`=DAc6&%Yybo2cL4BQvS%L>Svh~?-7(A&ipMhVKCZ?hOKrhm#2FBDE zImEsO=vh>zA6s6Bxq{Qj=E*J!PC-6Cn~YoF<^<8t?8O`QnLivSpXTAu*$zp|jvcAl z|B!H#Ra5|Se*Fc4j|W~aQ~DhY|FbO%xVwDIZw-j?P-9RpiPLYSdKeE1{bRkyg)7Iv z@I+r>Wy9YU(bsLqQbyrjMq}e2;O^BfX~TfO%caNTETGamd^*vm`E~828#mj4(W5qn zZTbl4{tE^F{9k`}{IAqD>&lg(0cQUxLWU6_d=Z)VMMXyX+PrGwceq}{zc){-(EGVD z*x7HqA1om8IE;_-|DdIYJsN4U%F^DmD#~7?QV%6$UhgEB8wCXgOo5Gc)+O8V)RT5~ z96TP*6~%pO6-mB(d~o`UzxkFkH_b&EO%`eapGTO2-V$d1A}=qml(Na;sJc-Pbm=O6 za$QIVp05%Yr}_^U=aCk+>D6!t*w7k-siEtf!j|3Np(3aemX#&V$H%vH>7!5I2|Jbb ze(vGIn%dg+#|oAZCXny};};4pNFC^GA7Wt!umm19D=RC+-MjYg6%h>9;V)UbXwANd z=)p&~!Gam?jGCIO8E`OLBdMV5YjG(Qc2N?PsibLAK=*FxALsqEmah7l9=vI!cjNy$ z0&^Ah(k{(_`QU9)HvST!)vGN`Okj)Y*Ux#-$m0|`ne6lDuNN0r-=x)1K&TA0wX}dB z&8KI6Qk)eg)FrZ*g-Q%1js|vL1vTV0P2C~##1!XZ76wPpr|T z{{6&<{%9{5S_4agJ!1G~xb~pcZNVHY=UjKSl6LwRW#Q{HihqGGBQZM%KBVEHLmN2L zOLt4vBp$rbts4#497p9|O*l8-jE~Ubxb4sqVNh?J}LY9wtl6psAbw;rRhe2CXs_zU36XS|>yyqKEG zVR(T`vu&*l#@wTykv^Ve4)1LtiW?u|ro)}0nD7Kh(@qmNjIP^xNAH;=Z8}ni(%%_o zO)J$xgq?m%i-L{s2t#5&3LxV9VmFXigleVEPrG$X!Ks#-w1qN+<%FhP&R-06XVhp9 ztG5SPJ5%HD#KZ`^_m{&2d3}KqY;gDtu^{xLm(;Vt!*S!rUV;NUYDiF>i0>0N$T|ri z1kNQu?0x-d2L<-Z9BVksF9JUu2sEwVV7M}vlnN1I@36v34i3_W84XH?7e0g{yhT@c zHkB7$gO^SZj_B~k-4(jK_E6+t-q@jpkSx?V+&$hhriE!iX?HF4mK)sN4?j_94Edu{ zsZc6Nt<%$q0$wO-BPdo4R#B`bmlS42({vSkV3AHR^igIF!*GTdrx*r_=9t@jxtp?T zW&}4hjw?+uPdO2IB4xINS=^oYs8A&?JB7h%Bo>1)4gTY7UbrspVr7L*nq!;&^oZ8^ zit+Zp5k}9W7WW<}MvzCbkK)88SlNOMx5vQ1B5nd{+VWgg*f0aILuZczT3Gry zP7h9w7svmIRP%cHi_2S%FV(j*B=A$@|&2&aSyuZ+7QfW?Lh>F#94e3%jL+Xy-pnmfXA zI7zYy_oWX!`9%kq`PO`RZJ_0tgn7-=*cg9+#rP~gc4>fovCxw{`c>nfU1s0bDrp-3244EsQOs=3Ye{YgDjxi`VC&!1?&o1-+baURZQXc^vv_7FCL&Qtt4F(L zy_i@;WTbi}ht-VU<`13S^lf#w6eDOkbDoou`DeK%zxe4ydHxal0G z=K0d%?)cI2wUY8TKG*uW<3j{2t}7wA68Z|V?iM)@Q4+~kgv%ueFgY=lXPB#&(#k&J zEjfcX@icBAu27WM7#-dFFs+5)O(9YV#&-tjvKJRaxPB!xRAf$A0D2`!To!phqovPc zs0@bX0^>-5LeI~JpU@J@5tJYXX+F=qy*-;Y5YWF2~uYhMS2Cb8vV?drK?UU?tnoEkO>dg~MR}41h z`W@d{)KZ?n&13BH!lx35G4O@G~gTg`kR;9J%ty! z`31dpN5MJ9=BGq7vnHH^=&v&0oYWCT%)}690ZSm%jm3t)KtRWvtuZokW#&!Ntg2sRM%sQAJ6^i$hvIl!jP2?-1XT8qw z_4CW=`N%1FJ0jw>x9AFfCOHTXn7B^vLkixY)Tn%Wd(g@fZ7U$#Fb&pi=rR_RN(_;K zPK}@=eAx=}f!=xIY91RSrx^12Ao-tXv4fG>Cire(_`IfOfu7x2A$6 z9=X^Geo9cZhO1xY)opiFe}@j`P-F{M;|b%d3TQvE@+-emKDI3fm0t+Va*b{+?V#A6NQy>B6p4i&Km?bur?}os;zE~ehSqz!6 zFf;3aZt3I~6l6N*6otS=#37v`p~l)S@*`9J~)V1 zEMI;T(q`~v3P4`PhrI@!cx5WV4wRWnqRhI_KF95GP&az!xAC^{@j)nU!RTFXrw=$vGTGT`ut^)ihPl zLQfmEE6;*5Npw_e9P2+nm#Dwjs!5V&B2t@pOOd=3ZDQz` z^))blfe_)fa_kL$1RYAS#E>HAvC>TC4LX@Aih5#5GSfJxykD?OaqPas}6EZaZ!Hb+-{ zWM!f<-I2+{s6XRl^riWML(-s=c8|HRqpbeFeTgJ|#4O(r zuLauEj0} zjDMv}^!_xi;`J-6XQ7qqGq(P%Qk+tzBvSZ-aRP5?;>}?Y4L8q`NpSOa?Yllb4h%LP zlksxH<|81Q5-*o`U-)kq$q)w1AOQ)=~olKYjSHV#SJXhivG8Jjprra^ML= z`~U$Zq4Q5!CBUXI>5rsAGb$#g2y`A*RYLgZ==dNd(LYu|K)~J03xe!wcq>qc86hEI>b_vMl!NnMX3^YDWnYndoJ;9JXy`B z^hxRJL`qm~GuUr;)eZ+hC|WBW>C5tYBQ%)oU=OUUy^8ypQxN zt#!u5w-&8CjL}8)_L7Et*7>0Q(Zq>QC%uapn-hOU&jn2v7ppgrkTwOyfRmn;6}BwT z+{7f@Ph3Kx&q3DbCO{6ck7xvMc%2Td9#Eo=-6jZiYLv(owvZ~k5nZ}8EIfR(rl3?< z((!F15|>Nu-wE_DW->N>=AyA362%5G4iJ9F2gEn?jztVqm6Zu0h}lZjAo1;y2_K+e zCu+dlA--L!K~#FLZF@jQisTZwZ@l`VT7!-c6EBnnnnVIaKj^IeK;uIO26f;O1_cG} zb?RvZrOu63QBi>pc1tqr!Eir{9jqT33NWY(=89Klk8toE;IS*kg}fnSS+ZCDF666ewczr|rP`;i5g>>$POe(!`m&o5I=(o& zKLq?(&nFHUtCfjbqJnj)OE4X-(;V(5G7jBGKco@AFnm5%Z9mpnow_UoY%<|ZPBV#r zc=e7r8Sm82KLPUjk9wf%R~zswPQVKbUbD0O^Y~gRTNfEp>Hi~je-;a~^~fERrv*0j z4h*99zQipzNVpUthZfB!6G~U(ht+<8L$C?s{a+!e#-*>i(>lhuZkWI;l`vdqp}j>OdZDt8AsEwA8JEmd-906ZJGu=v-n=PxFvJHRPKEtKe#XIq*{^TZ z4*F~RhvV?#SbHEBzA~KvFN(;Nqg~1vxY7mTtVais`r&fUWtvg_gh>zmt%%wQ48JWH z1_NXOV&4@*Z)~AGO~~pXg9yKW|5C$@@ZxJM9vv{=hWb(I957got25vMlz^GC#>Qcj zK#vY)sxslXyv0S3>CLOfeO9Dpp4hxfEm)G*iFzaoLdZAaOL^w~5HV*}R2NSo0OAbs6 zVPbL4v8i$qLvMik*wxz??2IC7p^Y1Rnk$n73)lp{A)kkLoZ>m0ljVDzgJ+`BC#L3Y0ekK+_R zP1y0?i`(QfkY?btD_Z`{t<47y9t0d1JAaB{C`d=hZ&(exrIenkHa!0;2w-VK=?7x!}z293e;7u-l0f> zmoeGo>gCHjDU_vx{=qvdH{L2s4KqkT>N*2*U)Gx@Hm#euB4T~ybYB{pvz{EH#gM1a zPDX>OC1;J%ytdS&m*7OZWu>L8s*mIb>JZK}&N-E0DI;};V56U-<0B9khlYmc;IV=s zf7Jrxe<;27c3W(cB*ql;1yt&MpFABf_s2;amZN}_xxWjJ5qWz>xTS1WQ>Wi$((~%4 zY}7E#pl{?EK*jf%>iMcgC$#Vzh7!$(Ri0KT(Xk^$yeGN*9Pc3SD@$H?BxsiWZhGmw ze(hSH4mG5u&=Op=K)s3L{eDIUiub)-Aels6^zx$j9*P1mGGnnnaI57`L}85l^~*ze zhJdi@Mngp(sGd!bjns8Kz%aAGH7{E~hSeN=K=RnisK+Rhi4hCH-;j`CzFNvi)sOlGNu@9qSX`|wH~Y=6(d2b7r( z8yYUzXr-X(3n2%l`tg7`KPZ&5{|aVm8Xi7u3)yPN7Mhh}L=vmv9Y{j?9)VY9YGU#g z$?=E!cEMA3FYTQsnP;Bn+_)>^F)$}Envm<8eJbBB)CWai9?ZWLuFfC^2=Y&o{{gA> zU(pza7o$wZjl8|d^|mnQ{oi1~!#>9A5-}}9m{BD*#0Vv9J9{x_(x^6V7>s^y14ScG|jiD}d8) z>F+OD<_wf^iPw)U|B?E*Ce@(r2d);j1I%It-6U)#TpwEx%CEmEOi+Rg3k#{A@e8pUI-zkRDn=qN zn!hxVu>2k&BKtSo-0F5&D%=%fU}SPxUe2jRivmDxo1TE|jMog}hLI3mRY;negWqQf zraztk<`+kk(f;2T_Tqivek~7gjz{TI^VUOIJt`&q{aO#z7`{tWcX%@`zt-o5aS)?X z^HOW1M@6sIzaKJ)~C(FvVy;#r+Oc4Ea5D1hl?i2r;& zbXoMjei;;;cuR;|%Zz5^S(lyE;`Rs#^l57miT{y&JUe~`zUBic@v%9gg6MF--KrMy z)#rjjM832BJ??LQIIC?UgqXPbH`|#GUum(8FuM^;)Z?!%5|7kvM@1fVh{S?NTv7Sp zo%CB`()7LOz`=tjnk$xa{F(Yx?m`9+i}lT$CoV}R)NcgU7&4n<7#Zq_?mrI5>yGp* zeZsiXQP^e343*@e^Tw+*_7mzVBMU&9zh@9S@kj2`rCT%UW2J_i=cr%KY&~ zaP_NKcX44`FQn=jI<7yDo&A%U4oHhTccNziV?>LV08s-$M36bCvyzuY z{LAOkdxON2ktoZ0bInsyD6Wx+$FaIPdMLYO<>Z{f(*&Qk%p#}no0Q;nnNtDkdxAXFRaEYsvFsr!i=Lb#F9^REJwKO%m2L>^KRqsCG z6}Dx|6A;EBncS}-p#V`1N+o%cH%>N$;}ZnMGEPEyN=qf_4bCAm!*GP>E65#?9E0uE zLWC63zBKi?7RAxuvDrG{G=#C%p;xbd`QC%5=-s~nzxB}TxRBwPk4o8!Beo5Ueo=Uo zAghPvC%W(Q^iulaG>4m0cz*GljD!?XY!CGP%*lR^qumFkx`OC%YLH%3{B3KIfguOu zP@yju9cXk;Ro6V6IGR|C}F2fJBO?9#!IWfloxEGh{rfMp5k0}%HKG5{Y{*z zbo_A0>_K+Ro|*z~XNRYkmm-jrr}f;=>AR2OYi=t%7!`!a|K{Q2EJmysV~dFlZ$&0C z;>@S!&`)Za%hmz`LLBg@p)xlbms zzvpQZv8<3C+-(?fw5Mk%@WI@o%DTEeoQ5hAu4(t|;d+8mS_fig#S29|ygwtW(ck3A zkS|0o+qZo$a--%uAloKjijixzR zW=B9>TK48!Yovd2;tQR#{M4|jOUw~Moc7TrGwTdyk|K{)lcytYYFt>gViqIcCDy9t zp}GG3Jp!EkLX+4V-nkx^^3ikTp%w@VnNKvnnY;MuSxJ2c=+Kg4U%+Eitc+Ih0F3W# z)jyFjmW+_Ge(;9L$!E~v`S-qFbKNUgY_8DomlNYgaFAD;P8tRdkyp@{VkEJs@|o$* zIg&^2TI7|XFvvd>etYWbK@hqU^^|O=h`6{doEF13!DS0}I0p_ipi}*|sVR65?6?^) z|0`Ea;SH$elC(Yo10poz%74~7iwG$`s=V#>2Li$`_@xb%hCbYK%HCxJ4`3iSMv1$m z7;fMG+&rze3^?kiQ0EYC_ls3+O2qNe@7e$~*y!1n{ZcDF&pg0+(JGslmv?;${H?qe zt@{Y08VEff682*!a{7Y#t2d`|AFMjHcDLTtljktNln!p7Htd8W{;}s`pmWUmE~X4?^saJSYNup0f(=PGl&lH76qDu_CZi6HPfL- z;6By7wx^&_{TVM>(V}A1+ zK0CSkpgpdd?LNKh^lqkCUq$y`dk<$3{&!(P{I)}JfwON3lqmXL(A)Cj*K>$-jvzc} zMwpx8J70WuW#Z~a@l{hLK1io%j(GrY&9qCstS-N37uLOZ1Z~wg^CBIFaQ}6ctr*-9 zqJU`l;OF{vRf)jjxS_$;q0}ysBATfR^XF14Sa9hbT(oPj;+yG{jZ?N>&_BD7Epp@$ zu)c|v>wbIY#*o&c(M%@YJYw=_HvT62hV4{(Sxvm1DHiWzPo<+hqwZ>JJPhyTI1TVC zOsQfmiLY9aB8mP-ieCHb#pe8An;eSZ=kL20{y-`sDU~c)(=&MckktJvRDRFRWU@zn z>+Olm7rEV&kGslwyo#3`7Vxb6F|$E@VUq*ooa+zfUqp1*6X8%CYN;PI2g-f@wr62UA0Gm&*0GZ2`3gwn)k+LPg_;y1j?) zb{dy{v%GL9<``FFSJlxSu3?MMBr^>z+rT7(QXzYunYo$VREZ`Ao7JPk|5xa>&=YVS zt&(i^_(?LX3W!5jH|eEJd!o z&1PQNldBp~`{J9KvZIGwvotI~UKGDr<3E92mvZq@PoPNNQJ@pWl?)0D*#jdzjldUaP?L!>bJS%j%vpGSim8s>In3!>W<{bbV1HC4zi~Ou1LT1n zVT5>20?kT^(e>jm?CN^RtNN5yr5X^7xiASiqtd1-2)Sj~u6+%DPs5>sY4JZ`7$P~8 zqa0I|;&m*eh<44^`#|KwX?L+^yQLB-T?r1n6;%~Z7pI$){WyL5cwxTwSK0BpE)!$bT7SO8Als@IR8a(c{H>-3)e=zf zon6L=WB|)7Oxik%M7$TSMYHt6CtF*iqTkp*Z?{QPfI}non53ECm~<%d)GY_d`NZO0)3pBAO84+(b75`!XX|Kf^aNXT4Bhvf!^|* zL4t^cTtM9lqX>@O3FK~@{o#bhd^4{p)xuOIfg+kf`t&TOkIUAu>sRJ<`0q14*hi`K zPKjN-?!nvSt7b{ z;pur{)*=Xxlk7W9Ow-^`@fCAUfT{=AYsNO0*xOc7QB$a&fp)&|hbm(mmc4mXgFGE% zc0@5h=dBgrw#9b07qz~x#TWs6hxvuc$2OUnPi}N5qS5$;ZYopqH|xYlQ7IfRZz=mJ zR4zywh|01kOG@6iN+_XigjoctA2|0Bk2E%~_Evupm9k3h2DiDhp*d#;w!dJbvOl{% zcI2nULCN{haa>5!Flig?YfVcXs8-R8G$Wq{OWpV$K>2Rxq1K_!FD0K~q5is4tzKL*y&WgzA(@rxF{~SYKh){BU!4YExlEj;^s5pv{BCXODoJZdW{x-s2prG!K|*ZIpCd)_^JrrP7p z$rKe9_6{bHDFer|4h%q;i|;zZ&nE{?A&oiWllRTAk8Z8KuRYj}Hh9S-J22cb zGBRKgZt-*bp3&F#F{*~qB!@t3=D8L^4`3R&5 zGS#s9j6mG*ESCP`N{k{+Fv(;2$6Fs$Xfv*Nsp$ThcL*TWx$oDm8B=lohiju7!7-rT zfB9DI`OyVud?4wS9kFqK1CU*&J(7zDL~hMRY>UwvmyUjK{>Nv-_}Z;WqXrGtTt}dG z`K-03Er7JdlkqIArQ?Pz(HQkN{hN-g@bvPk#kdn_e41UwUHRf&(=IOldsk}~l#m$` zz_Aa(>yU#9O(|}o<)V$_J-6Hbbl0e{f8kFilL5sd;SxXm>6xF@;M{ks3!K)0kLhgS))YB#QlYD6nJ9-8m=)Voo_A|fvf3zfHR zYwK|!O2buqPrf?`p6G5pA{f|Ko1+DmWCaJ5> zKBJ3<<_|P`c+jJ}zKm>7oqfM}+i3SR-`EnCi{@OEZ^R)rrJ<`?=2-Y#<; zXFVG-%HA=^{9_(q6vY3-xR8h$G+3<>M6f5 z!O4aeivY_K2DUFX>1?riUv)GE)o#I9DkS`^7A_%7I*ZJ z*0jcb#7RriKW%qkoZE0d8(Sy32zVE?WQ+yk_U<98s^T@65c4fc_}PmWcx_uj0900X z-;{w^S0s{ior(mqD$6c8LNjDr^dTcnEXFZh&CGJR=fbiDlxN7Sv~eYnzKdYKJq+F9 zAjLCtRYb8EY4S7e&>nub9rOD*NH?}#`Kg7lK_abwl(nZwDSGy^=g;G!qF8=Be1`f7 z2HPu5CcIj{*HM~S$7A8SHkg-4QkeX`&V*=zJ>{9HV>vY>Y-(x+_tOm~;F`0z79>=QyqEK~-taM+m3K91 zFke5H@%3_GkuQ|7U%xA3(V|6hx+$Ce!PvuQT}=u*u=)Ufv!9#-h#V`4%zh^zdl#uq z^gH(4O@HVi2l3#5Qapk*4p(z}9=prVwd{%X%_&U=76pJ1W2R2xQsotXJ^kZzi6n;f zF!=44Jf?kf{ZGmW8>H>ccjo$X^qB@9S--%Ei^Iij-|!`*vr0ecCJBenOSq8N)K%2| za`}==b{=EDs%CnKfdgp)#l8GVgH4}d|0kc>1=5U1Gkl@nCaa0al02hwoA$S74u}qZ z-*(|(NOJGYCXW<%%QleJEZhU{)VS*sSze{2bc&XVRn8d);FllJWs zb}R52%<(L532YBll3e`#jr%-ylJmjg%f-Et_D>$WhX3_{$#tJso+z?l63blrRjH|7 z{9+IP>V4+N)f&7c>bh%NolZ2Qg~U2voLn*_{$};ZL~_KuI+4D~*K@YMJ5bST99nf{ z9naj2#w;H`eJW4b>kMjtgR9B2jgh%ujR&Mow(ZMg$>kzdOdV%2svIq*O&PQBEq)-J zRZR%(M&EOfy833XtzI07&T5~TzW%V?d1;rRf16V!-`oC2+x0jnuTK$od#ZfqhQR~- z7_GQoXu|R)l}@HKbWB$ZB<-1YU=GRb%s8vtA}ewB^uZS-#_dKqcHegR&gu;861 z_&$sG{XFY*V}~VEDGgb3o=K50Fba#@aWVtkJP_+ zjfHnJ?NK{`;sx@taJg)I*F3rwryK_gNG2N^)RW}y;fw`;qDgZ=U*s#$ZgG8 z4&cy8NA7>{RmnyGe-~x7`TX1R-p(e#1MeFeAZG&4+(ZBrxWfBjFoPVHH8j{~cB7O~ z4+4(fpR(xjJ%{%|Q+M1U26h@?W=gQzoF(-dvzs9edLi?(29pD%!7q;GQ!_MdM6(g^ zZw0(diNW#e>Mx0j4G@|4Ym(JkLNynaLhA#n$X$T`)WhWO&wM^qla;9C2woa%A#E>v zbnh+lx(`#Q7!kHf{6HtrlcrAPLgzJevBD}+*TWLeIS-c!w%hN{vdFnOBwhUO%59H= z8+YGdS%(9>kM|oW#%@WiF(EC|IO}1x6->tPhic9g#LLsa^R%Lv<{U(>=kJp6781pBJy^+JWU9T{-AO zonSIR!2IWnrMIj&ms&hGLfzQCLxIf8eKaOaGbtYd7npw{YpIHJ(WG57JL9R28FCE+~Je6lzg~&0Ki&2TrLrw;TIX6wUbeT5^{4^`RMGTTHUGSFg-Tq!A zWt5D~%y%+@A@61qd;mvtpjl7XXEB#?nriB&7?*6_a3|<;*m{C}swxMCGWh9PSXfQo zq}kR#u!+BxC)A@S#U1%!?FCQOaPd`VYc_o@6au{ns<7xygM!a3O7E~)-kQ=$t*<%U z7E&b_EqVt{T>zg8>^nX$6G-#F#P3g5p(0Ufd@AH0O9DFm(tlG@<2@f7%oJ8g4345H<{46g-sglXz8f#?c)Q4X9g5`}BRelS#9JCxm06njqPumZc z{F@EdpIO+<9#d-1&Z=7>nFkmPT3gIwTlwe>HYG71Vb03!ec;_19Dgq6AaPz)l+0Tn z!0B)wD^sRKi;iFLEcu2Zuhf(XE5V4{v=Ew~;7u|O96|M)Sy}qVA?Fq=$0QO-ua;!E zrr@eXmL0b=Y1!WoKlNfQ4ZA6w)tppxC7<+sYu?=`!dl%W;kE442_&-vIk|-H5XVQ` zt1WX9EiVhka6}~G6t8#q?sY@6OB(Zkal$H-Uan9fC*04(0M- zVnJB4oTDQ7pj^9safR6DMpSP{c8HU|xT#0qQ?OeW;TudbK3~HFAYS%s*1ks*BiG8a zKZa43fC)icdTTo0dlQk>=i~;jGunZM5-}q=TPP;hgi4Ev&%6T+_q2ND@rGP?>t&Ij zC|a_78wLgk`U<5*eaQt#QT51Op0tFV!CrU)3ggT|#}E7)aH?re8s*YU=d@}Y7#N^Y zicJ9qQPE+3LBa6iOyUJ#J0ws^5j6%MP%Efl_`b2VaV(hBW_AM5q;fk)_=-tM1zm5c zOy(2H^4AcM+0~^Pf-@Zlu0Cq#^?bX0`!#17u80dwMYew{+{a6u{^%*g3H?%u9h%y4 zKYWK=GK+O)X0lk^ZxN@^^%#3^I*LwPe#tR$A!1@q?m+AElss^yk77`uyDp3DvX1t0 zx9e}tp(?&G5OQ4ph4lAlK%zZ$NzJam#qfkvnrOR0TR9*Zxd{1q!`14<&(&KV@ z;d}mQ&`Mw$`#8D$7KI&Ob!TIE5ynjPh%6NfQ@H`5QuqQ=_3!B*6BpZp1sL1}4-KuK zdp6Ewe8*ZNlH0V^!pG1$J^pA4yPGZx2aJ*7kqpQmi&K+g8hA3@7U{?y6$b|gsBFGj z9+>`$m+sp>)5W~)N5iDMZX-$Y9B%_Cz_m&b9X<@Z=-n`dJs2X{{;Y)_;)0OFkw|lX zziYVP?Xmz!f|S^sOQtH#QY0t3X}Ea!hqP9WOJ|owk%=U#!;IrbgWLBE7ccZes7aKr zm?n|hU^(nD2=8iV%o|@EGXtq7u}z7e?jQ^a(GgpP7Uye3d*lLNv#;r$x{*t~%ft`M zJT1o{U*BT5^aIkxJ9^c5Uq+X_JNq95Icb+)5ygN0{g_Sp+ z2u%-}dEQMRJ!IOq?&p{UH&Y2t%|LK%>r!n-b90h}%ULE8iQDCQ&0py|H66YoE2MGN zB(sm>rrgiQ`yP5CJs&H+f9iBltYk?+8GmITJE-Zzw*9wnNAW;k5&X}?2|GbcV*IpC z|8?WtlW~c|KMtq=_2x&i`*LDqkH0?jU(pmkhU^e}sC5VPCzafOIV12Qm&^{WsjFZP zqnlpnx@l zUFLMmESDpbg4X2nOt75sl)JB?Z(nB3rof<2F5My%lavm)pDN$;v*?LF|0PFX&JE|a ztwikU7e7UOznji8i76k{ymEg&vd%cOTH@t|_PvuQdt=4Z-ul;gay{BLRbJC|`@#bY zzHgtrrCAPVz@b zoiDe}=8*y?ubaQN;1QnYE9v9XPgc*pD8I^%QoApD3P@6jmoH(xf zZ04jax79zXo1^)Kmay0^ZF^cf(Zh_tdle?`A~CPTy?p_xVS_mG^H2nGB~_NiVY9_HFO-wFM>fYIUsb z&rD`_EiT?uzDEK>O#>iCfU{}P`Y$gMva3W+tn*x=cINV175%c6KcT-l@g-tQqs1k6 zyZtWguNyrLl`PW{hUknrLH3UAs`*`z`dr#zz zqR_jXFIO&JcldFvj`uVrSVIm4=3MkuDtuxy&z?zYUi?1VHJ%me%Fk}{#aLP-uZcfw_;>&5qUk{8_DWnQ1Hwoz-r_s1lW@S+EphA1x8=M7eVbH&>CrP}p|i$qP! zvNY6McHZ8xgcifA5|Z}gyxFZmIODVR25KAaJJ28yryHRfDtqDOal^x+J_%~I(f(Io z&cUqfUDm6=e^A}xm2sT?@_x8u476CP?FhD4+q{{zZh5xR_B{*e@9#N2@%>K%47mUZ zs@}# zk#0Lu68ZevdS#4SU(pz}=CbpmClviG-sLxoUIhEc&Pf5ALTh(=v_7|U9aqez7`x|U z8}B8(v8&5cR86?6~8Y?f&S+75TtJ8MMPoLufV0ndj0q)=pnNk@^V+bNfZ)dXETY z^pxo}efjqAM0IN1>5I3?yA8x1l~{Q_S}XpTf7?lN4J>S~sU}wK$+QN(e&Ojm>`Fhr zdd2dMoW8-1Y+q0@sfrW|cldb>o|_p6_*=*E<8!?Y2lMr3b>NbkIaZ_s3$xzzB&$2M-?}`dKFw*~eWUn)FT0 zIWzUvhnZE|B~N^#b?66PRXr>8_^65D$K-cKfjNRh&dJgnOLiXo{7Oi!&x|kcZ0g1R zPX-lkzn5t^Rrb{I|0(Rs5~cUNh#tBmL_B_4|K5pZUJadCob{d(Lz0w}A5I z?_$~r`>C?!lfCsQ5*W$U$1V7q{jzzRaE=L}{y-Cyallg3&O^_V#=0{JIIZ3v4h=Ap z$SI^r3V%F!ZmC==ml9{_= z9u;qZL}ClA=jC7Uuz+=d^4yeJ`C*ek(yrS)T)P7I!)p+Lbpfo=acpb3n~+=^zWAmJ zpqr=^qfP40>>lw6x4fQg@6TPysK)xq`7EZL{Wj8l>~232C!Z`6q%z?|;J$;XIOrL( znS2{uVY^T6M4Kg~y9Yr_@eZ_7bE)Y4#>RCoR8nJ`v_<#vfpr=bs#K!STd9LkOgUX@ z^3Wlbm*bX!WxU@9p=J`wuH5fw*)MMS&f$@)U=Cjv*}H$J*bz09`3T}0r`qdh-9xo7 z;4WC4#f8~q%wpl5InkrpN`)Hv<>~da|AgX4Di19@Qx&nY^bDFGTLNO|cAvl;4R?2* zWUXXd=pt@BAG|M_UGQr89K-lUN&{1Fl5Sg5C*Ju8E51zV2!00W_~>#T_(8GgtYf#; zE<|@RW6Wbl1^ltUi#qUt(Sr4_e5~n%FQ9%DidVl!$<>vbJf~7h`cK^5uH=HV=;=Hi z;)xe+sOMTIo%gvz8d@t0KyieX)e=au=axu~9_KoYYv2yZ>B|8bSs9W{(hfb=aye#( zjlyWW4|x@?b0ZV)p-^CM`$x)~It_gM$AE-#qp(I=iYlG3GQ3Vr8}DEND#mR!y#QE| zc?r=xj1QKKweisRf<J0)`>#*@vEOuMXT8CISNgObQ#8KIiM{FZNZ5y*XfX37F7CVN2ujR@N7e_oqucz%VHkArf`j2 zR2o1XdGJ8Z22Opx_;^O}56E5<`zUpP_dI!^4P^&ZDS_YVnRB?ZtVCB5mLUPM&mW9T zc0#lEnHfu^Yw}XdqA(JCH$@!hKs!P&RZj7apo_YXhb(Hiz|wW@Z9~R%aJmu+e>QX` z;J2y%UQmL97<0H}d_Nw|BDuCq0`AVITBdHGT2-J}bH`JD3q*75Q5A|E60bX7XXpmI z&>;b`a0L1D!@+#-yR4D(_*3bB$4(nr&h=+RsiC}S=_u{Rh$?x$X(=9y%l)7nx2>aAJ#FWeI;jd^arS{5HChGo7Nwzd9HPK>aq z-A|V-89_T4dPk?^h>b+WG`3ze_3qZEECTdSx!!4J*aRKQ0q?Tn;^7Kwy${{D0ry>w z@sUkg?$llTn_(lJCadM4^SGD7Mv0TuA_yj(A!r_i^=O9cU+>J^Sm?>ISdGYubPJlrGD=;D{3loEYT-SpW+WIvSozvKPf{Wabj((rIwCf#;i!mNpXG!S zk$jhBq3EK)eCaCBoOJ>nH7`z|QewZkqYs*$LrP$9hN&Zy+BS_{19Ys94QlYY4o06M zDCbzaN`V%1Zc5%q^d()S#m0+BOP`J2U38Dh$mZ-?D9tuqTw2Z(l<)l70YG$K~;$ zn2T6&(g>w*HxdX~$NRo^QFWIlQ>GQ#muotc;m%J_10Wsl1%camnQI#%rE!cL{7B`1 ztbgC3-_Ss>G1Io@Rkw%!SlIQx z{?l2YySIX`!czGiW->2rEO&P>`hD6Nq7^6Z0WqbRm_=NCd@UtPVEAsJAQsoU4Y9>f zfd;@!5H*6^4;aX9EB>!{eG`mltvcbAG?ag_7UY2yu=>xbR%z*k{i?lLSJO9`3-Ii& zXS-{BDYKm--Yj~jQ)k4&qYy_h>4=PG8y}BRJ)}X=+rVB-4rCmb z$`|+!wu<^)e^p9%bnNfa*K}qfy@Bj$U*9FvM4W^jTKSxpxFi^+l>cX?m-cH@(A?8H~4>uiHT7#j&;MWweZ5-A!-=vU?ban#e(%& zXrv07!p7kVb$!&Lx}P;~=};#bMhg>P^9QrZjr3S(E`pAj`cO!$$0UX-D>VHYxta&0 z$)bP0r_EpE1{wg{(VaKn+~+EfAq3=G7XRhPt0ZI-d&yHk)Gdy#eN0_&;jjp)J^?z` z79nuVv~^Z<3o{YTdzM5ozWj!?g!k!#pfA2DDB<cjmO**jk^Gcr1nN- zn+qu50$hOVR0bCVYw{m1K+*rU*`n#(uL)c38?PXEEPf+Dl3DoYx;|!my_@lo7N(=1 z%s?QOyX3?F&9$3k%UZ#hnECN)oYlc8<>87#1Q_KNMa9!^9^NJfd;l@9PmTiU16QXX zi2;Mv^Q!(J*kyr?#q!|vL7>Lx1C%>i;MI|rc>A3{diy*1n-m0l0lUJ*XwU!8clLq* zmbWQ(08>72jw(P~ST|%A<9U36SBB+I?NA5L-P=4; lq{Vl#4S(c2F-H;G6o#$y)8Jjbjhvre`1R7+Vk76Me*w7Rsonqp literal 0 HcmV?d00001 From c368035e6d16469602c76336d4be6f325f6f72bf Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Thu, 28 Mar 2024 13:20:34 +0800 Subject: [PATCH 057/162] Add sequence diagram of parser class --- docs/DeveloperGuide.md | 32 +++++++++++++++++++++++++++++++- docs/diagram/Parse.png | Bin 0 -> 45389 bytes docs/diagram/changeTaskType.png | Bin 0 -> 16503 bytes 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 docs/diagram/Parse.png create mode 100644 docs/diagram/changeTaskType.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 81a4b586f3..53c459c98a 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -41,13 +41,43 @@ ## Parser Component -Here is a partial class diagram for the method changeTaskTiming method in Parser Class. +Here is a general guide of how Parse Class looks like in sequence diagram. + +![Parse.png](diagram%2FParse.png) + +Here is a class diagram for the method changeTaskTiming method in Parser Class. + ![changeTaskTimingClassDiagram.png](diagram%2FchangeTaskTimingClassDiagram.png) + The following sequence diagram of changeTaskTiming shows the interactions with other objects. + ![changeTaskTiming_Sequence_Diagram.png](diagram%2FchangeTaskTiming_Sequence_Diagram.png) + Here is how this method works: + 1. The Parser calls the changeTaskTiming method with a command and the UserList. It calls InputValidator. + 2. The InputValidator validates the command, ensuring that it meets the required format in days and index. + 3. If validation is successful, the User calls the timetable and calls its changeFlexibleTaskTiming method with the specified parameters. + 4. The Timetable updates the timing of the flexible task. + 5. If successful, the InputValidator sends a success message back to the Parser. Otherwise, it throws a RuntimeException. + +## Timetable Component +Here is a sequence diagram of changeTaskType method in Timetable class. It shows the interactions with other objects. +![changeTaskType.png](diagram%2FchangeTaskType.png) + +Here is how this method works: +1. The sequence starts with the Parser sending a request to the Timetable to change the type of a task. + +2. The Timetable activates and processes the changeTaskType method. + +3. Within the Timetable, the dayOfWeek parameter is capitalized to ensure consistency. + +4. The Timetable calls the list of tasks associated with the specified day (dayOfWeek). It activates the Task object to fetch the task at the specified index (index). + +5. The Task object modifies the type of the task to the new type specified by the Parser. + +6. Finally, the modified task or any relevant status information is returned to the Parser. diff --git a/docs/diagram/Parse.png b/docs/diagram/Parse.png new file mode 100644 index 0000000000000000000000000000000000000000..b12766f59b34f7ced9c59e978fa67cd7fc3f893d GIT binary patch literal 45389 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

5)R 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 P|5wp>wqU;^7+@|Wc# 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 Date: Thu, 28 Mar 2024 17:31:04 +0800 Subject: [PATCH 058/162] Add storage feature in DG --- docs/DeveloperGuide.md | 12 +++-- docs/StorageUML.png | Bin 0 -> 130278 bytes docs/uml.puml | 63 ++++++++++++++++++++++++++ src/main/java/seedu/duke/Storage.java | 10 ++-- src/main/java/seedu/duke/ui/UI.java | 4 +- 5 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 docs/StorageUML.png create mode 100644 docs/uml.puml diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 0c327c7154..c8f0d8ee12 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -6,9 +6,15 @@ ## Design & implementation -{Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} - - +### Save timetable function +The saving timetable mechanism is facilitated by the Storage class. It implements the following operations: +* `Storgae#createFolder()`: Creates a folder in the directory where all the users' timetable will be stored in the local computer. +* `Storage#addExistingUsers()`: Loops through the folder to add all previous saved users upon opening the app, as well as their corresponding tasks. +* `Storage#addUserInFolder(User user)`: When a new user is added, a file with the name of the user will be created in the folder. +* `Storage#writeTaskInFile(User user)`: when a new task of a specific user is added, it will be written into the correct file. + +The following sequence diagram shows how the operations in the Storage class goes through when the app is opened and it loads data from history: +![Storage UML](StorageUML.png) ## Product scope ### Target user profile diff --git a/docs/StorageUML.png b/docs/StorageUML.png new file mode 100644 index 0000000000000000000000000000000000000000..da38ae8a8dc2073dc310c891e01117f0959c4960 GIT binary patch literal 130278 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�`w=HL>PMLC;oDP()KDo3$0wtMR8-o2$X6zr4) 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 storage: createFolder() +activate storage +storage -->> duke: +deactivate storage + +duke -> storage: addExistingUsers() +activate storage +storage -> file: listFiles() +activate file +file -->> storage: File +deactivate file + +alt directory is not empty + loop file + opt file is not null + storage -> userList: addUser(user: User) + activate userList + userList -> userList: add(user: User) + alt allUsers.size() == 1 + userList -> UI: printActiveUser() + activate UI + UI -->> userList + deactivate UI + end + userList -->> storage + deactivate userList + + storage -> storage: loadData(user: User) + storage -> storage: extractTaskInfo(String line, String day) + storage --> storage: Task + storage -> user: getTimetable() + activate user + user -> timetable: addUserTask(day: String, task: Task) + activate timetable + timetable --> user + deactivate timetable + user -->> storage + deactivate user + end + end + +else + storage -> UI: printEmptyDirectory(); + activate UI + UI -->> storage + deactivate UI +end + + + +storage --> duke +@enduml \ No newline at end of file diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 987697dae9..b1b78e05c1 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -1,5 +1,7 @@ package seedu.duke; +import seedu.duke.ui.UI; + import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; @@ -11,6 +13,8 @@ /** * Represents a storage manager that deals with loading tasks from the file and saving tasks in the file. */ + + public class Storage { public static String filePath; @@ -24,6 +28,7 @@ public Storage(String filePath) { Storage.filePath = filePath; } + public static void createFolder() { String folderPath = "data"; File folder = new File(folderPath); @@ -57,7 +62,7 @@ public static void addExistingUsers(UserList userList) throws FileNotFoundExcept } } } else { - System.out.println("Directory is empty."); + UI.printEmptyDirectory(); } } @@ -76,12 +81,11 @@ public static void loadData(User user) throws FileNotFoundException { day = line.substring(1, line.length() - 1).trim(); continue; } - user.getTimetable().getWeeklyTasks().get(day).add(extractTaskInfo(line, day)); + user.getTimetable().addUserTask(day, extractTaskInfo(line, day)); } } public static void addUserInFolder() { File f = new File(filePath); - String day = ""; try { if (f.createNewFile()) { System.out.println("File created: " + f.getName()); diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index d4c05df61a..2549abb5ca 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -47,7 +47,7 @@ public static void printAddForAll(Task task) { System.out.println("The following task is added for all users: " + task.toString()); } - public static void printLine() { - System.out.println("____________________________________________________________"); + public static void printEmptyDirectory() { + System.out.println("Directory is empty."); } } From a158be3f2ae61cb9032d214c01f788c5eab008ac Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Sat, 30 Mar 2024 10:16:19 +0800 Subject: [PATCH 059/162] Add next command, more parser tests --- src/main/java/seedu/duke/Duke.java | 8 ++- src/main/java/seedu/duke/InputValidator.java | 6 +- src/main/java/seedu/duke/Parser.java | 76 ++++++++++++++------ src/main/java/seedu/duke/ui/UI.java | 17 ++++- src/test/java/seedu/duke/DukeTest.java | 8 +++ src/test/java/seedu/duke/ParserTest.java | 67 +++++++++++++---- 6 files changed, 136 insertions(+), 46 deletions(-) diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 990d662970..f25df68f15 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -19,18 +19,20 @@ public static void main(String[] args) throws FileNotFoundException { Storage.createFolder(); Storage.addExistingUsers(userList); + if (userList.getListLength() == 0) { + UI.printHelp(); + } + while (!isFinished) { try { String input = IN.nextLine(); - Parser parser = new Parser(); - parser.parseCommand(input, userList); + Parser.parseCommand(input, userList); } catch (Exception e) { System.out.println(e.getMessage()); } } - //assert false: "dummy assertion set to fail"; } } diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 63cb694240..7a024d6d26 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -36,8 +36,8 @@ public static void validateAddTaskInput(String input) throws InvalidFormatExcept "+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})(\\s+/type\\s+[fc])$"; if (!input.matches(regex)) { - throw new InvalidFormatException("[ERROR] Invalid addTask format. " + - "Expected format: addTask /on [day] /task [description] /from [start time] /to [end time] " + + throw new InvalidFormatException("[ERROR] Invalid addtask format. " + + "Expected format: addtask /on [day] /task [description] /from [start time] /to [end time] " + "/type [f/c]"); } } @@ -160,7 +160,7 @@ public static void validateAddTaskForAll(String input) throws InvalidFormatExcep "+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})$"; if (!input.matches(regex)) { - throw new InvalidFormatException("[ERROR] Invalid addTask format. " + + throw new InvalidFormatException("[ERROR] Invalid addtask format. " + "Expected format: addforall /on [day] /task [description] /from [start time] /to [end time] " + "/type [f/c]"); } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 469bf3bb66..71c2730cee 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -6,13 +6,16 @@ import seedu.duke.ui.UI; import java.time.LocalTime; +import java.time.LocalDate; +import java.time.DayOfWeek; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Parser { protected static final String[] DAYS = new String[] - {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; + {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; /** * Parses User Input and Identifies the command used. @@ -33,6 +36,8 @@ public static void parseCommand(String command, UserList userList) throws UI.printActiveUser(userList.getActiveUser().getName()); } else if (command.equalsIgnoreCase("view")) { userList.getActiveUser().viewTimetable(); + } else if (command.equalsIgnoreCase("next")) { + printNextTask(userList.getActiveUser()); } else if (command.toLowerCase().startsWith("adduser")) { InputValidator.validateAddUserInput(command); String[] parts = command.split("\\s+"); @@ -63,20 +68,15 @@ public static void parseCommand(String command, UserList userList) throws UI.printComparingAll(); UI.printSharedTime(Timetable.compareAllTimetables(userList)); } else if (command.toLowerCase().startsWith("compare")) { - try { - InputValidator.validateCompareInput(command); - String[] parts = command.split("\\s+"); - String user1 = parts[1]; - String user2 = parts[2]; - InputValidator.validateUserInput(user1, userList); - InputValidator.validateUserInput(user2, userList); - UI.printSharedTime(Timetable.compareTimetable(userList.findUser(user1).getTimetable(), - userList.findUser(user2).getTimetable())); - - } catch (InvalidFormatException | InvalidUserException | NullPointerException e) { - System.out.println(e.getMessage()); - } + InputValidator.validateCompareInput(command); + String[] parts = command.split("\\s+"); + String user1 = parts[1]; + String user2 = parts[2]; + InputValidator.validateUserInput(user1, userList); + InputValidator.validateUserInput(user2, userList); + UI.printSharedTime(Timetable.compareTimetable(userList.findUser(user1).getTimetable(), + userList.findUser(user2).getTimetable())); } else if (command.toLowerCase().startsWith("addforall")) { addTaskForAll(command, userList); } else if (command.toLowerCase().startsWith("viewcommonevents")) { @@ -115,15 +115,14 @@ private static void deleteTask(String command, UserList userList) { } } - private static void addTask(String command, UserList userList) { - try { - InputValidator.validateAddTaskInput(command); - Task task = parseTask(command); - userList.getActiveUser().getTimetable().addUserTask(task.day, task); - UI.printAddTask(task); - } catch (InvalidFormatException | InvalidDayException e) { - System.out.println(e.getMessage()); - } + private static void addTask(String command, UserList userList) throws + InvalidDayException, InvalidFormatException { + + InputValidator.validateAddTaskInput(command); + Task task = parseTask(command); + userList.getActiveUser().getTimetable().addUserTask(task.day, task); + UI.printAddTask(task); + } public static Task parseTask(String command) throws InvalidDayException { @@ -227,4 +226,35 @@ private static void printConfirmedEvent(UserList userList) { } } } + + private static void printNextTask(User currentUser) { + LocalTime currentTime = LocalTime.now(); + String dayOfWeek = DayOfWeek.from(LocalDate.now()).toString().toLowerCase(); + String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); + Task current = new Task("temp", dayOfWeek, currentTime.toString(), currentTime.toString(), "f"); + + ArrayList tasksOfDay = currentUser.getTimetable().getWeeklyTasks().get(capitalizedDay); + int numOfTasks = tasksOfDay.size(); + + if (numOfTasks == 0) { + UI.printNoTasks(); + } else { + Task nextTask = null; + for (int i = numOfTasks - 1; i >= 0; i -= 1) { + if (current.getStartTime().isBefore(tasksOfDay.get(i).getStartTime())) { + nextTask = tasksOfDay.get(i); + } else { + UI.printNext(); + if (nextTask == null) { + UI.printNoTasks(); + } else { + System.out.println(nextTask.toString()); + } + return; + } + } + } + + + } } diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index 510e76e254..0a31d0f939 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -35,12 +35,13 @@ public static void printAddTask(Task task) { } public static void printHelp() { - System.out.println("List of available commands: \n" + - //"\n" + + System.out.println("Note: use hh:mm 24hr time format (ex. 13:00) \n" + + "List of available commands: \n" + "list: list all users \n" + "bye: exit the app \n" + "current: view current user \n" + "view: view timetable of current user \n" + + "next: view your next task \n" + "adduser: add new user \n" + "switch : switch to user \n" + "addtask /on /from /to : add task for current user\n" + @@ -50,7 +51,8 @@ public static void printHelp() { "compareall: compare timetables of all users \n" + "compare : compare timetables of specified users \n" + "addforall /on /from /to : add task for all users\n" + - "viewcommonevents: view common events \n"); + "viewcommonevents: view common events "); + printLine(); } public static void printAddForAll(Task task) { @@ -59,6 +61,7 @@ public static void printAddForAll(Task task) { public static void printEmptyDirectory() { System.out.println("Directory is empty."); + } public static void printLine() { System.out.println("____________________________________________________________"); @@ -82,4 +85,12 @@ public static void printSharedTime(Timetable merged) { public static void printComparingAll() { System.out.println("Comparing all timetables: "); } + + public static void printNext() { + System.out.println("Your next task is: "); + } + + public static void printNoTasks() { + System.out.println("You have no tasks today. "); + } } diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index 14f6b8864e..6ca414e690 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -32,5 +32,13 @@ public void testAddUser() { assertEquals(1, userList.getListLength()); assertEquals(user, userList.getActiveUser()); assertTrue(userList.getUsers().contains(user)); + + User user2 = new User("Test User 2"); + userList.addUser(user2); + + assertEquals(2, userList.getListLength()); + assertEquals(user, userList.getActiveUser()); + assertTrue(userList.getUsers().contains(user)); + assertTrue(userList.getUsers().contains(user2)); } } diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java index 93347582f8..4b70995bad 100644 --- a/src/test/java/seedu/duke/ParserTest.java +++ b/src/test/java/seedu/duke/ParserTest.java @@ -8,7 +8,6 @@ import java.util.ArrayList; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -91,30 +90,70 @@ public void addTaskCommandTest() throws InvalidDayException, InvalidUserExceptio Parser.parseCommand("addtask /on Monday /task test1 /from 9:00 /to 11:00 /type f", userlist); Parser.parseCommand("addtask /on Monday /task test2 /from 13:00 /to 15:00 /type f", userlist); - ArrayList testTasks = user1.getTimetable().getWeeklyTasks().get("Monday"); + ArrayList testTasksMon = user1.getTimetable().getWeeklyTasks().get("Monday"); + ArrayList testTasksTue = user1.getTimetable().getWeeklyTasks().get("Tuesday"); - assertEquals("test1", testTasks.get(0).getDescription()); - assertEquals("09:00", testTasks.get(0).getStartTime().toString()); - assertEquals("11:00", testTasks.get(0).getEndTime().toString()); + assertEquals("test1", testTasksMon.get(0).getDescription()); + assertEquals("09:00", testTasksMon.get(0).getStartTime().toString()); + assertEquals("11:00", testTasksMon.get(0).getEndTime().toString()); - assertEquals("test2", testTasks.get(1).getDescription()); - assertEquals("13:00", testTasks.get(1).getStartTime().toString()); - assertEquals("15:00", testTasks.get(1).getEndTime().toString()); + assertEquals("test2", testTasksMon.get(1).getDescription()); + assertEquals("13:00", testTasksMon.get(1).getStartTime().toString()); + assertEquals("15:00", testTasksMon.get(1).getEndTime().toString()); + + try { + String testDescription = testTasksTue.get(1).getDescription(); + fail(); + } catch (IndexOutOfBoundsException e) { + assertEquals("Index 1 out of bounds for length 0", e.getMessage()); + } catch (Exception e) { + fail(); + } } @Test public void invalidAddTaskCommandTest() { + User user1 = new User("User1"); + userlist.addUser(user1); - String expectedErrorMessage = "[ERROR] Invalid addTask format. Expected format: addTask /on [day]" + + String expectedErrorMessage = "[ERROR] Invalid addtask format. Expected format: addtask /on [day]" + " /task [description] /from [start time] /to [end time] /type [f/c]"; + String[] testMessages = {"addtask", + "addtask /on Monday", + "addtask /on Monday /task description", + "addtask /on Monday /task description /from 09:00 /to 11:00", + "addtask Monday description 09:00 11:00"}; + for (String message : testMessages) { + try { + Parser.parseCommand(message, userlist); + fail(); + } catch (Exception e) { + assertEquals(expectedErrorMessage, e.getMessage()); + } + } + try { - Parser.parseCommand("addtask", userlist); - fail(); - } catch (InvalidFormatException | InvalidDayException e) { - assertEquals(expectedErrorMessage, e.getMessage()); + Parser.parseCommand("addtask /on Oneday /task lecture /from 9:00 /to 11:00 /type f", userlist); } catch (Exception e) { - assertNull(e.getMessage()); + assertEquals("[ERROR] Invalid day. Please enter a day from Monday - Sunday.", e.getMessage()); } + try { + Parser.parseCommand("addtask /on Monday /task lecture /from 9:00 /to 25:00 /type f", userlist); + } catch (Exception e) { + assertEquals("Text '25:00' could not be parsed: Invalid value for HourOfDay" + + " (valid values 0 - 23): 25", e.getMessage()); + } + } + + public void addForAllTest() throws InvalidDayException, InvalidUserException, InvalidFormatException { + User user1 = new User("User1"); + User user2 = new User("User2"); + userlist.addUser(user1); + userlist.addUser(user2); + + Parser.parseCommand("addforall /on Monday /task lecture /from 9:00 /to 25:00 /type f", userlist); + + } } From 587bf370d3fa37fb8066c35d8ea2523367e63c44 Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Sat, 23 Mar 2024 22:16:52 +0800 Subject: [PATCH 060/162] working on inputValidator --- src/main/java/seedu/duke/InputValidator.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 7a024d6d26..e628b98999 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -10,10 +10,9 @@ public class InputValidator { * "compare user1 user2" * * @param input String Input. - * @throws InvalidFormatException If the input does not match the expected format. + * @throws InvalidFormatException If the input does not match the expected format: "compare (user1) (user2)". */ public static void validateCompareInput(String input) throws InvalidFormatException { - // Define the regex pattern for the expected format with case-insensitive flag String regex = "(?i)^compare\\s+\\w+\\s+\\w+$"; if (!input.matches(regex)) { @@ -24,14 +23,14 @@ public static void validateCompareInput(String input) throws InvalidFormatExcept /** * Validates correctly formatted addTask command. The expected format is - * "addtask /on [date] /task [description] /from [start time] /to [start time]" format + * "addtask /on [date] /task [description] /from [start time] /to [start time] /type [type]" format * Note: Start and End times should be formatted as such: HH:mm * * @param input String Input. - * @throws InvalidFormatException If the input does not match the expected format. + * @throws InvalidFormatException If the input does not match the expected format: + * "addtask /on (day) /task (description) /from (start time) /to (end time) /type (type)". */ public static void validateAddTaskInput(String input) throws InvalidFormatException { - // Define the regex pattern for the expected format with case-insensitive flag String regex = "(?i)^addtask\\s+/on\\s+(\\w+)\\s+/task\\s+(.+?)\\s" + "+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})(\\s+/type\\s+[fc])$"; @@ -48,10 +47,9 @@ public static void validateAddTaskInput(String input) throws InvalidFormatExcept * Note: index is the index of the task in the task list for the given day * * @param input String Input. - * @throws InvalidFormatException If the input does not match the expected format. + * @throws InvalidFormatException If the input does not match the expected format: "deletetask /on (day) /index (task index)". */ public static void validateDeleteTaskInput(String input) throws InvalidFormatException { - // Define the regex pattern for the expected format with case-insensitive flag String regex = "(?i)^deletetask\\s+/on\\s+(\\w+)\\s+/index\\s+(\\d+)$"; if (!input.matches(regex)) { @@ -64,10 +62,9 @@ public static void validateDeleteTaskInput(String input) throws InvalidFormatExc * Validates correctly formatted addUser command. The expected format is "adduser user" * * @param input String Input. - * @throws InvalidFormatException If the input does not match the expected format. + * @throws InvalidFormatException If the input does not match the expected format: "adduser (user)". */ public static void validateAddUserInput(String input) throws InvalidFormatException { - // Define the regex pattern for the expected format with case-insensitive flag String regex = "(?i)^adduser\\s+\\w+$"; if (!input.matches(regex)) { @@ -80,10 +77,9 @@ public static void validateAddUserInput(String input) throws InvalidFormatExcept * Validates correctly formatted switch command. The expected format is "switch user" * * @param input String Input. - * @throws InvalidFormatException If the input does not match the expected format. + * @throws InvalidFormatException If the input does not match the expected format: "switch (user)". */ public static void validateSwitchInput(String input) throws InvalidFormatException { - // Define the regex pattern for the expected format with case-insensitive flag String regex = "(?i)^switch\\s+\\w+$"; if (!input.matches(regex)) { From 4ab771e2b34829dc7622a3e250a38244fb97788b Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Mon, 1 Apr 2024 22:48:36 +0800 Subject: [PATCH 061/162] Fixed InputValidator for addforall command. Added Unit test for InputValidator (addtask and addforall) --- src/main/java/seedu/duke/InputValidator.java | 15 +++- .../java/seedu/duke/InputValidatorTest.java | 82 ++++++++++++++++++- 2 files changed, 91 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index e628b98999..941521b5af 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -25,14 +25,21 @@ public static void validateCompareInput(String input) throws InvalidFormatExcept * Validates correctly formatted addTask command. The expected format is * "addtask /on [date] /task [description] /from [start time] /to [start time] /type [type]" format * Note: Start and End times should be formatted as such: HH:mm + * Regex Guide: + * (?i)^ = case insensitive for command name + * \s+ = any amount of white space + * (\w+) = any non-digit word + * ((.+)?) = any combination of non numerical and numerical characters + * (\d{1,2}:\d{2}) = the format DD:DD (D = digit) + * (/type\s+[fc](\s+)?)$ = regex must end in "/type [f/c]" * * @param input String Input. * @throws InvalidFormatException If the input does not match the expected format: * "addtask /on (day) /task (description) /from (start time) /to (end time) /type (type)". */ public static void validateAddTaskInput(String input) throws InvalidFormatException { - String regex = "(?i)^addtask\\s+/on\\s+(\\w+)\\s+/task\\s+(.+?)\\s" + - "+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})(\\s+/type\\s+[fc])$"; + String regex = "(?i)^addtask\\s+/on\\s+(\\w+)\\s+/task\\s+((.+)?)\\s" + + "/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})\\s+(/type\\s+[fc](\\s+)?)$"; if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid addtask format. " + @@ -152,8 +159,8 @@ public static void validateChangeTaskTiming(String input) throws InvalidFormatEx } public static void validateAddTaskForAll(String input) throws InvalidFormatException { - String regex = "(?i)^addforall\\s+/on\\s+(\\w+)\\s+/task\\s+(.+?)\\s" + - "+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})$"; + String regex = "(?i)^addforall\\s+/on\\s+(\\w+)\\s+/task\\s+((.+)?)\\s" + + "/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})\\s+(/type\\s+[fc](\\s+)?)$"; if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid addtask format. " + diff --git a/src/test/java/seedu/duke/InputValidatorTest.java b/src/test/java/seedu/duke/InputValidatorTest.java index 185e76437a..d907e85608 100644 --- a/src/test/java/seedu/duke/InputValidatorTest.java +++ b/src/test/java/seedu/duke/InputValidatorTest.java @@ -65,8 +65,86 @@ public void testInvalidAddRepeatTaskFormat() { InputValidator.validateAddRepeatTask(invalidInput); fail("Expected InvalidFormatException"); } catch (InvalidFormatException e) { - assertEquals("[ERROR] Invalid addRepeatTask format. Expected format: " + - "addRepeatTask /task [description] /on [day(s)] /from [start time] /to [end time] /type [f/c]", e.getMessage()); + assertEquals("[ERROR] Invalid addRepeatTask format. Expected format: addRepeatTask " + + "/task [description] /on [day(s)] /from [start time] /to [end time] /type [f/c]", e.getMessage()); + } + } + + @Test + public void testCorrectInputsAddTask() { + String input1 = "addtask /on monday /task running together /from 10:00 /to 19:00 /type f"; + String input2 = "AddTask /on Saturday /task run /from 8:00 /to 12:00 /type c "; + String input3 = "addTASK /on sunday /task running together forever /from 11:00 /to 11:15 /type f "; + String input4 = "addtask /on tuesday /task do nothing /from 17:00 /to 23:59 /type c"; + String input5 = "addtask /on Wednesday /task tryitout_please /from 00:00 /to 01:00 /type f"; + + String[] inputs = {input1, input2, input3, input4, input5}; + + for (String input : inputs) { + try { + InputValidator.validateAddTaskInput(input); + } catch (InvalidFormatException e) { + fail("Unexpected exception: " + e.getMessage()); + } + } + } + + @Test + public void testInvalidInputsAddTask() { + String input1 = "ddtask /on monday /task running together /from 10:00 /to 19:00 /type f"; + String input2 = "addtask /o Saturday /task run /from 8:00 /to 12:00 /type c "; + String input3 = "addtask /on sunday //task running together forever /from 11:00 /to 11:15 /type f "; + String input4 = "addtask /on tuesday /task do nothing /from 17:00 /to 23:590 /type c"; + String input5 = "addtask /on Wednesday /task tryitout_please /from 00:00 /to 01:00 /type "; + + String[] inputs = {input1, input2, input3, input4, input5}; + + for (String input : inputs) { + try { + InputValidator.validateAddTaskInput(input); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid addtask format. Expected format: addtask " + + "/on [day] /task [description] /from [start time] /to [end time] /type [f/c]", e.getMessage()); + } + } + } + + @Test + public void testCorrectInputsAddForAll() { + String input1 = "addforall /on monday /task running together /from 10:00 /to 19:00 /type f"; + String input2 = "Addforall /on Saturday /task run /from 8:00 /to 12:00 /type c "; + String input3 = "addforall /on sunday /task running together forever /from 11:00 /to 11:15 /type f "; + String input4 = "addforall /on tuesday /task do nothing /from 17:00 /to 23:59 /type c"; + String input5 = "addforall /on Wednesday /task tryitout_please /from 00:00 /to 01:00 /type f"; + + String[] inputs = {input1, input2, input3, input4, input5}; + + for (String input : inputs) { + try { + InputValidator.validateAddTaskForAll(input); + } catch (InvalidFormatException e) { + fail("Unexpected exception: " + e.getMessage()); + } + } + } + + @Test + public void testInvalidInputsAddForAll() { + String input1 = "ddforall /on monday /task running together /from 10:00 /to 19:00 /type f"; + String input2 = "Addforall /o Saturday /task run /from 8:00 /to 12:00 /type c "; + String input3 = "addforall /on sunday //task running together forever /from 11:00 /to 11:15 /type f "; + String input4 = "addforall /on tuesday /task do nothing /from 17:00 /to 23:590 /type c"; + String input5 = "addforall /on Wednesday /task tryitout_please /from 00:00 /to 01:00 /type "; + + String[] inputs = {input1, input2, input3, input4, input5}; + + for (String input : inputs) { + try { + InputValidator.validateAddTaskForAll(input); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid addtask format. Expected format: addforall " + + "/on [day] /task [description] /from [start time] /to [end time] /type [f/c]", e.getMessage()); + } } } From 899ea6f72dac53ace02413a7b29e3f2a6f0f6b32 Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Mon, 1 Apr 2024 23:43:36 +0800 Subject: [PATCH 062/162] made UI for compare and view commands less cluttered to look at. --- src/main/java/seedu/duke/Timetable.java | 32 ++++----------- src/main/java/seedu/duke/User.java | 4 +- src/main/java/seedu/duke/ui/UI.java | 44 +++++++++++++++++++++ src/test/java/seedu/duke/TimetableTest.java | 3 +- 4 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index ccc509ad7d..f20deada25 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -1,5 +1,7 @@ package seedu.duke; +import seedu.duke.ui.UI; + import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -27,25 +29,6 @@ public Map> getWeeklyTasks() { return weeklyTasks; } - /** - * Prints tasks of the day specified. - * - * @param day day of the week the task is on. - */ - public void printTasksOfTheDay(String day) { - String capitalizedDay = day.substring(0, 1).toUpperCase() + day.substring(1); - if (weeklyTasks.get(capitalizedDay).isEmpty()) { - System.out.println("NO TASK FOR " + day); - return; - } - System.out.println(capitalizedDay + ":"); - int count = 1; - for (Task task : weeklyTasks.get(capitalizedDay)) { - System.out.println(count + ". " + task.toString()); - count++; - } - } - /** * Adds task on dayOfWeek at an index * @@ -71,7 +54,7 @@ public void deleteUserTask(String dayOfWeek, int index) { weeklyTasks.get(capitalizedDay).remove(index); System.out.println("Task " + taskDeleted.description + " is deleted from " + dayOfWeek); System.out.println("New task list for " + capitalizedDay + ":"); - printTasksOfTheDay(dayOfWeek); + UI.printTasksOfTheDay(dayOfWeek, getWeeklyTasks()); } else { System.out.println("Invalid task index. Please try again."); } @@ -149,17 +132,18 @@ public static void findOverlappingFreeTime(ArrayList tasks, String day) { LocalTime previousEndTime = LocalTime.MIN; for (Task task : tasks) { if (task.getStartTime().isAfter(previousEndTime)) { - System.out.println(previousEndTime + " - " + task.getStartTime() + ": Overlapping Free Time"); + //System.out.println(" "+previousEndTime + " - " + task.getStartTime()); + UI.printTimeFrame(previousEndTime, task.getStartTime()); } previousEndTime = task.getEndTime(); } if (previousEndTime.isBefore(LocalTime.MAX)) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm"); - System.out.println(previousEndTime + " - " + LocalTime.MAX.format(formatter) + - ": Overlapping Free Time"); + //System.out.println(" "+previousEndTime + " - " + LocalTime.MAX.format(formatter)); + UI.printTimeFrame(previousEndTime, LocalTime.MAX.format(formatter)); } } else { - System.out.println("** Whole day is free on " + day); + UI.printFreeDay(day); } } diff --git a/src/main/java/seedu/duke/User.java b/src/main/java/seedu/duke/User.java index 5b0d1e1fba..73174848cd 100644 --- a/src/main/java/seedu/duke/User.java +++ b/src/main/java/seedu/duke/User.java @@ -1,5 +1,7 @@ package seedu.duke; +import seedu.duke.ui.UI; + public class User { private Timetable timetable; private final String name; @@ -22,7 +24,7 @@ public String getName() { public void viewTimetable() { for (String day : Timetable.DAYS) { - timetable.printTasksOfTheDay(day); + UI.printTasksOfTheDay(day, timetable.getWeeklyTasks()); } } diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index 0a31d0f939..5e00abaeb9 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -3,6 +3,10 @@ import seedu.duke.Task; import seedu.duke.Timetable; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.Map; + import static seedu.duke.Timetable.findOverlappingFreeTime; public class UI { @@ -76,6 +80,7 @@ public static void printLine() { */ public static void printSharedTime(Timetable merged) { for (String day : Timetable.DAYS) { + System.out.println("_________________________________________"); System.out.println("Shared free time on " + day + ":"); findOverlappingFreeTime(merged.getWeeklyTasks().get(day), day); @@ -86,6 +91,45 @@ public static void printComparingAll() { System.out.println("Comparing all timetables: "); } + /** + * Prints tasks of the day specified. + * + * @param day day of the week the task is on. + */ + public static void printTasksOfTheDay(String day, Map> weeklyTask) { + String capitalizedDay = day.substring(0, 1).toUpperCase() + day.substring(1); + if (weeklyTask.get(capitalizedDay).isEmpty()) { + UI.printNoTask(day); + return; + } + System.out.println("_________________________________________"); + UI.printDayHeader(capitalizedDay); + int count = 1; + for (Task task : weeklyTask.get(capitalizedDay)) { + UI.printTaskInList(count, task.toString()); + count++; + } + } + + public static void printTimeFrame(LocalTime time1, String time2) { + System.out.println(" "+time1 + " - " + time2); + } + public static void printTimeFrame(LocalTime time1, LocalTime time2) { + System.out.println(" "+time1 + " - " + time2); + } + public static void printFreeDay(String day) { + System.out.println(" ** Whole day is free on " + day); + } + public static void printNoTask(String day) { + System.out.println("No task for " + day + "!"); + } + public static void printDayHeader(String day) { + System.out.println(day + " :"); + } + public static void printTaskInList(int count, String task) { + System.out.println(" "+count + ". " + task); + } + public static void printNext() { System.out.println("Your next task is: "); } diff --git a/src/test/java/seedu/duke/TimetableTest.java b/src/test/java/seedu/duke/TimetableTest.java index 218be2e572..c98e012231 100644 --- a/src/test/java/seedu/duke/TimetableTest.java +++ b/src/test/java/seedu/duke/TimetableTest.java @@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.fail; import org.junit.jupiter.api.Test; +import seedu.duke.ui.UI; import java.time.LocalTime; @@ -15,7 +16,7 @@ public void testAddUserTask() { timetable.addUserTask("Tuesday", task); - timetable.printTasksOfTheDay("Tuesday"); + UI.printTasksOfTheDay("Tuesday", timetable.getWeeklyTasks()); assertEquals(1, timetable.getWeeklyTasks().get("Tuesday").size()); assertEquals(task, timetable.getWeeklyTasks().get("Tuesday").get(0)); } From 6a09dd5f66ef414098144aad14c9dc3ea4af4ad3 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Tue, 2 Apr 2024 10:29:09 +0800 Subject: [PATCH 063/162] ADD USER GUIDE --- docs/UserGuide.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index b0294989ce..5234b2a90f 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -15,6 +15,42 @@ {Give detailed description of each feature} +### Adding a user: `adduser` + +add a new user into the user list. + +Format: `adduser /NAME` + +Example: `adduser /MIKE` + +### adding a task: `addtask' + +Format: `addtask /on DATE /task TASK_NAME /from TIME /to TIME /type TASK_TYPE` + +### showing current user: `current` + +Format:`current` + +### switch to another user:`switch` + +Format: `switch USER_NAME` + +### delete task from one user's timetable: `deletetask` + +Format: `deletetask /on DATE /index TASK_INDEX` + +### change the start time or end time of a task: `changetasktiming` + +Format:`changetasktiming /on DATE /index TASK_INDEX /from TIME /to TIME` + +### change the task type: `changetasktype` + +Format:`changetasktype /on DATE /index TASK_INDEX /type F_OR_C` + +### add task which happens on multiple days into the timetable: `addrepeaettask` + +Format:` addrepeattask /task TASK_NAME /on DATES /from START_TIME /to END_TIME /type F_OR_C` + ### Adding a todo: `todo` Adds a new item to the list of todo items. From 4c1431fa4e4940480ecd5164064312bed09780fa Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Tue, 2 Apr 2024 10:33:35 +0800 Subject: [PATCH 064/162] update --- .../duke/AddUserTaskSequenceDiagram.puml | 39 ++++++++++++++ src/main/java/seedu/duke/InputValidator.java | 11 ++++ src/main/java/seedu/duke/Parse.puml | 43 ++++++++++++++++ src/main/java/seedu/duke/Parser.java | 31 +++++++++++ src/main/java/seedu/duke/Task.java | 3 ++ src/main/java/seedu/duke/Timetable.java | 28 ++++++++-- .../duke/changeTaskTimingClassDiagram.puml | 51 +++++++++++++++++++ .../duke/changeTaskTimingObjectDiagram.puml | 19 +++++++ src/main/java/seedu/duke/changeTaskType.puml | 17 +++++++ 9 files changed, 239 insertions(+), 3 deletions(-) create mode 100644 src/main/java/seedu/duke/AddUserTaskSequenceDiagram.puml create mode 100644 src/main/java/seedu/duke/Parse.puml create mode 100644 src/main/java/seedu/duke/changeTaskTimingClassDiagram.puml create mode 100644 src/main/java/seedu/duke/changeTaskTimingObjectDiagram.puml create mode 100644 src/main/java/seedu/duke/changeTaskType.puml diff --git a/src/main/java/seedu/duke/AddUserTaskSequenceDiagram.puml b/src/main/java/seedu/duke/AddUserTaskSequenceDiagram.puml new file mode 100644 index 0000000000..82dfc71147 --- /dev/null +++ b/src/main/java/seedu/duke/AddUserTaskSequenceDiagram.puml @@ -0,0 +1,39 @@ +@startuml +title changeTaskTiming Sequence Diagram + +participant "Parser" as Caller +participant "changeTaskTiming" as Method +participant "changeFlexibleTaskTiming" as FlexibleMethod +participant "InputValidator" as InputValidator +participant "UserList" as UserList +participant "User" as User +participant "Timetable" as Timetable + +Caller -> Method: changeTaskTiming(command, userList) +activate Method +Method -> InputValidator: validateChangeTaskTiming(command) +activate InputValidator +Method -> InputValidator: command.split("\\s+") +Method <-- InputValidator: parts[] +Method -> InputValidator: Arrays.asList(parts) +Method <-- InputValidator: wordList[] +Method -> InputValidator: parts[2] +Method -> InputValidator: parts[wordList.indexOf("/index") + 1] +Method -> InputValidator: parts[wordList.indexOf("/from") + 1] +Method -> InputValidator: parts[wordList.indexOf("/to") + 1] +Method -> InputValidator: validateDay(day) +deactivate InputValidator +Method -> UserList: userList.getActiveUser() +Method <-- UserList: activeUser +Method -> User: activeUser.getTimetable() +activate User +Method <-- User: timetable +Method -> FlexibleMethod: timetable.changeFlexibleTaskTiming(day, index - 1, newStartTime, newEndTime) +activate FlexibleMethod +FlexibleMethod <-- Timetable: successful change +deactivate FlexibleMethod +deactivate User +Method -> System: println("Flexible task timing changed successfully.") +deactivate Method + +@enduml \ No newline at end of file diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 795a048698..f45bfc071e 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -37,6 +37,17 @@ public static void validateAddTaskInput(String input) throws InvalidFormatExcept "/type [f/c]"); } } + public static void validateAddTaskWDCInput(String input) throws InvalidFormatException { + // Define the regex pattern for the expected format with case-insensitive flag + String regex = "(?i)^addtwdc\\s+/on\\s+(\\w+)\\s+/task\\s+(.+?)\\s" + + "+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})(\\s+/type\\s+[fc])$"; + + if (!input.matches(regex)) { + throw new InvalidFormatException("[ERROR] Invalid addTaskWithDuplicationCheck format. " + + "Expected format: addtaskwdc /on [day] /task [description] /from [start time] /to [end time] " + + "/type [f/c]"); + } + } /** * Validates correctly formatted deleteTask command. The expected format is diff --git a/src/main/java/seedu/duke/Parse.puml b/src/main/java/seedu/duke/Parse.puml new file mode 100644 index 0000000000..e64e7622f4 --- /dev/null +++ b/src/main/java/seedu/duke/Parse.puml @@ -0,0 +1,43 @@ +@startuml +participant UI +participant Parser +participant UserList +participant Timetable +participant InputValidator + +UI -> Parser: parseCommand(command, userList) +activate Parser + +Parser -> UserList: setActiveUser(user) +activate UserList +UserList --> Parser: Confirmation + +alt command = "changeTaskType" + Parser -> InputValidator: validateChangeTaskType(command) + activate InputValidator + InputValidator -> Timetable: changeTaskType(dayOfWeek, index, newType) + activate Timetable + Timetable --> Parser: Success message + deactivate Timetable + InputValidator --> Parser: No exceptions thrown + deactivate InputValidator + Parser --> UI: "Task type changed successfully." +else command = "deleteTask" + Parser -> InputValidator: validateDeleteTaskInput(command) + activate InputValidator + InputValidator -> Timetable: deleteUserTask(day, index) + activate Timetable + Timetable --> Parser: Success message + deactivate Timetable + InputValidator --> Parser: No exceptions thrown + deactivate InputValidator + Parser --> UI: Success message +else + note right of Parser + Other command cases handled similarly + end note + Parser --> UI: Output message +end + +deactivate Parser +@enduml diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 012eee24f3..46ee26824e 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -53,6 +53,8 @@ public void parseCommand(String command, UserList userList) throws InvalidFormat addTask(command, userList); } else if (command.toLowerCase().startsWith("deletetask")) { deleteTask(command, userList); + } else if (command.toLowerCase().startsWith("addtwdc")) { + addTaskWithDuplicationCheck(command, userList); } else if(command.toLowerCase().startsWith("changetasktiming")){ changeTaskTiming(command, userList); } else if(command.toLowerCase().startsWith("addrepeattask")){ @@ -116,6 +118,35 @@ private static void deleteTask(String command, UserList userList) { } } + /** + * Adds a task to the timetable with task duplication detection. + * + * @param command The user input command. + * @param userList The list of users. + */ + /** + * Adds a task to the timetable with duplication check. + * + * @param command The user input command. + * @param userList The list of users. + */ + private void addTaskWithDuplicationCheck(String command, UserList userList) { + try { + InputValidator.validateAddTaskWDCInput(command); + Task task = parseTask(command); + boolean addedSuccessfully = userList.getActiveUser().getTimetable() + .addUserTaskWithDuplicationCheck(task.day, task); + + if (addedSuccessfully) { + UI.printAddTask(task); + } else { + System.out.println("Task already exists. Cannot add duplicate task."); + } + } catch (InvalidFormatException | InvalidDayException e) { + System.out.println(e.getMessage()); + } + } + private void addTask(String command, UserList userList) { try { InputValidator.validateAddTaskInput(command); diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index 448034ebbf..863a03f903 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -57,6 +57,9 @@ public void setType(String type){ private String formatDates(String time) { return time.length() == 1 ? "0" + time : time; } + public String getDescription(){ + return description; + } @Override public String toString() { diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 6cd72af423..e03b6b9aaf 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -58,11 +58,33 @@ public void addUserTask(String dayOfWeek, Task task) { } /** - * Deletes task on dayOfWeek at an index + * Adds a task to the timetable with duplication check. * - * @param dayOfWeek first Timetable. - * @param index index of task within task list + * @param dayOfWeek The day of the week. + * @param task The task to add. + * @return True if the task was added successfully, false if a duplicate was found. */ + public boolean addUserTaskWithDuplicationCheck(String dayOfWeek, Task task) { + String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); + ArrayList tasksOfDay = weeklyTasks.get(capitalizedDay); + for (Task existingTask : tasksOfDay) { + if (existingTask.getDescription().equalsIgnoreCase(task.getDescription()) + && existingTask.getStartTime().equals(task.getStartTime()) + && existingTask.getEndTime().equals(task.getEndTime())) { + return false; + } + } + tasksOfDay.add(task); + return true; + } + + + /** + * Deletes task on dayOfWeek at an index + * + * @param dayOfWeek first Timetable. + * @param index index of task within task list + */ public void deleteUserTask(String dayOfWeek, int index) { String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); //check if index is a valid number within a day's tasklist diff --git a/src/main/java/seedu/duke/changeTaskTimingClassDiagram.puml b/src/main/java/seedu/duke/changeTaskTimingClassDiagram.puml new file mode 100644 index 0000000000..80d572dc30 --- /dev/null +++ b/src/main/java/seedu/duke/changeTaskTimingClassDiagram.puml @@ -0,0 +1,51 @@ +@startuml +class InputValidator { + +validateChangeTaskTiming(command: String): void + +validateDay(day: String): void +} + +class UserList { + +getActiveUser(): User +} + +class User { + -timetable: Timetable + +getTimetable(): Timetable +} + +class Timetable { + +changeFlexibleTaskTiming(dayOfWeek: String, index: int, newStartTime: LocalTime, newEndTime: LocalTime): void +} + +class IndexOutOfBoundsException +class IllegalArgumentException + +class System { + +println(message: String): void +} + +class LocalTime +class InvalidDayException +class InvalidFormatException + +InputValidator "1" --> "0..1" InvalidFormatException +UserList "1" --> "1" User +User "1" --> "1" Timetable + +Caller "1" --> "1" InputValidator: <> +Caller "1" --> "1" UserList: <> +Caller "1" --> "1" System: <> +UserList "1" --> "1" System: <> +InputValidator "1" --> "1" InvalidDayException: <> +InputValidator "1" --> "1" IndexOutOfBoundsException: <> +InputValidator "1" --> "1" IllegalArgumentException: <> +InputValidator "1" --> "1" LocalTime: <> +Method "1" --> "1" InputValidator: <> +Method "1" --> "1" UserList: <> +Method "1" --> "1" User: <> +Method "1" --> "1" Timetable: <> +Method "1" --> "1" System: <> +Timetable "1" --> "0..1" LocalTime: <> +Timetable "1" --> "0..1" IndexOutOfBoundsException: <> +Timetable "1" --> "0..1" IllegalArgumentException: <> +@enduml \ No newline at end of file diff --git a/src/main/java/seedu/duke/changeTaskTimingObjectDiagram.puml b/src/main/java/seedu/duke/changeTaskTimingObjectDiagram.puml new file mode 100644 index 0000000000..551088e2a4 --- /dev/null +++ b/src/main/java/seedu/duke/changeTaskTimingObjectDiagram.puml @@ -0,0 +1,19 @@ +@startuml +object parser +object inputValidator +object userList +object user +object timetable +object indexOutOfBoundsException +object illegalArgumentException +object localTime +object task + +parser --> inputValidator +parser --> userList +userList --> user +user --> timetable +timetable --> task : weeklyTasks +@enduml + + diff --git a/src/main/java/seedu/duke/changeTaskType.puml b/src/main/java/seedu/duke/changeTaskType.puml new file mode 100644 index 0000000000..9fee949adb --- /dev/null +++ b/src/main/java/seedu/duke/changeTaskType.puml @@ -0,0 +1,17 @@ +@startuml +participant Parser +participant Timetable +participant Task + +Parser -> Timetable: changeTaskType(dayOfWeek, index, newType) +activate Timetable +Timetable -> Timetable: capitalizeDay(dayOfWeek) +Timetable -> Timetable: getTasks(dayOfWeek) +activate Task +Timetable -> Task: getTask(index) +Task -> Task: setType(newType) +Task -->Timetable +Timetable --> Parser: +deactivate Task +deactivate Timetable +@enduml From d3c0789e6b4c50be781522cf558a17ac41b7ccba Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Tue, 2 Apr 2024 10:49:17 +0800 Subject: [PATCH 065/162] Add UML diagram for next command, rename Duke to Main --- META-INF/MANIFEST.MF | 2 +- docs/DeveloperGuide.md | 18 +++++++++++ docs/NextCommand.png | Bin 0 -> 28804 bytes docs/NextCommand.puml | 21 +++++++++++++ docs/{uml.puml => Storage.puml} | 0 src/main/java/seedu/duke/InputValidator.java | 12 ++++---- .../java/seedu/duke/{Duke.java => Main.java} | 2 +- src/main/java/seedu/duke/Parser.java | 28 ++++++++---------- src/main/java/seedu/duke/Task.java | 15 ++++++---- src/main/java/seedu/duke/Timetable.java | 12 +++++--- src/main/java/seedu/duke/UserList.java | 1 - src/test/java/seedu/duke/ParserTest.java | 13 +++++--- 12 files changed, 86 insertions(+), 38 deletions(-) create mode 100644 docs/NextCommand.png create mode 100644 docs/NextCommand.puml rename docs/{uml.puml => Storage.puml} (100%) rename src/main/java/seedu/duke/{Duke.java => Main.java} (97%) diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF index 19e86fe56e..156ebfca20 100644 --- a/META-INF/MANIFEST.MF +++ b/META-INF/MANIFEST.MF @@ -1,3 +1,3 @@ Manifest-Version: 1.0 -Main-Class: seedu.duke.Duke +Main-Class: seedu.duke.Main diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 8dd08d4969..20b494dbb4 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -87,3 +87,21 @@ Here is how this method works: 5. The Task object modifies the type of the task to the new type specified by the Parser. 6. Finally, the modified task or any relevant status information is returned to the Parser. + +## Next Command + +Proposed implementation + +The next command displays the next task of the current user based on the current time. Given below is how it works. + +Step 1: The user launches the application, creates a user, and creates several tasks for the user. + +Step 2: The user types the command 'next' to see their next task. + +Step 3: The next command is triggered. It first determines the current day and takes the arraylist of tasks of the user's timetable on that day. + +Step 4: It then loops through the tasks on that day, starting from the back (the later tasks), until the task's start time is before the current time. + +Step 5: It displays the last task it looped though, or a special message if there is no task that day. + +![NextCommand UML](NextCommand.png) diff --git a/docs/NextCommand.png b/docs/NextCommand.png new file mode 100644 index 0000000000000000000000000000000000000000..904f47d9abbbdd29a79fbe5b8ec2e323c7e3f7c0 GIT binary patch literal 28804 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%0Aq2VX{GpH6k3kq^LQn~T} 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%0DY0zn%{ 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 literal 0 HcmV?d00001 diff --git a/docs/NextCommand.puml b/docs/NextCommand.puml new file mode 100644 index 0000000000..985e45bbbe --- /dev/null +++ b/docs/NextCommand.puml @@ -0,0 +1,21 @@ +@startuml +autonumber + +Main -> Parser: (parseCommand("next", userList)) +DayOfWeek -> Parser: dayOfWeek +Parser -> Parser: capitalizeDay(dayOfWeek) + +Parser -> Timetable: getWeeklyTasks(dayOfWeek) +Timetable -> Parser: tasksOfDay +Parser -> Parser: tasksOfDay.size() + +alt numOfTasks == 0 + Parser -> UI: printNoTasks() +else + loop numOfTasks + alt currentTime < task.startTime + Parser -> UI: nextTask() + end + end +end +@enduml \ No newline at end of file diff --git a/docs/uml.puml b/docs/Storage.puml similarity index 100% rename from docs/uml.puml rename to docs/Storage.puml diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 941521b5af..454803590e 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -23,7 +23,7 @@ public static void validateCompareInput(String input) throws InvalidFormatExcept /** * Validates correctly formatted addTask command. The expected format is - * "addtask /on [date] /task [description] /from [start time] /to [start time] /type [type]" format + * "addtask /on [date] /task [description] /from [start time] /to [start time] /type [type]" * Note: Start and End times should be formatted as such: HH:mm * Regex Guide: * (?i)^ = case insensitive for command name @@ -34,8 +34,7 @@ public static void validateCompareInput(String input) throws InvalidFormatExcept * (/type\s+[fc](\s+)?)$ = regex must end in "/type [f/c]" * * @param input String Input. - * @throws InvalidFormatException If the input does not match the expected format: - * "addtask /on (day) /task (description) /from (start time) /to (end time) /type (type)". + * @throws InvalidFormatException If the input does not match the expected format. */ public static void validateAddTaskInput(String input) throws InvalidFormatException { String regex = "(?i)^addtask\\s+/on\\s+(\\w+)\\s+/task\\s+((.+)?)\\s" + @@ -54,7 +53,7 @@ public static void validateAddTaskInput(String input) throws InvalidFormatExcept * Note: index is the index of the task in the task list for the given day * * @param input String Input. - * @throws InvalidFormatException If the input does not match the expected format: "deletetask /on (day) /index (task index)". + * @throws InvalidFormatException If the input does not match the expected format. */ public static void validateDeleteTaskInput(String input) throws InvalidFormatException { String regex = "(?i)^deletetask\\s+/on\\s+(\\w+)\\s+/index\\s+(\\d+)$"; @@ -142,7 +141,7 @@ public static void validateTableExistence(Timetable table) throws NullPointerExc } } - public static void validateChangeTaskTiming(String input) throws InvalidFormatException{ + public static void validateChangeTaskTiming(String input) throws InvalidFormatException { String prefix = "(?i)^changeTaskTiming\\s+/on\\s+"; String dayPattern = "(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)"; String indexPattern = "\\d+"; @@ -181,7 +180,8 @@ public static void validateChangeTaskType(String input) throws InvalidFormatExce "Expected format: changeTaskType /on [day] /index [index] /type [f/c]"); } } - public static void validateAddRepeatTask(String input) throws InvalidFormatException{ + + public static void validateAddRepeatTask(String input) throws InvalidFormatException { String regex = "(?i)^addrepeattask\\s+/task\\s+(.+?)\\s+/on\\s+(\\w+(\\s+\\w+)*)\\s+" + "/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})\\s+/type\\s+([fc])$"; diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Main.java similarity index 97% rename from src/main/java/seedu/duke/Duke.java rename to src/main/java/seedu/duke/Main.java index f25df68f15..3b8e02ea11 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Main.java @@ -5,7 +5,7 @@ import java.io.FileNotFoundException; import java.util.Scanner; -public class Duke { +public class Main { static final Scanner IN = new Scanner(System.in); static boolean isFinished = false; diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 71c2730cee..0e23c61f35 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -15,7 +15,7 @@ public class Parser { protected static final String[] DAYS = new String[] - {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; + {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; /** * Parses User Input and Identifies the command used. @@ -31,7 +31,7 @@ public static void parseCommand(String command, UserList userList) throws UI.printHelp(); } else if (command.equalsIgnoreCase("bye")) { UI.printBye(); - Duke.setIsFinished(true); + Main.setIsFinished(true); } else if (command.equalsIgnoreCase("current")) { UI.printActiveUser(userList.getActiveUser().getName()); } else if (command.equalsIgnoreCase("view")) { @@ -238,23 +238,21 @@ private static void printNextTask(User currentUser) { if (numOfTasks == 0) { UI.printNoTasks(); - } else { - Task nextTask = null; - for (int i = numOfTasks - 1; i >= 0; i -= 1) { - if (current.getStartTime().isBefore(tasksOfDay.get(i).getStartTime())) { - nextTask = tasksOfDay.get(i); + return; + } + Task nextTask = null; + for (int i = numOfTasks - 1; i >= 0; i -= 1) { + if (current.getStartTime().isBefore(tasksOfDay.get(i).getStartTime())) { + nextTask = tasksOfDay.get(i); + } else { + if (nextTask == null) { + UI.printNoTasks(); } else { UI.printNext(); - if (nextTask == null) { - UI.printNoTasks(); - } else { - System.out.println(nextTask.toString()); - } - return; + System.out.println(nextTask.toString()); } + return; } } - - } } diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index 85241ca587..f4b9d0c2ba 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -14,9 +14,9 @@ public class Task { * the day of the task, the starting time and the ending time of the task. * * @param description description of the task. - * @param day day of the task. - * @param from starting time of the task. - * @param to ending time of the task. + * @param day day of the task. + * @param from starting time of the task. + * @param to ending time of the task. */ public Task(String description, String day, String from, String to, String type) { this.description = description; @@ -39,18 +39,20 @@ public LocalTime getStartTime() { public LocalTime getEndTime() { return endTime; } - public String getType(){ + + public String getType() { return type; } public void setEndTime(LocalTime endTime) { this.endTime = endTime; } - public void setStartTime(LocalTime startTime){ + + public void setStartTime(LocalTime startTime) { this.startTime = startTime; } - public void setType(String type){ + public void setType(String type) { this.type = type; } @@ -61,6 +63,7 @@ private String formatDates(String time) { public String getDescription() { return description; } + @Override public String toString() { return description + " (" + day + " from " + startTime + " to " + endTime + ")" + " type: " + type; diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index f20deada25..1649de30d8 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -90,8 +90,8 @@ private Task readDay(String dayOfWeek, int index) { /** * Compares and prints overlapping free time between two Timetables. * - * @param table1 first Timetable. - * @param table2 second Timetable + * @param table1 First Timetable. + * @param table2 Second Timetable * @return Returns a merged timetable comprising both input timetables. */ public static Timetable compareTimetable(Timetable table1, Timetable table2) { @@ -112,6 +112,12 @@ public static Timetable compareTimetable(Timetable table1, Timetable table2) { return mergedTimetable; } + /** + * Compares and prints overlapping free time between all Timetables. + * + * @param userList List of all users. + * @return Returns a merged timetable comprising all timetables. + */ public static Timetable compareAllTimetables(UserList userList) { Timetable mergedTimetable = new Timetable(); for (User user : userList.getUsers()) { @@ -146,6 +152,4 @@ public static void findOverlappingFreeTime(ArrayList tasks, String day) { UI.printFreeDay(day); } } - - } diff --git a/src/main/java/seedu/duke/UserList.java b/src/main/java/seedu/duke/UserList.java index 3cd3b78156..d51600f53d 100644 --- a/src/main/java/seedu/duke/UserList.java +++ b/src/main/java/seedu/duke/UserList.java @@ -22,7 +22,6 @@ public void setActiveUser(User user) throws InvalidUserException { activeUser = user; } else { throw new InvalidUserException("User does not exist!"); - //System.out.println("User does not exist!"); } } diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java index 4b70995bad..07a6ce233a 100644 --- a/src/test/java/seedu/duke/ParserTest.java +++ b/src/test/java/seedu/duke/ParserTest.java @@ -7,9 +7,7 @@ import java.util.ArrayList; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.*; class ParserTest { UserList userlist = new UserList(); @@ -146,14 +144,21 @@ public void invalidAddTaskCommandTest() { } } + @Test public void addForAllTest() throws InvalidDayException, InvalidUserException, InvalidFormatException { User user1 = new User("User1"); User user2 = new User("User2"); userlist.addUser(user1); userlist.addUser(user2); - Parser.parseCommand("addforall /on Monday /task lecture /from 9:00 /to 25:00 /type f", userlist); + Parser.parseCommand("addforall /on Monday /task lecture /from 9:00 /to 11:00 /type f", userlist); + Task addedTaskUser1 = user1.getTimetable().getWeeklyTasks().get("Monday").get(0); + Task addedTaskUser2 = user1.getTimetable().getWeeklyTasks().get("Monday").get(0); + assertEquals("lecture", addedTaskUser1.getDescription()); + assertEquals("lecture", addedTaskUser2.getDescription()); + assertEquals("09:00", addedTaskUser2.getStartTime().toString()); + assertEquals("11:00", addedTaskUser2.getEndTime().toString()); } } From 0319f77310f1a0b4656a96fa5ed33d159d45d031 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Tue, 2 Apr 2024 20:46:07 +0800 Subject: [PATCH 066/162] 1. add a new method which serves to add a task with duplication check, if want to check for duplication, use this method. if not, use addtask method. 2. add user guide --- docs/UserGuide.md | 4 + src/main/java/seedu/duke/InputValidator.java | 2 +- src/main/java/seedu/duke/Parser.java | 82 ++++++++------------ src/main/java/seedu/duke/Task.java | 3 - src/main/java/seedu/duke/Timetable.java | 25 ++++++ src/main/java/seedu/duke/ui/UI.java | 1 + 6 files changed, 65 insertions(+), 52 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 5234b2a90f..5550004d1a 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -27,6 +27,10 @@ Example: `adduser /MIKE` Format: `addtask /on DATE /task TASK_NAME /from TIME /to TIME /type TASK_TYPE` +### adding a task with duplication check: `addtwdc' + +Format: `addtwdc /on DATE /task TASK_NAME /from TIME /to TIME /type TASK_TYPE` + ### showing current user: `current` Format:`current` diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index fbaefc2640..a50aad210b 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -54,7 +54,7 @@ public static void validateAddTaskWDCInput(String input) throws InvalidFormatExc if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid addTaskWithDuplicationCheck format. " + - "Expected format: addtaskwdc /on [day] /task [description] /from [start time] /to [end time] " + + "Expected format: addtwdc /on [day] /task [description] /from [start time] /to [end time] " + "/type [f/c]"); } } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 66a2b198ca..330e428011 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -56,15 +56,11 @@ public static void parseCommand(String command, UserList userList) throws addTask(command, userList); User currentUser = userList.getActiveUser(); currentUser.getStorage().writeTaskInFile(currentUser); - } else if (command.toLowerCase().startsWith("deletetask")) { - deleteTask(command, userList); -<<<<<<< HEAD - } else if (command.toLowerCase().startsWith("addtwdc")) { + } else if (command.toLowerCase().startsWith("addtwdc")) { addTaskWithDuplicationCheck(command, userList); - } else if(command.toLowerCase().startsWith("changetasktiming")){ -======= + }else if (command.toLowerCase().startsWith("deletetask")) { + deleteTask(command, userList); } else if (command.toLowerCase().startsWith("changetasktiming")) { ->>>>>>> 35e94f00ac998b11547605703311e15c5c33f6ba changeTaskTiming(command, userList); } else if (command.toLowerCase().startsWith("addrepeattask")) { addRepeatTask(command, userList); @@ -74,7 +70,6 @@ public static void parseCommand(String command, UserList userList) throws UI.printComparingAll(); UI.printSharedTime(Timetable.compareAllTimetables(userList)); } else if (command.toLowerCase().startsWith("compare")) { - InputValidator.validateCompareInput(command); String[] parts = command.split("\\s+"); String user1 = parts[1]; @@ -92,6 +87,7 @@ public static void parseCommand(String command, UserList userList) throws } } + private static void changeTaskType(String command, UserList userList) throws InvalidFormatException { try { InputValidator.validateChangeTaskType(command); @@ -121,36 +117,36 @@ private static void deleteTask(String command, UserList userList) { } } -// /** -// * Adds a task to the timetable with task duplication detection. -// * -// * @param command The user input command. -// * @param userList The list of users. -// */ -// /** -// * Adds a task to the timetable with duplication check. -// * -// * @param command The user input command. -// * @param userList The list of users. -// */ -// private void addTaskWithDuplicationCheck(String command, UserList userList) { -// try { -// InputValidator.validateAddTaskWDCInput(command); -// Task task = parseTask(command); -// boolean addedSuccessfully = userList.getActiveUser().getTimetable() -// .addUserTaskWithDuplicationCheck(task.day, task); -// -// if (addedSuccessfully) { -// UI.printAddTask(task); -// } else { -// System.out.println("Task already exists. Cannot add duplicate task."); -// } -// } catch (InvalidFormatException | InvalidDayException e) { -// System.out.println(e.getMessage()); -// } -// } + /** + * Adds a task to the timetable with task duplication detection. + * + * @param command The user input command. + * @param userList The list of users. + */ + /** + * Adds a task to the timetable with duplication check. + * + * @param command The user input command. + * @param userList The list of users. + */ + private static void addTaskWithDuplicationCheck(String command, UserList userList) { + try { + InputValidator.validateAddTaskWDCInput(command); + Task task = parseTask(command); + boolean addedSuccessfully = userList.getActiveUser().getTimetable() + .addUserTaskWithDuplicationCheck(task.day, task); - private void addTask(String command, UserList userList) { + if (addedSuccessfully) { + UI.printAddTask(task); + } else { + System.out.println("Task already exists. Cannot add duplicate task."); + } + } catch (InvalidFormatException | InvalidDayException e) { + System.out.println(e.getMessage()); + } + } + + private static void addTask(String command, UserList userList) { try { InputValidator.validateAddTaskInput(command); Task task = parseTask(command); @@ -159,17 +155,7 @@ private void addTask(String command, UserList userList) { } catch (InvalidFormatException | InvalidDayException e) { System.out.println(e.getMessage()); } -//======= -// private static void addTask(String command, UserList userList) throws -// InvalidDayException, InvalidFormatException { -// -// InputValidator.validateAddTaskInput(command); -// Task task = parseTask(command); -// userList.getActiveUser().getTimetable().addUserTask(task.day, task); -// UI.printAddTask(task); -// -//>>>>>>> 35e94f00ac998b11547605703311e15c5c33f6ba -// } + } public static Task parseTask(String command) throws InvalidDayException { String[] parts = command.split("\\s+"); diff --git a/src/main/java/seedu/duke/Task.java b/src/main/java/seedu/duke/Task.java index 3783c656c2..3b2e30ed63 100644 --- a/src/main/java/seedu/duke/Task.java +++ b/src/main/java/seedu/duke/Task.java @@ -61,9 +61,6 @@ public String getDescription(){ return description; } - public String getDescription() { - return description; - } @Override public String toString() { return description + " (" + day + " from " + startTime + " to " + endTime + ")" + " type: " + type; diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 59a8034ddf..8edceb38a8 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -168,6 +168,31 @@ public static void findOverlappingFreeTime(ArrayList tasks, String day) { UI.printFreeDay(day); } } + /** + * Adds a task to the timetable with duplication check. + * + * @param dayOfWeek The day of the week. + * @param task The task to add. + * @return True if the task was added successfully, false if a duplicate was found. + */ + public boolean addTaskWithDuplicationCheck(String dayOfWeek, Task task) { + String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); + ArrayList tasksOfDay = weeklyTasks.get(capitalizedDay); + + // Check for duplicates + for (Task existingTask : tasksOfDay) { + if (existingTask.getDescription().equalsIgnoreCase(task.getDescription()) + && existingTask.getStartTime().equals(task.getStartTime()) + && existingTask.getEndTime().equals(task.getEndTime())) { + System.out.println("Duplicate task detected. Task not added."); + return false; + } + } + + // No duplicate found, add the task + tasksOfDay.add(task); + return true; + } } diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index 5e00abaeb9..a8002d4f47 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -49,6 +49,7 @@ public static void printHelp() { "adduser: add new user \n" + "switch : switch to user \n" + "addtask /on /from /to : add task for current user\n" + + "addtwdc /on /from /to " + "deletetask: delete task \n" + "changetasktiming: \n" + "changetasktype : change the type of a task (flexible/confirmed)\n" + From 9d7de1102eba597090d2eaaa51329de3c79c1898 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 2 Apr 2024 20:55:31 +0800 Subject: [PATCH 067/162] add exception such that addtask is not allowed to be called when userlist is empty --- src/main/java/seedu/duke/exceptions/NoUserException.java | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 src/main/java/seedu/duke/exceptions/NoUserException.java diff --git a/src/main/java/seedu/duke/exceptions/NoUserException.java b/src/main/java/seedu/duke/exceptions/NoUserException.java new file mode 100644 index 0000000000..b4525953a5 --- /dev/null +++ b/src/main/java/seedu/duke/exceptions/NoUserException.java @@ -0,0 +1,2 @@ +package seedu.duke.exceptions;public class NoUserException { +} From 97862f50744f8645dd5240ec46a52fde40b78594 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 2 Apr 2024 20:56:38 +0800 Subject: [PATCH 068/162] change addforall function such that it does not require a type parameter as default type is common --- src/main/java/seedu/duke/InputValidator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 454803590e..4a39c9630c 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -159,7 +159,7 @@ public static void validateChangeTaskTiming(String input) throws InvalidFormatEx public static void validateAddTaskForAll(String input) throws InvalidFormatException { String regex = "(?i)^addforall\\s+/on\\s+(\\w+)\\s+/task\\s+((.+)?)\\s" + - "/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})\\s+(/type\\s+[fc](\\s+)?)$"; + "/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})\\s?"; if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid addtask format. " + From 6cfac071034a75ed1849c6043f1d63ddd03a85a5 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 2 Apr 2024 20:56:58 +0800 Subject: [PATCH 069/162] Remove magic numbers --- src/main/java/seedu/duke/Storage.java | 101 +++++++++++++------------- 1 file changed, 49 insertions(+), 52 deletions(-) diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 62de1faeff..b324d1b72b 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -16,7 +16,13 @@ public class Storage { - public static String filePath; + public static final int START_TIME_INDEX = 3; + public static final int END_TIME_INDEX_INCREMENT = 2; + public static final int END_TIME_END_INDEX = 16; + public static final int DESCRIPTION_INDEX = 18; + public static final int TYPE_INDEX_INCREMENT = 7; + public String filePath; + public static final String folderPath = "data"; private static final String boxOutline = "+---------+\n"; @@ -26,12 +32,11 @@ public class Storage { ".................................................................................................\n"; public Storage(String filePath) { - Storage.filePath = filePath; + this.filePath = filePath; } public static void createFolder() { - String folderPath = "data"; File folder = new File(folderPath); if (!folder.exists()) { @@ -47,8 +52,7 @@ public static void createFolder() { } public static void addExistingUsers(UserList userList) throws FileNotFoundException { - String directoryPath = "data"; - File directory = new File(directoryPath); + File directory = new File(folderPath); File[] files = directory.listFiles(); if (files != null) { @@ -59,7 +63,7 @@ public static void addExistingUsers(UserList userList) throws FileNotFoundExcept String userName = fileName.substring(0, indexOfDot); User user = new User(userName); userList.addUser(user); - loadData(user); + user.getStorage().loadData(user); } } } else { @@ -68,14 +72,14 @@ public static void addExistingUsers(UserList userList) throws FileNotFoundExcept } - public static void loadData(User user) throws FileNotFoundException { + public void loadData(User user) throws FileNotFoundException { File f = new File(filePath); String day = ""; Scanner s = new Scanner(f); while (s.hasNext()) { String line = s.nextLine(); // ignore lines for formatting and weeks that have no tasks - if (line.startsWith("+") || line.startsWith(".") || line.isEmpty() || line.equals("No task :)")) { + if (line.startsWith("Username") || line.startsWith("+") || line.startsWith(".") || line.isEmpty() || line.equals("No task :)")) { continue; } if (line.startsWith("|")) { @@ -86,15 +90,11 @@ public static void loadData(User user) throws FileNotFoundException { } } - public static void addUserInFolder() { + public void addUserInFolder() { File f = new File(filePath); try { if (f.createNewFile()) { System.out.println("File created: " + f.getName()); - String fileName = f.getName(); - int indexOfDot = fileName.indexOf("."); - String userName = fileName.substring(0, indexOfDot); - writeToFile(filePath, "Username: " + userName, true); } } catch (IOException e) { System.out.println("Something went wrong: " + e.getMessage()); @@ -110,11 +110,12 @@ public static void addUserInFolder() { */ public static Task extractTaskInfo(String line, String day) { int indexOfDash = line.indexOf("-"); - String startTime = line.substring(3, indexOfDash).trim(); - String endTime = line.substring(indexOfDash + 2, 16).trim(); + String startTime = line.substring(START_TIME_INDEX, indexOfDash).trim(); + String endTime = line.substring(indexOfDash + END_TIME_INDEX_INCREMENT, END_TIME_END_INDEX).trim(); int indexOfType = line.indexOf("(type:"); - String description = line.substring(18, indexOfType).trim(); - String type = line.substring(indexOfType + 7, indexOfType + 8); + String description = line.substring(DESCRIPTION_INDEX, indexOfType).trim(); + int indexOfRightParenthesis = line.indexOf(")"); + String type = line.substring(indexOfType + TYPE_INDEX_INCREMENT, indexOfRightParenthesis); return new Task(description, day, startTime, endTime, type); } @@ -138,45 +139,41 @@ public static void writeToFile(String filePath, String textToAdd, boolean isAppe * @param user the user that the timetable belongs to. */ - public void writeTaskInFile(User user) { + public void writeTaskInFile(User user) throws IOException { Timetable timetable = user.getTimetable(); + writeToFile(filePath, "Username: " + user.getName() + "\n", false); + for (String day : DAYS) { + String outline; + switch (day) { + case ("Wednesday"): + outline = boxOutlineForWednesday; + break; + case ("Friday"): + outline = boxOutlineForFriday; + break; + default: + outline = boxOutline; + break; + } + writeToFile(filePath, outline, true); + writeToFile(filePath, "| " + day + " |" + "\n", true); + writeToFile(filePath, outline, true); - try (FileWriter writer = new FileWriter(filePath)) { - for (String day : DAYS) { - String outline; - switch (day) { - case ("Wednesday"): - outline = boxOutlineForWednesday; - break; - case ("Friday"): - outline = boxOutlineForFriday; - break; - default: - outline = boxOutline; - break; - } - writeToFile(filePath, outline, true); - writeToFile(filePath, "| " + day + " |" + "\n", true); - writeToFile(filePath, outline, true); - - if (timetable.getWeeklyTasks().get(day).isEmpty()) { - writeToFile(filePath, "No task :)\n", true); - writer.write("No task :)\n"); - } else { - int taskCount = 1; - for (Task task : timetable.getWeeklyTasks().get(day)) { - writer.write(taskCount + ". " + task.getStartTime() + " - " + task.getEndTime() + - ": " + task.getDescription() + " (type: " + task.getType() + ")" + "\n"); - taskCount += 1; - } + if (timetable.getWeeklyTasks().get(day).isEmpty()) { + writeToFile(filePath, "No task :)\n", true); + } else { + int taskCount = 1; + for (Task task : timetable.getWeeklyTasks().get(day)) { + writeToFile(filePath, taskCount + ". " + task.getStartTime() + " - " + task.getEndTime() + + ": " + task.getDescription() + " (type: " + task.getType() + ")" + "\n", true); + taskCount += 1; } - writer.write(lineSeparator); - writer.write("\n"); } - - System.out.println("Timetable has been written to " + filePath); - } catch (IOException e) { - System.err.println("Error writing to file: " + e.getMessage()); + writeToFile(filePath, lineSeparator, true); + writeToFile(filePath, "\n", true); } + + System.out.println("Timetable has been written to " + filePath); + } } From ba7c4e4e41943c55f621b1115135ca899f021c70 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 2 Apr 2024 20:57:36 +0800 Subject: [PATCH 070/162] Bug fix for storage --- src/main/java/seedu/duke/Main.java | 3 ++ src/main/java/seedu/duke/Parser.java | 40 ++++++++++++++----- .../duke/exceptions/NoUserException.java | 4 +- src/main/java/seedu/duke/ui/UI.java | 4 ++ src/test/java/seedu/duke/ParserTest.java | 10 +++-- 5 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/main/java/seedu/duke/Main.java b/src/main/java/seedu/duke/Main.java index 3b8e02ea11..9c0f6f5486 100644 --- a/src/main/java/seedu/duke/Main.java +++ b/src/main/java/seedu/duke/Main.java @@ -1,5 +1,6 @@ package seedu.duke; +import seedu.duke.exceptions.NoUserException; import seedu.duke.ui.UI; import java.io.FileNotFoundException; @@ -28,6 +29,8 @@ public static void main(String[] args) throws FileNotFoundException { String input = IN.nextLine(); Parser.parseCommand(input, userList); + } catch (NoUserException e) { + UI.printNoUsers(); } catch (Exception e) { System.out.println(e.getMessage()); } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 0e23c61f35..6bd4fee98a 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -3,8 +3,10 @@ import seedu.duke.exceptions.InvalidDayException; import seedu.duke.exceptions.InvalidFormatException; import seedu.duke.exceptions.InvalidUserException; +import seedu.duke.exceptions.NoUserException; import seedu.duke.ui.UI; +import java.io.IOException; import java.time.LocalTime; import java.time.LocalDate; import java.time.DayOfWeek; @@ -23,7 +25,7 @@ public class Parser { * @param command The users text input. */ public static void parseCommand(String command, UserList userList) throws - InvalidFormatException, InvalidDayException, InvalidUserException { + InvalidFormatException, InvalidDayException, InvalidUserException, NoUserException, IOException { if (command.equalsIgnoreCase("list")) { UI.printListingUsers(); userList.listAll(); @@ -45,7 +47,7 @@ public static void parseCommand(String command, UserList userList) throws User newUser = new User(userName); UI.printNewUser(newUser.getName()); userList.addUser(newUser); - Storage.addUserInFolder(); + newUser.getStorage().addUserInFolder(); } else if (command.toLowerCase().startsWith("switch")) { InputValidator.validateSwitchInput(command); String[] parts = command.split("\\s+"); @@ -53,6 +55,9 @@ public static void parseCommand(String command, UserList userList) throws userList.setActiveUser(userList.findUser(userName)); UI.printActiveUser(userList.getActiveUser().getName()); } else if (command.toLowerCase().startsWith("addtask")) { + if (userList.getUsers().isEmpty()) { + throw new NoUserException(); + } addTask(command, userList); User currentUser = userList.getActiveUser(); currentUser.getStorage().writeTaskInFile(currentUser); @@ -95,9 +100,12 @@ private static void changeTaskType(String command, UserList userList) throws Inv int index = Integer.parseInt(wordList.get(wordList.indexOf("/index") + 1)); String newType = wordList.get(wordList.indexOf("/type") + 1); InputValidator.validateDay(day); - userList.getActiveUser().getTimetable().changeTaskType(day, index - 1, newType); + + User currentUser = userList.getActiveUser(); + currentUser.getTimetable().changeTaskType(day, index - 1, newType); System.out.println("Task type changed successfully."); - } catch (InvalidDayException | IndexOutOfBoundsException | NumberFormatException e) { + currentUser.getStorage().writeTaskInFile(currentUser); + } catch (InvalidDayException | IndexOutOfBoundsException | NumberFormatException | IOException e) { throw new RuntimeException(e); } } @@ -107,11 +115,15 @@ private static void deleteTask(String command, UserList userList) { InputValidator.validateDeleteTaskInput(command); String[] parts = command.split("\\s+"); String day = parts[2]; - int index = Integer.parseInt(parts[4]); + int index = Integer.parseInt(parts[4]) - 1; InputValidator.validateDay(day); - userList.getActiveUser().getTimetable().deleteUserTask(day, index); + User currentUser = userList.getActiveUser(); + currentUser.getTimetable().deleteUserTask(day, index); + currentUser.getStorage().writeTaskInFile(currentUser); } catch (InvalidFormatException | InvalidDayException e) { System.out.println(e.getMessage()); + } catch (IOException e) { + System.out.println("Something went wrong: " + e.getMessage()); } } @@ -154,10 +166,13 @@ private static void changeTaskTiming(String command, UserList userList) throws I LocalTime newStartTime = LocalTime.parse(parts[wordList.indexOf("/from") + 1]); LocalTime newEndTime = LocalTime.parse(parts[wordList.indexOf("/to") + 1]); InputValidator.validateDay(day); - userList.getActiveUser().getTimetable().changeFlexibleTaskTiming(day, + + User currentUser = userList.getActiveUser(); + currentUser.getTimetable().changeFlexibleTaskTiming(day, index - 1, newStartTime, newEndTime); + currentUser.getStorage().writeTaskInFile(currentUser); System.out.println("Flexible task timing changed successfully."); - } catch (InvalidDayException e) { + } catch (InvalidDayException | IOException e) { throw new RuntimeException(e); } } @@ -181,13 +196,17 @@ private static void addRepeatTask(String command, UserList userList) { String startTime = parts[wordlist.indexOf("/from") + 1]; String endTime = parts[wordlist.indexOf("/to") + 1]; String type = parts[wordlist.indexOf("/type") + 1]; + User currentUser = userList.getActiveUser(); for (String day : days) { Task task = new Task(description, day, startTime, endTime, type); - userList.getActiveUser().getTimetable().addUserTask(day, task); + currentUser.getTimetable().addUserTask(day, task); } + currentUser.getStorage().writeTaskInFile(currentUser); System.out.println("Repeated task added successfully!"); } catch (InvalidFormatException e) { System.out.println("Please enter at least 2 days, or you want to use addtask command!"); + } catch (IOException e) { + System.out.println("Something went wrong: " + e.getMessage()); } } @@ -205,12 +224,13 @@ private static String parseDescription(List words) { } private static void addTaskForAll(String command, UserList userList) - throws InvalidFormatException, InvalidDayException { + throws InvalidFormatException, InvalidDayException, IOException { InputValidator.validateAddTaskForAll(command); Task task = parseTask(command); assert !userList.getUsers().isEmpty() : "There is no user added."; for (User user : userList.getUsers()) { user.getTimetable().addUserTask(task.day, task); + user.getStorage().writeTaskInFile(user); } UI.printAddForAll(task); } diff --git a/src/main/java/seedu/duke/exceptions/NoUserException.java b/src/main/java/seedu/duke/exceptions/NoUserException.java index b4525953a5..c94c1fd6e8 100644 --- a/src/main/java/seedu/duke/exceptions/NoUserException.java +++ b/src/main/java/seedu/duke/exceptions/NoUserException.java @@ -1,2 +1,4 @@ -package seedu.duke.exceptions;public class NoUserException { +package seedu.duke.exceptions; + +public class NoUserException extends Exception { } diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index 5e00abaeb9..7f8a562b9c 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -137,4 +137,8 @@ public static void printNext() { public static void printNoTasks() { System.out.println("You have no tasks today. "); } + + public static void printNoUsers() { + System.out.println("Please add a user before adding tasks."); + } } diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java index 07a6ce233a..d8fdbfca5a 100644 --- a/src/test/java/seedu/duke/ParserTest.java +++ b/src/test/java/seedu/duke/ParserTest.java @@ -4,7 +4,9 @@ import seedu.duke.exceptions.InvalidDayException; import seedu.duke.exceptions.InvalidFormatException; import seedu.duke.exceptions.InvalidUserException; +import seedu.duke.exceptions.NoUserException; +import java.io.IOException; import java.util.ArrayList; import static org.junit.jupiter.api.Assertions.*; @@ -18,7 +20,7 @@ public void sampleTest() { } @Test - public void adduserCommandTest() throws InvalidDayException, InvalidFormatException, InvalidUserException { + public void adduserCommandTest() throws InvalidDayException, InvalidFormatException, InvalidUserException, NoUserException, IOException { Parser.parseCommand("addUser User1", userlist); assertEquals(1, userlist.getListLength()); @@ -43,7 +45,7 @@ public void invalidAdduserCommandTest() { } @Test - public void switchCommandTest() throws InvalidDayException, InvalidFormatException, InvalidUserException { + public void switchCommandTest() throws InvalidDayException, InvalidFormatException, InvalidUserException, NoUserException, IOException { User user1 = new User("User1"); User user2 = new User("User2"); userlist.addUser(user1); @@ -82,7 +84,7 @@ public void invalidSwitchCommandTest() { } @Test - public void addTaskCommandTest() throws InvalidDayException, InvalidUserException, InvalidFormatException { + public void addTaskCommandTest() throws InvalidDayException, InvalidUserException, InvalidFormatException, NoUserException, IOException { User user1 = new User("User1"); userlist.addUser(user1); @@ -145,7 +147,7 @@ public void invalidAddTaskCommandTest() { } @Test - public void addForAllTest() throws InvalidDayException, InvalidUserException, InvalidFormatException { + public void addForAllTest() throws InvalidDayException, InvalidUserException, InvalidFormatException, NoUserException, IOException { User user1 = new User("User1"); User user2 = new User("User2"); userlist.addUser(user1); From e0611a7598e6f47a01b7f886b4c3aa81770e24dc Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Tue, 2 Apr 2024 21:51:02 +0800 Subject: [PATCH 071/162] add a method to view today's tasks --- docs/UserGuide.md | 4 +++ src/main/java/seedu/duke/Parser.java | 34 ++++++++++++++++-- src/main/java/seedu/duke/Timetable.java | 46 +++++++++++++++++++++---- 3 files changed, 76 insertions(+), 8 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 5550004d1a..27ad312562 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -55,6 +55,10 @@ Format:`changetasktype /on DATE /index TASK_INDEX /type F_OR_C` Format:` addrepeattask /task TASK_NAME /on DATES /from START_TIME /to END_TIME /type F_OR_C` +### view today's tasks: `todaytask` + +Format: `todaytask` + ### Adding a todo: `todo` Adds a new item to the list of todo items. diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 330e428011..edc14322ee 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -66,7 +66,10 @@ public static void parseCommand(String command, UserList userList) throws addRepeatTask(command, userList); } else if (command.toLowerCase().startsWith("changetasktype")) { changeTaskType(command, userList); - } else if (command.toLowerCase().startsWith("compareall")) { + } else if(command.toLowerCase().startsWith("todaytask")){ + todaytask(userList); + } + else if (command.toLowerCase().startsWith("compareall")) { UI.printComparingAll(); UI.printSharedTime(Timetable.compareAllTimetables(userList)); } else if (command.toLowerCase().startsWith("compare")) { @@ -87,7 +90,6 @@ public static void parseCommand(String command, UserList userList) throws } } - private static void changeTaskType(String command, UserList userList) throws InvalidFormatException { try { InputValidator.validateChangeTaskType(command); @@ -176,6 +178,30 @@ public static Task parseTask(String command) throws InvalidDayException { return new Task(description, day, startTime, endTime, type); } + /** + * Prints tasks for today. + * + * @param userList The list of users. + */ + public static void todaytask(UserList userList) { + String dayOfWeek = DayOfWeek.from(LocalDate.now()).toString().toLowerCase(); + String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); + ArrayList tasksForToday = userList.getActiveUser().getTimetable().getWeeklyTasks().get(capitalizedDay); + + if (tasksForToday.isEmpty()) { + UI.printNoTask("today"); + return; + } + + System.out.println("_________________________________________"); + UI.printDayHeader("Today"); + int count = 1; + for (Task task : tasksForToday) { + UI.printTaskInList(count, task.toString()); + count++; + } + } + private static void changeTaskTiming(String command, UserList userList) throws InvalidFormatException { try { InputValidator.validateChangeTaskTiming(command); @@ -223,6 +249,8 @@ private static void addRepeatTask(String command, UserList userList) { } } + + private static String parseDescription(List words) { int startIndex = words.indexOf("/task") + 1; int endIndex = words.indexOf("/from") - 1; @@ -236,6 +264,8 @@ private static String parseDescription(List words) { return description.toString(); } + + private static void addTaskForAll(String command, UserList userList) throws InvalidFormatException, InvalidDayException { InputValidator.validateAddTaskForAll(command); diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 8edceb38a8..73879326e3 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -2,12 +2,13 @@ import seedu.duke.ui.UI; +import java.time.LocalDate; import java.time.LocalTime; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; +import java.time.format.TextStyle; +import java.util.*; + +import static seedu.duke.ui.UI.printTasksOfTheDay; /** * This class represents the Timetable object consisting of Arraylist of Tasks for each day of the week. @@ -76,7 +77,7 @@ public void deleteUserTask(String dayOfWeek, int index) { weeklyTasks.get(capitalizedDay).remove(index); System.out.println("Task " + taskDeleted.description + " is deleted from " + dayOfWeek); System.out.println("New task list for " + capitalizedDay + ":"); - UI.printTasksOfTheDay(dayOfWeek, getWeeklyTasks()); + printTasksOfTheDay(dayOfWeek, getWeeklyTasks()); } else { System.out.println("Invalid task index. Please try again."); } @@ -193,6 +194,39 @@ public boolean addTaskWithDuplicationCheck(String dayOfWeek, Task task) { tasksOfDay.add(task); return true; } - + /** + * Get tasks for today. + * + * @return An ArrayList of tasks for today. + */ + public ArrayList getTasksForToday() { + Calendar calendar = Calendar.getInstance(); + int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); + String day = null; + switch (dayOfWeek) { + case Calendar.MONDAY: + day = "Monday"; + break; + case Calendar.TUESDAY: + day = "Tuesday"; + break; + case Calendar.WEDNESDAY: + day = "Wednesday"; + break; + case Calendar.THURSDAY: + day = "Thursday"; + break; + case Calendar.FRIDAY: + day = "Friday"; + break; + case Calendar.SATURDAY: + day = "Saturday"; + break; + case Calendar.SUNDAY: + day = "Sunday"; + break; + } + return weeklyTasks.get(day); + } } From ed1d1e2e5ab8e654857d536966c9b14bc999fa72 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 2 Apr 2024 22:04:16 +0800 Subject: [PATCH 072/162] Add method to check if a task the user wants to add clashes with tasks in the list --- src/main/java/seedu/duke/Parser.java | 32 +++++++++++++++++++++------- src/main/java/seedu/duke/ui/UI.java | 4 ++++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index ce215e16ba..b9f308e86d 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -12,6 +12,7 @@ import java.time.DayOfWeek; import java.util.ArrayList; import java.util.Arrays; +import java.util.Comparator; import java.util.List; public class Parser { @@ -58,8 +59,13 @@ public static void parseCommand(String command, UserList userList) throws if (userList.getUsers().isEmpty()) { throw new NoUserException(); } - addTask(command, userList); + Task task = parseTask(command); User currentUser = userList.getActiveUser(); + if (checkClash(task, currentUser)) { + UI.printClashTasks(); + return; + } + addTask(command, userList); currentUser.getStorage().writeTaskInFile(currentUser); } else if (command.toLowerCase().startsWith("addtwdc")) { addTaskWithDuplicationCheck(command, userList); @@ -135,12 +141,6 @@ private static void deleteTask(String command, UserList userList) { * @param command The user input command. * @param userList The list of users. */ - /** - * Adds a task to the timetable with duplication check. - * - * @param command The user input command. - * @param userList The list of users. - */ private static void addTaskWithDuplicationCheck(String command, UserList userList) { try { InputValidator.validateAddTaskWDCInput(command); @@ -162,13 +162,29 @@ private static void addTask(String command, UserList userList) { try { InputValidator.validateAddTaskInput(command); Task task = parseTask(command); - userList.getActiveUser().getTimetable().addUserTask(task.day, task); + User currentuser = userList.getActiveUser(); + currentuser.getTimetable().addUserTask(task.day, task); UI.printAddTask(task); + } catch (InvalidFormatException | InvalidDayException e) { System.out.println(e.getMessage()); } } + public static boolean checkClash(Task taskToBeAdded, User user) { + Timetable timetable = user.getTimetable(); + String day = taskToBeAdded.day; + String capitalisedDay = day.substring(0, 1).toUpperCase() + day.substring(1); + timetable.getWeeklyTasks().get(capitalisedDay).sort(Comparator.comparing(Task::getStartTime)); + for (Task task : timetable.getWeeklyTasks().get(capitalisedDay)) { + if (taskToBeAdded.startTime.isAfter(task.getStartTime()) && taskToBeAdded.startTime.isBefore(task.getEndTime()) + || (taskToBeAdded.endTime.isAfter(task.getStartTime()) && taskToBeAdded.endTime.isBefore(task.getEndTime()))) { + return true; + } + } + return false; + } + public static Task parseTask(String command) throws InvalidDayException { String[] parts = command.split("\\s+"); List wordList = Arrays.asList(parts); diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index 10b16b515e..4ea146a245 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -142,4 +142,8 @@ public static void printNoTasks() { public static void printNoUsers() { System.out.println("Please add a user before adding tasks."); } + + public static void printClashTasks() { + System.out.println("The task you want to add clashes with existing tasks. Please check again."); + } } From f65e95a91a96b33800cda316401394d2251c8cc6 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 2 Apr 2024 22:19:00 +0800 Subject: [PATCH 073/162] Update User guide --- docs/UserGuide.md | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 5550004d1a..f5828a5970 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -25,12 +25,17 @@ Example: `adduser /MIKE` ### adding a task: `addtask' -Format: `addtask /on DATE /task TASK_NAME /from TIME /to TIME /type TASK_TYPE` +Format: `addtask /on DAY /task TASK_NAME /from TIME /to TIME /type TASK_TYPE` +* Both starting time and end time must be in the format of HH:MM. +* Task_type is either `f` (for flexible tasks) or `c` (for compulsory tasks). +Example: `addtask /on monday /task lecture /from 11:00 /to 12:00 /type f` ### adding a task with duplication check: `addtwdc' Format: `addtwdc /on DATE /task TASK_NAME /from TIME /to TIME /type TASK_TYPE` +Example: `addtwdc /on monday /task lecture /from 11:00 /to 12:00 /type f` + ### showing current user: `current` Format:`current` @@ -39,41 +44,41 @@ Format:`current` Format: `switch USER_NAME` +Example: `switch max` + ### delete task from one user's timetable: `deletetask` -Format: `deletetask /on DATE /index TASK_INDEX` +Format: `deletetask /on DAY /index TASK_INDEX` + +Example: `deletetask /on monday /index 1` ### change the start time or end time of a task: `changetasktiming` -Format:`changetasktiming /on DATE /index TASK_INDEX /from TIME /to TIME` +Format:`changetasktiming /on DAY /index TASK_INDEX /from TIME /to TIME` + +Example: `changetasktiming /on monday /index 1 /from 12:00 /to 13:00` ### change the task type: `changetasktype` -Format:`changetasktype /on DATE /index TASK_INDEX /type F_OR_C` +Format:`changetasktype /on DAY /index TASK_INDEX /type F_OR_C` + +Example: `changetasktype /on monday /index 1 /type c` ### add task which happens on multiple days into the timetable: `addrepeaettask` -Format:` addrepeattask /task TASK_NAME /on DATES /from START_TIME /to END_TIME /type F_OR_C` +Format:` addrepeattask /task TASK_NAME /on DAYS /from START_TIME /to END_TIME /type F_OR_C` + +Example: `addrepeattask /task lecture /on monday tuesday /from 9:00 /to 11:00 /type c` ### Adding a todo: `todo` Adds a new item to the list of todo items. -Format: `todo n/TODO_NAME d/DEADLINE` - -* The `DEADLINE` can be in a natural language format. -* The `TODO_NAME` cannot contain punctuation. - -Example of usage: - -`todo n/Write the rest of the User Guide d/next week` - -`todo n/Refactor the User Guide to remove passive voice d/13/04/2020` - ## FAQ -**Q**: How do I transfer my data to another computer? +**Q**: Where are the timetables stored? -**A**: {your answer here} +**A**: The timetables are stored in the folder named "data" in the same directory. +The name of the file indicates the owner of the timetable. ## Command Summary From 1ce4aa5752d009c3b965fb45f4e2f4a6e1381900 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 2 Apr 2024 22:24:35 +0800 Subject: [PATCH 074/162] Update UG --- docs/UserGuide.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index f5828a5970..b7978dc9bd 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -70,8 +70,6 @@ Format:` addrepeattask /task TASK_NAME /on DAYS /from START_TIME /to END_TIME /t Example: `addrepeattask /task lecture /on monday tuesday /from 9:00 /to 11:00 /type c` -### Adding a todo: `todo` -Adds a new item to the list of todo items. ## FAQ From cb23ae08d6d0a9c333f39ed29558e51e129d31a1 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Thu, 4 Apr 2024 10:52:07 +0800 Subject: [PATCH 075/162] Add test for storage --- src/main/java/seedu/duke/Storage.java | 6 +- src/main/java/seedu/duke/User.java | 7 +- src/main/java/seedu/duke/UserList.java | 9 +++ .../java/seedu/duke/InputValidatorTest.java | 2 +- src/test/java/seedu/duke/StorageTest.java | 73 +++++++++++++++++++ src/test/java/seedu/duke/TimetableTest.java | 2 +- 6 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 src/test/java/seedu/duke/StorageTest.java diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index b324d1b72b..86897bc914 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -22,7 +22,7 @@ public class Storage { public static final int DESCRIPTION_INDEX = 18; public static final int TYPE_INDEX_INCREMENT = 7; public String filePath; - public static final String folderPath = "data"; + public static String folderPath = "data"; private static final String boxOutline = "+---------+\n"; @@ -31,6 +31,10 @@ public class Storage { private static final String lineSeparator = ".................................................................................................\n"; + + public static void setFolderPath(String newPath) { + folderPath = newPath; + } public Storage(String filePath) { this.filePath = filePath; } diff --git a/src/main/java/seedu/duke/User.java b/src/main/java/seedu/duke/User.java index 73174848cd..7685dba063 100644 --- a/src/main/java/seedu/duke/User.java +++ b/src/main/java/seedu/duke/User.java @@ -6,12 +6,17 @@ public class User { private Timetable timetable; private final String name; + private static String folderPath = "data"; private Storage storage; public User(String name) { this.name = name; this.timetable = new Timetable(); - this.storage = new Storage("data/" + name + ".txt"); + this.storage = new Storage(folderPath + "/" + name + ".txt"); + } + + public static void setFolderPath(String newPath) { + User.folderPath = newPath; } public Storage getStorage() { diff --git a/src/main/java/seedu/duke/UserList.java b/src/main/java/seedu/duke/UserList.java index d51600f53d..be6b0f235e 100644 --- a/src/main/java/seedu/duke/UserList.java +++ b/src/main/java/seedu/duke/UserList.java @@ -55,4 +55,13 @@ public User findUser(String name) { } return null; } + + public boolean containsUser(String userName) { + for (User user : allUsers) { + if (userName.equalsIgnoreCase(user.getName())) { + return true; + } + } + return false; + } } diff --git a/src/test/java/seedu/duke/InputValidatorTest.java b/src/test/java/seedu/duke/InputValidatorTest.java index e9e56e55cd..7a4ab2821a 100644 --- a/src/test/java/seedu/duke/InputValidatorTest.java +++ b/src/test/java/seedu/duke/InputValidatorTest.java @@ -2,7 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; - +import seedu.duke.exceptions.InvalidFormatException; class InputValidatorTest { @Test public void testValidChangeTaskTimingFormat() { diff --git a/src/test/java/seedu/duke/StorageTest.java b/src/test/java/seedu/duke/StorageTest.java new file mode 100644 index 0000000000..8362e61adb --- /dev/null +++ b/src/test/java/seedu/duke/StorageTest.java @@ -0,0 +1,73 @@ +package seedu.duke; + +import org.junit.jupiter.api.*; + +import java.io.File; +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.duke.Storage.*; + +public class StorageTest { + + private static String filePath; + + @BeforeAll + static void setUp() { + String userName = "testUser"; + filePath = "test_data/" + userName + ".txt"; + //File f = new File(filePath); + Storage.setFolderPath("test_data"); + User.setFolderPath("test_data"); + File folder = new File(folderPath); + boolean folderCreated; + if (!folder.exists()) { + folderCreated = folder.mkdirs(); + if (folderCreated) { + System.out.println("Folder created successfully."); + } else { + System.out.println("Failed to create folder."); + } + } else { + System.out.println("Folder already exists."); + } + } + + + @AfterAll + static void deleteTestFile() { + Storage.setFolderPath("data"); + User.setFolderPath("data"); + } + + @Test + void testAddExistingUsers() throws IOException { + setFolderPath("test_data"); + String userName = "testUser"; + + writeToFile(filePath, "Username: " + userName, false); + UserList userList = new UserList(); + Storage.addExistingUsers(userList); + assertTrue(userList.containsUser(userName), "UserList should contain the added user"); + } + +// @Test +// public void testWriteToFileAndLoadData() throws Exception { +// String testPath = tempDir.resolve("testUser.txt").toString(); +// Storage storage = new Storage(testPath); +// User user = new User("testUser"); +// user.getTimetable().addUserTask("Monday", new Task("lecture", "Monday", "10:00", "11:00", "c")); +// +// storage.writeTaskInFile(user); +// +// Scanner scanner = new Scanner(new File(testPath)); +// assertTrue(scanner.hasNextLine(), "Empty file."); +// assertEquals("Username: testUser", scanner.nextLine().trim(), "First line should contain the username"); +// +// // Load data and check if tasks are loaded correctly (requires modification to User and Timetable for assertion) +// User newUser = new User("tempUser"); +// newUser.setStorage(new Storage(tempFilePath)); +// newUser.getStorage().loadData(newUser); +// // Add assertions to verify tasks are loaded correctly +// } +} diff --git a/src/test/java/seedu/duke/TimetableTest.java b/src/test/java/seedu/duke/TimetableTest.java index 218be2e572..2efec1b266 100644 --- a/src/test/java/seedu/duke/TimetableTest.java +++ b/src/test/java/seedu/duke/TimetableTest.java @@ -15,7 +15,7 @@ public void testAddUserTask() { timetable.addUserTask("Tuesday", task); - timetable.printTasksOfTheDay("Tuesday"); + //timetable.printTasksOfTheDay("Tuesday"); assertEquals(1, timetable.getWeeklyTasks().get("Tuesday").size()); assertEquals(task, timetable.getWeeklyTasks().get("Tuesday").get(0)); } From 12f57c8550a1a10cdc0f0b4b290655735b10af74 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Thu, 4 Apr 2024 15:48:49 +0800 Subject: [PATCH 076/162] clean up code on indentation error --- src/main/java/seedu/duke/Parser.java | 4 +--- src/main/java/seedu/duke/Timetable.java | 19 ++++++------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index baf2a5207b..81a74b61a9 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -79,8 +79,7 @@ public static void parseCommand(String command, UserList userList) throws changeTaskType(command, userList); } else if(command.toLowerCase().startsWith("todaytask")){ todaytask(userList); - } - else if (command.toLowerCase().startsWith("compareall")) { + } else if (command.toLowerCase().startsWith("compareall")) { UI.printComparingAll(); UI.printSharedTime(Timetable.compareAllTimetables(userList)); } else if (command.toLowerCase().startsWith("compare")) { @@ -139,7 +138,6 @@ private static void deleteTask(String command, UserList userList) { /** * Adds a task to the timetable with task duplication detection. - * * @param command The user input command. * @param userList The list of users. */ diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index d86fa190c1..107081a51c 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -2,10 +2,8 @@ import seedu.duke.ui.UI; -import java.time.LocalDate; import java.time.LocalTime; import java.time.format.DateTimeFormatter; -import java.time.format.TextStyle; import java.util.*; import static seedu.duke.ui.UI.printTasksOfTheDay; @@ -32,7 +30,6 @@ public Map> getWeeklyTasks() { /** * Adds task on dayOfWeek at an index - * * @param dayOfWeek first Timetable. * @param task task to add. */ @@ -43,7 +40,6 @@ public void addUserTask(String dayOfWeek, Task task) { /** * Adds a task to the timetable with duplication check. - * * @param dayOfWeek The day of the week. * @param task The task to add. * @return True if the task was added successfully, false if a duplicate was found. @@ -63,12 +59,11 @@ public boolean addUserTaskWithDuplicationCheck(String dayOfWeek, Task task) { } - /** - * Deletes task on dayOfWeek at an index - * - * @param dayOfWeek first Timetable. - * @param index index of task within task list - */ + /** + * Deletes task on dayOfWeek at an index + * @param dayOfWeek first Timetable. + * @param index index of task within task list + */ public void deleteUserTask(String dayOfWeek, int index) { String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); //check if index is a valid number within a day's tasklist @@ -195,8 +190,6 @@ public boolean addTaskWithDuplicationCheck(String dayOfWeek, Task task) { return false; } } - - // No duplicate found, add the task tasksOfDay.add(task); return true; } @@ -231,8 +224,8 @@ public ArrayList getTasksForToday() { case Calendar.SUNDAY: day = "Sunday"; break; + default: break; } return weeklyTasks.get(day); } - } From 9dbe139124adfecf78f4c94d8f662b283788a8fa Mon Sep 17 00:00:00 2001 From: john-nng <89668122+john-nng@users.noreply.github.com> Date: Fri, 5 Apr 2024 22:01:54 +0800 Subject: [PATCH 077/162] Update UserGuide.md Updated user guide to most recent project version --- docs/UserGuide.md | 273 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 243 insertions(+), 30 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index a759730fec..eb4359fa1c 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,82 +1,295 @@ # User Guide -## Introduction +### Introduction -{Give a product intro} +Welcome to **TimeTableComparer**! This application is meant for creating and storing task within a weekly calendar and seeing shared time between user's timetables. A convient way to determine shared free time! -## Quick Start +## Table of Contents +- [Quick Start](#quick-start) -{Give steps to get started quickly} +## Quick Start +Downloading TimeTableComparer -1. Ensure that you have Java 11 or above installed. -2. Down the latest version of `Duke` from [here](http://link.to/duke). +1. Ensure that you have [Java 11](https://www.oracle.com/java/technologies/javase-jdk11-downloads.html) or above installed. +2. Down the latest version of `tP.jar` from [here](http://link.to/duke). +3. Copy the file to the folder you want to use as the home folder for the application. For example,`C:\Users\setupuser\Documents\StockPal\stockpal.jar`. +4. Open your terminal or gitBash and `cd` into the folder you placed the .jar file. +5. Run `java -jar tP.jar` ## Features +> Note: `CAPITAL_LETTERS` Indicate the section for user's input. -{Give detailed description of each feature} +## Adding a user: `adduser` -### Adding a user: `adduser` +Add a new user into the user list. -add a new user into the user list. +Format: `adduser NAME` -Format: `adduser /NAME` +Example: `adduser mike` -Example: `adduser /MIKE` +Expected Output: +``` +New user added: mike +The active user is: mike\n +File created: mike.txt +``` +> *If this is the first user created then the active user will be set to the new user* -### adding a task: `addtask' +## Show current user: `current` + +Displays the active user. + +Format:`current` + +Example: `current` +``` +adduser john +adduser jill +adduser jack +current +``` +Expected Output: +``` +The active user is: john +``` + +## Listing all existing users: `list` + +View the list of existing user names. + +Format: `list` + +Example: `list` + +Expected Output: +``` +The current users are: +jane +john +jill +``` + +## Switch to another user: `switch` + +Switch the active user to the inputted name. + +Format: `switch USER_NAME` + +Example: `switch jane` + +Expected Output: +``` +The active user is: jane +``` + +## Adding a task: `addtask` + +Add a new task into the active user's list. Format: `addtask /on DAY /task TASK_NAME /from TIME /to TIME /type TASK_TYPE` -* Both starting time and end time must be in the format of HH:MM. -* Task_type is either `f` (for flexible tasks) or `c` (for compulsory tasks). +> * Both starting time and end time must be in the format of HH:MM or H:MM. +> * TASK_TYPE is either `f` (for flexible tasks) or `c` (for compulsory tasks). Example: `addtask /on monday /task lecture /from 11:00 /to 12:00 /type f` -### adding a task with duplication check: `addtwdc' -Format: `addtwdc /on DATE /task TASK_NAME /from TIME /to TIME /type TASK_TYPE` +Expected Output: +``` +The following task is added: lecture (monday from 11:00 to 12:00) type: f +Timetable has been written to data/mike.txt +``` -Example: `addtwdc /on monday /task lecture /from 11:00 /to 12:00 /type f` +## Adding a task with duplication check: `addtwdc` -### showing current user: `current` +Adding a new task with a duplication check, ensuring that task of this type does not get duplicated. -Format:`current` +Format: `addtwdc /on DATE /task TASK_NAME /from TIME /to TIME /type TASK_TYPE` +>* Both starting time and end time must be in the format of HH:MM or H:MM. +>* TASK_TYPE is either `f` (for flexible tasks) or `c` (for compulsory tasks). -### switch to another user:`switch` +Example: `addtwdc /on monday /task lecture /from 11:00 /to 12:00 /type f` -Format: `switch USER_NAME` +Expected Output (Duplicate Found): +``` +Invalid command. +Task already exists. Cannot add duplicate task. +``` -Example: `switch max` +## Delete task from one user's timetable: `deletetask` -### delete task from one user's timetable: `deletetask` +Delete a task given a specific day and task number. Format: `deletetask /on DAY /index TASK_INDEX` Example: `deletetask /on monday /index 1` -### change the start time or end time of a task: `changetasktiming` +Expected Output: +``` +Task lecture is deleted from monday +New task list for Monday: +No task for monday! +Timetable has been written to data/jane.txt +``` +> This output is given that we deleted the only task on monday. + +## Compare two timetables: `compare` + +Compare timetables between two specified users. + +Format: `compare NAME_1 NAME_2` + +Example: `compare john jane` + +Expected Output: +``` +_________________________________________ +Shared free time on Monday: + 00:00 - 09:00 + 11:00 - 12:00 + 13:00 - 23:59 +_________________________________________ +Shared free time on Tuesday: + 00:00 - 09:00 + 11:00 - 23:59 +_________________________________________ +Shared free time on Wednesday: + ** Whole day is free on Wednesday +_________________________________________ +Shared free time on Thursday: + ** Whole day is free on Thursday +_________________________________________ +Shared free time on Friday: + 00:00 - 13:00 + 14:00 - 23:59 +_________________________________________ +Shared free time on Saturday: + ** Whole day is free on Saturday +_________________________________________ +Shared free time on Sunday: + ** Whole day is free on Sunday +``` + +## Compare all timetables: `compareall` + +Compare timetables between all existing users. + +Format: `compareall` + +Example: `compareall` + +Expected Output: +``` +Comparing all timetables: +_________________________________________ +Shared free time on Monday: + 00:00 - 09:00 + 11:00 - 12:00 + 13:00 - 23:59 +_________________________________________ +Shared free time on Tuesday: + 00:00 - 09:00 + 11:00 - 23:59 +_________________________________________ +Shared free time on Wednesday: + ** Whole day is free on Wednesday +_________________________________________ +Shared free time on Thursday: + ** Whole day is free on Thursday +_________________________________________ +Shared free time on Friday: + 00:00 - 13:00 + 14:00 - 23:59 +_________________________________________ +Shared free time on Saturday: + 00:00 - 02:00 + 04:00 - 23:59 +_________________________________________ +Shared free time on Sunday: + ** Whole day is free on Sunday + +``` + +## Add a task for all existing users: `addforall` + +Add a task for all existing users. + +Format: `addforall /on DAY /task TASK_NAME /from TIME /to TIME /type TASK_TYPE` + +Example: `addforall /on sunday /task laundry /from 7:00 /to 9:00 /type f` + +Expected Output: +``` +Timetable has been written to data/jane.txt +Timetable has been written to data/john.txt +Timetable has been written to data/jill.txt +The following task is added for all users: laundry (sunday from 07:00 to 09:00) type: f +``` + +## Change the start time or end time of a task: `changetasktiming` + +Change the starting/ending time of a task given a day and task number. Format:`changetasktiming /on DAY /index TASK_INDEX /from TIME /to TIME` Example: `changetasktiming /on monday /index 1 /from 12:00 /to 13:00` -### change the task type: `changetasktype` +Expected Output: +``` +Flexible task timing changed successfully. +Timetable has been written to data/jane.txt +``` + +## Change the task type: `changetasktype` Format:`changetasktype /on DAY /index TASK_INDEX /type F_OR_C` -### view today's tasks: `todaytask` +Example: `changetasktype /on monday /index 1 /type c` + +Expected Output: +``` +Task type changed successfully. +Timetable has been written to data/jane.txt +``` + +## View today's tasks: `todaytask` Format: `todaytask` -### Adding a todo: `todo` -Adds a new item to the list of todo items. +Example: `todaytask` -Example: `changetasktype /on monday /index 1 /type c` +Expected Output: +``` +_________________________________________ +Today : + 1. walk dog (friday from 13:00 to 14:00) type: c +``` +>Given that tasks exist the day this command is ran. + +## Add a task which occurs on multiple days: `addrepeaettask` -### add task which happens on multiple days into the timetable: `addrepeaettask` +Add a task which occurs on multiple days given a set of days. Format:` addrepeattask /task TASK_NAME /on DAYS /from START_TIME /to END_TIME /type F_OR_C` Example: `addrepeattask /task lecture /on monday tuesday /from 9:00 /to 11:00 /type c` +Expected Output: +``` +Timetable has been written to data/user.txt +Repeated task added successfully! +``` +## List name of commands: `help` + +Format: `help` + +Example: `help` + +## Exit the program: `bye` + +Format: `bye` + +Example: `bye` + +Expected Output: `Bye.` ## FAQ From 65c01a9d7d4875eedc494afa923108eec9e48055 Mon Sep 17 00:00:00 2001 From: john-nng <89668122+john-nng@users.noreply.github.com> Date: Fri, 5 Apr 2024 22:16:43 +0800 Subject: [PATCH 078/162] Added Table of Contents to UserGuide.md addind table of contents to user guide --- docs/UserGuide.md | 57 +++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index eb4359fa1c..cb05b9691b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -6,6 +6,25 @@ Welcome to **TimeTableComparer**! This application is meant for creating and sto ## Table of Contents - [Quick Start](#quick-start) +- [Features](#features) + - [Adding a user: `adduser`](#adduser) + - [Show current user: `current`](#current) + - [Listing all users: `list`](#list) + - [Switch users: `switch`](#switch) + - [Adding a task: `task`](#addtask) + - [Adding a task (duplication check): `addtwdc`](#addtwdc) + - [Deleting a task: `deletetask`](#deletetask) + - [Comparing two timetables: `compare`](#compare) + - [Comparing all timetables: `compareall`](#compareall) + - [Add a task for all users: `addforall`](#addforall) + - [Changing a task's times: `changetasktiming`](#changetasktiming) + - [Changing a task's type: `changetasktype`](#changetasktype) + - [View today's tasks: `todaytask`](#todaytask) + - [Add a recurring task: `addrepeattask`](#addrepeattask) + - [Help: `help`](#help) + - [Exit program: `bye`](#bye) +- [FAQ](#faq) +- [Command Summary](#commandsummary) ## Quick Start Downloading TimeTableComparer @@ -16,10 +35,10 @@ Downloading TimeTableComparer 4. Open your terminal or gitBash and `cd` into the folder you placed the .jar file. 5. Run `java -jar tP.jar` -## Features +## Features > Note: `CAPITAL_LETTERS` Indicate the section for user's input. -## Adding a user: `adduser` +## Adding a user: `adduser` Add a new user into the user list. @@ -35,7 +54,7 @@ File created: mike.txt ``` > *If this is the first user created then the active user will be set to the new user* -## Show current user: `current` +## Show current user: `current` Displays the active user. @@ -53,7 +72,7 @@ Expected Output: The active user is: john ``` -## Listing all existing users: `list` +## Listing all existing users: `list` View the list of existing user names. @@ -69,7 +88,7 @@ john jill ``` -## Switch to another user: `switch` +## Switch to another user: `switch` Switch the active user to the inputted name. @@ -82,7 +101,7 @@ Expected Output: The active user is: jane ``` -## Adding a task: `addtask` +## Adding a task: `addtask` Add a new task into the active user's list. @@ -98,7 +117,7 @@ The following task is added: lecture (monday from 11:00 to 12:00) type: f Timetable has been written to data/mike.txt ``` -## Adding a task with duplication check: `addtwdc` +## Adding a task with duplication check: `addtwdc` Adding a new task with a duplication check, ensuring that task of this type does not get duplicated. @@ -114,7 +133,7 @@ Invalid command. Task already exists. Cannot add duplicate task. ``` -## Delete task from one user's timetable: `deletetask` +## Delete task from one user's timetable: `deletetask` Delete a task given a specific day and task number. @@ -131,7 +150,7 @@ Timetable has been written to data/jane.txt ``` > This output is given that we deleted the only task on monday. -## Compare two timetables: `compare` +## Compare two timetables: `compare` Compare timetables between two specified users. @@ -168,7 +187,7 @@ Shared free time on Sunday: ** Whole day is free on Sunday ``` -## Compare all timetables: `compareall` +## Compare all timetables: `compareall` Compare timetables between all existing users. @@ -208,7 +227,7 @@ Shared free time on Sunday: ``` -## Add a task for all existing users: `addforall` +## Add a task for all existing users: `addforall` Add a task for all existing users. @@ -224,7 +243,7 @@ Timetable has been written to data/jill.txt The following task is added for all users: laundry (sunday from 07:00 to 09:00) type: f ``` -## Change the start time or end time of a task: `changetasktiming` +## Change the start time or end time of a task: `changetasktiming` Change the starting/ending time of a task given a day and task number. @@ -238,7 +257,7 @@ Flexible task timing changed successfully. Timetable has been written to data/jane.txt ``` -## Change the task type: `changetasktype` +## Change the task type: `changetasktype` Format:`changetasktype /on DAY /index TASK_INDEX /type F_OR_C` @@ -250,7 +269,7 @@ Task type changed successfully. Timetable has been written to data/jane.txt ``` -## View today's tasks: `todaytask` +## View today's tasks: `todaytask` Format: `todaytask` @@ -264,7 +283,7 @@ Today : ``` >Given that tasks exist the day this command is ran. -## Add a task which occurs on multiple days: `addrepeaettask` +## Add a task which occurs on multiple days: `addrepeaettask` Add a task which occurs on multiple days given a set of days. @@ -277,13 +296,13 @@ Expected Output: Timetable has been written to data/user.txt Repeated task added successfully! ``` -## List name of commands: `help` +## List name of commands: `help` Format: `help` Example: `help` -## Exit the program: `bye` +## Exit the program: `bye` Format: `bye` @@ -291,14 +310,14 @@ Example: `bye` Expected Output: `Bye.` -## FAQ +## FAQ **Q**: Where are the timetables stored? **A**: The timetables are stored in the folder named "data" in the same directory. The name of the file indicates the owner of the timetable. -## Command Summary +## Command Summary {Give a 'cheat sheet' of commands here} From 47db8ea97ed3da106a83d75a7ae90152a5e80200 Mon Sep 17 00:00:00 2001 From: john-nng <89668122+john-nng@users.noreply.github.com> Date: Sat, 6 Apr 2024 16:18:33 +0800 Subject: [PATCH 079/162] Fix issues in regards to UserGuide.md --- docs/UserGuide.md | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index cb05b9691b..10ffe786c2 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -49,7 +49,7 @@ Example: `adduser mike` Expected Output: ``` New user added: mike -The active user is: mike\n +The active user is: mike File created: mike.txt ``` > *If this is the first user created then the active user will be set to the new user* @@ -283,11 +283,11 @@ Today : ``` >Given that tasks exist the day this command is ran. -## Add a task which occurs on multiple days: `addrepeaettask` +## Add a task which occurs on multiple days: `addrepeattask` Add a task which occurs on multiple days given a set of days. -Format:` addrepeattask /task TASK_NAME /on DAYS /from START_TIME /to END_TIME /type F_OR_C` +Format: `addrepeattask /task TASK_NAME /on DAYS /from START_TIME /to END_TIME /type F_OR_C` Example: `addrepeattask /task lecture /on monday tuesday /from 9:00 /to 11:00 /type c` @@ -319,6 +319,19 @@ The name of the file indicates the owner of the timetable. ## Command Summary -{Give a 'cheat sheet' of commands here} - -* Add todo `todo n/TODO_NAME d/DEADLINE` +- Add User `adduser NAME` +- Show Active User `current` +- List All Users `list` +- Switch Users `switch` +- Adding a Task `addtask /on DAY /task DESCRIPTION /from START /to END /type [f/c]` +- Adding a Task (Duplication Check) `addtwdc /on DAY /task DESCRIPTION /from START /to END /type [f/c]` +- Delete a Task `deletetask /on DAY /index TASK_NUMBER` +- Compare Two Timetables `compare NAME_1 NAME_2` +- Compare All Timetables `compareall` +- Add a Task For All Users `addforall /on DAY /task DESCRIPTION /from START /to END /type [f/c]` +- Changing a Task's Time `changetasktiming /on DAY /index TASK_INDEX /from TIME /to TIME` +- Changing a Task's Type `changetasktype /on DAY /index TASK_INDEX /type F_OR_C` +- List Today's Tasks `todaytask` +- Add a Recurring task `addrepeattask /task TASK_NAME /on DAYS /from START_TIME /to END_TIME /type F_OR_C` +- Help `help` +- Exit Program `bye` From 3b0a08837a0255008372962afb522738895ad5d8 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Sun, 7 Apr 2024 09:45:06 +0800 Subject: [PATCH 080/162] Clean up files --- .../duke => docs}/AddUserTaskSequenceDiagram.puml | 0 {src/main/java/seedu/duke => docs}/Parse.puml | 0 .../duke => docs}/changeTaskTimingClassDiagram.puml | 0 .../duke => docs}/changeTaskTimingObjectDiagram.puml | 0 {src/main/java/seedu/duke => docs}/changeTaskType.puml | 0 src/main/java/seedu/duke/InvalidDayException.java | 8 -------- src/main/java/seedu/duke/InvalidFormatException.java | 10 ---------- src/main/java/seedu/duke/InvalidUserException.java | 10 ---------- 8 files changed, 28 deletions(-) rename {src/main/java/seedu/duke => docs}/AddUserTaskSequenceDiagram.puml (100%) rename {src/main/java/seedu/duke => docs}/Parse.puml (100%) rename {src/main/java/seedu/duke => docs}/changeTaskTimingClassDiagram.puml (100%) rename {src/main/java/seedu/duke => docs}/changeTaskTimingObjectDiagram.puml (100%) rename {src/main/java/seedu/duke => docs}/changeTaskType.puml (100%) delete mode 100644 src/main/java/seedu/duke/InvalidDayException.java delete mode 100644 src/main/java/seedu/duke/InvalidFormatException.java delete mode 100644 src/main/java/seedu/duke/InvalidUserException.java diff --git a/src/main/java/seedu/duke/AddUserTaskSequenceDiagram.puml b/docs/AddUserTaskSequenceDiagram.puml similarity index 100% rename from src/main/java/seedu/duke/AddUserTaskSequenceDiagram.puml rename to docs/AddUserTaskSequenceDiagram.puml diff --git a/src/main/java/seedu/duke/Parse.puml b/docs/Parse.puml similarity index 100% rename from src/main/java/seedu/duke/Parse.puml rename to docs/Parse.puml diff --git a/src/main/java/seedu/duke/changeTaskTimingClassDiagram.puml b/docs/changeTaskTimingClassDiagram.puml similarity index 100% rename from src/main/java/seedu/duke/changeTaskTimingClassDiagram.puml rename to docs/changeTaskTimingClassDiagram.puml diff --git a/src/main/java/seedu/duke/changeTaskTimingObjectDiagram.puml b/docs/changeTaskTimingObjectDiagram.puml similarity index 100% rename from src/main/java/seedu/duke/changeTaskTimingObjectDiagram.puml rename to docs/changeTaskTimingObjectDiagram.puml diff --git a/src/main/java/seedu/duke/changeTaskType.puml b/docs/changeTaskType.puml similarity index 100% rename from src/main/java/seedu/duke/changeTaskType.puml rename to docs/changeTaskType.puml diff --git a/src/main/java/seedu/duke/InvalidDayException.java b/src/main/java/seedu/duke/InvalidDayException.java deleted file mode 100644 index 99dfff6a7b..0000000000 --- a/src/main/java/seedu/duke/InvalidDayException.java +++ /dev/null @@ -1,8 +0,0 @@ -package seedu.duke; - -public class InvalidDayException extends Exception { - public InvalidDayException(String message) { - super(message); - } - -} diff --git a/src/main/java/seedu/duke/InvalidFormatException.java b/src/main/java/seedu/duke/InvalidFormatException.java deleted file mode 100644 index db2ba7fbff..0000000000 --- a/src/main/java/seedu/duke/InvalidFormatException.java +++ /dev/null @@ -1,10 +0,0 @@ -package seedu.duke; - -/** - * This class represents Expections expected from the InputValidator class. - */ -public class InvalidFormatException extends Exception{ - public InvalidFormatException(String message) { - super(message); - } -} diff --git a/src/main/java/seedu/duke/InvalidUserException.java b/src/main/java/seedu/duke/InvalidUserException.java deleted file mode 100644 index bd836c0681..0000000000 --- a/src/main/java/seedu/duke/InvalidUserException.java +++ /dev/null @@ -1,10 +0,0 @@ -package seedu.duke; - -/** - * This class represents user Expections expected from the InputValidator class. - */ -public class InvalidUserException extends Exception{ - public InvalidUserException(String message) { - super(message); - } -} From b3ace78f33937363f7357ac042df29d9268c2890 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Sun, 7 Apr 2024 09:54:57 +0800 Subject: [PATCH 081/162] Fixed issue: [PE-D][Tester A] Using CAPS for dates will return a unknown output. --- data/simon.txt | 43 +++++++++++++++++++ src/main/java/seedu/duke/Parser.java | 5 ++- .../java/seedu/duke/InputValidatorTest.java | 21 +++++++-- src/test/java/seedu/duke/ParserTest.java | 3 +- 4 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 data/simon.txt diff --git a/data/simon.txt b/data/simon.txt new file mode 100644 index 0000000000..a1a823afb9 --- /dev/null +++ b/data/simon.txt @@ -0,0 +1,43 @@ +Username: simon ++---------+ +| Monday | ++---------+ +1. 09:00 - 11:00: lecture (type: f) +................................................................................................. + ++---------+ +| Tuesday | ++---------+ +No task :) +................................................................................................. + ++-------------+ +| Wednesday | ++-------------+ +No task :) +................................................................................................. + ++---------+ +| Thursday | ++---------+ +No task :) +................................................................................................. + ++------+ +| Friday | ++------+ +No task :) +................................................................................................. + ++---------+ +| Saturday | ++---------+ +No task :) +................................................................................................. + ++---------+ +| Sunday | ++---------+ +No task :) +................................................................................................. + diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 81a74b61a9..a2a474fb91 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -185,10 +185,11 @@ public static boolean checkClash(Task taskToBeAdded, User user) { return false; } - public static Task parseTask(String command) throws InvalidDayException { + public static Task parseTask(String command) throws InvalidDayException, InvalidFormatException { + InputValidator.validateAddTaskInput(command); String[] parts = command.split("\\s+"); List wordList = Arrays.asList(parts); - String day = parts[2]; + String day = parts[2].toLowerCase(); String description = parseDescription(wordList); String startTime = parts[wordList.indexOf("/from") + 1]; String endTime = parts[wordList.indexOf("/to") + 1]; diff --git a/src/test/java/seedu/duke/InputValidatorTest.java b/src/test/java/seedu/duke/InputValidatorTest.java index 7a4ab2821a..5b4985ff23 100644 --- a/src/test/java/seedu/duke/InputValidatorTest.java +++ b/src/test/java/seedu/duke/InputValidatorTest.java @@ -2,6 +2,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; + +import seedu.duke.exceptions.InvalidDayException; import seedu.duke.exceptions.InvalidFormatException; class InputValidatorTest { @Test @@ -21,8 +23,8 @@ public void testInvalidChangeTaskTimingFormat() { InputValidator.validateChangeTaskTiming(invalidInput); fail("Expected InvalidFormatException"); } catch (InvalidFormatException e) { - assertEquals("[ERROR] Invalid changeTaskTiming format. Expected format: " + - "changeTaskTiming /on [day] /index [index] /from [new start time] /to [new end time]", e.getMessage()); + assertEquals("[ERROR] Invalid changeTaskTiming format. Expected format: changeTaskTiming " + + "/on [day] /index [index] /from [new start time] /to [new end time]", e.getMessage()); } } @Test @@ -63,9 +65,20 @@ public void testInvalidAddRepeatTaskFormat() { InputValidator.validateAddRepeatTask(invalidInput); fail("Expected InvalidFormatException"); } catch (InvalidFormatException e) { - assertEquals("[ERROR] Invalid addRepeatTask format. Expected format: " + - "addRepeatTask /task [description] /on [day(s)] /from [start time] /to [end time] /type [f/c]", e.getMessage()); + assertEquals("[ERROR] Invalid addRepeatTask format. Expected format: addRepeatTask /task " + + "[description] /on [day(s)] /from [start time] /to [end time] /type [f/c]", e.getMessage()); } } + @Test + public void testValidateDay() { + String[] inputList = {"monday", "tuesday", "wednesday", "thursday", "friday", "Monday", "MONDAY"}; + for (String input : inputList) { + try { + InputValidator.validateDay(input); + } catch (InvalidDayException e) { + fail(); + } + } + } } \ No newline at end of file diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java index d8fdbfca5a..e35506a6b5 100644 --- a/src/test/java/seedu/duke/ParserTest.java +++ b/src/test/java/seedu/duke/ParserTest.java @@ -122,7 +122,8 @@ public void invalidAddTaskCommandTest() { "addtask /on Monday", "addtask /on Monday /task description", "addtask /on Monday /task description /from 09:00 /to 11:00", - "addtask Monday description 09:00 11:00"}; + "addtask Monday description 09:00 11:00", + "addtask /on MONDAY /task description /from 09:00 /to 11:00"}; for (String message : testMessages) { try { Parser.parseCommand(message, userlist); From 6d73ef5651d9599832de9f5552a4bfa7ba501c09 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Sun, 7 Apr 2024 10:02:10 +0800 Subject: [PATCH 082/162] Fixed issue: [PE-D][Tester D] Inconsistent formatting of days for tasks added --- data/simon.txt | 43 ---------------------------- src/main/java/seedu/duke/Parser.java | 3 +- 2 files changed, 2 insertions(+), 44 deletions(-) delete mode 100644 data/simon.txt diff --git a/data/simon.txt b/data/simon.txt deleted file mode 100644 index a1a823afb9..0000000000 --- a/data/simon.txt +++ /dev/null @@ -1,43 +0,0 @@ -Username: simon -+---------+ -| Monday | -+---------+ -1. 09:00 - 11:00: lecture (type: f) -................................................................................................. - -+---------+ -| Tuesday | -+---------+ -No task :) -................................................................................................. - -+-------------+ -| Wednesday | -+-------------+ -No task :) -................................................................................................. - -+---------+ -| Thursday | -+---------+ -No task :) -................................................................................................. - -+------+ -| Friday | -+------+ -No task :) -................................................................................................. - -+---------+ -| Saturday | -+---------+ -No task :) -................................................................................................. - -+---------+ -| Sunday | -+---------+ -No task :) -................................................................................................. - diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index a2a474fb91..0b6ab49afb 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -189,7 +189,8 @@ public static Task parseTask(String command) throws InvalidDayException, Invalid InputValidator.validateAddTaskInput(command); String[] parts = command.split("\\s+"); List wordList = Arrays.asList(parts); - String day = parts[2].toLowerCase(); + String dayBase = parts[2].toLowerCase(); + String day = dayBase.substring(0, 1).toUpperCase() + dayBase.substring(1); String description = parseDescription(wordList); String startTime = parts[wordList.indexOf("/from") + 1]; String endTime = parts[wordList.indexOf("/to") + 1]; From 1a9448e02d2b3146a170dd2f59768ba8b1f9eff6 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Sun, 7 Apr 2024 10:05:02 +0800 Subject: [PATCH 083/162] Revert "Fixed issue: [PE-D][Tester D] Inconsistent formatting of days for tasks added" This reverts commit 6d73ef5651d9599832de9f5552a4bfa7ba501c09. --- data/simon.txt | 43 ++++++++++++++++++++++++++++ src/main/java/seedu/duke/Parser.java | 3 +- 2 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 data/simon.txt diff --git a/data/simon.txt b/data/simon.txt new file mode 100644 index 0000000000..a1a823afb9 --- /dev/null +++ b/data/simon.txt @@ -0,0 +1,43 @@ +Username: simon ++---------+ +| Monday | ++---------+ +1. 09:00 - 11:00: lecture (type: f) +................................................................................................. + ++---------+ +| Tuesday | ++---------+ +No task :) +................................................................................................. + ++-------------+ +| Wednesday | ++-------------+ +No task :) +................................................................................................. + ++---------+ +| Thursday | ++---------+ +No task :) +................................................................................................. + ++------+ +| Friday | ++------+ +No task :) +................................................................................................. + ++---------+ +| Saturday | ++---------+ +No task :) +................................................................................................. + ++---------+ +| Sunday | ++---------+ +No task :) +................................................................................................. + diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 0b6ab49afb..a2a474fb91 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -189,8 +189,7 @@ public static Task parseTask(String command) throws InvalidDayException, Invalid InputValidator.validateAddTaskInput(command); String[] parts = command.split("\\s+"); List wordList = Arrays.asList(parts); - String dayBase = parts[2].toLowerCase(); - String day = dayBase.substring(0, 1).toUpperCase() + dayBase.substring(1); + String day = parts[2].toLowerCase(); String description = parseDescription(wordList); String startTime = parts[wordList.indexOf("/from") + 1]; String endTime = parts[wordList.indexOf("/to") + 1]; From 2a9b50ab8be08c938d815f7714199312fc084389 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Sun, 7 Apr 2024 10:09:21 +0800 Subject: [PATCH 084/162] Fixed issue: [PE-D][Tester D] Inconsistent formatting of days for tasks added --- data/simon.txt | 43 ---------------------------- src/main/java/seedu/duke/Parser.java | 3 +- 2 files changed, 2 insertions(+), 44 deletions(-) delete mode 100644 data/simon.txt diff --git a/data/simon.txt b/data/simon.txt deleted file mode 100644 index a1a823afb9..0000000000 --- a/data/simon.txt +++ /dev/null @@ -1,43 +0,0 @@ -Username: simon -+---------+ -| Monday | -+---------+ -1. 09:00 - 11:00: lecture (type: f) -................................................................................................. - -+---------+ -| Tuesday | -+---------+ -No task :) -................................................................................................. - -+-------------+ -| Wednesday | -+-------------+ -No task :) -................................................................................................. - -+---------+ -| Thursday | -+---------+ -No task :) -................................................................................................. - -+------+ -| Friday | -+------+ -No task :) -................................................................................................. - -+---------+ -| Saturday | -+---------+ -No task :) -................................................................................................. - -+---------+ -| Sunday | -+---------+ -No task :) -................................................................................................. - diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index a2a474fb91..0b6ab49afb 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -189,7 +189,8 @@ public static Task parseTask(String command) throws InvalidDayException, Invalid InputValidator.validateAddTaskInput(command); String[] parts = command.split("\\s+"); List wordList = Arrays.asList(parts); - String day = parts[2].toLowerCase(); + String dayBase = parts[2].toLowerCase(); + String day = dayBase.substring(0, 1).toUpperCase() + dayBase.substring(1); String description = parseDescription(wordList); String startTime = parts[wordList.indexOf("/from") + 1]; String endTime = parts[wordList.indexOf("/to") + 1]; From 74ce60483d22a7416f91ba4d46cee50857c3c772 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Sun, 7 Apr 2024 16:49:59 +0800 Subject: [PATCH 085/162] Fixed issue: [PE-D][Tester C] Exception message is not self-generated --- src/main/java/seedu/duke/Parser.java | 28 +++++++++----- src/main/java/seedu/duke/Storage.java | 15 ++++---- src/main/java/seedu/duke/Timetable.java | 6 ++- src/main/java/seedu/duke/User.java | 3 +- src/test/java/seedu/duke/ParserTest.java | 47 ++++++++++++++++++++++-- 5 files changed, 74 insertions(+), 25 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 0b6ab49afb..3b1ed02847 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -67,9 +67,9 @@ public static void parseCommand(String command, UserList userList) throws } addTask(command, userList); currentUser.getStorage().writeTaskInFile(currentUser); - } else if (command.toLowerCase().startsWith("addtwdc")) { + } else if (command.toLowerCase().startsWith("addtwdc")) { addTaskWithDuplicationCheck(command, userList); - }else if (command.toLowerCase().startsWith("deletetask")) { + } else if (command.toLowerCase().startsWith("deletetask")) { deleteTask(command, userList); } else if (command.toLowerCase().startsWith("changetasktiming")) { changeTaskTiming(command, userList); @@ -77,7 +77,7 @@ public static void parseCommand(String command, UserList userList) throws addRepeatTask(command, userList); } else if (command.toLowerCase().startsWith("changetasktype")) { changeTaskType(command, userList); - } else if(command.toLowerCase().startsWith("todaytask")){ + } else if (command.toLowerCase().startsWith("todaytask")) { todaytask(userList); } else if (command.toLowerCase().startsWith("compareall")) { UI.printComparingAll(); @@ -114,8 +114,12 @@ private static void changeTaskType(String command, UserList userList) throws Inv currentUser.getTimetable().changeTaskType(day, index - 1, newType); System.out.println("Task type changed successfully."); currentUser.getStorage().writeTaskInFile(currentUser); - } catch (InvalidDayException | IndexOutOfBoundsException | NumberFormatException | IOException e) { + } catch (NumberFormatException | IOException e) { throw new RuntimeException(e); + } catch (IndexOutOfBoundsException e) { + throw new InvalidFormatException("The selected task does not exist. "); + } catch (InvalidDayException e) { + throw new InvalidFormatException("[ERROR] Invalid day. Please enter a day from Monday - Sunday. "); } } @@ -138,6 +142,7 @@ private static void deleteTask(String command, UserList userList) { /** * Adds a task to the timetable with task duplication detection. + * * @param command The user input command. * @param userList The list of users. */ @@ -177,8 +182,10 @@ public static boolean checkClash(Task taskToBeAdded, User user) { String capitalisedDay = day.substring(0, 1).toUpperCase() + day.substring(1); timetable.getWeeklyTasks().get(capitalisedDay).sort(Comparator.comparing(Task::getStartTime)); for (Task task : timetable.getWeeklyTasks().get(capitalisedDay)) { - if (taskToBeAdded.startTime.isAfter(task.getStartTime()) && taskToBeAdded.startTime.isBefore(task.getEndTime()) - || (taskToBeAdded.endTime.isAfter(task.getStartTime()) && taskToBeAdded.endTime.isBefore(task.getEndTime()))) { + if (taskToBeAdded.startTime.isAfter(task.getStartTime()) && + taskToBeAdded.startTime.isBefore(task.getEndTime()) + || (taskToBeAdded.endTime.isAfter(task.getStartTime()) && + taskToBeAdded.endTime.isBefore(task.getEndTime()))) { return true; } } @@ -230,7 +237,8 @@ public static void todaytask(UserList userList) { } } - private static void changeTaskTiming(String command, UserList userList) throws InvalidFormatException { + private static void changeTaskTiming(String command, UserList userList) throws + InvalidFormatException, InvalidDayException { try { InputValidator.validateChangeTaskTiming(command); String[] parts = command.split("\\s+"); @@ -246,8 +254,10 @@ private static void changeTaskTiming(String command, UserList userList) throws I index - 1, newStartTime, newEndTime); currentUser.getStorage().writeTaskInFile(currentUser); System.out.println("Flexible task timing changed successfully."); - } catch (InvalidDayException | IOException e) { + } catch (IOException e) { throw new RuntimeException(e); + } catch (InvalidDayException e) { + throw new InvalidDayException("[ERROR] Invalid day. Please enter a day from Monday - Sunday."); } } @@ -285,7 +295,6 @@ private static void addRepeatTask(String command, UserList userList) { } - private static String parseDescription(List words) { int startIndex = words.indexOf("/task") + 1; int endIndex = words.indexOf("/from") - 1; @@ -300,7 +309,6 @@ private static String parseDescription(List words) { } - private static void addTaskForAll(String command, UserList userList) throws InvalidFormatException, InvalidDayException, IOException { InputValidator.validateAddTaskForAll(command); diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 86897bc914..5006ccbe4c 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -21,24 +21,22 @@ public class Storage { public static final int END_TIME_END_INDEX = 16; public static final int DESCRIPTION_INDEX = 18; public static final int TYPE_INDEX_INCREMENT = 7; - public String filePath; - public static String folderPath = "data"; + public static String folderPath = "data"; private static final String boxOutline = "+---------+\n"; - private static final String boxOutlineForWednesday = "+-------------+\n"; private static final String boxOutlineForFriday = "+------+\n"; private static final String lineSeparator = ".................................................................................................\n"; + public String filePath; - - public static void setFolderPath(String newPath) { - folderPath = newPath; - } public Storage(String filePath) { this.filePath = filePath; } + public static void setFolderPath(String newPath) { + folderPath = newPath; + } public static void createFolder() { File folder = new File(folderPath); @@ -83,7 +81,8 @@ public void loadData(User user) throws FileNotFoundException { while (s.hasNext()) { String line = s.nextLine(); // ignore lines for formatting and weeks that have no tasks - if (line.startsWith("Username") || line.startsWith("+") || line.startsWith(".") || line.isEmpty() || line.equals("No task :)")) { + if (line.startsWith("Username") || line.startsWith("+") || line.startsWith(".") + || line.isEmpty() || line.equals("No task :)")) { continue; } if (line.startsWith("|")) { diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 107081a51c..8a88eea287 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -4,7 +4,11 @@ import java.time.LocalTime; import java.time.format.DateTimeFormatter; -import java.util.*; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; import static seedu.duke.ui.UI.printTasksOfTheDay; diff --git a/src/main/java/seedu/duke/User.java b/src/main/java/seedu/duke/User.java index 7685dba063..2b8cde1684 100644 --- a/src/main/java/seedu/duke/User.java +++ b/src/main/java/seedu/duke/User.java @@ -3,10 +3,9 @@ import seedu.duke.ui.UI; public class User { + private static String folderPath = "data"; private Timetable timetable; private final String name; - - private static String folderPath = "data"; private Storage storage; public User(String name) { diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java index e35506a6b5..1e4939e42e 100644 --- a/src/test/java/seedu/duke/ParserTest.java +++ b/src/test/java/seedu/duke/ParserTest.java @@ -20,7 +20,8 @@ public void sampleTest() { } @Test - public void adduserCommandTest() throws InvalidDayException, InvalidFormatException, InvalidUserException, NoUserException, IOException { + public void adduserCommandTest() throws InvalidDayException, InvalidFormatException, InvalidUserException, + NoUserException, IOException { Parser.parseCommand("addUser User1", userlist); assertEquals(1, userlist.getListLength()); @@ -45,7 +46,8 @@ public void invalidAdduserCommandTest() { } @Test - public void switchCommandTest() throws InvalidDayException, InvalidFormatException, InvalidUserException, NoUserException, IOException { + public void switchCommandTest() throws InvalidDayException, InvalidFormatException, InvalidUserException, + NoUserException, IOException { User user1 = new User("User1"); User user2 = new User("User2"); userlist.addUser(user1); @@ -84,7 +86,8 @@ public void invalidSwitchCommandTest() { } @Test - public void addTaskCommandTest() throws InvalidDayException, InvalidUserException, InvalidFormatException, NoUserException, IOException { + public void addTaskCommandTest() throws InvalidDayException, InvalidUserException, InvalidFormatException, + NoUserException, IOException { User user1 = new User("User1"); userlist.addUser(user1); @@ -148,7 +151,8 @@ public void invalidAddTaskCommandTest() { } @Test - public void addForAllTest() throws InvalidDayException, InvalidUserException, InvalidFormatException, NoUserException, IOException { + public void addForAllTest() throws InvalidDayException, InvalidUserException, InvalidFormatException, + NoUserException, IOException { User user1 = new User("User1"); User user2 = new User("User2"); userlist.addUser(user1); @@ -164,4 +168,39 @@ public void addForAllTest() throws InvalidDayException, InvalidUserException, In assertEquals("09:00", addedTaskUser2.getStartTime().toString()); assertEquals("11:00", addedTaskUser2.getEndTime().toString()); } + + @Test + public void changeTaskTypeTest() throws InvalidDayException, NoUserException, IOException, + InvalidUserException, InvalidFormatException { + User user1 = new User("User1"); + userlist.addUser(user1); + Parser.parseCommand("addtask /on Monday /task test1 /from 9:00 /to 11:00 /type f", userlist); + Task task = user1.getTimetable().getWeeklyTasks().get("Monday").get(0); + assertEquals("f", task.getType()); + + Parser.parseCommand("changetasktype /on Monday /index 1 /type c", userlist); + assertEquals("c", task.getType()); + + Parser.parseCommand("changetasktype /on Monday /index 1 /type c", userlist); + assertEquals("c", task.getType()); + } + + @Test + public void invalidChangeTaskTypeTest() throws InvalidDayException, NoUserException, IOException, + InvalidUserException, InvalidFormatException { + User user1 = new User("User1"); + userlist.addUser(user1); + Parser.parseCommand("addtask /on Monday /task test1 /from 9:00 /to 11:00 /type f", userlist); + Task task = user1.getTimetable().getWeeklyTasks().get("Monday").get(0); + assertEquals("f", task.getType()); + + try { + Parser.parseCommand("changetasktype /on Monday /index 2 /type c", userlist); + fail(); + } catch (InvalidFormatException e) { + assertEquals("The selected task does not exist. ", e.getMessage()); + } catch (IOException e) { + fail(); + } + } } From 1204eb8fbab6225d583cdd3b32faea6cd4b3f854 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Sun, 7 Apr 2024 17:15:51 +0800 Subject: [PATCH 086/162] Fix test --- src/main/java/seedu/duke/InputValidator.java | 3 +- src/main/java/seedu/duke/Storage.java | 15 ++- src/main/java/seedu/duke/User.java | 2 + src/test/java/seedu/duke/StorageTest.java | 110 +++++++++++++++---- 4 files changed, 102 insertions(+), 28 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index d1b1598b5d..371fbc7027 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -174,8 +174,7 @@ public static void validateAddTaskForAll(String input) throws InvalidFormatExcep if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid addtask format. " + - "Expected format: addforall /on [day] /task [description] /from [start time] /to [end time] " + - "/type [f/c]"); + "Expected format: addforall /on [day] /task [description] /from [start time] /to [end time] "); } } diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 86897bc914..6a1724ce9d 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -24,13 +24,20 @@ public class Storage { public String filePath; public static String folderPath = "data"; - private static final String boxOutline = "+---------+\n"; + public static final String boxOutline = "+---------+\n"; - private static final String boxOutlineForWednesday = "+-------------+\n"; - private static final String boxOutlineForFriday = "+------+\n"; - private static final String lineSeparator = + public static final String boxOutlineForWednesday = "+-------------+\n"; + public static final String boxOutlineForFriday = "+------+\n"; + public static final String lineSeparator = ".................................................................................................\n"; + public String getFilePath() { + return filePath; + } + + public static String getFolderPath() { + return folderPath; + } public static void setFolderPath(String newPath) { folderPath = newPath; diff --git a/src/main/java/seedu/duke/User.java b/src/main/java/seedu/duke/User.java index 7685dba063..5f86c061f3 100644 --- a/src/main/java/seedu/duke/User.java +++ b/src/main/java/seedu/duke/User.java @@ -36,4 +36,6 @@ public void viewTimetable() { public Timetable getTimetable() { return timetable; } + + } diff --git a/src/test/java/seedu/duke/StorageTest.java b/src/test/java/seedu/duke/StorageTest.java index 8362e61adb..692c07226d 100644 --- a/src/test/java/seedu/duke/StorageTest.java +++ b/src/test/java/seedu/duke/StorageTest.java @@ -3,17 +3,26 @@ import org.junit.jupiter.api.*; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; +import java.util.Scanner; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.duke.Parser.DAYS; import static seedu.duke.Storage.*; +import static seedu.duke.Storage.boxOutline; +import static seedu.duke.Storage.boxOutlineForWednesday; +import static seedu.duke.Storage.boxOutlineForFriday; +import static seedu.duke.Storage.lineSeparator; + public class StorageTest { private static String filePath; - @BeforeAll - static void setUp() { + @BeforeEach + void setUp() { String userName = "testUser"; filePath = "test_data/" + userName + ".txt"; //File f = new File(filePath); @@ -35,11 +44,23 @@ static void setUp() { @AfterAll - static void deleteTestFile() { + static void resetFolderPath() { Storage.setFolderPath("data"); User.setFolderPath("data"); } + @Test + void testStorageInit() { + User testUser = new User("testUser"); + assertEquals("test_data/testUser.txt", testUser.getStorage().getFilePath()); + } + + @Test + void testSetFolderPath() { + Storage.setFolderPath("testPath"); + assertEquals("testPath", Storage.getFolderPath()); + } + @Test void testAddExistingUsers() throws IOException { setFolderPath("test_data"); @@ -51,23 +72,68 @@ void testAddExistingUsers() throws IOException { assertTrue(userList.containsUser(userName), "UserList should contain the added user"); } -// @Test -// public void testWriteToFileAndLoadData() throws Exception { -// String testPath = tempDir.resolve("testUser.txt").toString(); -// Storage storage = new Storage(testPath); -// User user = new User("testUser"); -// user.getTimetable().addUserTask("Monday", new Task("lecture", "Monday", "10:00", "11:00", "c")); -// -// storage.writeTaskInFile(user); -// -// Scanner scanner = new Scanner(new File(testPath)); -// assertTrue(scanner.hasNextLine(), "Empty file."); -// assertEquals("Username: testUser", scanner.nextLine().trim(), "First line should contain the username"); -// -// // Load data and check if tasks are loaded correctly (requires modification to User and Timetable for assertion) -// User newUser = new User("tempUser"); -// newUser.setStorage(new Storage(tempFilePath)); -// newUser.getStorage().loadData(newUser); -// // Add assertions to verify tasks are loaded correctly -// } + @Test + public void testAddNewUserToFolder() { + UserList userList = new UserList(); + User newUser = new User("testAddUser"); + userList.addUser(newUser); + newUser.getStorage().addUserInFolder(); + + File directory = new File(folderPath); + File file = new File(directory, "testAddUser.txt"); + System.out.println(directory.getAbsolutePath()); + assertTrue(file.exists()); + } + + @Test + public void testWriteToFile() throws Exception { + User testUser = new User("testUser"); + testUser.getTimetable().addUserTask("Monday", new Task("lecture", "Monday", "10:00", "11:00", "c")); + + testUser.getStorage().writeTaskInFile(testUser); + + Scanner scanner = new Scanner(new File(filePath)); + assertTrue(scanner.hasNextLine(), "Empty file."); + assertEquals("Username: testUser", scanner.nextLine().trim(), "First line should contain the username"); + } + + @Test + public void testExtractTaskInfo() { + String line = "1. 01:00 - 02:00: lecture (type: c)"; + Task task = extractTaskInfo(line, "Monday"); + assertEquals("lecture", task.getDescription()); + assertEquals("01:00", task.getStartTime().toString()); + assertEquals("02:00", task.getEndTime().toString()); + assertEquals("c", task.getType()); + } + + @Test + public void testLoadData() throws IOException { + writeToFile(filePath, "Username: " + "testUser" + "\n", false); + for (String day : DAYS) { + String outline; + switch (day) { + case ("Wednesday"): + outline = boxOutlineForWednesday; + break; + case ("Friday"): + outline = boxOutlineForFriday; + break; + default: + outline = boxOutline; + break; + } + writeToFile(filePath, outline, true); + writeToFile(filePath, "| " + day + " |" + "\n", true); + writeToFile(filePath, outline, true); + + if (day.equals("Monday")) { + writeToFile(filePath, "1. 01:00 - 02:00: lecture (type: c)", true); + } else if (day.equals("Thursday")) { + + } + writeToFile(filePath, lineSeparator, true); + writeToFile(filePath, "\n", true); + } + } } From dc31f1c86ac42e3ff1c0db10c6e410cb85a63731 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Sun, 7 Apr 2024 18:00:16 +0800 Subject: [PATCH 087/162] Fix addforall bugs --- docs/UserGuide.md | 7 +++-- src/main/java/seedu/duke/InputValidator.java | 4 +-- src/main/java/seedu/duke/Parser.java | 30 ++++++++++++++------ src/main/java/seedu/duke/Storage.java | 8 +++--- src/test/java/seedu/duke/StorageTest.java | 3 +- 5 files changed, 32 insertions(+), 20 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 10ffe786c2..178dee8b3c 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -231,16 +231,17 @@ Shared free time on Sunday: Add a task for all existing users. -Format: `addforall /on DAY /task TASK_NAME /from TIME /to TIME /type TASK_TYPE` +Format: `addforall /on DAY /task TASK_NAME /from TIME /to TIME` -Example: `addforall /on sunday /task laundry /from 7:00 /to 9:00 /type f` +Example: `addforall /on sunday /task laundry /from 7:00 /to 9:00` +* Note: there is no need to specify type for common events as tasks added for all users are assumed to be of type "common", Expected Output: ``` Timetable has been written to data/jane.txt Timetable has been written to data/john.txt Timetable has been written to data/jill.txt -The following task is added for all users: laundry (sunday from 07:00 to 09:00) type: f +The following task is added for all users: laundry (sunday from 07:00 to 09:00) ``` ## Change the start time or end time of a task: `changetasktiming` diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 371fbc7027..5c9ced72f1 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -173,8 +173,8 @@ public static void validateAddTaskForAll(String input) throws InvalidFormatExcep "/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})\\s?"; if (!input.matches(regex)) { - throw new InvalidFormatException("[ERROR] Invalid addtask format. " + - "Expected format: addforall /on [day] /task [description] /from [start time] /to [end time] "); + throw new InvalidFormatException("[ERROR] Invalid addforall format. " + + "Expected format: addforall /on [day] /task [description] /from [start time] /to [end time]"); } } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 3b1ed02847..dbba3859b1 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -92,6 +92,7 @@ public static void parseCommand(String command, UserList userList) throws UI.printSharedTime(Timetable.compareTimetable(userList.findUser(user1).getTimetable(), userList.findUser(user2).getTimetable())); } else if (command.toLowerCase().startsWith("addforall")) { + InputValidator.validateAddTaskForAll(command); addTaskForAll(command, userList); } else if (command.toLowerCase().startsWith("viewcommonevents")) { printConfirmedEvent(userList); @@ -201,14 +202,21 @@ public static Task parseTask(String command) throws InvalidDayException, Invalid String description = parseDescription(wordList); String startTime = parts[wordList.indexOf("/from") + 1]; String endTime = parts[wordList.indexOf("/to") + 1]; + String type = parts[wordList.indexOf("/type") + 1]; + InputValidator.validateDay(day); + return new Task(description, day, startTime, endTime, type); + } - String type; - if (wordList.contains("/type")) { - type = parts[wordList.indexOf("/type") + 1]; - } else { - type = "common"; - } + public static Task parseAddForAllTask(String command) throws InvalidDayException { + String[] parts = command.split("\\s+"); + List wordList = Arrays.asList(parts); + String dayBase = parts[2].toLowerCase(); + String day = dayBase.substring(0, 1).toUpperCase() + dayBase.substring(1); + String description = parseDescription(wordList); + String startTime = parts[wordList.indexOf("/from") + 1]; + String endTime = parts[wordList.indexOf("/to") + 1]; + String type = "common"; InputValidator.validateDay(day); return new Task(description, day, startTime, endTime, type); } @@ -310,9 +318,9 @@ private static String parseDescription(List words) { private static void addTaskForAll(String command, UserList userList) - throws InvalidFormatException, InvalidDayException, IOException { - InputValidator.validateAddTaskForAll(command); - Task task = parseTask(command); + throws InvalidDayException, IOException { + //InputValidator.validateAddTaskForAll(command); + Task task = parseAddForAllTask(command); assert !userList.getUsers().isEmpty() : "There is no user added."; for (User user : userList.getUsers()) { user.getTimetable().addUserTask(task.day, task); @@ -328,9 +336,13 @@ private static void printConfirmedEvent(UserList userList) { for (Task task : userList.getActiveUser().getTimetable().getWeeklyTasks().get(day)) { if (task.type.equals("common")) { System.out.println(taskCount + ". " + task); + taskCount++; } } } + if (taskCount == 1) { + System.out.println("There is no common events."); + } } private static void printNextTask(User currentUser) { diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 4e555ea7a5..0d3359d549 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -23,10 +23,10 @@ public class Storage { public static final int TYPE_INDEX_INCREMENT = 7; public static String folderPath = "data"; - private static final String boxOutline = "+---------+\n"; - private static final String boxOutlineForWednesday = "+-------------+\n"; - private static final String boxOutlineForFriday = "+------+\n"; - private static final String lineSeparator = + public static final String boxOutline = "+---------+\n"; + public static final String boxOutlineForWednesday = "+-------------+\n"; + public static final String boxOutlineForFriday = "+------+\n"; + public static final String lineSeparator = ".................................................................................................\n"; public String filePath; diff --git a/src/test/java/seedu/duke/StorageTest.java b/src/test/java/seedu/duke/StorageTest.java index 692c07226d..90d377f17a 100644 --- a/src/test/java/seedu/duke/StorageTest.java +++ b/src/test/java/seedu/duke/StorageTest.java @@ -3,7 +3,6 @@ import org.junit.jupiter.api.*; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.Scanner; @@ -130,7 +129,7 @@ public void testLoadData() throws IOException { if (day.equals("Monday")) { writeToFile(filePath, "1. 01:00 - 02:00: lecture (type: c)", true); } else if (day.equals("Thursday")) { - + writeToFile(filePath, "2. 02:00 - 03:00: lecture (type: f)", true); } writeToFile(filePath, lineSeparator, true); writeToFile(filePath, "\n", true); From 476a247afe032ab33d1b9af4e5e70d427f581c49 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Tue, 9 Apr 2024 09:57:04 +0800 Subject: [PATCH 088/162] Fixed issue: [PE-D][Tester D] Inputting correct user for compare command does not leads to an error --- src/main/java/seedu/duke/InputValidator.java | 2 +- src/main/java/seedu/duke/Parser.java | 34 +++++++++++--------- src/main/java/seedu/duke/ui/UI.java | 7 +++- src/test/java/seedu/duke/ParserTest.java | 18 ++++++++++- 4 files changed, 43 insertions(+), 18 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 5c9ced72f1..a54ea1732d 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -116,7 +116,7 @@ public static void validateUserInput(String input, UserList userList) throws Inv throw new InvalidUserException("[ERROR] Current User List is empty. Please add users."); } for (User u : userList.getUsers()) { - if (u.getName().toLowerCase().equals(input)) { + if (u.getName().equals(input)) { return; } } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index dbba3859b1..fef8057a84 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -20,6 +20,11 @@ public class Parser { protected static final String[] DAYS = new String[] {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; + public static String capitalizeFirstLetter(String input) { + String lowerCase = input.toLowerCase(); + return lowerCase.substring(0, 1).toUpperCase() + lowerCase.substring(1); + } + /** * Parses User Input and Identifies the command used. * @@ -44,7 +49,7 @@ public static void parseCommand(String command, UserList userList) throws } else if (command.toLowerCase().startsWith("adduser")) { InputValidator.validateAddUserInput(command); String[] parts = command.split("\\s+"); - String userName = parts[1]; + String userName = Parser.capitalizeFirstLetter(parts[1]); User newUser = new User(userName); UI.printNewUser(newUser.getName()); userList.addUser(newUser); @@ -78,17 +83,18 @@ public static void parseCommand(String command, UserList userList) throws } else if (command.toLowerCase().startsWith("changetasktype")) { changeTaskType(command, userList); } else if (command.toLowerCase().startsWith("todaytask")) { - todaytask(userList); + todayTask(userList); } else if (command.toLowerCase().startsWith("compareall")) { UI.printComparingAll(); UI.printSharedTime(Timetable.compareAllTimetables(userList)); } else if (command.toLowerCase().startsWith("compare")) { InputValidator.validateCompareInput(command); String[] parts = command.split("\\s+"); - String user1 = parts[1]; - String user2 = parts[2]; + String user1 = capitalizeFirstLetter(parts[1]); + String user2 = capitalizeFirstLetter(parts[2]); InputValidator.validateUserInput(user1, userList); InputValidator.validateUserInput(user2, userList); + UI.printCompareUsers(user1, user2); UI.printSharedTime(Timetable.compareTimetable(userList.findUser(user1).getTimetable(), userList.findUser(user2).getTimetable())); } else if (command.toLowerCase().startsWith("addforall")) { @@ -180,7 +186,7 @@ private static void addTask(String command, UserList userList) { public static boolean checkClash(Task taskToBeAdded, User user) { Timetable timetable = user.getTimetable(); String day = taskToBeAdded.day; - String capitalisedDay = day.substring(0, 1).toUpperCase() + day.substring(1); + String capitalisedDay = Parser.capitalizeFirstLetter(day); timetable.getWeeklyTasks().get(capitalisedDay).sort(Comparator.comparing(Task::getStartTime)); for (Task task : timetable.getWeeklyTasks().get(capitalisedDay)) { if (taskToBeAdded.startTime.isAfter(task.getStartTime()) && @@ -197,8 +203,7 @@ public static Task parseTask(String command) throws InvalidDayException, Invalid InputValidator.validateAddTaskInput(command); String[] parts = command.split("\\s+"); List wordList = Arrays.asList(parts); - String dayBase = parts[2].toLowerCase(); - String day = dayBase.substring(0, 1).toUpperCase() + dayBase.substring(1); + String day = Parser.capitalizeFirstLetter(parts[2]); String description = parseDescription(wordList); String startTime = parts[wordList.indexOf("/from") + 1]; String endTime = parts[wordList.indexOf("/to") + 1]; @@ -210,8 +215,7 @@ public static Task parseTask(String command) throws InvalidDayException, Invalid public static Task parseAddForAllTask(String command) throws InvalidDayException { String[] parts = command.split("\\s+"); List wordList = Arrays.asList(parts); - String dayBase = parts[2].toLowerCase(); - String day = dayBase.substring(0, 1).toUpperCase() + dayBase.substring(1); + String day = Parser.capitalizeFirstLetter(parts[2]); String description = parseDescription(wordList); String startTime = parts[wordList.indexOf("/from") + 1]; String endTime = parts[wordList.indexOf("/to") + 1]; @@ -226,9 +230,9 @@ public static Task parseAddForAllTask(String command) throws InvalidDayException * * @param userList The list of users. */ - public static void todaytask(UserList userList) { - String dayOfWeek = DayOfWeek.from(LocalDate.now()).toString().toLowerCase(); - String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); + public static void todayTask(UserList userList) { + String dayOfWeek = DayOfWeek.from(LocalDate.now()).toString(); + String capitalizedDay = Parser.capitalizeFirstLetter(dayOfWeek); ArrayList tasksForToday = userList.getActiveUser().getTimetable().getWeeklyTasks().get(capitalizedDay); if (tasksForToday.isEmpty()) { @@ -236,7 +240,7 @@ public static void todaytask(UserList userList) { return; } - System.out.println("_________________________________________"); + UI.printLine(); UI.printDayHeader("Today"); int count = 1; for (Task task : tasksForToday) { @@ -347,8 +351,8 @@ private static void printConfirmedEvent(UserList userList) { private static void printNextTask(User currentUser) { LocalTime currentTime = LocalTime.now(); - String dayOfWeek = DayOfWeek.from(LocalDate.now()).toString().toLowerCase(); - String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); + String dayOfWeek = DayOfWeek.from(LocalDate.now()).toString(); + String capitalizedDay = Parser.capitalizeFirstLetter(dayOfWeek); Task current = new Task("temp", dayOfWeek, currentTime.toString(), currentTime.toString(), "f"); ArrayList tasksOfDay = currentUser.getTimetable().getWeeklyTasks().get(capitalizedDay); diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index 4ea146a245..d9546107a5 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -2,6 +2,7 @@ import seedu.duke.Task; import seedu.duke.Timetable; +import seedu.duke.User; import java.time.LocalTime; import java.util.ArrayList; @@ -81,13 +82,17 @@ public static void printLine() { */ public static void printSharedTime(Timetable merged) { for (String day : Timetable.DAYS) { - System.out.println("_________________________________________"); + UI.printLine(); System.out.println("Shared free time on " + day + ":"); findOverlappingFreeTime(merged.getWeeklyTasks().get(day), day); } } + public static void printCompareUsers(String user1, String user2) { + System.out.println("Comparing timetables of " + user1 + " and " + user2 + ": "); + } + public static void printComparingAll() { System.out.println("Comparing all timetables: "); } diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java index 1e4939e42e..707ee764b7 100644 --- a/src/test/java/seedu/duke/ParserTest.java +++ b/src/test/java/seedu/duke/ParserTest.java @@ -45,6 +45,22 @@ public void invalidAdduserCommandTest() { } } + @Test + public void compareCommandTest() { + User user1 = new User("User1"); + User user2 = new User("User2"); + userlist.addUser(user1); + userlist.addUser(user2); + + try { + Parser.parseCommand("compare User1 User1", userlist); + Parser.parseCommand("compare user1 user1", userlist); + Parser.parseCommand("compare User1 User2", userlist); + } catch (Exception e) { + fail(); + } + } + @Test public void switchCommandTest() throws InvalidDayException, InvalidFormatException, InvalidUserException, NoUserException, IOException { @@ -158,7 +174,7 @@ public void addForAllTest() throws InvalidDayException, InvalidUserException, In userlist.addUser(user1); userlist.addUser(user2); - Parser.parseCommand("addforall /on Monday /task lecture /from 9:00 /to 11:00 /type f", userlist); + Parser.parseCommand("addforall /on Monday /task lecture /from 9:00 /to 11:00", userlist); Task addedTaskUser1 = user1.getTimetable().getWeeklyTasks().get("Monday").get(0); Task addedTaskUser2 = user1.getTimetable().getWeeklyTasks().get("Monday").get(0); From 095f5fc788e63085c97ebc068d440e74ff2d4e2b Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 10:09:06 +0800 Subject: [PATCH 089/162] FIx test --- src/main/java/seedu/duke/InputValidator.java | 1 + src/test/java/seedu/duke/ParserTest.java | 9 ++++++++- src/test/java/seedu/duke/StorageTest.java | 1 - 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 5c9ced72f1..a219657ff8 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -202,3 +202,4 @@ public static void validateAddRepeatTask(String input) throws InvalidFormatExcep } } } + diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java index 1e4939e42e..3dec5d1c57 100644 --- a/src/test/java/seedu/duke/ParserTest.java +++ b/src/test/java/seedu/duke/ParserTest.java @@ -6,10 +6,12 @@ import seedu.duke.exceptions.InvalidUserException; import seedu.duke.exceptions.NoUserException; +import java.io.File; import java.io.IOException; import java.util.ArrayList; import static org.junit.jupiter.api.Assertions.*; +import static seedu.duke.Storage.folderPath; class ParserTest { UserList userlist = new UserList(); @@ -88,6 +90,11 @@ public void invalidSwitchCommandTest() { @Test public void addTaskCommandTest() throws InvalidDayException, InvalidUserException, InvalidFormatException, NoUserException, IOException { + + // + Storage.setFolderPath("test_data"); + User.setFolderPath("test_data"); + User user1 = new User("User1"); userlist.addUser(user1); @@ -158,7 +165,7 @@ public void addForAllTest() throws InvalidDayException, InvalidUserException, In userlist.addUser(user1); userlist.addUser(user2); - Parser.parseCommand("addforall /on Monday /task lecture /from 9:00 /to 11:00 /type f", userlist); + Parser.parseCommand("addforall /on Monday /task lecture /from 9:00 /to 11:00", userlist); Task addedTaskUser1 = user1.getTimetable().getWeeklyTasks().get("Monday").get(0); Task addedTaskUser2 = user1.getTimetable().getWeeklyTasks().get("Monday").get(0); diff --git a/src/test/java/seedu/duke/StorageTest.java b/src/test/java/seedu/duke/StorageTest.java index 90d377f17a..b1867618e2 100644 --- a/src/test/java/seedu/duke/StorageTest.java +++ b/src/test/java/seedu/duke/StorageTest.java @@ -24,7 +24,6 @@ public class StorageTest { void setUp() { String userName = "testUser"; filePath = "test_data/" + userName + ".txt"; - //File f = new File(filePath); Storage.setFolderPath("test_data"); User.setFolderPath("test_data"); File folder = new File(folderPath); From 6aec41b7a09087400eb116e98418e48f48745c62 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Tue, 9 Apr 2024 10:15:50 +0800 Subject: [PATCH 090/162] Fixed issue: [PE-D][Tester C] addrepeattask does not support upper case inputs for day --- src/main/java/seedu/duke/Parser.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index fef8057a84..9cecfa0716 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -294,8 +294,9 @@ private static void addRepeatTask(String command, UserList userList) { String type = parts[wordlist.indexOf("/type") + 1]; User currentUser = userList.getActiveUser(); for (String day : days) { - Task task = new Task(description, day, startTime, endTime, type); - currentUser.getTimetable().addUserTask(day, task); + String capitalizedDay = Parser.capitalizeFirstLetter(day); + Task task = new Task(description, capitalizedDay, startTime, endTime, type); + currentUser.getTimetable().addUserTask(capitalizedDay, task); } currentUser.getStorage().writeTaskInFile(currentUser); System.out.println("Repeated task added successfully!"); From e87f238ced7f3517fa97559d7b53f5eb0765cbf9 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 10:22:56 +0800 Subject: [PATCH 091/162] Clean up code --- src/main/java/seedu/duke/Storage.java | 24 ++++++++-------- src/main/java/seedu/duke/ui/UI.java | 1 - .../java/seedu/duke/InputValidatorTest.java | 4 +-- src/test/java/seedu/duke/ParserTest.java | 2 -- src/test/java/seedu/duke/StorageTest.java | 28 +++++++++++-------- src/test/java/seedu/duke/TimetableTest.java | 10 +++---- 6 files changed, 37 insertions(+), 32 deletions(-) diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 0d3359d549..8b2abe8e81 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -23,13 +23,17 @@ public class Storage { public static final int TYPE_INDEX_INCREMENT = 7; public static String folderPath = "data"; - public static final String boxOutline = "+---------+\n"; - public static final String boxOutlineForWednesday = "+-------------+\n"; - public static final String boxOutlineForFriday = "+------+\n"; - public static final String lineSeparator = + public static final String BOX_OUTLINE = "+---------+\n"; + public static final String BOX_OUTLINE_FOR_WEDNESDAY = "+-------------+\n"; + public static final String BOX_OUTLINE_FOR_FRIDAY = "+------+\n"; + public static final String LINE_SEPARATOR = ".................................................................................................\n"; public String filePath; + public Storage(String filePath) { + this.filePath = filePath; + } + public String getFilePath() { return filePath; } @@ -42,9 +46,7 @@ public static void setFolderPath(String newPath) { folderPath = newPath; } - public Storage(String filePath) { - this.filePath = filePath; - } + public static void createFolder() { File folder = new File(folderPath); @@ -157,13 +159,13 @@ public void writeTaskInFile(User user) throws IOException { String outline; switch (day) { case ("Wednesday"): - outline = boxOutlineForWednesday; + outline = BOX_OUTLINE_FOR_WEDNESDAY; break; case ("Friday"): - outline = boxOutlineForFriday; + outline = BOX_OUTLINE_FOR_FRIDAY; break; default: - outline = boxOutline; + outline = BOX_OUTLINE; break; } writeToFile(filePath, outline, true); @@ -180,7 +182,7 @@ public void writeTaskInFile(User user) throws IOException { taskCount += 1; } } - writeToFile(filePath, lineSeparator, true); + writeToFile(filePath, LINE_SEPARATOR, true); writeToFile(filePath, "\n", true); } diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index d9546107a5..1630952504 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -2,7 +2,6 @@ import seedu.duke.Task; import seedu.duke.Timetable; -import seedu.duke.User; import java.time.LocalTime; import java.util.ArrayList; diff --git a/src/test/java/seedu/duke/InputValidatorTest.java b/src/test/java/seedu/duke/InputValidatorTest.java index 5b4985ff23..7697a574cc 100644 --- a/src/test/java/seedu/duke/InputValidatorTest.java +++ b/src/test/java/seedu/duke/InputValidatorTest.java @@ -1,7 +1,7 @@ package seedu.duke; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.fail; import seedu.duke.exceptions.InvalidDayException; import seedu.duke.exceptions.InvalidFormatException; @@ -81,4 +81,4 @@ public void testValidateDay() { } } } -} \ No newline at end of file +} diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java index b473a092dc..0065860f6c 100644 --- a/src/test/java/seedu/duke/ParserTest.java +++ b/src/test/java/seedu/duke/ParserTest.java @@ -6,12 +6,10 @@ import seedu.duke.exceptions.InvalidUserException; import seedu.duke.exceptions.NoUserException; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import static org.junit.jupiter.api.Assertions.*; -import static seedu.duke.Storage.folderPath; class ParserTest { UserList userlist = new UserList(); diff --git a/src/test/java/seedu/duke/StorageTest.java b/src/test/java/seedu/duke/StorageTest.java index b1867618e2..ae379f730e 100644 --- a/src/test/java/seedu/duke/StorageTest.java +++ b/src/test/java/seedu/duke/StorageTest.java @@ -1,6 +1,9 @@ package seedu.duke; -import org.junit.jupiter.api.*; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.io.File; import java.io.IOException; @@ -9,11 +12,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static seedu.duke.Parser.DAYS; -import static seedu.duke.Storage.*; -import static seedu.duke.Storage.boxOutline; -import static seedu.duke.Storage.boxOutlineForWednesday; -import static seedu.duke.Storage.boxOutlineForFriday; -import static seedu.duke.Storage.lineSeparator; +import static seedu.duke.Storage.folderPath; +import static seedu.duke.Storage.setFolderPath; +import static seedu.duke.Storage.writeToFile; +import static seedu.duke.Storage.extractTaskInfo; +import static seedu.duke.Storage.BOX_OUTLINE; +import static seedu.duke.Storage.BOX_OUTLINE_FOR_WEDNESDAY; +import static seedu.duke.Storage.BOX_OUTLINE_FOR_FRIDAY; +import static seedu.duke.Storage.LINE_SEPARATOR; public class StorageTest { @@ -24,7 +30,7 @@ public class StorageTest { void setUp() { String userName = "testUser"; filePath = "test_data/" + userName + ".txt"; - Storage.setFolderPath("test_data"); + setFolderPath("test_data"); User.setFolderPath("test_data"); File folder = new File(folderPath); boolean folderCreated; @@ -112,13 +118,13 @@ public void testLoadData() throws IOException { String outline; switch (day) { case ("Wednesday"): - outline = boxOutlineForWednesday; + outline = BOX_OUTLINE_FOR_WEDNESDAY; break; case ("Friday"): - outline = boxOutlineForFriday; + outline = BOX_OUTLINE_FOR_FRIDAY; break; default: - outline = boxOutline; + outline = BOX_OUTLINE; break; } writeToFile(filePath, outline, true); @@ -130,7 +136,7 @@ public void testLoadData() throws IOException { } else if (day.equals("Thursday")) { writeToFile(filePath, "2. 02:00 - 03:00: lecture (type: f)", true); } - writeToFile(filePath, lineSeparator, true); + writeToFile(filePath, LINE_SEPARATOR, true); writeToFile(filePath, "\n", true); } } diff --git a/src/test/java/seedu/duke/TimetableTest.java b/src/test/java/seedu/duke/TimetableTest.java index 2efec1b266..b7af23eb0e 100644 --- a/src/test/java/seedu/duke/TimetableTest.java +++ b/src/test/java/seedu/duke/TimetableTest.java @@ -31,7 +31,7 @@ public void testCompareTimetables() { Timetable.compareTimetable(timetable1, timetable2); } @Test - public void testChangeFlexibleTaskTiming_CorrectInput() { + public void testChangeFlexibleTaskTiming_correctInput() { Timetable timetable = new Timetable(); Task flexibleTask = new Task("lec", "monday", "09:00", "11:00", "f"); timetable.addUserTask("monday", flexibleTask); @@ -43,7 +43,7 @@ public void testChangeFlexibleTaskTiming_CorrectInput() { } } @Test - public void testChangeFlexibleTaskTiming_InvalidIndex(){ + public void testChangeFlexibleTaskTiming_invalidIndex(){ Timetable timetable = new Timetable(); try{ timetable.changeFlexibleTaskTiming("monday", 0, LocalTime.of(11, 0), @@ -54,7 +54,7 @@ public void testChangeFlexibleTaskTiming_InvalidIndex(){ } } @Test - public void testChangeFlexibleTaskTiming_NonFlexibleTask() { + public void testChangeFlexibleTaskTiming_nonFlexibleTask() { Timetable timetable = new Timetable(); Task nonFlexibleTask = new Task("lec", "monday", "09:00", "11:00", "c"); timetable.addUserTask("monday", nonFlexibleTask); @@ -67,7 +67,7 @@ public void testChangeFlexibleTaskTiming_NonFlexibleTask() { } } @Test - public void testChangeTaskType_ValidInput() { + public void testChangeTaskType_validInput() { Timetable timetable = new Timetable(); Task task = new Task("lec", "monday", "09:00", "11:00", "f"); timetable.addUserTask("monday", task); @@ -78,7 +78,7 @@ public void testChangeTaskType_ValidInput() { } } @Test - public void testChangeTaskType_InvalidIndex() { + public void testChangeTaskType_invalidIndex() { Timetable timetable = new Timetable(); try { timetable.changeTaskType("monday", 0, "c"); From 8bab691e2cf365af02c9d915aeb4c2f13a8dd257 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 10:31:08 +0800 Subject: [PATCH 092/162] Change indentation --- src/test/java/seedu/duke/ParserTest.java | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java index 0065860f6c..d4cf616759 100644 --- a/src/test/java/seedu/duke/ParserTest.java +++ b/src/test/java/seedu/duke/ParserTest.java @@ -9,7 +9,9 @@ import java.io.IOException; import java.util.ArrayList; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; class ParserTest { UserList userlist = new UserList(); @@ -143,11 +145,11 @@ public void invalidAddTaskCommandTest() { String expectedErrorMessage = "[ERROR] Invalid addtask format. Expected format: addtask /on [day]" + " /task [description] /from [start time] /to [end time] /type [f/c]"; String[] testMessages = {"addtask", - "addtask /on Monday", - "addtask /on Monday /task description", - "addtask /on Monday /task description /from 09:00 /to 11:00", - "addtask Monday description 09:00 11:00", - "addtask /on MONDAY /task description /from 09:00 /to 11:00"}; + "addtask /on Monday", + "addtask /on Monday /task description", + "addtask /on Monday /task description /from 09:00 /to 11:00", + "addtask Monday description 09:00 11:00", + "addtask /on MONDAY /task description /from 09:00 /to 11:00"}; for (String message : testMessages) { try { Parser.parseCommand(message, userlist); @@ -174,6 +176,9 @@ public void invalidAddTaskCommandTest() { @Test public void addForAllTest() throws InvalidDayException, InvalidUserException, InvalidFormatException, NoUserException, IOException { + Storage.setFolderPath("test_data"); + User.setFolderPath("test_data"); + User user1 = new User("User1"); User user2 = new User("User2"); userlist.addUser(user1); @@ -193,6 +198,9 @@ public void addForAllTest() throws InvalidDayException, InvalidUserException, In @Test public void changeTaskTypeTest() throws InvalidDayException, NoUserException, IOException, InvalidUserException, InvalidFormatException { + Storage.setFolderPath("test_data"); + User.setFolderPath("test_data"); + User user1 = new User("User1"); userlist.addUser(user1); Parser.parseCommand("addtask /on Monday /task test1 /from 9:00 /to 11:00 /type f", userlist); @@ -209,6 +217,9 @@ public void changeTaskTypeTest() throws InvalidDayException, NoUserException, IO @Test public void invalidChangeTaskTypeTest() throws InvalidDayException, NoUserException, IOException, InvalidUserException, InvalidFormatException { + Storage.setFolderPath("test_data"); + User.setFolderPath("test_data"); + User user1 = new User("User1"); userlist.addUser(user1); Parser.parseCommand("addtask /on Monday /task test1 /from 9:00 /to 11:00 /type f", userlist); From 3d3fa9b3ef888a6baeade4ee6ee95d28e122c6e7 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 10:34:43 +0800 Subject: [PATCH 093/162] Add test_data --- test_data/User1.txt | 43 +++++++++++++++++++++++++++++++++++++++ test_data/User2.txt | 43 +++++++++++++++++++++++++++++++++++++++ test_data/User3.txt | 0 test_data/User4.txt | 0 test_data/testAddUser.txt | 0 test_data/testUser.txt | 1 + 6 files changed, 87 insertions(+) create mode 100644 test_data/User1.txt create mode 100644 test_data/User2.txt create mode 100644 test_data/User3.txt create mode 100644 test_data/User4.txt create mode 100644 test_data/testAddUser.txt create mode 100644 test_data/testUser.txt diff --git a/test_data/User1.txt b/test_data/User1.txt new file mode 100644 index 0000000000..c5f331da6d --- /dev/null +++ b/test_data/User1.txt @@ -0,0 +1,43 @@ +Username: User1 ++---------+ +| Monday | ++---------+ +1. 09:00 - 11:00: test1 (type: c) +................................................................................................. + ++---------+ +| Tuesday | ++---------+ +No task :) +................................................................................................. + ++-------------+ +| Wednesday | ++-------------+ +No task :) +................................................................................................. + ++---------+ +| Thursday | ++---------+ +No task :) +................................................................................................. + ++------+ +| Friday | ++------+ +No task :) +................................................................................................. + ++---------+ +| Saturday | ++---------+ +No task :) +................................................................................................. + ++---------+ +| Sunday | ++---------+ +No task :) +................................................................................................. + diff --git a/test_data/User2.txt b/test_data/User2.txt new file mode 100644 index 0000000000..4a28a75079 --- /dev/null +++ b/test_data/User2.txt @@ -0,0 +1,43 @@ +Username: User2 ++---------+ +| Monday | ++---------+ +1. 09:00 - 11:00: lecture (type: common) +................................................................................................. + ++---------+ +| Tuesday | ++---------+ +No task :) +................................................................................................. + ++-------------+ +| Wednesday | ++-------------+ +No task :) +................................................................................................. + ++---------+ +| Thursday | ++---------+ +No task :) +................................................................................................. + ++------+ +| Friday | ++------+ +No task :) +................................................................................................. + ++---------+ +| Saturday | ++---------+ +No task :) +................................................................................................. + ++---------+ +| Sunday | ++---------+ +No task :) +................................................................................................. + diff --git a/test_data/User3.txt b/test_data/User3.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test_data/User4.txt b/test_data/User4.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test_data/testAddUser.txt b/test_data/testAddUser.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test_data/testUser.txt b/test_data/testUser.txt new file mode 100644 index 0000000000..f7c6c3dddf --- /dev/null +++ b/test_data/testUser.txt @@ -0,0 +1 @@ +Username: testUser \ No newline at end of file From 3cfae3268a9f1a3147620c2852fb5208b17fa51c Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 10:39:05 +0800 Subject: [PATCH 094/162] fix error --- text-ui-test/EXPECTED.TXT | 1 - 1 file changed, 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index a04860ca1d..d3ee0326f1 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -14,7 +14,6 @@ NO TASK FOR Saturday NO TASK FOR Sunday New user added: tim The active user is: tim -[ERROR] Invalid day. Please enter a day from Monday - Sunday. The following task is added: lecture (Monday from 09:00 to 11:00) Monday: lecture (Monday from 09:00 to 11:00) From 17a9fe33652192de587b6b964a26650b4b1a45c8 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 10:53:27 +0800 Subject: [PATCH 095/162] Update class --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0aa8c3246f..2be7bf5439 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ test { } application { - mainClass.set("seedu.duke.Duke") + mainClass.set("seedu.duke.Main") } shadowJar { From e2c142bd2a2dd568ea28b1b353ea0e6a45849420 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 11:46:37 +0800 Subject: [PATCH 096/162] Change expected.txt --- text-ui-test/EXPECTED.TXT | 1 + 1 file changed, 1 insertion(+) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index d3ee0326f1..2b9e9c2515 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -45,4 +45,5 @@ Shared Free Time on Saturday: ---------------------- Shared Free Time on Sunday: ** Whole day is free on Sunday +[ERROR] Invalid day. Please enter a day from Monday - Sunday. Bye. From 17371f87cdf025a88d2e84a1d62a78e431615702 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 12:10:04 +0800 Subject: [PATCH 097/162] Update expected.txt --- text-ui-test/EXPECTED.TXT | 109 +++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 48 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 2b9e9c2515..9ff0baf754 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,49 +1,62 @@ Timetable comparison app opened. -New user added: simon -The active user is: simon -The current users are: -simon -The following task is added: lecture (Monday from 09:00 to 11:00) -Monday: -lecture (Monday from 09:00 to 11:00) -NO TASK FOR Tuesday -NO TASK FOR Wednesday -NO TASK FOR Thursday -NO TASK FOR Friday -NO TASK FOR Saturday -NO TASK FOR Sunday -New user added: tim -The active user is: tim -The following task is added: lecture (Monday from 09:00 to 11:00) -Monday: -lecture (Monday from 09:00 to 11:00) -NO TASK FOR Tuesday -NO TASK FOR Wednesday -NO TASK FOR Thursday -NO TASK FOR Friday -NO TASK FOR Saturday -NO TASK FOR Sunday ----------------------- -Shared Free Time on Monday: -00:00 - 09:00: Overlapping Free Time -11:00 - 23:59: Overlapping Free Time ----------------------- -Shared Free Time on Tuesday: -** Whole day is free on Tuesday ----------------------- -Shared Free Time on Wednesday: -** Whole day is free on Wednesday ----------------------- -Shared Free Time on Thursday: -** Whole day is free on Thursday ----------------------- -Shared Free Time on Friday: -** Whole day is free on Friday ----------------------- -Shared Free Time on Saturday: -** Whole day is free on Saturday ----------------------- -Shared Free Time on Sunday: -** Whole day is free on Sunday -[ERROR] Invalid day. Please enter a day from Monday - Sunday. -Bye. +Folder created successfully. +Note: use hh:mm 24hr time format (ex. 13:00) +List of available commands: +list: list all users +bye: exit the app +current: view current user +view: view timetable of current user +next: view your next task +adduser: add new user +switch : switch to user +addtask /on /from /to : add task for current user +addtwdc /on /from /to deletetask: delete task +changetasktiming: +changetasktype : change the type of a task (flexible/confirmed) +compareall: compare timetables of all users +compare : compare timetables of specified users +addforall /on /from /to : add task for all users +viewcommonevents: view common events +____________________________________________________________ +New user added: Simon +The active user is: Simon +File created: Simon.txt +The following task is added: lecture (Monday from 09:00 to 11:00) type: f +Timetable has been written to data/Simon.txt +New user added: Tim +File created: Tim.txt +The active user is: Tim +The following task is added: lecture (Monday from 09:00 to 11:00) type: f +Timetable has been written to data/Tim.txt +_________________________________________ +Monday : + 1. lecture (Monday from 09:00 to 11:00) type: f +No task for Tuesday! +No task for Wednesday! +No task for Thursday! +No task for Friday! +No task for Saturday! +No task for Sunday! +Comparing timetables of Simon and Tim: +____________________________________________________________ +Shared free time on Monday: + 00:00 - 09:00 + 11:00 - 23:59 +____________________________________________________________ +Shared free time on Tuesday: + ** Whole day is free on Tuesday +____________________________________________________________ +Shared free time on Wednesday: + ** Whole day is free on Wednesday +____________________________________________________________ +Shared free time on Thursday: + ** Whole day is free on Thursday +____________________________________________________________ +Shared free time on Friday: + ** Whole day is free on Friday +____________________________________________________________ +Shared free time on Saturday: + ** Whole day is free on Saturday +____________________________________________________________ +Shared free time on Sunday: + ** Whole day is free on Sunday \ No newline at end of file From b943f7de1d9cdec4ef6e24c5e337a4a910984251 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 12:11:49 +0800 Subject: [PATCH 098/162] remove unused imports --- src/test/java/seedu/duke/StorageTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/seedu/duke/StorageTest.java b/src/test/java/seedu/duke/StorageTest.java index ae379f730e..fec75e3aac 100644 --- a/src/test/java/seedu/duke/StorageTest.java +++ b/src/test/java/seedu/duke/StorageTest.java @@ -1,6 +1,5 @@ package seedu.duke; - import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; From c406d0e5eddd3391dba3d732a1819aa7c0fa6e70 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 12:15:39 +0800 Subject: [PATCH 099/162] Update expected.txt --- text-ui-test/EXPECTED.TXT | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 9ff0baf754..f486f42ea1 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -59,4 +59,6 @@ Shared free time on Saturday: ** Whole day is free on Saturday ____________________________________________________________ Shared free time on Sunday: - ** Whole day is free on Sunday \ No newline at end of file + ** Whole day is free on Sunday +[ERROR] Invalid day. Please enter a day from Monday - Sunday. +Bye. \ No newline at end of file From 374cdf63e5638e69f83c6e269b2c32a514c6d6a5 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 12:17:23 +0800 Subject: [PATCH 100/162] Add newline at the end of expected.txt --- text-ui-test/EXPECTED.TXT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index f486f42ea1..ec77d5891a 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -61,4 +61,4 @@ ____________________________________________________________ Shared free time on Sunday: ** Whole day is free on Sunday [ERROR] Invalid day. Please enter a day from Monday - Sunday. -Bye. \ No newline at end of file +Bye. From d430fdd5516c0f960d2c8f7227f704175e6b4a19 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 12:32:19 +0800 Subject: [PATCH 101/162] Update expected.txt to match with actual output --- text-ui-test/EXPECTED.TXT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index ec77d5891a..2fc1559c6e 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -61,4 +61,4 @@ ____________________________________________________________ Shared free time on Sunday: ** Whole day is free on Sunday [ERROR] Invalid day. Please enter a day from Monday - Sunday. -Bye. +Bye. From f93fd8ae0d50ca0ad71a8a44f1a8b984ea98c367 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Tue, 9 Apr 2024 12:32:41 +0800 Subject: [PATCH 102/162] Add a new exception such that less than 2 input days will be detected --- src/main/java/seedu/duke/Parser.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 9cecfa0716..29d82f09c9 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -287,7 +287,7 @@ private static void addRepeatTask(String command, UserList userList) { int endDaysIndex = wordlist.indexOf("/from"); String[] days = Arrays.copyOfRange(parts, daysIndex, endDaysIndex); if (days.length < 2) { - throw new InvalidFormatException("Please enter at least 2 days, or you want to use addtask command!"); + throw new InvalidDayException("Please enter at least 2 days, or you want to use addtask command!"); } String startTime = parts[wordlist.indexOf("/from") + 1]; String endTime = parts[wordlist.indexOf("/to") + 1]; @@ -300,10 +300,14 @@ private static void addRepeatTask(String command, UserList userList) { } currentUser.getStorage().writeTaskInFile(currentUser); System.out.println("Repeated task added successfully!"); + } catch (InvalidDayException e) { + System.out.println("Invalid day input: " + e.getMessage()); } catch (InvalidFormatException e) { - System.out.println("Please enter at least 2 days, or you want to use addtask command!"); + System.out.println("[ERROR] Invalid addRepeatTask format.\n" + + "Expected format: addRepeatTask /task [description] /on [day(s)] /from [start time]" + + "/to [end time] /type [f/c]"); } catch (IOException e) { - System.out.println("Something went wrong: " + e.getMessage()); + System.out.println("Error: " + e.getMessage()); } } From f9e50fca4d36abbed652cb3f6f6b215559d57b4e Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 12:54:24 +0800 Subject: [PATCH 103/162] Update runtest.bat to trim both expected and actual output --- text-ui-test/runtest.bat | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat index 25ac7a2989..181ca9d40c 100644 --- a/text-ui-test/runtest.bat +++ b/text-ui-test/runtest.bat @@ -16,4 +16,8 @@ java -jar %jarloc% < ..\..\text-ui-test\input.txt > ..\..\text-ui-test\ACTUAL.TX cd ..\..\text-ui-test +:: PowerShell commands to trim trailing spaces +powershell -Command "(Get-Content -Path EXPECTED.TXT) | ForEach-Object { $_.TrimEnd() } | Set-Content -Path EXPECTED.TXT" +powershell -Command "(Get-Content -Path ACTUAL.TXT) | ForEach-Object { $_.TrimEnd() } | Set-Content -Path ACTUAL.TXT" + FC ACTUAL.TXT EXPECTED.TXT >NUL && ECHO Test passed! || Echo Test failed! From db022be86ac8242378256c878df5aa5b97eb1d59 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 12:56:18 +0800 Subject: [PATCH 104/162] Trim expected and actual output --- text-ui-test/runtest.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh index 1dcbd12021..194962e678 100755 --- a/text-ui-test/runtest.sh +++ b/text-ui-test/runtest.sh @@ -12,6 +12,10 @@ java -jar $(find ../build/libs/ -mindepth 1 -print -quit) < input.txt > ACTUAL. cp EXPECTED.TXT EXPECTED-UNIX.TXT dos2unix EXPECTED-UNIX.TXT ACTUAL.TXT + +sed -i 's/[[:space:]]*$//' EXPECTED.TXT +sed -i 's/[[:space:]]*$//' ACTUAL.TXT + diff EXPECTED-UNIX.TXT ACTUAL.TXT if [ $? -eq 0 ] then From ff00609388c8a0e77de9a2863c5be8afd4f580f2 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Tue, 9 Apr 2024 13:00:36 +0800 Subject: [PATCH 105/162] solve issue on todaytask --- src/main/java/seedu/duke/Parser.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 29d82f09c9..2835582d7b 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -16,7 +16,7 @@ import java.util.List; public class Parser { - + private static final int COMMAND_INDEX_DAY = 2; protected static final String[] DAYS = new String[] {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; @@ -83,7 +83,7 @@ public static void parseCommand(String command, UserList userList) throws } else if (command.toLowerCase().startsWith("changetasktype")) { changeTaskType(command, userList); } else if (command.toLowerCase().startsWith("todaytask")) { - todayTask(userList); + todayTask(command,userList); } else if (command.toLowerCase().startsWith("compareall")) { UI.printComparingAll(); UI.printSharedTime(Timetable.compareAllTimetables(userList)); @@ -112,7 +112,7 @@ private static void changeTaskType(String command, UserList userList) throws Inv InputValidator.validateChangeTaskType(command); String[] parts = command.split("\\s+"); List wordList = Arrays.asList(parts); - String day = wordList.get(2); + String day = wordList.get(COMMAND_INDEX_DAY); int index = Integer.parseInt(wordList.get(wordList.indexOf("/index") + 1)); String newType = wordList.get(wordList.indexOf("/type") + 1); InputValidator.validateDay(day); @@ -230,16 +230,20 @@ public static Task parseAddForAllTask(String command) throws InvalidDayException * * @param userList The list of users. */ - public static void todayTask(UserList userList) { + public static void todayTask(String command, UserList userList) { + String[] parts = command.trim().split("\\s+"); + if(parts.length > 1){ + System.out.println("Please simply use 'todaytask' to view today's task" + + " without additional text!"); + return; + } String dayOfWeek = DayOfWeek.from(LocalDate.now()).toString(); String capitalizedDay = Parser.capitalizeFirstLetter(dayOfWeek); ArrayList tasksForToday = userList.getActiveUser().getTimetable().getWeeklyTasks().get(capitalizedDay); - if (tasksForToday.isEmpty()) { UI.printNoTask("today"); return; } - UI.printLine(); UI.printDayHeader("Today"); int count = 1; From 4ba3ae1a357c00e1d81fc196cd9cfb4995e2cbd3 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 13:05:48 +0800 Subject: [PATCH 106/162] Update runtest.sh to trim expected and actual outcome --- text-ui-test/EXPECTED.TXT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 2fc1559c6e..ec77d5891a 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -61,4 +61,4 @@ ____________________________________________________________ Shared free time on Sunday: ** Whole day is free on Sunday [ERROR] Invalid day. Please enter a day from Monday - Sunday. -Bye. +Bye. From 95a50bf60f815d76921759eb6f8e7d2ce34cac31 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 13:13:30 +0800 Subject: [PATCH 107/162] Update days to be public --- src/main/java/seedu/duke/Parser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index fef8057a84..73d4d90957 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -17,7 +17,7 @@ public class Parser { - protected static final String[] DAYS = new String[] + public static final String[] DAYS = new String[] {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; public static String capitalizeFirstLetter(String input) { From f99a4b860eb4d730ce1d39ae6a0c050bf432151c Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 13:37:17 +0800 Subject: [PATCH 108/162] Update order --- src/main/java/seedu/duke/Parser.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index fba68f0216..4d5a5fed12 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -16,13 +16,14 @@ import java.util.List; public class Parser { + public static final String[] DAYS = new String[] + {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; + public static String capitalizeFirstLetter(String input) { String lowerCase = input.toLowerCase(); return lowerCase.substring(0, 1).toUpperCase() + lowerCase.substring(1); } - protected static final String[] DAYS = new String[] - {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; private static final int COMMAND_INDEX_DAY = 2; /** From 55c4ba2a034a71af571f7b565c2046fa788cb3bf Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 13:40:12 +0800 Subject: [PATCH 109/162] Update order --- src/main/java/seedu/duke/Parser.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 4d5a5fed12..9c983a618f 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -19,12 +19,14 @@ public class Parser { public static final String[] DAYS = new String[] {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; + private static final int COMMAND_INDEX_DAY = 2; + public static String capitalizeFirstLetter(String input) { String lowerCase = input.toLowerCase(); return lowerCase.substring(0, 1).toUpperCase() + lowerCase.substring(1); } - private static final int COMMAND_INDEX_DAY = 2; + /** * Parses User Input and Identifies the command used. From 57bd5f063ee8079db89f7e9f6b61ef98c8b90576 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 14:02:35 +0800 Subject: [PATCH 110/162] Clean up code --- src/main/java/seedu/duke/Storage.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 8b2abe8e81..b64ec40ae9 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -45,9 +45,7 @@ public static String getFolderPath() { public static void setFolderPath(String newPath) { folderPath = newPath; } - - - + public static void createFolder() { File folder = new File(folderPath); From c18dccdb69a6afd3b4a73a56f05f5309fa4d88e1 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 14:14:42 +0800 Subject: [PATCH 111/162] update runtest.sh --- text-ui-test/runtest.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh index 9c70273743..254ea58953 100755 --- a/text-ui-test/runtest.sh +++ b/text-ui-test/runtest.sh @@ -13,8 +13,8 @@ java -jar $(find ../build/libs/ -mindepth 1 -print -quit) < input.txt > ACTUAL. cp EXPECTED.TXT EXPECTED-UNIX.TXT dos2unix EXPECTED-UNIX.TXT ACTUAL.TXT -sed -i 's/[[:space:]]*$//' EXPECTED-UNIX.TXT -sed -i 's/[[:space:]]*$//' ACTUAL.TXT +sed -i '' 's/[[:space:]]*$//' EXPECTED-UNIX.TXT +sed -i '' 's/[[:space:]]*$//' ACTUAL.TXT diff EXPECTED-UNIX.TXT ACTUAL.TXT if [ $? -eq 0 ] From ae5fcc49824143d63eceab32ff5526a858e68f52 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 14:23:22 +0800 Subject: [PATCH 112/162] Update runtest.sh --- text-ui-test/runtest.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh index 254ea58953..9c70273743 100755 --- a/text-ui-test/runtest.sh +++ b/text-ui-test/runtest.sh @@ -13,8 +13,8 @@ java -jar $(find ../build/libs/ -mindepth 1 -print -quit) < input.txt > ACTUAL. cp EXPECTED.TXT EXPECTED-UNIX.TXT dos2unix EXPECTED-UNIX.TXT ACTUAL.TXT -sed -i '' 's/[[:space:]]*$//' EXPECTED-UNIX.TXT -sed -i '' 's/[[:space:]]*$//' ACTUAL.TXT +sed -i 's/[[:space:]]*$//' EXPECTED-UNIX.TXT +sed -i 's/[[:space:]]*$//' ACTUAL.TXT diff EXPECTED-UNIX.TXT ACTUAL.TXT if [ $? -eq 0 ] From 0b4df7dc15c4a88d4734b4157e76ac68564de5e1 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Tue, 9 Apr 2024 15:29:28 +0800 Subject: [PATCH 113/162] PPP --- docs/team/zhusijia0711.md | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 docs/team/zhusijia0711.md diff --git a/docs/team/zhusijia0711.md b/docs/team/zhusijia0711.md new file mode 100644 index 0000000000..7a717e7118 --- /dev/null +++ b/docs/team/zhusijia0711.md @@ -0,0 +1,50 @@ +# Zhu Sijia's Project Portfolio Page + +## Project: Time Comparer + +Time Comparer is a desktop application used for time management between users. + +The user can add and delete tasks using the application and can compare their + +timetable with other users using the same desktop. + +Given below are my contributions to the project. + +- **New Feature:** Add a command that allows an user to add one task to his/her timetable. + - What it does: Allows the user to add a task with a task description, start time, end time and task type one at a time. + - Justification: This is the basic functionality for a time management application. +- **New Feature:** Add a command that allows an user to delete the task he/she previously added. + - What it does: Allow the user to delete a task using the index of the task in a day. + - Justification: This is the basic functionality for a time management application. +- **New Feature:** Add a command that allows an user to add a same task to different days. + - What it does: Allow the user to add a task which can happen in multiple days to the timetable. + - Justification: This feature reduces troublesome of users as they would not need to add repeated task one by one. +- **New Feature:** Add a command that allows an user to change their task timing + - What is does: Allow the user to change the start time and end time for the previously added task. + - Justification: This feature reduces troublesome of users as they do not need to first delete the task and add the + task one more time in order to change the time. +- **New Feature:** Add a command that allows an user to change their task type. + - What it does: In our application logic, if the task type is assigned to be flexible(f), it means the timings of the + task can be changed. If a task is marked as compulsory(c), it means its timing cannot be changed. This feature helps + users to change the task type whenever there is a change in their plan. + - Justification: This feature reduces troublesome of users as they do not need to first delete the task and add the + task one more time in order to change the task type. +- - **New Feature:** Add a command that allows an user to see today's tasks(if any). + - What it does: Allow the users to see the tasks that happens today. + +- Code contributed: + - https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2024-02-23&tabOpen=true&tabType=authorship&tabAuthor=ZhuSijia0711&tabRepo=AY2324S2-CS2113-T13-2%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code~other&authorshipIsBinaryFileTypeChecked=false&authorshipIsIgnoredFilesChecked=false + +- Project management: + - Managed releases v1.release, v2.0 release jar file and user guide pdf + +- Enhancement to existing features: + - Wrote tests for timetable class and input validator class (Pull Request #57, #59) + +- Documentation: + - User guide: + - Added documentation for the features addtask, delete task and so on. #73 + - Added developer guide. #64 + +- Community: + - Reported 9 bugs and suggestions for other teams in the class (above average). \ No newline at end of file From b9640ada85429a85f313c5e87fd892838ad1a276 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 22:36:46 +0800 Subject: [PATCH 114/162] Add addfor method --- src/main/java/seedu/duke/InputValidator.java | 17 ++++ src/main/java/seedu/duke/Main.java | 1 - src/main/java/seedu/duke/Parser.java | 82 +++++++++++++++++--- src/main/java/seedu/duke/Storage.java | 2 +- 4 files changed, 90 insertions(+), 12 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 52612ee764..198d62f3ac 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -201,5 +201,22 @@ public static void validateAddRepeatTask(String input) throws InvalidFormatExcep "/to [end time] /type [f/c]"); } } + + public static void validAddFor(String input) throws InvalidFormatException { + String commandPattern = "(?i)addfor\\s+"; + String usersPattern = "/user\\s+([\\w\\s,]+)\\s+"; + String dayPattern = "/on\\s+(monday|tuesday|wednesday|thursday|friday|saturday|sunday)\\s+"; + String taskDescriptionPattern = "(?i)/task\\s+([\\w\\s]+)\\s+"; + String startPattern = "/from\\s+(\\d{1,2}:\\d{2})\\s+"; + String endPattern = "/to\\s+(\\d{1,2}:\\d{2})\\s+"; + String typePattern = "/type\\s+([cfCF])"; + String suffix = "$"; + String pattern = commandPattern + usersPattern + dayPattern + taskDescriptionPattern + startPattern + endPattern + typePattern + suffix; + + if (!input.matches(pattern)) { + throw new InvalidFormatException("[ERROR] Invalid addfor format. " + + "Expected format: addfor /user [user1], [user2], ... /on [day] /index [index] /type [f/c]"); + } + } } diff --git a/src/main/java/seedu/duke/Main.java b/src/main/java/seedu/duke/Main.java index 9c0f6f5486..d8151d6240 100644 --- a/src/main/java/seedu/duke/Main.java +++ b/src/main/java/seedu/duke/Main.java @@ -37,5 +37,4 @@ public static void main(String[] args) throws FileNotFoundException { } } - } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 9c983a618f..c5fbafa612 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -20,21 +20,32 @@ public class Parser { {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; private static final int COMMAND_INDEX_DAY = 2; - + public static final int USERS_INDEX = 5; + public static final int DAY_INDEX = 3; + public static final int DESCRIPTION_INDEX = 5; + public static final int START_INDEX = 5; + public static final int END_INDEX = 3; + public static final int TYPE_INDEX = 5; + public static final int DAY_INDEX_IN_ADD_FOR_ALL = 2; + public static final int USER_PART = 1; + public static final int DAY_PART = 2; + public static final int DESCRIPTION_PART = 3; + public static final int START_PART = 4; + public static final int END_PART = 5; + public static final int TYPE_PART = 6; + public static String capitalizeFirstLetter(String input) { String lowerCase = input.toLowerCase(); return lowerCase.substring(0, 1).toUpperCase() + lowerCase.substring(1); } - - /** * Parses User Input and Identifies the command used. * * @param command The users text input. */ public static void parseCommand(String command, UserList userList) throws - InvalidFormatException, InvalidDayException, InvalidUserException, NoUserException, IOException { + InvalidFormatException, InvalidDayException, InvalidUserException, NoUserException, IOException { if (command.equalsIgnoreCase("list")) { UI.printListingUsers(); userList.listAll(); @@ -103,7 +114,11 @@ public static void parseCommand(String command, UserList userList) throws } else if (command.toLowerCase().startsWith("addforall")) { InputValidator.validateAddTaskForAll(command); addTaskForAll(command, userList); - } else if (command.toLowerCase().startsWith("viewcommonevents")) { + } else if (command.toLowerCase().startsWith("addfor")) { + InputValidator.validAddFor(command); + addFor(command, userList); + } + else if (command.toLowerCase().startsWith("viewcommonevents")) { printConfirmedEvent(userList); } else { UI.printInvalidCommand(); @@ -193,9 +208,13 @@ public static boolean checkClash(Task taskToBeAdded, User user) { timetable.getWeeklyTasks().get(capitalisedDay).sort(Comparator.comparing(Task::getStartTime)); for (Task task : timetable.getWeeklyTasks().get(capitalisedDay)) { if (taskToBeAdded.startTime.isAfter(task.getStartTime()) && - taskToBeAdded.startTime.isBefore(task.getEndTime()) - || (taskToBeAdded.endTime.isAfter(task.getStartTime()) && - taskToBeAdded.endTime.isBefore(task.getEndTime()))) { + taskToBeAdded.startTime.isBefore(task.getEndTime()) + || (taskToBeAdded.endTime.isAfter(task.getStartTime()) && + taskToBeAdded.endTime.isBefore(task.getEndTime())) + || (taskToBeAdded.startTime.equals(task.getStartTime())) + || (taskToBeAdded.endTime.equals(task.getEndTime())) + || (taskToBeAdded.startTime.isBefore(task.getStartTime()) && + taskToBeAdded.endTime.isAfter(task.getEndTime()))) { return true; } } @@ -218,7 +237,7 @@ public static Task parseTask(String command) throws InvalidDayException, Invalid public static Task parseAddForAllTask(String command) throws InvalidDayException { String[] parts = command.split("\\s+"); List wordList = Arrays.asList(parts); - String day = Parser.capitalizeFirstLetter(parts[2]); + String day = Parser.capitalizeFirstLetter(parts[DAY_INDEX_IN_ADD_FOR_ALL]); String description = parseDescription(wordList); String startTime = parts[wordList.indexOf("/from") + 1]; String endTime = parts[wordList.indexOf("/to") + 1]; @@ -383,10 +402,53 @@ private static void printNextTask(User currentUser) { UI.printNoTasks(); } else { UI.printNext(); - System.out.println(nextTask.toString()); + System.out.println(nextTask); } return; } } } + + private static void addFor(String command, UserList userList) throws IOException, InvalidUserException { + String[] words = command.split("/"); + String users = words[USER_PART].substring(USERS_INDEX).trim(); // to exclude words "/user" + String day = words[DAY_PART].substring(DAY_INDEX).trim(); // to exclude words "/on" + String description = words[DESCRIPTION_PART].substring(DESCRIPTION_INDEX).trim(); // to exclude words "/task" + String start = words[START_PART].substring(START_INDEX).trim(); // to exclude words "/from" + String end = words[END_PART].substring(END_INDEX).trim(); // to exclude words "/to" + String type = words[TYPE_PART].substring(TYPE_INDEX).trim(); // to exclude words "/type" + String[] usernames = users.split(","); + + Task task = new Task(description, day, start, end, type); + ArrayList clashedUsers = new ArrayList<>(); + ArrayList invalidUsers = new ArrayList<>(); + for (String username : usernames) { + User user = userList.findUser(username.trim()); + if (user == null) { + invalidUsers.add(username.trim()); + continue; + } + if (checkClash(task, user)) { + clashedUsers.add(username.trim()); + } + } + + if (!invalidUsers.isEmpty() || !clashedUsers.isEmpty()) { + StringBuilder errorMessage = new StringBuilder(); + if (!invalidUsers.isEmpty()) { + errorMessage.append("Invalid users: ").append(String.join(", ", invalidUsers)).append(". "); + } + if (!clashedUsers.isEmpty()) { + errorMessage.append("Users with task clashes: ").append(String.join(", ", clashedUsers)).append(". "); + } + throw new InvalidUserException(errorMessage.toString()); + } + + + for (String username : usernames) { + User user = userList.findUser(username.trim()); + user.getTimetable().addUserTask(day, task); + user.getStorage().writeTaskInFile(user); + } + } } diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index b64ec40ae9..0a4d835d3a 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -45,7 +45,7 @@ public static String getFolderPath() { public static void setFolderPath(String newPath) { folderPath = newPath; } - + public static void createFolder() { File folder = new File(folderPath); From ae0642f1b15b78f6eb29a7e0093c5e4842c7bdc9 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 22:45:41 +0800 Subject: [PATCH 115/162] Update runtest.sh --- text-ui-test/runtest.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh index 9c70273743..fade424594 100755 --- a/text-ui-test/runtest.sh +++ b/text-ui-test/runtest.sh @@ -13,8 +13,8 @@ java -jar $(find ../build/libs/ -mindepth 1 -print -quit) < input.txt > ACTUAL. cp EXPECTED.TXT EXPECTED-UNIX.TXT dos2unix EXPECTED-UNIX.TXT ACTUAL.TXT -sed -i 's/[[:space:]]*$//' EXPECTED-UNIX.TXT -sed -i 's/[[:space:]]*$//' ACTUAL.TXT +sed -i'' -e 's/[[:space:]]*$//' EXPECTED-UNIX.TXT +sed -i'' -e 's/[[:space:]]*$//' ACTUAL.TXT diff EXPECTED-UNIX.TXT ACTUAL.TXT if [ $? -eq 0 ] From 322318b9ded356dc54b3971f2c6d05fba5364b1b Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 23:41:16 +0800 Subject: [PATCH 116/162] Fix variable declaration order and indentation --- src/main/java/seedu/duke/InputValidator.java | 6 ++-- src/main/java/seedu/duke/Parser.java | 29 ++++++++++---------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 198d62f3ac..4e3e3db7f3 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -211,11 +211,13 @@ public static void validAddFor(String input) throws InvalidFormatException { String endPattern = "/to\\s+(\\d{1,2}:\\d{2})\\s+"; String typePattern = "/type\\s+([cfCF])"; String suffix = "$"; - String pattern = commandPattern + usersPattern + dayPattern + taskDescriptionPattern + startPattern + endPattern + typePattern + suffix; + String pattern = commandPattern + usersPattern + dayPattern + taskDescriptionPattern + + startPattern + endPattern + typePattern + suffix; if (!input.matches(pattern)) { throw new InvalidFormatException("[ERROR] Invalid addfor format. " + - "Expected format: addfor /user [user1], [user2], ... /on [day] /index [index] /type [f/c]"); + "Expected format: addfor /user [user1], [user2], ... /on [day] /task [description] " + + "/from [start time] /to [end time] /type [f/c]"); } } } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index c5fbafa612..d028b5c4da 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -20,19 +20,19 @@ public class Parser { {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; private static final int COMMAND_INDEX_DAY = 2; - public static final int USERS_INDEX = 5; - public static final int DAY_INDEX = 3; - public static final int DESCRIPTION_INDEX = 5; - public static final int START_INDEX = 5; - public static final int END_INDEX = 3; - public static final int TYPE_INDEX = 5; - public static final int DAY_INDEX_IN_ADD_FOR_ALL = 2; - public static final int USER_PART = 1; - public static final int DAY_PART = 2; + private static final int USERS_INDEX = 5; + private static final int DAY_INDEX = 3; + private static final int DESCRIPTION_INDEX = 5; + private static final int START_INDEX = 5; + private static final int END_INDEX = 3; + private static final int TYPE_INDEX = 5; + private static final int DAY_INDEX_IN_ADD_FOR_ALL = 2; + private static final int USER_PART = 1; + private static final int DAY_PART = 2; public static final int DESCRIPTION_PART = 3; - public static final int START_PART = 4; - public static final int END_PART = 5; - public static final int TYPE_PART = 6; + private static final int START_PART = 4; + private static final int END_PART = 5; + private static final int TYPE_PART = 6; public static String capitalizeFirstLetter(String input) { String lowerCase = input.toLowerCase(); @@ -45,7 +45,7 @@ public static String capitalizeFirstLetter(String input) { * @param command The users text input. */ public static void parseCommand(String command, UserList userList) throws - InvalidFormatException, InvalidDayException, InvalidUserException, NoUserException, IOException { + InvalidFormatException, InvalidDayException, InvalidUserException, NoUserException, IOException { if (command.equalsIgnoreCase("list")) { UI.printListingUsers(); userList.listAll(); @@ -117,8 +117,7 @@ public static void parseCommand(String command, UserList userList) throws } else if (command.toLowerCase().startsWith("addfor")) { InputValidator.validAddFor(command); addFor(command, userList); - } - else if (command.toLowerCase().startsWith("viewcommonevents")) { + } else if (command.toLowerCase().startsWith("viewcommonevents")) { printConfirmedEvent(userList); } else { UI.printInvalidCommand(); From f4b5a47607ff72a71542f1dfe72c84ded40ef561 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Tue, 9 Apr 2024 23:42:58 +0800 Subject: [PATCH 117/162] fix variable declaration order --- src/main/java/seedu/duke/Parser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index d028b5c4da..a5db4a56a5 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -29,7 +29,7 @@ public class Parser { private static final int DAY_INDEX_IN_ADD_FOR_ALL = 2; private static final int USER_PART = 1; private static final int DAY_PART = 2; - public static final int DESCRIPTION_PART = 3; + private static final int DESCRIPTION_PART = 3; private static final int START_PART = 4; private static final int END_PART = 5; private static final int TYPE_PART = 6; From 2dac2500f77f72faa9fa54c0297058807f729841 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Wed, 10 Apr 2024 10:23:00 +0800 Subject: [PATCH 118/162] add method on urgent --- src/main/java/seedu/duke/Parser.java | 62 ++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index c5fbafa612..f08c3be94b 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -7,13 +7,12 @@ import seedu.duke.ui.UI; import java.io.IOException; +import java.time.LocalDateTime; import java.time.LocalTime; import java.time.LocalDate; import java.time.DayOfWeek; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; +import java.time.chrono.ChronoLocalDateTime; +import java.util.*; public class Parser { public static final String[] DAYS = new String[] @@ -117,14 +116,63 @@ public static void parseCommand(String command, UserList userList) throws } else if (command.toLowerCase().startsWith("addfor")) { InputValidator.validAddFor(command); addFor(command, userList); - } - else if (command.toLowerCase().startsWith("viewcommonevents")) { + } else if(command.toLowerCase().startsWith("viewcommonevents")) { printConfirmedEvent(userList); - } else { + } else if (command.toLowerCase().startsWith("urgent /in")) { + try { + String[] parts = command.split("\\s+"); + int hours = Integer.parseInt(parts[2]); + + LocalDateTime now = LocalDateTime.now(); + int currentHour = now.getHour(); + if(currentHour + hours >= 24){ + System.out.println("Hour input exceeds current day."); + } + LocalDateTime deadline = now.plusHours(hours); + List urgentTasks = findUrgentTasks(userList.getActiveUser(), now, deadline); + if (urgentTasks.isEmpty()) { + System.out.println("No urgent tasks within the specified timeframe."); + } else { + if(currentHour + hours >= 24){ + System.out.println("Urgent tasks until end of today: "); + for (Task task : urgentTasks) { + System.out.println(task); + } + } + else { + System.out.println("Urgent tasks within the next " + hours + " hours:"); + for (Task task : urgentTasks) { + System.out.println(task); + } + } + } + } catch (NumberFormatException | IndexOutOfBoundsException e) { + System.out.println("Invalid command format. Please use: urgent /in [hours]"); + } + }else { UI.printInvalidCommand(); } } + private static List findUrgentTasks(User user, LocalDateTime now, LocalDateTime deadline) { + List urgentTasks = new ArrayList<>(); + Timetable userTimetable = user.getTimetable(); + for (Map.Entry> entry : userTimetable.getWeeklyTasks().entrySet()) { + ArrayList tasks = entry.getValue(); + if (tasks != null) { + for (Task task : tasks) { + LocalDateTime taskStartTime = LocalDateTime.of(now.toLocalDate(), task.getStartTime()); + if (now.isBefore(taskStartTime) && taskStartTime.isBefore(deadline)) { + urgentTasks.add(task); + } + } + } + } + return urgentTasks; + } + + + private static void changeTaskType(String command, UserList userList) throws InvalidFormatException { try { InputValidator.validateChangeTaskType(command); From 17be789d153aa3a1b0208dc9ec540effb6762a71 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Wed, 10 Apr 2024 11:26:38 +0800 Subject: [PATCH 119/162] add method on find urgent task in next few hours in a day --- src/main/java/seedu/duke/InputValidator.java | 1 - src/main/java/seedu/duke/Parser.java | 68 ++++++++++++-------- 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index 4e3e3db7f3..e83befabad 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -47,7 +47,6 @@ public static void validateAddTaskInput(String input) throws InvalidFormatExcept } } public static void validateAddTaskWDCInput(String input) throws InvalidFormatException { - // Define the regex pattern for the expected format with case-insensitive flag String regex = "(?i)^addtwdc\\s+/on\\s+(\\w+)\\s+/task\\s+(.+?)\\s" + "+/from\\s+(\\d{1,2}:\\d{2})\\s+/to\\s+(\\d{1,2}:\\d{2})(\\s+/type\\s+[fc])$"; diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 7cad87a934..59b76664b7 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -92,10 +92,19 @@ public static void parseCommand(String command, UserList userList) throws } else if (command.toLowerCase().startsWith("changetasktiming")) { changeTaskTiming(command, userList); } else if (command.toLowerCase().startsWith("addrepeattask")) { + if (userList.getUsers().isEmpty()) { + throw new NoUserException(); + } addRepeatTask(command, userList); } else if (command.toLowerCase().startsWith("changetasktype")) { + if (userList.getUsers().isEmpty()) { + throw new NoUserException(); + } changeTaskType(command, userList); } else if (command.toLowerCase().startsWith("todaytask")) { + if (userList.getUsers().isEmpty()) { + throw new NoUserException(); + } todayTask(command,userList); } else if (command.toLowerCase().startsWith("compareall")) { UI.printComparingAll(); @@ -119,38 +128,45 @@ public static void parseCommand(String command, UserList userList) throws } else if (command.toLowerCase().startsWith("viewcommonevents")) { printConfirmedEvent(userList); } else if (command.toLowerCase().startsWith("urgent /in")) { - try { - String[] parts = command.split("\\s+"); - int hours = Integer.parseInt(parts[2]); + if (userList.getUsers().isEmpty()) { + throw new NoUserException(); + } + printUrgentTasks(command, userList); + }else { + UI.printInvalidCommand(); + } + } - LocalDateTime now = LocalDateTime.now(); - int currentHour = now.getHour(); + private static void printUrgentTasks(String command, UserList userList) { + try { + String[] parts = command.split("\\s+"); + int hours = Integer.parseInt(parts[2]); + + LocalDateTime now = LocalDateTime.now(); + int currentHour = now.getHour(); + if(currentHour + hours >= 24){ + System.out.println("Hour input exceeds current day."); + } + LocalDateTime deadline = now.plusHours(hours); + List urgentTasks = findUrgentTasks(userList.getActiveUser(), now, deadline); + if (urgentTasks.isEmpty()) { + System.out.println("No urgent tasks within the specified timeframe."); + } else { if(currentHour + hours >= 24){ - System.out.println("Hour input exceeds current day."); - } - LocalDateTime deadline = now.plusHours(hours); - List urgentTasks = findUrgentTasks(userList.getActiveUser(), now, deadline); - if (urgentTasks.isEmpty()) { - System.out.println("No urgent tasks within the specified timeframe."); - } else { - if(currentHour + hours >= 24){ - System.out.println("Urgent tasks until end of today: "); - for (Task task : urgentTasks) { - System.out.println(task); - } + System.out.println("Urgent tasks until end of today: "); + for (Task task : urgentTasks) { + System.out.println(task); } - else { - System.out.println("Urgent tasks within the next " + hours + " hours:"); - for (Task task : urgentTasks) { - System.out.println(task); - } + } + else { + System.out.println("Urgent tasks within the next " + hours + " hours:"); + for (Task task : urgentTasks) { + System.out.println(task); } } - } catch (NumberFormatException | IndexOutOfBoundsException e) { - System.out.println("Invalid command format. Please use: urgent /in [hours]"); } - }else { - UI.printInvalidCommand(); + } catch (NumberFormatException | IndexOutOfBoundsException e) { + System.out.println("Invalid command format. Please use: urgent /in [hours]"); } } From fc3400745f7fce30d2947805af3b7d356507d8f3 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Wed, 10 Apr 2024 11:43:06 +0800 Subject: [PATCH 120/162] Fix issues to pass checkstyle gradle test --- src/main/java/seedu/duke/Parser.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 59b76664b7..7505d9887f 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -11,8 +11,11 @@ import java.time.LocalTime; import java.time.LocalDate; import java.time.DayOfWeek; -import java.time.chrono.ChronoLocalDateTime; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Map; public class Parser { public static final String[] DAYS = new String[] @@ -132,7 +135,7 @@ public static void parseCommand(String command, UserList userList) throws throw new NoUserException(); } printUrgentTasks(command, userList); - }else { + } else { UI.printInvalidCommand(); } } @@ -157,8 +160,7 @@ private static void printUrgentTasks(String command, UserList userList) { for (Task task : urgentTasks) { System.out.println(task); } - } - else { + } else { System.out.println("Urgent tasks within the next " + hours + " hours:"); for (Task task : urgentTasks) { System.out.println(task); From 5d8b2f321f2e23f884594809163904395480b905 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Wed, 10 Apr 2024 15:52:28 +0800 Subject: [PATCH 121/162] Fixed issue where the same user can be readded --- src/main/java/seedu/duke/Parser.java | 12 ++++++++---- src/test/java/seedu/duke/ParserTest.java | 8 ++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 7505d9887f..8c1367d6a7 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -66,10 +66,14 @@ public static void parseCommand(String command, UserList userList) throws InputValidator.validateAddUserInput(command); String[] parts = command.split("\\s+"); String userName = Parser.capitalizeFirstLetter(parts[1]); - User newUser = new User(userName); - UI.printNewUser(newUser.getName()); - userList.addUser(newUser); - newUser.getStorage().addUserInFolder(); + if (userList.containsUser(userName)) { + throw new InvalidUserException("User already exists. Use a different name. "); + } else { + User newUser = new User(userName); + UI.printNewUser(newUser.getName()); + userList.addUser(newUser); + newUser.getStorage().addUserInFolder(); + } } else if (command.toLowerCase().startsWith("switch")) { InputValidator.validateSwitchInput(command); String[] parts = command.split("\\s+"); diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java index d4cf616759..0ba0caea35 100644 --- a/src/test/java/seedu/duke/ParserTest.java +++ b/src/test/java/seedu/duke/ParserTest.java @@ -45,6 +45,14 @@ public void invalidAdduserCommandTest() { assertEquals("[ERROR] Invalid addUser format. Expected format: adduser ", e.getMessage()); } + + try { + Parser.parseCommand("addUser User1", userlist); + Parser.parseCommand("addUser User1", userlist); + fail(); + } catch (Exception e) { + assertEquals("User already exists. Use a different name. ", e.getMessage()); + } } @Test From e2a8ab8a0858d2c0978510350d845e1e180e245b Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Wed, 10 Apr 2024 19:37:34 +0800 Subject: [PATCH 122/162] 1.Fixed repeattask partial task description error. 2.Fixed Compareall command concerning extending l's --- src/main/java/seedu/duke/InputValidator.java | 9 +++++++++ src/main/java/seedu/duke/Parser.java | 4 +++- src/main/java/seedu/duke/Timetable.java | 8 ++++++-- src/main/java/seedu/duke/ui/UI.java | 3 +++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index e83befabad..b3c5ac59c5 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -21,6 +21,15 @@ public static void validateCompareInput(String input) throws InvalidFormatExcept } } + public static void validateCompareAllInput(String input) throws InvalidFormatException { + String regex = "(?i)^compareall(\\s+)?$"; + + if (!input.matches(regex)) { + throw new InvalidFormatException("[ERROR] Invalid compareall format. " + + "Expected format: compareall"); + } + } + /** * Validates correctly formatted addTask command. The expected format is * "addtask /on [date] /task [description] /from [start time] /to [start time] /type [type]" diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 8c1367d6a7..c3952282c0 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -114,6 +114,7 @@ public static void parseCommand(String command, UserList userList) throws } todayTask(command,userList); } else if (command.toLowerCase().startsWith("compareall")) { + InputValidator.validateCompareAllInput(command); UI.printComparingAll(); UI.printSharedTime(Timetable.compareAllTimetables(userList)); } else if (command.toLowerCase().startsWith("compare")) { @@ -378,7 +379,8 @@ private static void addRepeatTask(String command, UserList userList) { if (taskIndex == -1 || taskIndex + 1 >= wordlist.size()) { throw new InvalidFormatException(("Please enter a task name!")); } - String description = wordlist.get(taskIndex + 1); + String description = command.substring(command.indexOf("/task") + "/task".length(), + command.indexOf("/on")).trim(); int daysIndex = wordlist.indexOf("/on") + 1; int endDaysIndex = wordlist.indexOf("/from"); String[] days = Arrays.copyOfRange(parts, daysIndex, endDaysIndex); diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index 8a88eea287..d2d10bc15c 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -167,8 +167,12 @@ public static void findOverlappingFreeTime(ArrayList tasks, String day) { } if (previousEndTime.isBefore(LocalTime.MAX)) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm"); - //System.out.println(" "+previousEndTime + " - " + LocalTime.MAX.format(formatter)); - UI.printTimeFrame(previousEndTime, LocalTime.MAX.format(formatter)); + if (previousEndTime.format(formatter).equals("23:59")) { + UI.printFullDay(); + } else { + //System.out.println(" "+previousEndTime + " - " + LocalTime.MAX.format(formatter)); + UI.printTimeFrame(previousEndTime, LocalTime.MAX.format(formatter)); + } } } else { UI.printFreeDay(day); diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index 1630952504..7a6ba1511a 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -122,6 +122,9 @@ public static void printTimeFrame(LocalTime time1, String time2) { public static void printTimeFrame(LocalTime time1, LocalTime time2) { System.out.println(" "+time1 + " - " + time2); } + public static void printFullDay() { + System.out.println(" None"); + } public static void printFreeDay(String day) { System.out.println(" ** Whole day is free on " + day); } From b5974cdf35554456984cd02415fbd7d87facab7a Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Wed, 10 Apr 2024 20:43:24 +0800 Subject: [PATCH 123/162] Updated help command --- src/main/java/seedu/duke/ui/UI.java | 58 ++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index 7a6ba1511a..8318629308 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -11,7 +11,8 @@ public class UI { public static void printGreeting() { - System.out.println("Timetable comparison app opened. "); + System.out.println("Timetable comparison app opened. \n" + + "type 'help' for commands."); } public static void printBye() { @@ -39,24 +40,41 @@ public static void printAddTask(Task task) { } public static void printHelp() { - System.out.println("Note: use hh:mm 24hr time format (ex. 13:00) \n" + + System.out.println( + "**Note: use hh:mm 24hr time format (ex. 13:00) \n" + "List of available commands: \n" + - "list: list all users \n" + - "bye: exit the app \n" + - "current: view current user \n" + - "view: view timetable of current user \n" + - "next: view your next task \n" + - "adduser: add new user \n" + - "switch : switch to user \n" + - "addtask /on /from /to : add task for current user\n" + - "addtwdc /on /from /to " + - "deletetask: delete task \n" + - "changetasktiming: \n" + - "changetasktype : change the type of a task (flexible/confirmed)\n" + - "compareall: compare timetables of all users \n" + - "compare : compare timetables of specified users \n" + - "addforall /on /from /to : add task for all users\n" + - "viewcommonevents: view common events "); + "List all users: \n" + "list" + UI.Line() + + "Exit the app: \n" + "bye" + UI.Line() + + "View current user: \n" + "current" + UI.Line() + + "View timetable of current user: \n" + "view" + UI.Line() + + "View your next task: \n" + "next" + UI.Line() + + "Add new user: \n" + "adduser " + UI.Line() + + "Switch to user: \n" + "switch " + UI.Line() + + "Add task for current user:\n" + + "addtask /on /task /from /to /type " + + UI.Line() + + "Add task for current user (check duplicates):\n" + + "addtwdc /on /task /from /to /type " + + UI.Line() + + "Add a task for all users: \n" + + "addforall /on /task /from /to /type " + + UI.Line() + + "Add a task that repeats over certain days: \n" + + "addrepeattask /on /task /from /to /type " + + UI.Line() + + "Add a task for certain users: \n" + + "addfor /user /on /task /from /to /type " + + UI.Line() + + "Delete task: \n" + "deletetask" + UI.Line() + + "Change a task's timing: \n" + + "changetasktiming /on /index /from /to " + UI.Line() + + "Change a task's type: \n" + + "changetasktype /on /index /type " + UI.Line() + + "Compare timetables of all users: \n" + "compareall" + UI.Line() + + "Compare timetables between two users: \n" + "compare " + UI.Line() + + "List today's tasks: \n" + "todaytasks" + UI.Line() + + "List urgent tasks within certain timeframe: \n" + "urgent /in " + UI.Line() + + "View common events: \n" + "viewcommonevents"); printLine(); } @@ -72,6 +90,10 @@ public static void printLine() { System.out.println("____________________________________________________________"); } + public static String Line() { + return ("\n_________________________________________\n"); + } + /** *

* Prints the overlapping free time for each day in the format: From 0ec71330e706feae7023ff54f39fafc9adc044b2 Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Wed, 10 Apr 2024 20:50:22 +0800 Subject: [PATCH 124/162] Fixed gradle check --- src/main/java/seedu/duke/ui/UI.java | 40 ++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index 8318629308..c76e02637d 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -43,37 +43,37 @@ public static void printHelp() { System.out.println( "**Note: use hh:mm 24hr time format (ex. 13:00) \n" + "List of available commands: \n" + - "List all users: \n" + "list" + UI.Line() + - "Exit the app: \n" + "bye" + UI.Line() + - "View current user: \n" + "current" + UI.Line() + - "View timetable of current user: \n" + "view" + UI.Line() + - "View your next task: \n" + "next" + UI.Line() + - "Add new user: \n" + "adduser " + UI.Line() + - "Switch to user: \n" + "switch " + UI.Line() + + "List all users: \n" + "list" + UI.line() + + "Exit the app: \n" + "bye" + UI.line() + + "View current user: \n" + "current" + UI.line() + + "View timetable of current user: \n" + "view" + UI.line() + + "View your next task: \n" + "next" + UI.line() + + "Add new user: \n" + "adduser " + UI.line() + + "Switch to user: \n" + "switch " + UI.line() + "Add task for current user:\n" + "addtask /on /task /from /to /type " - + UI.Line() + + + UI.line() + "Add task for current user (check duplicates):\n" + "addtwdc /on /task /from /to /type " - + UI.Line() + + + UI.line() + "Add a task for all users: \n" + "addforall /on /task /from /to /type " - + UI.Line() + + + UI.line() + "Add a task that repeats over certain days: \n" + "addrepeattask /on /task /from /to /type " - + UI.Line() + + + UI.line() + "Add a task for certain users: \n" + "addfor /user /on /task /from /to /type " - + UI.Line() + - "Delete task: \n" + "deletetask" + UI.Line() + + + UI.line() + + "Delete task: \n" + "deletetask" + UI.line() + "Change a task's timing: \n" + - "changetasktiming /on /index /from /to " + UI.Line() + + "changetasktiming /on /index /from /to " + UI.line() + "Change a task's type: \n" + - "changetasktype /on /index /type " + UI.Line() + - "Compare timetables of all users: \n" + "compareall" + UI.Line() + - "Compare timetables between two users: \n" + "compare " + UI.Line() + - "List today's tasks: \n" + "todaytasks" + UI.Line() + - "List urgent tasks within certain timeframe: \n" + "urgent /in " + UI.Line() + + "changetasktype /on /index /type " + UI.line() + + "Compare timetables of all users: \n" + "compareall" + UI.line() + + "Compare timetables between two users: \n" + "compare " + UI.line() + + "List today's tasks: \n" + "todaytasks" + UI.line() + + "List urgent tasks within certain timeframe: \n" + "urgent /in " + UI.line() + "View common events: \n" + "viewcommonevents"); printLine(); } @@ -90,7 +90,7 @@ public static void printLine() { System.out.println("____________________________________________________________"); } - public static String Line() { + public static String line() { return ("\n_________________________________________\n"); } From 5c99c67ca7ea8a769065eb7b21c0c62533c5c482 Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Wed, 10 Apr 2024 21:10:31 +0800 Subject: [PATCH 125/162] Fixing ui test --- text-ui-test/EXPECTED.TXT | 1 + 1 file changed, 1 insertion(+) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index ec77d5891a..bb91503485 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,4 +1,5 @@ Timetable comparison app opened. +type 'help' for commands. Folder created successfully. Note: use hh:mm 24hr time format (ex. 13:00) List of available commands: From ee68d5edefd31fafafd25d137c9c3577bc51ba08 Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Wed, 10 Apr 2024 21:23:40 +0800 Subject: [PATCH 126/162] Updated EXPECTED.TXT sh test script --- text-ui-test/EXPECTED.TXT | 76 ++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index bb91503485..7dfa43adc9 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,23 +1,67 @@ Timetable comparison app opened. type 'help' for commands. Folder created successfully. -Note: use hh:mm 24hr time format (ex. 13:00) +**Note: use hh:mm 24hr time format (ex. 13:00) List of available commands: -list: list all users -bye: exit the app -current: view current user -view: view timetable of current user -next: view your next task -adduser: add new user -switch : switch to user -addtask /on /from /to : add task for current user -addtwdc /on /from /to deletetask: delete task -changetasktiming: -changetasktype : change the type of a task (flexible/confirmed) -compareall: compare timetables of all users -compare : compare timetables of specified users -addforall /on /from /to : add task for all users -viewcommonevents: view common events +List all users: +list +_________________________________________ +Exit the app: +bye +_________________________________________ +View current user: +current +_________________________________________ +View timetable of current user: +view +_________________________________________ +View your next task: +next +_________________________________________ +Add new user: +adduser +_________________________________________ +Switch to user: +switch +_________________________________________ +Add task for current user: +addtask /on /task /from /to /type +_________________________________________ +Add task for current user (check duplicates): +addtwdc /on /task /from /to /type +_________________________________________ +Add a task for all users: +addforall /on /task /from /to /type +_________________________________________ +Add a task that repeats over certain days: +addrepeattask /on /task /from /to /type +_________________________________________ +Add a task for certain users: +addfor /user /on /task /from /to /type +_________________________________________ +Delete task: +deletetask +_________________________________________ +Change a task's timing: +changetasktiming /on /index /from /to +_________________________________________ +Change a task's type: +changetasktype /on /index /type +_________________________________________ +Compare timetables of all users: +compareall +_________________________________________ +Compare timetables between two users: +compare +_________________________________________ +List today's tasks: +todaytasks +_________________________________________ +List urgent tasks within certain timeframe: +urgent /in +_________________________________________ +View common events: +viewcommonevents ____________________________________________________________ New user added: Simon The active user is: Simon From b2950b5f018a4b238fa9019fbccd8cd38ca77faf Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Wed, 10 Apr 2024 21:46:52 +0800 Subject: [PATCH 127/162] Working on PPP --- docs/team/john-nng.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 docs/team/john-nng.md diff --git a/docs/team/john-nng.md b/docs/team/john-nng.md new file mode 100644 index 0000000000..f24053eccd --- /dev/null +++ b/docs/team/john-nng.md @@ -0,0 +1,14 @@ + +

John Nguyen Project Portfolio Page

+ +

Project: Task Scheduler and Calendar Comparison App

+

Team: AY2324S2-CS2113-T13-2 +

[Code Contribution](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=john-nng&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2024-02-23&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) +

+ +Description of the project + +

Contributions

+- **Features** +- **Enchancements to current features** +- **Documentation** \ No newline at end of file From ae4bda69094f8e8fa38de958bc8e2bf0060798b8 Mon Sep 17 00:00:00 2001 From: john-nng <89668122+john-nng@users.noreply.github.com> Date: Thu, 11 Apr 2024 15:49:50 +0800 Subject: [PATCH 128/162] Update john-nng.md --- docs/team/john-nng.md | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/docs/team/john-nng.md b/docs/team/john-nng.md index f24053eccd..3b9fa29ea7 100644 --- a/docs/team/john-nng.md +++ b/docs/team/john-nng.md @@ -1,14 +1,31 @@ -

John Nguyen Project Portfolio Page

+# John Nguyen Project Portfolio Page -

Project: Task Scheduler and Calendar Comparison App

-

Team: AY2324S2-CS2113-T13-2 -

[Code Contribution](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=john-nng&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2024-02-23&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) -

+## Project: Task Scheduler and Calendar Comparison App +### Team: AY2324S2-CS2113-T13-2 +[Code Contribution](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=john-nng&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2024-02-23&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) -Description of the project +This is a task scheduler and timetable comparison command line app that allows users to create timetables consisting of task throughout a given week. Multiple users have their own timetable compare timetables to see shared time between users, seeing upcoming task and viewing their timetables for the week. This makes it easy for people to schedule events in relation to each other based on their shared free time. -

Contributions

-- **Features** -- **Enchancements to current features** -- **Documentation** \ No newline at end of file +### Contributions + +#### Features +- **Structured the Timetable Class datastructure.** I adjusted the parameters of the Timetable Class to conventiently do calculations with other tables, for example, the data structure of the timetable is a HashMap of days associated with list of tasks which are the values for the dictionary keys. +- **Implemented InputValidator Class and set up the framework for this class.** This class is used to validate the correct syntax for every command in this app. This uses regex to make sure the String pattern of a command correct matches how the comand should be called. I setup the logic for this InputValidator class and my functions I created could be referenced for future additions of new commands. +- **Implemented Compare function between 2 users.** I added the essential feature of comparing two timetables of two users and displaying their shared free time bassed on each day. This is done by merging the two timetables then finding the free time within the merged timetables then displaying the results. +- **Abstracted the Main Class.** I abstracted the Parsing logic that was originally in the Main class, this significantly decluttered the main Class and abstracted the logic into the Parser Class. The while loop simply takes in Input and then Parsing will take care of the bulk of the work. +- **Implemented the Parser Class.** I set up the framework for the Parser class which takes in a string command and will identify that command it is. Based on that It will perform the command logic, abstracting other parts of the code if neccesary. +- example of InputValidator within Parser Class: +- image + + +#### Testing +- Wrote test for InputValidator class. I wrote J-Unit test for InputValidator class to ensure that the functions were correctly validating various input commands. +- Wrote some test in the TimetableTest Class for addtask function and compare functions to see if various task would be added properly and compared properly. + +#### Enhancements to Current Features +- Enchanced the UI ouput for timetables and timetable comparison commands. Making these outputs more readable. +- Updated the help message UI output. To reflect the complete set of commands and their usages in a clean format. + +#### Documentation +- Updated Documentation for all commands in User Guide and formatted them in a easy to read manner. Bulk of work done during these PR's ([1](https://github.com/AY2324S2-CS2113-T13-2/tp/blob/9dbe139124adfecf78f4c94d8f662b283788a8fa/docs/UserGuide.md), [2](https://github.com/AY2324S2-CS2113-T13-2/tp/blob/65c01a9d7d4875eedc494afa923108eec9e48055/docs/UserGuide.md), [3](https://github.com/AY2324S2-CS2113-T13-2/tp/blob/47db8ea97ed3da106a83d75a7ae90152a5e80200/docs/UserGuide.md)) From 0c69f8f0ef05f636abcf0af064dff83ae8a55a16 Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Thu, 11 Apr 2024 15:52:47 +0800 Subject: [PATCH 129/162] Added more testing for InputValidatorTest. --- docs/team/john-nng.md | 2 +- src/main/java/seedu/duke/InputValidator.java | 4 +- .../java/seedu/duke/InputValidatorTest.java | 163 ++++++++++++++++++ 3 files changed, 166 insertions(+), 3 deletions(-) diff --git a/docs/team/john-nng.md b/docs/team/john-nng.md index 3b9fa29ea7..310064eeb6 100644 --- a/docs/team/john-nng.md +++ b/docs/team/john-nng.md @@ -20,7 +20,7 @@ This is a task scheduler and timetable comparison command line app that allows u #### Testing -- Wrote test for InputValidator class. I wrote J-Unit test for InputValidator class to ensure that the functions were correctly validating various input commands. +- Wrote test for InputValidator class. I wrote J-Unit test for InputValidator class to ensure that the functions were correctly validating various input commands. Such as Adduser, addtask, deletetask, compareall, compare. - Wrote some test in the TimetableTest Class for addtask function and compare functions to see if various task would be added properly and compared properly. #### Enhancements to Current Features diff --git a/src/main/java/seedu/duke/InputValidator.java b/src/main/java/seedu/duke/InputValidator.java index b3c5ac59c5..0a763f0863 100644 --- a/src/main/java/seedu/duke/InputValidator.java +++ b/src/main/java/seedu/duke/InputValidator.java @@ -13,7 +13,7 @@ public class InputValidator { * @throws InvalidFormatException If the input does not match the expected format: "compare (user1) (user2)". */ public static void validateCompareInput(String input) throws InvalidFormatException { - String regex = "(?i)^compare\\s+\\w+\\s+\\w+$"; + String regex = "(?i)^compare\\s+\\w+\\s+\\w+(\\s+)?$"; if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid compare format. " + @@ -90,7 +90,7 @@ public static void validateDeleteTaskInput(String input) throws InvalidFormatExc * @throws InvalidFormatException If the input does not match the expected format: "adduser (user)". */ public static void validateAddUserInput(String input) throws InvalidFormatException { - String regex = "(?i)^adduser\\s+\\w+$"; + String regex = "(?i)^adduser\\s+\\w+(\\s+)?$"; if (!input.matches(regex)) { throw new InvalidFormatException("[ERROR] Invalid addUser format. " + diff --git a/src/test/java/seedu/duke/InputValidatorTest.java b/src/test/java/seedu/duke/InputValidatorTest.java index 7697a574cc..39f27f5017 100644 --- a/src/test/java/seedu/duke/InputValidatorTest.java +++ b/src/test/java/seedu/duke/InputValidatorTest.java @@ -6,6 +6,22 @@ import seedu.duke.exceptions.InvalidDayException; import seedu.duke.exceptions.InvalidFormatException; class InputValidatorTest { + @Test + public void testAddUser() { + String[] inputList = {"adduser john", + "adduser john100 ", + "ADDUSEr j", + "ADDUSER xjohnx", + "addUser 20 "}; + for (String input : inputList) { + try { + InputValidator.validateAddUserInput(input); + } catch (InvalidFormatException e){ + fail(); + } + } + } + @Test public void testValidChangeTaskTimingFormat() { String validInput = "changeTaskTiming /on monday /index 1 /from 09:00 /to 10:00"; @@ -81,4 +97,151 @@ public void testValidateDay() { } } } + + @Test + public void testAddTask() { + String[] inputList = {"addtask /on MONDAY /task walk dogs /from 10:00 /to 16:00 /type c", + "ADDTASK /on tuesday /task walk dogs /from 00:00 /to 23:59 /type f", + "addtask /on MONDAY /task walk dogs100 /from 10:00 /to 16:00 /type c", + "Addtask /on sunday /task walk dogssSS /from 10:00 /to 16:00 /type f", + "addtask /on Friday /task walk dogs /from 10:00 /to 16:00 /type c"}; + for (String input : inputList) { + try { + InputValidator.validateAddTaskInput(input); + } catch (InvalidFormatException e){ + fail(); + } + } + } + + @Test + public void testInvalidAddTask() { + //addtask mispelled + String invalidInput1 = "addtas /on MONDAY /task walk dogs /from 10:00 /to 16:00 /type c"; + try { + InputValidator.validateAddTaskInput(invalidInput1); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid addtask format. " + + "Expected format: addtask /on [day] /task [description] /from [start time] /to [end time] " + + "/type [f/c]", e.getMessage()); + } + //No space between from time and "/to" + String invalidInput2 = "addtask /on MONDAY /task walk dogs /from 10:00/to 16:00 /type c"; + try { + InputValidator.validateAddTaskInput(invalidInput2); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid addtask format. " + + "Expected format: addtask /on [day] /task [description] /from [start time] /to [end time] " + + "/type [f/c]", e.getMessage()); + } + //Monday extra y + String invalidInput3 = "addtask /on MONDAYy /task walk dogs /from 10:00 /to 16:00 /type c"; + try { + InputValidator.validateAddTaskInput(invalidInput3); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid addtask format. " + + "Expected format: addtask /on [day] /task [description] /from [start time] /to [end time] " + + "/type [f/c]", e.getMessage()); + } + //different type v + String invalidInput4 = "addtask /on MONDAY /task walk dogs /from 10:00 /to 16:00 /type v"; + try { + InputValidator.validateAddTaskInput(invalidInput4); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid addtask format. " + + "Expected format: addtask /on [day] /task [description] /from [start time] /to [end time] " + + "/type [f/c]", e.getMessage()); + } + } + + @Test + public void testDeleteTask() { + String[] inputList = {"deletetask /on MONDAY /index 1", + "deletetask /on saturday /index 100", + "Deletetask /on MONDAY /index 12", + "DELETETASK /on tuesdAY /index 1", + "deleteTASK /on saturday /index 4000"}; + for (String input : inputList) { + try { + InputValidator.validateDeleteTaskInput(input); + } catch (InvalidFormatException e){ + fail(); + } + } + } + + + @Test + public void testCompare() { + String[] inputList = {"compare john jill", "COMPARE john jill ", "COMpare john bill", "comPArE jane yu"}; + for (String input : inputList) { + try { + InputValidator.validateCompareInput(input); + } catch (InvalidFormatException e) { + fail(); + } + } + } + + @Test + public void testInvalidCompare() { + String invalidInput1 = "compare john jack jill"; + try { + InputValidator.validateCompareInput(invalidInput1); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid compare format. " + + "Expected format: compare ", e.getMessage()); + } + String invalidInput2 = "compar john jack "; + try { + InputValidator.validateCompareInput(invalidInput2); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid compare format. " + + "Expected format: compare ", e.getMessage()); + } + String invalidInput3 = "compare jo"; + try { + InputValidator.validateCompareInput(invalidInput3); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid compare format. " + + "Expected format: compare ", e.getMessage()); + } + } + + @Test + public void testCompareAll() { + String[] inputList = {"compareall ", "COMPAREALL ", "COMpareAll", "comPArEall"}; + for (String input : inputList) { + try { + InputValidator.validateCompareAllInput(input); + } catch (InvalidFormatException e) { + fail(); + } + } + } + + @Test + public void testInvalidCompareAll() { + String invalidInput1 = "compareall l"; + try { + InputValidator.validateCompareAllInput(invalidInput1); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid compareall format. " + + "Expected format: compareall", e.getMessage()); + } + String invalidInput2 = "comparall "; + try { + InputValidator.validateCompareAllInput(invalidInput2); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid compareall format. " + + "Expected format: compareall", e.getMessage()); + } + String invalidInput3 = "compareallllll"; + try { + InputValidator.validateCompareAllInput(invalidInput3); + } catch (InvalidFormatException e) { + assertEquals("[ERROR] Invalid compareall format. " + + "Expected format: compareall", e.getMessage()); + } + } } From 8b4733bec0dad4d9d415cba9f4ddb4bca6e05662 Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Thu, 11 Apr 2024 16:07:29 +0800 Subject: [PATCH 130/162] Fixing gradle check for InputValidatorTest. --- .../java/seedu/duke/InputValidatorTest.java | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/test/java/seedu/duke/InputValidatorTest.java b/src/test/java/seedu/duke/InputValidatorTest.java index 39f27f5017..afc8bd4544 100644 --- a/src/test/java/seedu/duke/InputValidatorTest.java +++ b/src/test/java/seedu/duke/InputValidatorTest.java @@ -8,11 +8,13 @@ class InputValidatorTest { @Test public void testAddUser() { - String[] inputList = {"adduser john", - "adduser john100 ", - "ADDUSEr j", - "ADDUSER xjohnx", - "addUser 20 "}; + String[] inputList = { + "adduser john", + "adduser john100 ", + "ADDUSEr j", + "ADDUSER xjohnx", + "addUser 20 " + }; for (String input : inputList) { try { InputValidator.validateAddUserInput(input); @@ -100,11 +102,13 @@ public void testValidateDay() { @Test public void testAddTask() { - String[] inputList = {"addtask /on MONDAY /task walk dogs /from 10:00 /to 16:00 /type c", - "ADDTASK /on tuesday /task walk dogs /from 00:00 /to 23:59 /type f", - "addtask /on MONDAY /task walk dogs100 /from 10:00 /to 16:00 /type c", - "Addtask /on sunday /task walk dogssSS /from 10:00 /to 16:00 /type f", - "addtask /on Friday /task walk dogs /from 10:00 /to 16:00 /type c"}; + String[] inputList = { + "addtask /on MONDAY /task walk dogs /from 10:00 /to 16:00 /type c", + "ADDTASK /on tuesday /task walk dogs /from 00:00 /to 23:59 /type f", + "addtask /on MONDAY /task walk dogs100 /from 10:00 /to 16:00 /type c", + "Addtask /on sunday /task walk dogssSS /from 10:00 /to 16:00 /type f", + "addtask /on Friday /task walk dogs /from 10:00 /to 16:00 /type c" + }; for (String input : inputList) { try { InputValidator.validateAddTaskInput(input); @@ -156,11 +160,13 @@ public void testInvalidAddTask() { @Test public void testDeleteTask() { - String[] inputList = {"deletetask /on MONDAY /index 1", - "deletetask /on saturday /index 100", - "Deletetask /on MONDAY /index 12", - "DELETETASK /on tuesdAY /index 1", - "deleteTASK /on saturday /index 4000"}; + String[] inputList = { + "deletetask /on MONDAY /index 1", + "deletetask /on saturday /index 100", + "Deletetask /on MONDAY /index 12", + "DELETETASK /on tuesdAY /index 1", + "deleteTASK /on saturday /index 4000" + }; for (String input : inputList) { try { InputValidator.validateDeleteTaskInput(input); @@ -227,7 +233,7 @@ public void testInvalidCompareAll() { InputValidator.validateCompareAllInput(invalidInput1); } catch (InvalidFormatException e) { assertEquals("[ERROR] Invalid compareall format. " + - "Expected format: compareall", e.getMessage()); + "Expected format: compareall", e.getMessage()); } String invalidInput2 = "comparall "; try { From a336551e1e42b58c2ee875acfafbc3f652502f11 Mon Sep 17 00:00:00 2001 From: john-nng <89668122+john-nng@users.noreply.github.com> Date: Thu, 11 Apr 2024 16:11:14 +0800 Subject: [PATCH 131/162] Update john-nng.md --- docs/team/john-nng.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/team/john-nng.md b/docs/team/john-nng.md index 310064eeb6..065741729b 100644 --- a/docs/team/john-nng.md +++ b/docs/team/john-nng.md @@ -20,7 +20,7 @@ This is a task scheduler and timetable comparison command line app that allows u #### Testing -- Wrote test for InputValidator class. I wrote J-Unit test for InputValidator class to ensure that the functions were correctly validating various input commands. Such as Adduser, addtask, deletetask, compareall, compare. +- Wrote test for InputValidator class. I wrote J-Unit test for InputValidator class to ensure that the functions were correctly validating various input commands. Such as Adduser, addtask, deletetask, compareall, compare. PR [here](https://github.com/AY2324S2-CS2113-T13-2/tp/commit/e9c5d00429e60a5d1a5d2938cabfeb0007e9c21d) - Wrote some test in the TimetableTest Class for addtask function and compare functions to see if various task would be added properly and compared properly. #### Enhancements to Current Features From 11cb304f78b4eab58430dd7a8bde6d7ab6e9fdea Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Thu, 11 Apr 2024 19:33:31 +0800 Subject: [PATCH 132/162] Add Leong-ZM PPP --- docs/team/Leong-ZM.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 docs/team/Leong-ZM.md diff --git a/docs/team/Leong-ZM.md b/docs/team/Leong-ZM.md new file mode 100644 index 0000000000..57e137c748 --- /dev/null +++ b/docs/team/Leong-ZM.md @@ -0,0 +1,29 @@ +# Leong Zhe Ming's Project Portfolio Page + +## Project: Time Comparer + +### Team: AY2324S2-CS2113-T13-2 + +Time Comparer is a desktop application used for time management between users. + +This is a task scheduler and timetable comparison command line app that allows users to create timetables consisting of +task throughout a week. Each user has their own timetable, which can be compared to see shared time between +users. This makes it easy for people to schedule events based on their shared free time. + +### Summary of Contributions +[Code Contribution](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=Leong-ZM&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2024-02-23&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) + +#### Features +- **Added the base User and UserList classes:** Created the basic class that track the current active users, allowing user creation and switching between users, as well as setting a framework for future functionality. +- **Added the help command:** To show currently available commands and their formatting. +- **Added compareAll command:** Improved existing code of comparing two timetables to allow it to iteratively compare all currently existing timetables. +- **Added the next command:** Allows users to easily view the next upcoming task based on the current system time. + +#### Testing +- **Parser Tests:** Wrote the majority of tests on the Parser to ensure that proper input formatting can be read properly, and that incorrect inputs are caught as exceptions and produce relevant error messages. + +#### Documentation +- **Developer Guide - next command:** Added documentation and UML diagram for the implementation of the next command. + +#### Community +- **Bug Reports:** Reported bugs and suggestions for other teams in the class. [Issues. ](https://github.com/Leong-ZM/ped/issues) From f5d23ae64ab723577d2d98a4b94924786fca6098 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Thu, 11 Apr 2024 21:15:42 +0800 Subject: [PATCH 133/162] Add PPP --- docs/team/z-wenqing.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/team/z-wenqing.md diff --git a/docs/team/z-wenqing.md b/docs/team/z-wenqing.md new file mode 100644 index 0000000000..e69de29bb2 From d4857b19068d04b54ba74c70301bbd56080e1619 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Thu, 11 Apr 2024 21:16:41 +0800 Subject: [PATCH 134/162] Add PPP --- docs/team/z-wenqing.md | 49 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/docs/team/z-wenqing.md b/docs/team/z-wenqing.md index e69de29bb2..e3a5449020 100644 --- a/docs/team/z-wenqing.md +++ b/docs/team/z-wenqing.md @@ -0,0 +1,49 @@ +# Zhang Wenqing's Project Portfolio Page + +## Project: Timetable Comparer + +### Team: AY2324S2-CS2113-T13-2 + +Timetable Comparer is a desktop application used for timetable management among a group of users. It operates through a Command Line Interface (CLI), enabling users to add their weekly tasks and utilize the tool to find common free time slots for group activities. + +Given below are my contributions to the project. + +* **Code Contributed**: https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=z-wenqing&breakdown=true + + +* **New feature**: Added the ability to store user data such as usernames and timetables of each user. + * When the user launches the application for the first time, a designated folder is created in the application's directory to store all data. + * When a new user is added, a file named after the user's name will be created within the created data folder. + * Tasks added by users are recorded in their respective files. + * On subsequent launches, all the existing users and their corresponding timetables will be retrieved and loaded. + + +* **New feature**: Added the feature to check whether the task added clashes with the existing tasks. + + +* **New feature**: Added the feature to add tasks for multiple users. + * The users are able to add a task for multiple specified users simultaneously. This feature makes it more convenient for users to add common activities for multiple users, such as attending lectures, and they do not have to add tasks one by one. + * The usernames inputted by the user will be checked against the existing users and their timetables to make sure that the users specified are valid users and the task added does not clash with the existing tasks. The usernames that are invalid, as well as users that have conflict tasks will be outputted for users to clearly see the issue. + + +* **New feature**: Added the feature to add tasks for all users. + * The user can add a confirmed group activity for all users and they can also check events that are common for all users. + + +* **Contributions to the UG** + * Add examples of command in version 1.0. + + +* **Contributions to the DG** + * Add sequence diagram for the interaction between Storage class and other classes, illustrating how the storing and retrieving data work. + + +* **Contributions to team-based tasks** + * Set up the GitHub team org/repo. + * General code enhancements to fix testing errors and style errors to pass gradle checks. + + +* **Testing** + * Added extensive testing for storage class. A new folder named "test_data" is created for testing. During testing, the directory will be directed to "test_data" instead of "data" folder where all the actual user data is stored. + * Helped teammates to fix test case errors where storage is involved. + From ea2ac6a5fe53692388bd9072f537fbe6e5c6ae0e Mon Sep 17 00:00:00 2001 From: john-nng <89668122+john-nng@users.noreply.github.com> Date: Sat, 13 Apr 2024 23:38:22 +0800 Subject: [PATCH 135/162] Update john-nng.md --- docs/team/john-nng.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/team/john-nng.md b/docs/team/john-nng.md index 065741729b..a1a0d08ed3 100644 --- a/docs/team/john-nng.md +++ b/docs/team/john-nng.md @@ -1,7 +1,7 @@ # John Nguyen Project Portfolio Page -## Project: Task Scheduler and Calendar Comparison App +## Project: Timetable Comparer ### Team: AY2324S2-CS2113-T13-2 [Code Contribution](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=john-nng&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2024-02-23&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) @@ -25,7 +25,7 @@ This is a task scheduler and timetable comparison command line app that allows u #### Enhancements to Current Features - Enchanced the UI ouput for timetables and timetable comparison commands. Making these outputs more readable. -- Updated the help message UI output. To reflect the complete set of commands and their usages in a clean format. +- Updated the help message UI output. To reflect the complete set of commands and their usages in a clean format. [PR Here](https://github.com/AY2324S2-CS2113-T13-2/tp/commit/b5974cdf35554456984cd02415fbd7d87facab7a) #### Documentation - Updated Documentation for all commands in User Guide and formatted them in a easy to read manner. Bulk of work done during these PR's ([1](https://github.com/AY2324S2-CS2113-T13-2/tp/blob/9dbe139124adfecf78f4c94d8f662b283788a8fa/docs/UserGuide.md), [2](https://github.com/AY2324S2-CS2113-T13-2/tp/blob/65c01a9d7d4875eedc494afa923108eec9e48055/docs/UserGuide.md), [3](https://github.com/AY2324S2-CS2113-T13-2/tp/blob/47db8ea97ed3da106a83d75a7ae90152a5e80200/docs/UserGuide.md)) From db55a585fd3e401347721100ecc208aecae836fd Mon Sep 17 00:00:00 2001 From: john-nng <89668122+john-nng@users.noreply.github.com> Date: Sat, 13 Apr 2024 23:50:05 +0800 Subject: [PATCH 136/162] Update john-nng.md --- docs/team/john-nng.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/team/john-nng.md b/docs/team/john-nng.md index a1a0d08ed3..597a5183b4 100644 --- a/docs/team/john-nng.md +++ b/docs/team/john-nng.md @@ -1,5 +1,5 @@ -# John Nguyen Project Portfolio Page +# John Nguyen Project Portfolio Page ## Project: Timetable Comparer ### Team: AY2324S2-CS2113-T13-2 From fb1c7980eb4f00623b4b3eb2dc1800f7ddbad3a4 Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Sun, 14 Apr 2024 09:30:53 +0800 Subject: [PATCH 137/162] Rename PPP --- docs/team/{Leong-ZM.md => leong-zm.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/team/{Leong-ZM.md => leong-zm.md} (100%) diff --git a/docs/team/Leong-ZM.md b/docs/team/leong-zm.md similarity index 100% rename from docs/team/Leong-ZM.md rename to docs/team/leong-zm.md From 66c6d4568ddfce34f1fe9bd1783988beb3460ef2 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 15 Apr 2024 01:18:26 +0800 Subject: [PATCH 138/162] Fix bug --- docs/UserGuide.md | 16 ++++++++++++++++ src/main/java/seedu/duke/Parser.java | 16 ++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 178dee8b3c..f5767c3815 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -296,7 +296,23 @@ Expected Output: ``` Timetable has been written to data/user.txt Repeated task added successfully! + +``` + +### Add a task for multiple users: `addfor` + +Format: `addfor /user USER1, USER2, ... /on DAYS /task TASK /from START_TIME /to END_TIME /type F_OR_C` + +Example: `addfor /user simon, helen, tim /on monday /task project meeting /from 9:00 /to 11:00 /type f` + +Expected Output: ``` +Timetable has been written to data/Simon.txt +Timetable has been written to data/Helen.txt +Timetable has been written to data/Tim.txt + +``` + ## List name of commands: `help` Format: `help` diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index c3952282c0..8a1c4ce7d9 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -497,11 +497,15 @@ private static void addFor(String command, UserList userList) throws IOException for (String username : usernames) { User user = userList.findUser(username.trim()); if (user == null) { - invalidUsers.add(username.trim()); + if (!invalidUsers.contains(username.trim())) { + invalidUsers.add(username.trim()); + } continue; } if (checkClash(task, user)) { - clashedUsers.add(username.trim()); + if (!clashedUsers.contains(username.trim())) { + clashedUsers.add(username.trim()); + } } } @@ -519,8 +523,12 @@ private static void addFor(String command, UserList userList) throws IOException for (String username : usernames) { User user = userList.findUser(username.trim()); - user.getTimetable().addUserTask(day, task); - user.getStorage().writeTaskInFile(user); + if (!checkClash(task, user)) { + user.getTimetable().addUserTask(day, task); + user.getStorage().writeTaskInFile(user); + } else { + System.out.println("For " + user.getName() + ", the task " + task + " clashes with existing tasks OR already exist!"); + } } } } From dcc4a12feb331d641bd003d8bfdf0d2c88409672 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 15 Apr 2024 01:21:29 +0800 Subject: [PATCH 139/162] Shorten line --- src/main/java/seedu/duke/Parser.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 8a1c4ce7d9..16561fe6fa 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -527,7 +527,8 @@ private static void addFor(String command, UserList userList) throws IOException user.getTimetable().addUserTask(day, task); user.getStorage().writeTaskInFile(user); } else { - System.out.println("For " + user.getName() + ", the task " + task + " clashes with existing tasks OR already exist!"); + System.out.println("For " + user.getName() + + ", the task " + task + " clashes with existing tasks OR already exist!"); } } } From b728fe42cca72c80beab7f7b971df12c7b4faa3a Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 15 Apr 2024 01:30:58 +0800 Subject: [PATCH 140/162] Fix indentation error --- src/main/java/seedu/duke/Parser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 16561fe6fa..687890930b 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -528,7 +528,7 @@ private static void addFor(String command, UserList userList) throws IOException user.getStorage().writeTaskInFile(user); } else { System.out.println("For " + user.getName() - + ", the task " + task + " clashes with existing tasks OR already exist!"); + + ", the task " + task + " clashes with existing tasks OR already exist!"); } } } From 49010b1a79777845984a7f5069ea10611b40bd78 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 15 Apr 2024 10:20:14 +0800 Subject: [PATCH 141/162] Update Storage UML --- docs/DeveloperGuide.md | 2 +- docs/Storage.puml | 20 ++++++++++---------- docs/StorageUML.png | Bin 130278 -> 0 bytes 3 files changed, 11 insertions(+), 11 deletions(-) delete mode 100644 docs/StorageUML.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 20b494dbb4..edf214c92b 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -8,7 +8,7 @@ ### Save timetable function The saving timetable mechanism is facilitated by the Storage class. It implements the following operations: -* `Storgae#createFolder()`: Creates a folder in the directory where all the users' timetable will be stored in the local computer. +* `Storage#createFolder()`: Creates a folder in the directory where all the users' timetable will be stored in the local computer. * `Storage#addExistingUsers()`: Loops through the folder to add all previous saved users upon opening the app, as well as their corresponding tasks. * `Storage#addUserInFolder(User user)`: When a new user is added, a file with the name of the user will be created in the folder. * `Storage#writeTaskInFile(User user)`: when a new task of a specific user is added, it will be written into the correct file. diff --git a/docs/Storage.puml b/docs/Storage.puml index 5e02d18d56..420ecd4134 100644 --- a/docs/Storage.puml +++ b/docs/Storage.puml @@ -1,14 +1,14 @@ @startuml -participant Duke as duke -participant Storage as storage -participant File as file -participant UserList as userList -participant UI as UI -participant Timetable as timetable -participant User as user +scale 1.5 +participant ":Duke" as duke +participant ":Storage" as storage +participant ":File" as file +participant ":UserList" as userList +participant ":UI" as UI +participant ":Timetable" as timetable +participant ":User" as user -activate duke duke -> storage: createFolder() activate storage storage -->> duke: @@ -57,7 +57,7 @@ else deactivate UI end - - storage --> duke +deactivate storage + @enduml \ No newline at end of file diff --git a/docs/StorageUML.png b/docs/StorageUML.png deleted file mode 100644 index da38ae8a8dc2073dc310c891e01117f0959c4960..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130278 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�`w=HL>PMLC;oDP()KDo3$0wtMR8-o2$X6zr4) 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 Date: Mon, 15 Apr 2024 10:40:25 +0800 Subject: [PATCH 142/162] Update developer guide --- docs/DeveloperGuide.md | 108 +++++++++++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 32 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 20b494dbb4..9f45d5d935 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,9 +1,5 @@ # Developer Guide -## Acknowledgements - -{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} - ## Design & implementation ### Save timetable function @@ -15,35 +11,7 @@ The saving timetable mechanism is facilitated by the Storage class. It implement The following sequence diagram shows how the operations in the Storage class goes through when the app is opened and it loads data from history: ![Storage UML](StorageUML.png) -## Product scope -### Target user profile - -{Describe the target user profile}: Students (NUS student?) - -### Value proposition - -{Describe the value proposition: what problem does it solve?} - -## User Stories - -|Version| As a ... | I want to ... | So that I can ... | -|--------|----------|---------------|-------------------------------------------------------------| -|v1.0| new user |see usage instructions| refer to them when I forget how to use the application | -|v2.0| user |find a to-do item by name| locate a to-do without having to go through the entire list | -| | user |add a task to the timetable| record when a task needs to be done | - - -## Non-Functional Requirements -{Give non-functional requirements} - -## Glossary - -* *glossary item* - Definition - -## Instructions for manual testing - -{Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing} ## Parser Component @@ -105,3 +73,79 @@ Step 4: It then loops through the tasks on that day, starting from the back (the Step 5: It displays the last task it looped though, or a special message if there is no task that day. ![NextCommand UML](NextCommand.png) + +# Appendix: Project Requirements +## Product scope +### Target user profile + +People who +* have busy timetables +* wish to be able to compare theirs with their friends' easily +* prefer desktop apps over other types +* can type fast +* prefer typing to mouse interactions +* are reasonably comfortable using CLI apps + +### Value proposition + +The app can store multiple timetables and easily display and compare them automatically, saving the time and effort of doing so by hand. + +## User Stories + +| Version | As a ... | I want to ... | So that I can ... | +|---------|----------|---------------------------|------------------------------------------------------------------| +| v1.0 | new user | see usage instructions | refer to them when I forget how to use the application | +| | user | add a new user | store my timetable | +| | user | switch users | interact with my own timetable | +| | user | add a task | | +| | user | compare two timetables | see the common time between them | +| v2.0 | user | find a to-do item by name | locate a to-do without having to go through the entire list | +| | user | specify task importance | remember if a task is important or not | +| | user | compare all timetables | view a summurized timetable comprising of all current timetables | + + +## Non-Functional Requirements + +1. Should work on any mainstream OS (Windows, Linux, Unix, MacOS) as long as it has Java 11 or above installed. +2. Should be able to hold up to 10 persons without a noticeable sluggishness in performance for typical usage. +3. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse. + +## Glossary + +* **User** - A person using this app. +* **Timetable** - A number of tasks belonging to a specific user. +* **Task** - An event in a timetable, with a description, start time, end time, and type. + +## Instructions for manual testing + +Given below are instructions to test the app manually. + +### Launch and Shutdown + +1. Initial launch + +Download the jar file and copy into an empty folder. Double-click the jar file. Expected: Shows the GUI with a list of commands. The window size may not be optimum; adjust it as necessary. + +2. Shutdown + +Enter 'bye'. The app should close and all current data should be saved in a data folder. + +### Add user + +Prerequisites: None + +* Valid command: `adduser User1`. Expected: Confirmation that user was added. +* Invalid command: `adduser`. Expected: Error message shown. +* Invalid command: `adduser User1`, where User1 already exists. Expected: Error message shown. + +### Add task + +Prerequisites: At least one user has been added + +* Valid command: `addtask /on Monday /task test1 /from 9:00 /to 11:00 /type f`. Expected: Confirmation that task was added. +* Invalid commands. Expected: Error message shown detailing expected format. + * `addtask /on Monday` + * `addtask /on Monday /task description` + * `addtask /on Monday /task description /from 09:00 /to 11:00` + * `addtask Monday description 09:00 11:00` + * `addtask /on MONDAY /task description /from 09:00 /to 11:00` From afc1f429c45bda99b36cf8cae4ac14941c0ccd2a Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Mon, 15 Apr 2024 10:42:41 +0800 Subject: [PATCH 143/162] Fixing DG diagrams --- docs/AddUserTaskSequenceDiagram.puml | 15 ++++---- docs/NextCommand.png | Bin 28804 -> 0 bytes docs/NextCommand.puml | 24 ++++++++++++- docs/Parse.puml | 10 +++--- docs/changeTaskTimingClassDiagram.puml | 32 +++++++++--------- docs/changeTaskType.puml | 18 ++++++++-- docs/diagram/NextCommand.png | Bin 0 -> 43238 bytes docs/diagram/Parse.png | Bin 45389 -> 53031 bytes docs/diagram/changeTaskTimingClassDiagram.png | Bin 77678 -> 88798 bytes docs/diagram/changeTaskType.png | Bin 16503 -> 23443 bytes 10 files changed, 66 insertions(+), 33 deletions(-) delete mode 100644 docs/NextCommand.png create mode 100644 docs/diagram/NextCommand.png diff --git a/docs/AddUserTaskSequenceDiagram.puml b/docs/AddUserTaskSequenceDiagram.puml index 82dfc71147..414e78de32 100644 --- a/docs/AddUserTaskSequenceDiagram.puml +++ b/docs/AddUserTaskSequenceDiagram.puml @@ -1,13 +1,13 @@ @startuml title changeTaskTiming Sequence Diagram -participant "Parser" as Caller -participant "changeTaskTiming" as Method -participant "changeFlexibleTaskTiming" as FlexibleMethod -participant "InputValidator" as InputValidator -participant "UserList" as UserList -participant "User" as User -participant "Timetable" as Timetable +participant ":Parser" as Caller +participant ":changeTaskTiming" as Method +participant ":changeFlexibleTaskTiming" as FlexibleMethod +participant ":InputValidator" as InputValidator +participant ":UserList" as UserList +participant ":User" as User +participant ":Timetable" as Timetable Caller -> Method: changeTaskTiming(command, userList) activate Method @@ -33,7 +33,6 @@ activate FlexibleMethod FlexibleMethod <-- Timetable: successful change deactivate FlexibleMethod deactivate User -Method -> System: println("Flexible task timing changed successfully.") deactivate Method @enduml \ No newline at end of file diff --git a/docs/NextCommand.png b/docs/NextCommand.png deleted file mode 100644 index 904f47d9abbbdd29a79fbe5b8ec2e323c7e3f7c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28804 zcmdSBcRbeZ|37@9B(o$lq(MTqk{v?!%FNz7ds9{=WMpKEtYmK@LiUy|S!HK$_v<8G z*Y){)zMseUao_jv@wo5n9~YhH`99vq`#4^&=Q_^kGEyQqn538p1Oi7)R7ehiK=ni* zPzEqi;V)73PaiEcJm~egU5D~53lS8tta-|e2;%dqewBen6F3|6cG`L(sY-t zif6K4Ib}a|JKzk95Ci>S((SyT$&+nroC2I zdnxv;eWP*{t7;*J#*Tbshwt)rBStEl820xx6Ak2^#m;ZvcNVH+Q7_d!vEt<}m8H-e zc!2N9sMSJ;$>Ob6$(GVJcS%Ij!-~U`_NQG!;j?_-;Pcw$t=CES5GE!aV#VC=f)NOd zr(!|^3XU4{v1c6#6#F(OB2SB6K7~qsjUWHs<+IVJI?kOEzK3{y{hJVnez4o-X%+SQ z^ZJqJRmk~kST29WJ%@izflz>7@@aK7QJs>X692|^W)xKIrKSGODXEkl`;_iSBW`s2 zhdk?(oNkM9sZ#MD4?jMN{oH&Co;@OBBE=s0vwEA~6S){}BT&%c$1vg)G5oMXGeJ36 zD6VlB-JXj-SX(5steE&d(RzE#X)eoQb8#dU^DN@J1-+~qZdmRu(F6MO>73l~n^qsx zqfp4&Qy5K9+&4$6$a$P+d(y8skW+fZ6V);7SqCK23_l4%!X~3ke{q~<7hNjiKkTTTN59N$GxIcGT`4;-$6w|M;G+PFP!2h z;d&|?r~mcRVBzFhFreb(=;Wkww-8TBgOBM_--Dhx6g-|a8GioW(Mrub){{id7Pq)$>H}q_^IMiT zHpHY4`}3j$8V>i`2ZFCQ`1$m%udin+G3xZBJ?A@c^ew)nRun#M**D*rmiEK4YTskH z%5~eLJ6-AhmbXhqvlse3@}BDV6X zGRH4Lctkpx2>BAp=%THI-O%CHiJ(-n+kxFB*yYD#CB5EcezR>Le}-?@jPds9Q$_aRcxbd6TDl$Hw9ZNb914e+gSzEi_O{-(A;gn3z%e*(stH952mo+*Lrz zZqk>rjmPa??xNZyRDLcn_HbVB zy{(Ynna81BlbPB=^ZgYQ-?{?Jk|5c4k3C)T{mD3*`1yjz6C4IunRRb8oj73|3cGCy zPQm8rv#!HyPJWC>Vl#6qvD%~$`{0|`#qQLqi^R&03VGG;e~@USl^xuk)bw!MDxHx- zL(Q=NvAnjiFs53s%UQad!-zIWWHAs=J~-1AVU5A0U#gNXQcA;|OMdZo)yu6dgKO=4 z`?i4`lnQ-?rhdy$h7+h;V6U`P zL^{fWJNXlh6aoFCvb$HVyjYLo^Z5B*#m2ao*LpHyb9C3!Y+Sh+O@AJPgSYu+>hkk< z4x*H91;Gx~&lkE=vrBEdmp<-N_9_evI0cY3q`ylE!NAE9Waqb+YQvLop6kn!<{;ra zbd6Ire(T!gT&TRdD*s-s*lzjT`IaK?0@Fs-4_n$%Y*Tr|nO`YAw#Jo0w4LX~q7r*( zzs|5+<p2HCZ5y8eRr4hmyEU#k%iSio_13) zgGr5(;rW>bXX&VQmoKk^^(wZ$H+$^Q-D7!}wL>GnCf^4uAU^gAs|{JJG)p^I8t#H> zUO1h*^0Y`Peg4pp?YQ33*x}m@FZ;=GzuEQmb`J|}4#|5fiKM3H*3Gpav6a!&E3BFi z<~w*JK88tqrb-{K=4k7FiR4(2K3vyiEr};rQ5m98XI(5Nq&(U2}^oC0@Eajs9e#gGhQ_7`Ra=q+z@1bav*{)YV5o}C| z8gPHJR-#r+p@&V(NF!6hnd6@(RL|4-tj#UY0J zEB#6i!?pvog@k(M2e8uO(xRvAGHxk{%$@NSEEn<-iK=VFQ+=nDJ=&4cJ0a*7s1xVu ziAd~F4OAq*p(}FZYrgvQO*Yu^Gx19z_cs?S$J{pEre6kGnmFxVrkOd@9F!m(wPYkD zEFAixC;dYG?D$N4``7m*d)?AAKVI%-#Ubx3RbGa>04rGxmtwCm4~^^3(j6D)H!>A! zGdDG+@yh!=KheOrx}+DzSvsYyiT^WQ7_ zv-9!QX&$g-D`oSk+H3jQGpICQzsiSGNNy~?JcY7`s# zp0>03?HkK}YQ^ro1;$tgYSZ47M+FFL888Y_9<0jzCg~;5>2}QrmWD>ZUih2pY@fPr=@e%#3JvIu}_U{coI?u+VCx#<`!lYOgvplH&2QiWA7emvz}RQLsI z?Bd|-X7}Dv)xk!``P`zl#hKLjHp#d>)hc%{vzXx(sJd((_wGfHlyAzL4HdbCzFO|z zU1Btl4Cfp_sy)M~5|(-t?px#Y^W3lbu1@$zM%J(CB+zJmda55ToiqFNda1kCohEwO z=C>{1^%~wua;1B1F6|xI8BKFLtrT~@r8#}NcX@MjsV5!lFh*v=b{_et>+|0WZA--F z9SC*jYS+%Jy&|~BNtV?Ndp0F@z>DuQ^OL2Zfzq(p&85R&?%j=jf0vC#9wCY;rSvR# z&{Zo0rhR%c{WaM-#zzfS(2nXsP@b5Pn!oGLTJe|K#RxTVE|RqmKJ{|l7o@rMw{aMe zkK5kxTf0Y`d$Ji?HH2}}8V6G4U=?oI_$l86D zHpzpYaAb4Y;cY%RIC%biAx!fbdmnt_&h&$}|L}=gVSq|u@jBf@0^fiAl>1KMk8F&- zhR{ql{rh14-+ZgTs^^&N>Z4{)b*C6ko4TWdJ0yN|E0=v8VGv;|;um?9KD6*h&2$kJ zBHH74M79qT)ji&;MMS-Ro$>+`5%}L;uUTq6W$6*U+QyY{*tX|C7vwM&yTATbGxHuQ z|8tk)3*A}aYyQA#mY(t=7GQUExXn)(75U7NWtCz%;uRSI!?~w5=X5#>M2U+IQ0JTQ zI#4=J|Lu<)z&hYpuivlv@4vz)(2oaLAPNLJQK@cVQ=v=xduz`zRs(NA+_-?j1V6r^ zUq=4wN#=<_gP#`s9w_0<_irNx6O5jmBk(=v^-j1ZXPrpvY}G7|C&vxd%cp#(J|`Fl zGnv8L;aBwk-LLznm21dG5Jp}}r|-!S-@|@Gc(%4r^N3H$P@mI+D_7(ErdQwOP(Hft zZpcgXOik&pCv(})i;9WKy2RE>^X;#-u(m5?sj^?W@_otUu)ItKH>~t~qqbB4Tev?K z(Jd>ru_$u^$6JY^wP=gOrL0q*yMU?*CKPrJ_!W|koWY}T{r;S$q9tvJ;?=8HR$I&3 zg_VgLH!5ts9tQNBTI_^n47i`P(^)PGHOM57;cKYr@vRhqTbQj{Qz z-S-Vep5q2hcoDfWo$9yo1SW4{HU@m(M~hS067Su5qr(R|%mi|8XJvA$_kSn5juVdYZQ}|oZ=%F*|z<`mCv9|hmI2_7!nflqcp#u*}pL9 zGzBiE;4^{lE86{28V60E2Zc9gdovRf_ys*1f++bs4qOf7Z4(f6t}oh^k9B_44rSkj+;z+q{0Bu87&)|PFKKYFC1qJqm| zF*!9=I*vPvlMXiZI)7axvo0aMvW&XAgdqu!Gn-A93OWv{kf71D2&LOvR`F<={lZ{< z0NKx%9QHYcd;Ph(Kh>M!1pRPhIc=r`$Zmi6R@${?rE%x^a)!s=FOd+Q7m3E*@AwY) zSSj1Ehh%ZbixwJ{c=c=YP21BiS^wyuI%v%Ay2UssjKxiOvX@Rb$9oxRPA;v`soFe; zN80WCe4u9rE=9fS&UWouvI5^~MCsNwy=4Y#YikzsdHcm-r~Mtf(Ng#Qoofiaju(^{ zFV@8B*pnNyS~dSR>}GB)PXcc1Yd+`~pph2^o6|PM_4EPb)JD{i^Rb-kin7rGBl$v94XtztWSX7Qs1GXnNaeWfG|G6zW>oE)Zih7YKvV$$~T`+RZ8U=K!0mTMHDy(6Ew8pK@_)0B^4o+xh|LBd^3 z`%Tkh|Mg4xRH?_QESxvrOX@iFQm^7hUP)}8p=dr8ewNaDdquz3N-cyDTlx7$Ow&Wm zgojzG;T#CWmmrwQn@7`_rCK;x<-wPq-VV$0gGS|DcubEc>X{9-v@V-_VPawVVUyI* z$hO_z9kiS4>y&!t=H$mI@{;)RDGj`n2TalnR4s+7e+$KFY78R&Pe5~-t6<1xV zTcd9u{!ERJ48^xQ*mE)%!oW$y)~s@mZL4WFI$0VdOjF(-ZjX%75T1J&;e4sz_3tmR zvl@3LZ;pAy5A^uWdwP0O@Hj8K#FLPa1dy^PN%jtx+W3%$hlUDveP38;C3wn-g^6i| z|0YAfIb0-&Vk%b5ff6^M!JjQuVGsXSdM*+{SeIA-PLvDY)g^QmR_!<3#?uSl{{~U9G>kAPsJNt7&8j! z5}Z*i`Y%#iORUCg1`ADpN(ObEMIb^hD{G9Lrqzk&Fpq4F(5jZ9Zg`DN$*aB)a&~ZK zdU{%QFlK&!zQ4bpS+`z!cMqD=u+PEWnJ)nrgNv8$SXG}wA^a3N@!*|g^gDYoG<`3Q zzVM*Ly_pQH=sqZLsg3>({UQ`1oA= z;B^M?*3FwbSGG-WfI%O$kCZzQ-BSNz#xV|Hnv1UrPM2 zU{;1$)8{}Lx|@Ln_fOX!;k$iJV|CA4!VbtO27UDYJpWENBJpIz&ANqqK$4nzlJX;id2w;o-A3uJ~ zea#MC{i^8^@a);;x7xM7dZ7Xb%gf6yn~TA2Q%$dXdU~p>tK)cFG%B56w^G}#$QS}L z)2+ugaH0NdY=AvCh|IOMsf=l8`@Yxt_nK38cO(izA$6Ll$6+bS2>xiGr`Pe(31Gsf zPoG*iVY)ZOSj??7ou)2MzgI}dH+PC^rOMSqkGF#17R+7u(sN(?(W%#g{qyHfy;p}R z5gIxp)Dn@eA|f1S+Q?1ba69GshPFxszXZY6iJPz->#dINZ;*Zrv2(MHj5h}gO_f42 z+hVywvn)8GjDlRITS!8;qh-S5=SDxeMRVon<;ls(eMva$usGZp^O{bH+IVvRxmvMB zXJ6ES>->jD<@a9_3*1*#9fVra*q?9MzS_BQ%$=Ak(od`BA-uG!ZdT8rO2t>|#XTb&igXL|g!m}L6uAQ7moo{7b*#hm_{PA(S zcF-ubzJB?#=NpsW47=57Nzhe-l-y29vJ4a$%Nwlb7KmGPCe>BCY}VA)4j6V$K7aNs zA=aVR7iarx{{G&c`(exA%k1oI-%zuz6+n-nG}0`1h-wnp?Kys$?%OGHDGv(7c&xs8 zmMx%YYirMI%)>$~(I_(gYOyles8(dw*xWoJH64HFu@1N-r89+JHHOL^7(I+wEX|?G z+8NL_;F7YXK`%1HYb9pVLYO}_=4<64z;?NvAoL?Ss)l@`W_nwKab3Qo|!GES&sa zB=AzHvF}SFP1oQ<(h%$U>DK6<<4;dxl^E{ttWV0eap-);;OOm25x;QZ0(*>^!Ju5R z*}%&3c&#fs!V_3C+^z_Plee37v+O1lol(TCM@A8)VBw5X0Zx^Ddw(*9%i)7{&%yrg z&%{~zF;>I2H9$!B14sn~1oU#any{z(LqhPO@#!`MK5hrx4wDWG(QLE+s}v_uqi-WWuJ1?hO++}zxOfq_|${TsJ##qqk8`5ks;c^eV<(j2X5 zWQi5%>~go=S{^@t{(NF$qO7c}l%nR9%a;=X3M+k3m%WWB)=?p@*6RnB3NQDR6Bbt+ zEixbSjWizn=oU&X8I$#qUp42=*`v-!hKgOiB-~tFA>sTSa00&@&!zVUe<Rqj2l6O|ii*uoyRkIJ zr}Oz4{0Gq8&&Nl=>-b+h5g(~=ad1*_nAwOC30%N33leaC!K#Sacd14o@PtmNZkS5J ztu1k7{(DXI*zL#U7Rgt$ozW6-UJzoOba1#2#0$b_|GQt+PCoo!cr<_sMA+Hi*5N;i z?|*NR+MN`f*4M6IPXR#5ZrXQ=NsHgz{bQM5t)tWa7*-9o2$f~!T}z9Ersi0NVkQNjdkoiY^Fbk+ zL4c5(GNu#t0o#IVIoO53A#G)Ers8XBBaW1S-itr)9CZZ@|BWcaI4Y9x zK|8#C3|!oY}+Du<2;0Ixsw)7i6Uq0v6%T)=prkl-m4@$M!qEiFC$wa4V# zj#jd==S}r3&uh4?_X_(H{-V;YfB8Hph?2{mep6;Hj8=XNIgHmj3I1}NuQ9ODj+gWY z(T3pVD<~cJ%Z;)%tE5betE#HX1o-F+1%#u>*<=E)<4_07JDX8)ag_r~GRdx+EMl^o z?a8h>Q2kj7ouS?ePMgMw!GTqYJDk&jx z?GvoLN64nwh20#%n98sYirwR1--Q?T_(%q88E~ZD-Vcae1<5o$J^jg(Cp<1270&A! zCKw{S>NuoqT9k(rFa;bO;hZOIU-P4DDbxtS9&hRLbTdjy?liZr#=EYFg?>+39IK)v zCzrHz`?5WkU3Fhb=v5~W;XKLdVxjTzaj37XDy4dfp?-Hw``(kV8ZfzxRyf%j18{!J z#7%PiT(c!$N|Cyc5dj0ket}i!D*^(7v>}Oi$;C-y-;goxg1yw*Jpc;)f&wPC*nA5>h%t&!^q_oLE1dsSZX&% zc<3D;Gy<=DcK+%YQE~Ah*din@8}r&k;sdU(rtP|p9;(5yvoNH&+!aaNpNuRgYj!oR9@as#-3hm$|xKU=Mg(? zY}&@xLA|%PS3&V@Zmv0|iRxz1vih|G6cm&mh0KQxgTt(;#l^RkB=f}dB@M<4bThWL z9D7ANu7yfQbLewWikD9kGN=wi>*eN-scfc_77{wOPytquBVggD zy8Sbuc^nVL>iVn_HG=oDSS zySXC!1=WLB7+6@kU1>s`pY;xSC=YP?9dG>s12lK;L}pUQ`i%JV*v%49>hCIKS8faf zblw&Wbu!)EnagHX`U86=X z-EcH|8~&mHcd`J^m}j2k;72*H@YuS)*B@?|^V7!wnh~?0P+^ zlw^H<{Z8RuF7-7w=fT$C@F~!1#9uV-&FBRP5XA%C92BEY6=-I4A_KgNQ2uD?{6jBK z)DdY;R{17hDtB5na4ymMgu19w<<8?2mVcH}<%b??cX%0a=RJ3hM+#uhM&Wq+cWQbb zx6Ya*_*5ehi=Z?J3JSuR=e z(Akr=q9k<&fIW~F0?OfS+DMm}#%l*~q6P&mA>lGhzaiQQrtz>}iV;}Sg2frO?-N09 zyAlOkPpX|h|7Q}Ld%UtTarH6L_}yy*uwFb&r(3aE9OgVov8ca2<_b8DET!Q-eQF5i z-~kZxj7mH!0d3;*$D*_*!8IVW1&;+fNku*V{ryv=M%I5!++S&U>CIb(KC;3`fenpeKrz&Hv_4H_DB$ zu&_YRb{VfZZRbV7@0pU)QnM^^BD)_i98%%v&`?&bYEMu)=I71qqNU(u^NB$2PgnHRR>Y3z#D8L zw*vh=W@m)%GT+~j;4y@iB{Y|kk}@&5S$<|1*0WI#jaRS4u}BVAJSE(G`}3_WLbg|g z%{2(>TBLJ9RgEyZ$YB2L4DO|8ZaIcYvcz#OkNP>hzUh`~>cMsT%MAL2zJ@1`%m2sy zk~C2QBBHPFRl1v-JC!gGxw>HDdENK!Y+4Q$Jf}tqfSWRO>*ILl0>p70jm!9ni^*c8 zJ4^k!SFc|eo}&MX9Rq!MV{xQhwb0~03LB4JjRJk`7EX^rgb~?kqaeas;`zpK-SVzM zQ6}k5mDVgUI=>l2!b;7{>kiZzqyzbP62C8)UK7rHuZf+BifSAf(oMrs11)H5uYPnX z{EzZR23D6ibH`toy93PF7#xLLs4a$DzX94lw4ZqQ9oqd#3X^@P{s2wS`O?^CkNG9>{@Twe^ z;;bl4rQBy#V97=@3r;0(o|~5+0F+i&U(b@7fp_)x?c2=EonvEsY;0j4VmVn^S&eN} z(&bVbC|t~dDYejYzs;Eefgbuw`#j)8(1vp1$-w{3uwqExe93w1Rv>S`gP~89Wkexq?8nHUfzT1CunB+O1Gm)K>uB+e(~Z3I2)gLB_f%q z7#V}?+X1{CA+RZI7+#7w2}!abXu{MJuaz_s+fD=z?^TRgGwT<6!zGVfYGXemaaw9# z&l9Q7TsL-^L}yu8SROoh@bJCzCq7mh$ww8A%nR(d&HDKV>tkwIF8Es$0&%lxJ%R8R-HqABkl5 zl?w`#X|7+7qL}~C(`rytQv=*jayolsnRk8eYwE?Am(XN^vooh!`+~C+K+OE~WkEqf zmRfO0F8Ek8@g8y5D{$pty9;esZM!DH@<}%ODT%hqM8lewm)Gx*0Paqi&5YEjz<@{{ zkZ>n?YwH!8b{-M5fuay9coP3abqaSMU78Z}VFtn*^@wW*1epRm0}jeeU1t?-494(L zJ5cU^`BC^RuV3NA_sw$0xf2KqttSUOkkb+N*3^RG1N>>MgFJlS>yuZ<<(d} z&lZ~tu%KmH*G__wNUPaD#Xkv991rIBoUl76(-rUUJpDcNDJ*7@ky^bBrECgg&&Itu z<_a`(|EQK5vN)7%Mlx0I`(afv&@vE%DV@GSF39!5#>olwNHFw9?6Aex40v+%k-p0E83w4$gTM&%q&m%eOG>A36S;Z{Lb z6p5j+Z#GzI0TeWzQ9VY2qfmE&)!ZFi&RtSwPF;Rk6L;d{ z05#z;A7sOH?@5z&bsra#Oo|++w71_rMZ)-T>&hYfwJGJwuIAJIdXIB$WnsCxGesFD z?mGvA1%ABxkq&+5t--OWuP+eYqaQ$Ifu0Hw{2QexAprsCSyw@*>zjl9%3`RhstQi- z7XKji&h9SIU`A>!6}+F>|Q&4Jv}y)o@e$? zfX+`za&mHl?UR~$mGhduzSKC04-bvxo3(@8CD!QAd9cUW_*JU$6z)QG8gbG4;68PD8%Ek z6Ik%nl5f%~Z;gY!0Sho-&=k$$d z%I=^*C~3N}v$HFX(4VQRtAoxnQ&m0dY^3H2EW1$YLUF@;oJY9k!M&rHpF*ySgG@Qs zlim%<0l>)vc~t23NVMe+Ec9(s66g>;xw;MT8JW>jmydOrgx+x{dbyb%bt zL>%V*m(QOMRJs%k5IG%X9Io$W{EkxuF}#H71dT5!(-Mr^)oG-0-(p{V0`B-bQJLdZ zh}GQy;)~x0xm!8%cho=we@v~uLiM*Qc}i41fdQB`o*$=5qA-u`Hv^=cjbd=kWNN$ z>dcwUM;uz^2qGl-px|{aNls1%1sLeWiM=9WYB^Gt67#C&gIo$G$b%#~>nXShnU&eh z?2sJTE@@;0{kKvcm{GF-n{G5CD=A7UG5CHBjIXCzjCMoEx(V1xAg^9Ks|Mr~TF)@B z5!0_9((iI_b!;AL=#-Y0LS2Wj6zHjdK@8eJeCw(Kt%GNyUl-`p1X>jHu{vY4cH*4) zp|ZZ_<%)mxmR!*b9Vd{IPpTePv5v0p_6@whT&9OrEaW0bVr2li@KCAE3;+myL&GXC z_L2>=D^^~Vi5O2^z5aH=T1>3*#YMU;k?!Ple=>!?i0AU*F9D)l!WCA(ee!ZufI=xD(b5=7vu&l_eyn-)WFfm?k+7$a?4#fAhmpSr zY{NtBRqji)FENj)!K~7|2~o#jgwcd(CkX3LlIiH_B}Qaax4}XFD@2e^kPGe$4-e0^ zYu-G`4+n!j015fytO&^wIqH)Mz}{@NI_ z>{dDQLE@g1`;4DGp`K{p&h9PO;w66q1qm2JB$GDkf@Cj`#Jhq5HaRW>!{b)M(S&Rz zauK1SNV;ulX(`8b>qUj#u}MM7BRO4lrmNUe^99w78_%$vzeIpPl8<~`G!r_1qD$CCsC?zf>;p8=iv^|*UZe!-oB`; z^r@V>I=9=7?E&2v1cC+y1)aYdk8f|ef$xBso12@BjqT>mCYzoJj3ZiK3u~?i2Z4C> zM=7Z=8VE0j3=@?>oYQm^v?j-}9n|ap#xfI=rqnd3D?fuOnfQ?c_aWW`1pWv6F$XZpIqTj$!<=XBKv+9S$Q-mN#~=K3DKEII3Qz&v_xcrwa9dW zc6hW9o~Dr5li`Tlh{!=8ZXv*(Kp;v`fSn^#eNgI;ETVrCEHX#`nZogEyC)tq@LyZpa# z(0E?A6Ay!yx+B2ar*$A#R|I$mm|Kl9#VFqf`d43|R$oAxqk?cQXFA#v>2E`21$%6k zf?D3nDhIkq5uJ*F0Lt@4*bm|l9srX7dxOn!`5S1}eN6=$faaUdf~%^W^57zkaSk~& z^-COrzGXOw_WC}bYWovzB`GO+UAx@zS5le4lLfhq&l|E3{<*%bkCP7CoxXm4XVB3zDlxZGKhA3( zS?E_5UW2>>T1smSg!Phr{+87{!=l^wUWL`5rQ-()5m7{Ze7jj&s5GzfO*i}32s)mc zG*UJrtG%tqEMWE!l94rwJof&y%(<;#}7cwd+XQ2 zfq62(OwHooWJFD{biz{*`53?1Liy^k;|0w-(Odhor+7aCV|vm@8JA=v)az zh+j^rl-bSQmusCrdx09_SRa*m$pA z$|6SUAv#=U=U;arjX}}7RZv2nILb}*o1wPgqEd?7n)ju8pea~;gdBh71Tjn8) z1PbTq*ttJOl>6(uC#3KCugi^zl@mbYzND$-zk{YL*>u#Ps25&?a8?@MlLqbSW7W6j6Mmwl##e|l|WW7_iamju6xDynl(CXSLu`(<{Qjy8WljuBKDQE{WO`=k>0 zVcL3m9+=8OYK&Sst^#m!MFsckD_zLQ1Nb2GRE1#r0(wD1$Cj~YRatXgDEtaiQRX}{ zCJKp-*nvIzjP6{nl7FU$?_st?XKzX=mjE;KAV!IT%4->~YnLzZusat#EMR zXt_f+QUNDS&!K5NOc3w_f@j^0eL}Gk5r+Euis^DbV{b0r7p?#fXB&P*@9?#mT(`j4 z(Qx0MI$Yxr+}3`45};EnG%55rbTu51g2uC)MGP!XFhr!s7J;cnDPmEndVJ%>Nh%A+VvGuodJm7Zad0o(X@ z*6nwQyrkHOs=Dj@Xw56aW6d522!AQGt#45fov>m>4jq|8w?Ie5_B2Fx{Z{zvPFdv zlKPA{9^EVQB{BsdZbR$P)zJY)bs}!(eE!pJkGpkO_-%0Aq2VX{GpH6k3kq^LQn~T} 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%0DY0zn%{ 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 diff --git a/docs/NextCommand.puml b/docs/NextCommand.puml index 985e45bbbe..0ed15eb02d 100644 --- a/docs/NextCommand.puml +++ b/docs/NextCommand.puml @@ -1,20 +1,42 @@ @startuml autonumber +participant ":Main" as Main +participant ":Parser" as Parser +participant ":DayOfWeek" as DayOfWeek +participant ":Timetable" as Timetable +participant ":UI" as UI + + Main -> Parser: (parseCommand("next", userList)) +activate Parser DayOfWeek -> Parser: dayOfWeek Parser -> Parser: capitalizeDay(dayOfWeek) +activate Parser +Parser --> Parser: result +deactivate Parser Parser -> Timetable: getWeeklyTasks(dayOfWeek) -Timetable -> Parser: tasksOfDay +activate Timetable +Timetable --> Parser: tasksOfDay +deactivate Timetable Parser -> Parser: tasksOfDay.size() +activate Parser +Parser --> Parser: result +deactivate Parser alt numOfTasks == 0 Parser -> UI: printNoTasks() + activate UI + UI --> Main: display no text + deactivate UI else loop numOfTasks alt currentTime < task.startTime Parser -> UI: nextTask() + activate UI + + deactivate UI end end end diff --git a/docs/Parse.puml b/docs/Parse.puml index e64e7622f4..5961d48e23 100644 --- a/docs/Parse.puml +++ b/docs/Parse.puml @@ -1,9 +1,9 @@ @startuml -participant UI -participant Parser -participant UserList -participant Timetable -participant InputValidator +participant ":UI" as UI +participant ":Parser" as Parser +participant ":UserList" as UserList +participant ":Timetable" as Timetable +participant ":InputValidator" as InputValidator UI -> Parser: parseCommand(command, userList) activate Parser diff --git a/docs/changeTaskTimingClassDiagram.puml b/docs/changeTaskTimingClassDiagram.puml index 80d572dc30..4c7c546cb0 100644 --- a/docs/changeTaskTimingClassDiagram.puml +++ b/docs/changeTaskTimingClassDiagram.puml @@ -32,20 +32,20 @@ InputValidator "1" --> "0..1" InvalidFormatException UserList "1" --> "1" User User "1" --> "1" Timetable -Caller "1" --> "1" InputValidator: <> -Caller "1" --> "1" UserList: <> -Caller "1" --> "1" System: <> -UserList "1" --> "1" System: <> -InputValidator "1" --> "1" InvalidDayException: <> -InputValidator "1" --> "1" IndexOutOfBoundsException: <> -InputValidator "1" --> "1" IllegalArgumentException: <> -InputValidator "1" --> "1" LocalTime: <> -Method "1" --> "1" InputValidator: <> -Method "1" --> "1" UserList: <> -Method "1" --> "1" User: <> -Method "1" --> "1" Timetable: <> -Method "1" --> "1" System: <> -Timetable "1" --> "0..1" LocalTime: <> -Timetable "1" --> "0..1" IndexOutOfBoundsException: <> -Timetable "1" --> "0..1" IllegalArgumentException: <> +Caller "1" --> "1" InputValidator: use +Caller "1" --> "1" UserList: use +Caller "1" --> "1" System: use +UserList "1" --> "1" System: use +InputValidator "1" --> "1" InvalidDayException: use +InputValidator "1" --> "1" IndexOutOfBoundsException: use +InputValidator "1" --> "1" IllegalArgumentException: use +InputValidator "1" --> "1" LocalTime: use +Method "1" --> "1" InputValidator: use +Method "1" --> "1" UserList: use +Method "1" --> "1" User: use +Method "1" --> "1" Timetable: use +Method "1" --> "1" System: use +Timetable "1" --> "0..1" LocalTime: use +Timetable "1" --> "0..1" IndexOutOfBoundsException: use +Timetable "1" --> "0..1" IllegalArgumentException: use @enduml \ No newline at end of file diff --git a/docs/changeTaskType.puml b/docs/changeTaskType.puml index 9fee949adb..a4d66c246b 100644 --- a/docs/changeTaskType.puml +++ b/docs/changeTaskType.puml @@ -1,15 +1,27 @@ @startuml -participant Parser -participant Timetable -participant Task +participant ":Parser" as Parser +participant ":Timetable" as Timetable +participant ":Task" as Task Parser -> Timetable: changeTaskType(dayOfWeek, index, newType) activate Timetable Timetable -> Timetable: capitalizeDay(dayOfWeek) +activate Timetable +Timetable --> Timetable: result +deactivate Timetable Timetable -> Timetable: getTasks(dayOfWeek) +activate Timetable +Timetable --> Timetable: result +deactivate Timetable + activate Task Timetable -> Task: getTask(index) Task -> Task: setType(newType) +activate Task +Task --> Task: result +deactivate Task + + Task -->Timetable Timetable --> Parser: deactivate Task diff --git a/docs/diagram/NextCommand.png b/docs/diagram/NextCommand.png new file mode 100644 index 0000000000000000000000000000000000000000..ea24d77fd931ad4a26d4d029c6088948b3027f44 GIT binary patch literal 43238 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 F{{=war`rGk literal 0 HcmV?d00001 diff --git a/docs/diagram/Parse.png b/docs/diagram/Parse.png index b12766f59b34f7ced9c59e978fa67cd7fc3f893d..9658e89108e63706411a7a905bacf76e1ce062ea 100644 GIT binary patch literal 53031 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

avPrLIlUhqH{Q;No10riE?U4e#amxr-_^Bf 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

P1CR6w(}}D1B)dj%2=Sn^C3@AdF$V z){g%}7c*JNKTOS60@^2pLXL8KXyOIv3Zc!-t;LJc*)+xMM|#V;6&I@NRZE6n6vh8r z|Jms>7{A^jvoh@uNcL=_dm0(^WMq_jlKn!8lS)f_i>(EfXD;*8yKAX@@Ji~&4*5GN zvlH&w1Q97eEGtk5N<=BO)S;1w!a5=&uO;zMBE@RyDJRoo+Ypur>A0~1)-y@?&R>8G zxiw9{)g~a7_lbJ`br}N9Hptgv8t(7+i2ha;lsh;ov;(yb#mC{ASf%zWhY)@9Sq{Lz z`ss>iFjBey_Th9&pEzfVCB-_U*r z)ezP+_>qeNPYzubXHft;CK-`L_Mr4M-gS_?Aff9pqnK|>$KQ^XX0hjt4L^SB0$Bz_ z%t2)%%l}-TxGf^oA^Xennl}dlDgPCV>YVPYkU8BvSfGoA5q z2=SjzK(B*s`<4|9YIo8;FYbbHTR8vgw`!$d0(Of=e@xS>v52H06EL2k#~mI0p5s8^ z6EYrwC?giiukdUhT}&>HF9iELEkU-;{YsncjEqkJG84YmS-m~Feb3psOg0M9U?|`y zTk$&p0@bB5n0$bqgO|G*ZQo~|9{G1eXfCVq&$`Y>}t)H_Y7@=JX z21~g<7$3S$MHhUSY>NF;);r&-6wWL9>3bl-%SYU$9NU0fJU~0FhuR6C7&@&@yRmzw zIyLXkFF3_FuXTC9NVub0;0)F??@<~CE{t1mLUG=aa8T;ug;J(D>*E!3qn64@gk?#N z?)dopz)@}BE6tM)$MEb+ICo?;O+aTE&q0oI6B)MXdP;j zKjy@s_D4w`$^e$4F4FyRp+0CmU?>%#QD-Os#_t(3aa5S6W%b3iv?SD^aDTSU}Gjk|8m(_VdH9 z+mL%lr{Hp%g!h6Sd&bfdr#l1GJ{r2a5r=z_pWTU_kAHAoSuI>svQvyi^fNv7Wq!$; zRkuL-kS5T(!mJPMH=-{tb2OTb)}H-{kx`ir&*!Ke)sq)nkZgx*JMH!Dj0*-sF(;1Y z!h|Xp)8kCDCOTs|x4@h?qNLu4{RO1W2&sr5ZK2xo9yaTd8^U}P*&v)uScFmhIQ*TU z>OhQt-|pcu)4we_4=~>)|HlTNPZIDM!d*%CtyBNI`}qG?0Fm+$D`5jGDbOhP+x4sL zeFGVfjgMD%F1FZ0*UaWQ3Om=(&6IDR@dXYn@ic?(c3-k2xJ8#&R1EP#j3=1T@dHo= zWHX#lpZwmqR3dI=djqYamcZ*Z(-pj~Z$<+JG0kb2ff%1Yur&rDk8V6IGQ?dk`~3{O zJC7K`XJ%!~B`jKbwMs;UHz_G;c8V(1bu4%xzpn1;=E;pR5s|EcZ{Hdk8*?9}NxyvJ zo6etaeYVYX;hM{VJQlwJdD;%-0SFz?#-&#O2;aH&U;lCG0XG#$&Od08?UW-^KO{^E S`Y}}p-wkw(wQDqQNB#>J3J*sB literal 45389 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

5)R zOzM|+v&4K7`)HJmADCYh5=WmT&e-NC)$&f zlbPZWL06_bioCb$86qL8Vg&dGpOrIij;n+`NbTqC9UmrrmRhv~gokLGsW-NBMe>ER zQDzk$*ewCr5H&xJN7-Jp8MXONvnOck;84sM9Tt|vF#N{uL+h=tukWyu!%G8zu_6P) zQX&MpN1xnIX=!NrM{o3s_2T zrea|}B_*YM_wd?OOC0Pw(p6n)r){p`P0i-^zg}PIP{(HqrP^8kDslYed6V_|2h2JN zt8@K(AV}i{?QwOy%;_t#o$LK5Um@!~1(3~Eua?=FRm^a8@~coWkgEHr$hb6EKYPON z4WNG!5fMP?I90+Fm>3vUJ_P3o2)ZEQ+;%_hIkLVm{OQvtIJ3?9raBv{O0|{V__YFo zN(u@uATyfVE>Dn^B$7>eDJUgtRQpM7x5=w}hSde1g#e=V>bfDoFoC^v#SemGJ9GK% zS)X6B>JOH?lJ^0cZ8PkAH<+nauNhwYGVyw4ZVFJI7j8d;Z)sT1x%m{^^_dTiMkPBI z$Otg`m5Po|ADEA(>k6UwpJ~9XAuQdQ2pJL!ydZZjxMMv<%WnUmBO$Rtl4%52S;BEs zWSPlS6=GHmrOy=&avOJzy`d+K}ku;&i?YkI5KY!_B>m`R|8Zubc+Y}CAeK-&!2-lNXmnc%p$x% zSK)vnpGp6mK^c#Ts3%SUbC$@Nef{r;!~{e}M!tBVYX=GT;LAUWH_-s{Eh(nozun~7 z>&JFrv}!}SuZ|Ye{kVa7pV*6al%ATu=pyeNK5trVZb_PgB_+f_lL*BPaMuoykZ|;MVt#pu*cMEG&pUr*E!z2nY{X zOuhH^IEmdmLEjjL9@FtJwKqIIzdQnqIfeMO$?vx~#vY=umD-}KtyIDV1TFv<-*&Pk z5pE*TUBivV(al@9*m!t3TJ_I?)J(e4HUZVQujBsbwY5iPm_I1K1Gd-N?5*b4kN)^V zEP=$2EQMT{VkC}pK5{%O{1uzAS4>RIeJGefv;=Cnyw>l?6r|aFFHNEO^&O%GwU`=o zetK^PrL1JzweRFGW%J-CzzYiC5W^8wjO>I92;iKb|LAB(nqs`ZOix<0YKjGN<&Qhr z<2vb8A4oO(*8n+h0l41Y-rg%+Pg+`9`s|iI1K-F1wYx5ahFqjdf2#FO$Tx@`)=c5o zjsYz$G8uI7paQO}gCtPR@zr8XMP^WnFh^G5ZYs3yy&npC1;-#0qAt0kEkoJvr{3EV%U6l+nRvIIp>8(eO(#HSVZJ0lAgC`d;VtRk$1P(~1dJq$Qu*d_p$$q%%6vl-5u(DIP z0zpkb>-0lx-Qn%+ZIF9jCnRJU^>+XJ<0}7?9=Q}7#tGios>cw^&9~!w~nR^P%Qv;-BWJcYWE;?>M4wNNiqMWDl^YW_u z{F#BCKH|pXIB_>u*GMkgd-5#@>xYEVo&>f98r&);00@#Of#2f6bSIXM6T!S}+nzWC?X&lv+Hg@b(c>Qw+xLA5X*nJ}}EvO0q5SnqIdW1mw12fmoHwt0Fuzb zi++EsTqf}MwE}r>0Bw%UNAJOd!3?Nne~IJ}5)y*C6ro_#H6PPhS9xN@svIJP_=kvD zIKcJn-sjp{0yZNR0|WZ}QYdIb20tO#B)%O@BjoZAr&fBD$aw_Sn2w5u20ms-8$n}V zr+6p`qTat`g~g`_`p7${vvu^U1tAW+2@2aUJUXAP=Xhz0MgxkELH!Y!9xHEbxqvv^ zTFlh>R+-ICt789o5U-suegyUX(Lu(>j>ey9iajzDQ@hS11AB7*AZiK972olg!+z!S zm@#Yq$7cNwkv=bjgO@rr{0DpazW%jNkYg&Tic#L7A(tI%w;%f)G93QBHb*mlgvtN^ ze`hI-`E_(~U!3?e1n#3l_gec)#2X0|L_=k9 z{e0^i8KshHYrZG4tnd<8@26IPz_T4P9x~kk334N6sFo@^!AK&KedP{ zE4aL@gNxyWY(^2>XoxHL9E_iUL>(JKt5vl(rsLk8zdf}|vbQd@V}+PMvTLgSD@XZl zT*^gsB0t}u?ntb5#t8$NNe>p+iJ0UT;>Jl1Mx?Ax>-H-ZnIrr*u&@yCm@HJ>U=?If z9-i~}1ooo)zE76Bnj{sOs5b>C(7dJI+^s7w*4wB%j{g{sVe@RU)blkXajBTh8o@&4 zl`i@VZsr5~Ij=NQp%N2dl3}S6N}tV@6AhSCAKK%kchZz|jiB0|*)MB7tupw*KymbO@q z$<)N+;{}iN3##@bp65ok;u>Aj!;H#CR`;y20@)P%+IZrhhJm26A%TqN=M;&J2hW!E9_PB`t( z0?yQW*1Pf9*kK7MPdjxkekO(%AbF-Cz;hRGm^h&>671rTvMjsvY!5EB;O$fA9+Qd3Vp zLyZALa*=0miH9cUA;5l|CW6r}Edu8S`emld{QUf$T;rqxKaTGK*?l(C44YxveD}hF zJoeTc_riv5nvO||JG>XPHWolB&}|jL5cIz|`@l9?peGOe#>wf@{RqzCpi7K!e^8Aq z-OTiUTmx`l3|L6@qlHv2GM~a~Xk0L(l!y}dZH%}n!*jl0H+lzj$ArAJH1QPVRyB-1 zq1J6r3r~A83%&`!A9-0>vQ@h{;77Yg5C-bfREp$#kZo%;Wo2>DE?>SZpRN*Ei@4$^ zmL>m|_dn|UYH3mz^i)lRp^@EyVGxy^8^O~)jnJb@0?DFv|o->&I^9JNtlANK$XL)=(@&KP&=kqIvy^rXSq_Aua&G0 z8P6KT9`RS#87L{;nBhJKW$WIB?8&}aM&8+F44vij*3~|AYI1C``e5kxyEbST;s6oA@k9tEsM|YasnSjrK?StdDyvI1+ z5*NJs6S;TShgs_!!wU4;XffdaCZ_IBg1&FQ=e>q|1GTqje^okzkaA4s`RYVY)kK?> zp8nnITwJP@B=*Zv7|-p4E7y<+EX&lGEBY$pRgDr>i+m5|#ZpXxz^bCg&jt zYFm|gc%Y{|$-J;2j%%&{_#JvDx=ms9PLf14^5g+?4Gs#bu%!3$@}j&OL0!zj42T#M zAyr(hG;zJ*+DzN@#1{Jail`As1x@*9ov73zLje+%nSg}rCR*&T_1#$#S}V`c_$}EKVZF9 z!a@4B#vH#hjm+yN&*aqBV)xltJdI(c3v*Wtj_#+wne{WMr4KqEBYEEN&`@$6@G&*J z1p(xo4C(vu*d4alOH$-~Q_k~A2sAp}N9xZRMXQ90bPGkj0R5)KUI;&WM3Y|tQ3~k< z097ko_@36?jRHT*^VePWIg!P76FcJcCqHCqG|ytT8%kE!_1ndZ{Vy+eTUC1DLh!Wg zw_k(TIMWjHHTpO15*Cx}@m9|{tbK$+-B*fspdyeR070p*To!*;AO!&&MEIs6s$die zU01fJ!^CdBKeNe;L9{!srv%R+hz}?8ymLv`eCPSjU>qi3CR8XkWmM62i?^rAc4Myj zkfO8y@tt5qQH+)|_R&}*z52=Ue$D1xi<;!_LLbjP-`ZfRX&E_6Ha7WwRfG%5ugo}w zm|3r;|8ZPGS6%8bQ0`ZIqp4sX`oKN|gXO1vOZ+F=IH0R=VOqM&{=gUq_;UYCk-$Oy zKrl{sJv7374my)}GPM26Ng&$3zq30EqBN5F?>9l&_-;u1>A%^j36-e+@t-{XqSBoL zUT-vS$;szZw@Sh2Wx={u+5*{K{29t89^A%FPfqC^z`}`a60>Dy-ksHQMZ6mZ zVMc!tu+1X%Dc=NI+P^p{_G4G`r(&f^8nm>R9T?BEa&UZv2(g(a7pO7UU&3=IwLt?Z zC%hkKmQ~`YJWVHc4;{gwMn9l*9&2zR76=CtUL8m4ci3X6#DSVB6(lxt2#xGEpf$z4 zuuHBdWnwa}2_S=j><9rxvqd2nS?2`~MMFa)B_#!_6$2w9UM&C*k{c$x6)woM<3wA$ z)@KXe&C{5eJ(*hG!i0_FqUk^D%NrXTmVMSbOJkp5*~{1XNbAuk^ zf3%##6H$D;yS>rKvsdV09^_x($pFGi&ZhF!fhBIV!tj(UD9sTMcR&G_4 zf|}Ox-xcx}wPXxTY9`mkmvqKHNVK)3|8SpELY_FdMWVS>QYny`nmgZX&y%#q zw?(`aotuCoeFV;&J13){FtPAGArlLAnC58rxl_dKX3G=J9G2fH+-WfbHX&62q*E`B ze-oO;lxxt%Y|we-r8o8^LCH&*4WPnvjm}N=-t(&#;yDn|_XYPYQV)NBe0d)q)%}9H z_w7^C;yQuWJeb0?g=2L@PYsMfR2G;iE5>j_d$)f(b|@1C6v-gmflEax#7H7eR!mfs zT3ty=)ZgR*{o>Nn_?Jkr_IIEpbte@wCM$lR>_WwW#7h}$ry2(-fz=@aAP{*MoZ(OI zSoO>!m;kn!9vZ6dHIffQVFhrPRUyZlnWwxx9@W*JHQ}cSuX)f4^7D_3jd@YL8Lsw+ zqrU^5h+VloA(5@12o+6DO(+|KRZTQZ^?B??o4U8>R}>pUGNaA9T=|wm{J-dOy?K6~ zc_-DrM`BCgQc5P#tOb;hFnW{O!_)Jo^&$ltNHIYo#p%hHeO#W0v*_rRa0CSg zHkUX$V$<~sy6OZzh9XLBffO&^ogPySlB3;%oZNRQNUoV9SV1x#fQM^!3G^!wi}<=qt<@re*TG zevdNyJzPvNT4SHWLe9nF%qs}QQKy#fNlOKW{kfhFWKE{=$LR;Jk1{!m)Pl-bd$LIUuyde7oMx*F!dsE;n%9dIO)V`cX9%p8v)ytOj}jJ_ zT>N=<^ZuIq$*B+9MmJ#QZhy}lH+p(=Dm9~`9CwSC`Cnh9FIzyllKJqdwjP1!t4LF+sf=ST_)p^JJ0;o?b z#HkB{JGr?HWknUdW6+c&sl>5!I#oas1)(zxbr!3(E`=$}5I|UwtDj6SK2_J$_7YzL zj+x%56vb_ibOS-59w8eJ+AyTryLKX97O3C;MivWaqP%2MvG(1)+!6gpA`n2?+@?@g0sn7+i(rnAJY$`3uSHtGzL|Ev{U>`W`kr%Q=81A^PS< z?ul6>Li(oEzRK`kBYr@YJ%=MfG*SZ3tqp zclbf20*Yk(=gUC+3&J!26<$f{<@U#AR0oYgIq#S(i+u@-N&A-s<%CoTD=I6qb(?Q( zf!*L=KZmyviam_1vG}^mGq@a}%90n>zm%)9d&n}%!E0bfc2xwO=zmVA)b8iE!w1n8 z*t7s#;$pJH*xoHOh#kkb~P?R+0^H;ENGm9po$ z!}JJM?ZfV+&0C=(NJZgI7}LhVZaxkZfdo9Ci}lBr@CvWBrSS042_R7}v-JICIDdP) zI|Z5u9U5wC(mkO&P^Q4a!wYKM>S}bbSQrwBg+OoEl{p%&6J6S%+>q!%A@epOM>J7g*6IrkP({<_< zcPEKzS{q)0gUPr&w4+)Dy9h5APKh}buXG8v$X-WV)U z`;S*U+4}#V; zAAkR(7>GbPGQ1m*X&`%+4aeu!QJB8zp-g4NCzUfy~uNulQudcs9-_waMJkyK#wVZ$7K=k(FmoHxyzz#uWYI6m8O)P0yHjj1n3BuO4Arb3?ZSe!_JuW-0bhr8$o`s5YkhOq^(xUxXI8lq|f@BX*gkxdX9GgsWSRZu92~Y=P zD+XFCs<|g>9S^8VaW66tR?CQbT;3Wjgo+CiKA3hUGtFkZSEe&cz?w(hsAXWWI8qCt zdO3s%Ws_hGtSze{{&WlscX~p6xVS0H_qz5L>zPI~Jb&Inh>5p133L!Hn7^XT6v8Dt zBL_lr;a-BP#V)`kwW_|jaqxgDWsvsE1lB_BsJ#4^#D@F@%}lw}d&?e)1K>A2apD9y z&6TKIF#>2)Yd#Jb;EWsUq?a^5@ z0ML8Aa}Gjf(a^l(e$mDQwJuosY-LE19A&t^*0X5!QC!KWRv9C`;NW1L&o3{t6iY_c zcg}#)G(YeZ%cjmziW^?@@q2;y5V+1UrqfaxCGS4l`yk=)9s=L5gOya`pG{4N7%=!9 z`$j1>6=k^Nxtfquzq-cDnOo(yxZzGCjG;tO&W5kViW89)n`NhSd`~ z3I4`0zNg2e1Tyb{c1$iptC$EB+FPAauQ^-fE+aE@kdhJH;YW|&(BI}taJsm+=u54| zqYnn1Qx_^V*E##*WmXlfTOh1WI|zy2p6r zWb1=5>#~%1m$Fu-+nl}@zs2oi-3rK4bGdk9jHvDckAsS~T`XtV`>vs(A!MP!T=!ev z)tw6PehKhc1;__?@GGmvM0gN7G;-s{ka@p22$qo@D=o2U2&WIfBbGA-BV&3(0)JR5 zx2P89{Zc0=#T$cz1jsP+8~QHrdn~d=E%HQ>2SX{docDb5b-Ne< zrGx|L5FX1sw8QY^gc&iv^geA6J|cuxF}`{?lD$&>LSRSaGJeT=B}k4s8!a-sZvBos z9gdy~%9iENPC$LcV->5b=?aO>L@dz88lQu!GryEt2xr8mt{)!?v z)Qn;qIHR_8JbD`-@OoMvzg!l%0~CZg@X#qx1NjGGa{X75rwvF*Oa!_g`usUC;=c9o zA=eLAg30G_UrR)D8}}80WgmRM;Stv!wSZ4xf*(rs5_j)D&*pTa%3b6K1PT4;w-pt` z*Ux$iW30H7I81bXNcxUde7?7o$#Fw0B@ZYtEXTEN*eWzkyc&t--<-ng2jz)H4W^P9 zWAYO+mtMFk`WVB-WpCYoFThboP}vfE-UUMQpeWG98{UBf5tM&VaQ#QX9UVslz1Q!; zP4XbP8)9Aby{eGlU-CF|SHht_g@r|>Pd#np!nJj61v(zEua>-@PZ2;O^_7;mzYf8( z86eN1KwzQqAVENqI}{p;TVrp#L#Pn&##>M$7${cfwUZZE)f4F zP?NOLtDO0vRCTqrWITLto6kkg#0ZP7fIaIXyIC^mLC>NlLRxp-Le#+I8BoAa987Xt zcGa{!O;J|5Vx$KW@7>-@#&zl!{HGEsfVp0DSby+@1z9QKE#$b|)P5NgyzOM%Unxn4 zr9WC28d_@^hl;3o)LF%5iHvU3W;iV-EZSC>wLlo~N=S+e*3;1Xp!xAlDb$1pY4%Kc zaDttK&AC!mea}gKn(In>xR`Ns@c`R>Rc8WjigG5c@y3z+sJ{+J%8}%mV$mpL5S>6p z_=*|Jzg3^DHx8XG!RjG+=ZT*(ac|9h*!MWE92pjQE2yWJ!i{Uw!1LxY`F8Zq0mG@- zt}0K(<9jrlryrYk22r-za~$ykaVSo2_sc^H*qZ-@WeIv22ZwTos~g;AIF+i9UjPn4 z;k&uMtqfRhwC(qsyT)f0DK1~GEh(9xstZ=~g(}sAOl#) z_Yn^!Hn0cyB>U4Z?9T3lv4+GaU~7Yu#lX%EEw#^I6YxoF^t;{_7EYE)`Vv5P`))M% z+pyH9H8nL*5v*57!`L=E;^GgkF=!}k)=> z2@c>D7sSy+G@-1{p^Css@7b?+WM3-pyPBonaTm-5M~QaoT1)rW9qhp1i2D6lzxhk# z*p#(YPW`Pb9 zNIdf`pJj#=!B?@TrK|WK+=8Rrzb3gZ_e6YrJeZmu97joJuX26;PYg&;XdU}%iq)&8 zh7ypyWgg(YOd>}z8DPR^`iW7lyBwO~wue=l%pLG?BThe6*WKqdz&v!f;ZP|Y;(##6 zAvpxERCqvEzK~(nZ0CrFL^&CUcG{1oiIDzRb ziu7Lm>)=)@Z)0&S*U@DlX$@LKW1}O0$MJ^nc&4MYNXrLuo57GzNE{UO?L50^?_jL06^# zPV!Jb3?n!q;sQ1{-)E$cm11dWX|8bT%h=~v$Zo#V>el3!{%L%mCsbGp{osL{m^G_VapMdukJY4j2bnzp|_OKwkPVkG@+GuNPW*PQ8 z7txFTAo1dgb0I$NZ>w7(Gz!TGNX2-Ki;9bX%X%auB2t?oms(@wMR7_GEZF!=Y6&v+ zgLD#_NN;5JCAc)Wh%-3ru2p{p1R#0a0l~p6kl-QB10B_l&p&|@st5C;~;XNg-A}L9_M2_B`kJQwApu>rVo<3m! z)b?#pA7laj@5}I`-Ub52&d65@9$#uMWe&&2Yj%4 z8#`_h<(EQ7Tp{S6GOxw4r4+! zwsv2iKWNsPGr1zdAi9_2n`*_FSpqN|%<|``?uHmbzOo08H59p^ec)f#{%}a0@-8ea z1Za6pw`rhV+1RkJa0B*(p?~n4`WM|FHthrg@=wTS3h;(Q6$^|vEVV!MSjkKf8lgk* zZ0)|jngAAWjQCoLZ0eop>*+)J*AL^S+UszA;D}!!B6<}V$Tun={a>z6f5?w`KSg5+ zo%nAd_C%;5=rzOWw%G8IMrX(>9^lvIb3O?E`!XVs8l)L@r*Ut)5j>zXGX_P+?3(^V zHw||U$CMEGx2SSG1r`!^b{eWP5c}-xIDPIX)_|esPe7o!Zy)@ZL-yewFqt`ke0@-H zgStu}Cb*3*`NV{SUGIz2f98aP?3Pf+hI;PoStGh6;PO{o#$*P?CuOd?|L5oTBeeAJ z@USadh@>`{gfa2xV-yN8{W_m1Y-MCH-}N$1MaM#rR{RxWjp-cKO}<3j1cQyYpC4Z1 z09-8i9SVXu%$MS>EQw%;<82%GQw3~KK{hM1o9Tjale!BGES-G83y!bB7ft;aTp^O1 z?Rf@4)Q$MssbLk}K`^8LR`Gu49+oN4ORM}z{7aa02^&uy4i=TfgiTefl``kYP=Dr#77gpG}gkK@~XE|}-dHMqDCuD<8EAHWw z21gH}Qt$`-e)3-s3QXmwPCu2mefPjGxfOvpgZSt1ph1D)uQfhUTEX&o6!HIIDC<4P z4}*P_rQA1&T8#@jza%i42)LS2Bryo$VEe=5S&vo!#powzXf!9xm@ zE-^&h*~QWNZXdziqjz3jYff_U%GrrI8U53P|9io|`K1BeU-w~ohm8b~$Twzc)-E;j zWPH{&6FW1-_^1b~F8`-3{I?3d|4yj+0boVGus82 z1!nI+>>5;ZNelm0T)KOptxtIk> z;YbgCu{=;41A`fV)?EQ4a;TN!rKBMv;~T5pq@bc|e90=Nt(2w9_g%CYhdT9Z7qILp z8po|We!`Pzp}m*n3ST8N0FgduQv2F@+&SHT_M;DTz-Pk7t+L}Joa+NmaZZwO+d(7) z+a>;r9rRrwOPJ~Dx>w$XgDLpf-?x3mHH!m|&NQ^%g0VyMHB`KpgHSi+i*LVn#b{ke z;*8pDwtlcBVwcUp@XsPtB5p znZSx``x{R1;=#UzhJ#ab;g|vdZxEcdu8REVRa@y=TtkCquPdfw;^Cg&-gGoH%{Uu8 zA#i{}^NS_r;fdC(O~`RV59x(gImzQKU%!UR*UB@z#Sak~wXW4K2A~1{F1AWAu26-4 z0g+HlxawG_y~$ZHD*e8w5TdtdkKDh6lm?5N*h67JaLey#BYOmn4SN z@w*Q7lgXtdZPyn9LioC?s^y<6Lk2p^B^LM*h)Y6#J{}(MD;wu4yB`8rIj9~3qF(|* zmz<_VXnUcWM8-TYK_&@GytPo`o#`)$hAX6=XF_&a1e)Z}BKs8F-QDYvQK3<{&;zId z^K0mqqi7Veki-k1?&+xNPFO4i>?Jz}ZF?~{I5=KC%*?MU0H*D9rtGiU7807=5fc*= z7pHg?*Fo?0Umu9LOz zPN$xH2z`>ruNJ>0=X@^oX!alxC+vcwzc$V4~R@Q7dS61pxn#fiOaOOBtBTPVN#5&rKt z1paK2$UC=RlkHxBU(wmG=Ks-bx9tkmqW*x=Z|mhj2iCs3=Fg6|gATfXE#&J} z?|&(68f~(*+tGJ|?wzbcU&9`6PWhK-E_yc~AvCqM+f(GGAx^hqj@C%6^IVW>*<1W& z>r6R@ z*xw>WV8UxCB^N=~@LntBm%fQdoByy9W6D2A)4^dEeoe0n81ZGX=QZ4Pwn1P)(X0u8 z;+0He=$L28y>5k@XTa8TZq(C9WR{=$C`e3PKY;T&Qb}GqeUI2cEh3`w*a7{pd}WC#0YW z0AobsHLQfD4RxN$AUI&k_cAh&N=>&Bdh(ltQelSzb-)~7ohCGnKX^cfh6JD@S`u(P zpp7A(?oDM!Hgi>-Gj(uX6tzTxxL)-a3ayxkw3PoiVy-*^NIm!rkIEaCYkySQLTX%2 z5?)INo`{W&yk>{#;pe1m8Dc)y~kyk$kYg=uV^#lST&W7KpYw>gCK zz_8bHO455l$rDVw5(i6)Zbl_d>8sIU@#(yk>>nrl`2T6{yW_F$-?uL!qC%3=uu4{l zmQ+SVgh)mal2IuQ31y{4l${Y7*?UCPWtC(#ttgRIG>nk#IX;(>y1Reh-}5}b*Xw!w z@g4Wgb$!PBeZJ50IFI8vnG3;LVJ3tCie{fGIIV5><5Km6gTq{AN*I0M2yq`B(6lu1 z?kXD3g&jb;UV+gH45Mt(%Kbfnb9!((4eluw*2z>diMa~41GM~Vfx(Kd{;eev*KGX>gPd1;6uq8;`{p4m%zeraI(}NX zJ8^G~dGk@=S-9|T{5g)O-GUd-0!SpBaqbvppYu}*C2KZa6hvOT(rT5N0A09};KlGQ zp5g*8W4>Nn+cn@XyhLl!wCK8uislRv>j~A#o4PaZO5ljZbQyX^YC~BTF#bdSsx4ZT zJ+7%vac^CjJ^lP@fMMEI+bv!lFE~RV9{QMg)5j@C(ybpGabV=zW}QWb447FJZHx2g zGxg%PAt4<>!?S&CZkQ$60Mt{wswBOfp>m0r1LLcGf^VEni=&=F{P)L)8qB9GpJ#(h zjjx8DM$(B=2^!|j_~GU**tg5W+0Bh$ON{JH$=|FeCL!T1a&QJq?yLCUqAlgq1i_JR z!`~0;nYHK5c%4UoqM4FmK#2|}7iBNm-VsC7 z3=uTta{lHSZ!A9xT@R%qN~RF^j8PFjP*TU==#Deljk!M+(pjRTWXtrM^bvR5C8`!}LObP_604JM|@!rqZ1?Wb3Uq+axTY^b8nH z`8r#VcJs#?C#^#yizI4NZ)4#}#JIk%w6q&W9OPvxDGz?)7i97+u;7jbWzF-gR=Li8 zuIajv?96{pdZ9t;SiagEN{0%lR!=h%*-a>`{Tjk%ARGx9QJl~b&+XNmyhViJ!fTf| zb+r9Xg}@>|%MY=xHLQ6Chk#PDvw}t&%NO^-jK&(4wMd@tNvwcB)n#Tf*9UeQHQI6e z1)(6;tRWBGfWI2av8uT_K9GtgLGcz;I#I36X%w}n@(k-eTkD3?iK9MdR z5+7_>A!;JiMR}tt0~w7P?4jejv?Tx2O&jhXd=&VK92%ym`Z@1F28Su?3z!lc&RuCM zZK<|OR#PJEgmJKQ8b{-dYmgbwW*~`uEIfHM|NJ}XzH!^T31yanAPSavv~ME#R=d9@CfE&VF0Kov#@%Qi$gI!+prdi_P;+Q36@0wj|56Xolc3MVmKKQqgR&{ec zsZWWMGZZY2FWXH0#b_gvm3!gCO54Mijsg4N(0Lv#<>v(NoBKuLEM}j$789FCX7$Ly zt~kciO|Hx&ktZ(iULF4i`2+3N6--ZIH#mE=HhM2-sRv8M0LXkBt{VaDzTzZvc?;Vm^>58lcKoB2vjFEqy!Rgs_;?XDY{KjaKd| zxsn#55BJ`MuUe6}@P}sCEdD+_c_^MsOfz0h`Sw^u7FxOR8(cWjNGI))2=$$k!<&<)RaI3y zNeKx)XT;cGoj3CNo_l{sRaxbgxL|1qJwDWe{IG817Zvp@VOH(uof~kaP47t7QgTPK zQ@(cMuJyHdPUQwTfir>Lg2(8ZHEVnmMY3DGX5VI8Z`iSnW)=~PKVQ*jM3ctxb0P5v zztf`TUtI;HYGYO-EzmyYOPgG8D*L30A9G92ZsTCkyZCK=fSM+&mS~=1s#9uUA%6hA z*$WhbqCnZWF+qB_s^j~;SNV-VcA)~vq=0~nIFNY1#3-czf&g5lp;gkxrxbkIfKoq9 z?=0=aL&}H9jmWwL?7_L@&>h*>1bV}xf~yX^dZ~uAw8$D#VqL^F`EI6K-!sS2BYrPo z1L20Gm+hD;cT%n20xxo3%F);1gtnKuoA$6C+xWKv5ao*11%>F1R%2<=&0n^=0I!g} zyR!|9;dPl0NBiFiSVNd)#I);QuL(yl)>IK_hJ*~c^A>#ifVV2xS{b3fXJccF;w#k- zSXTtC(H6-Fsqa~rPZ84R-riokP8WC3IWl(EzQnPH3?FGfSU2{)_c-mKZeM?Gk5CoP zlT4ftkd~IGra9%W+yBL=eVg~z$VZB8UbY_r)Vn2KVIPN#k>{e=zr3_2+RM*eIFruN zg(YhFJRwf6$tXJ&B;zyU=R9YuuGZUx*d)Sr|0(r!xU8aW)TIsmaAqQ`)Lkfeb-L*} zwHigAM_C${RGZ-EVnvC>1ftD3WBcW2GsxsLQ=&NVmVp^-{P*}A3{4F4L}@$`%N#A( z94|a`c?V_5IY6TpnG||~0 zwuWzX!P9Xj)!Dn?4GTtcxqv>$VrW}RUcTH|(-kS=C!x2;FsU#+Az4X$K!YZjnPiJP?v2WC8@_aEa=FjK3L4{#mt{v<|2E`4%wxgHqK8IrB8se{mW zfpupirTwgI&Vb5dpLxCtvmMO1XNy)LaGC(%p7`8#2RYIYq|bPOSx>ZTxoCo{(`71~ zULK~m_Pzddv!$AuFkA6_v{4sJ@D0qj(O6)#Ua0h1>B`G_8O)>fgmMi%&2=>?LOt_| z!Y4E|Uu)gvUoU0yGbyiaz+y3VWZ>=F{hbcucbqUZ#mSHXer}$3@2+5H_w)Bhnxm+u zocpE>%IAS=OU)r5uSH+N_)T4A!Ok65k@mYk^Tt77{yqyRxJyLUZrTG4akDKXFSUnP zd$Iy3Y*EDdB@U_|T30tBPQWJbJ;WjJeIgp4vg?0+6Y1K``A9&)sy(etiH+v(cT0%RyOtbEW-GN32%*}1@mLE_Ki$-p0i=^>zgTSpDZie-{_c)gB9;ML zbOH>Zsw4~l5=e!F1O?&6!#$p(fxB-6f&izMe(=TkJrr`+ti^GPPDor_9Qv{e3BqQy z>erHA#v?*1v1{B4vSq3dLf4)+ITyDEy3S)?b8w}(-&z4DFyk8$_#|>4DU<*w{?bz7 zeNF`NCbr0(-RF|FK(jQnsgV&G&%xK%cO46O$V7KUe%T?{qAfUUYo7oaC>eO;k5?=O zx+h%n?#zCorTT%PmF)8}A9TRQ<4{VtF&aCnw*z#*WvMa@kXutSNE>S;K=1+=_d0Iv}6quG@DIZTDY#yT_QIRNf84h<4&*2IjnrTHm$yBnEO08WR#>Qk}4bSlii0%YFQO5vX+e z6YCvb@(GpBCS_41bm|}~+kxWI0FR}nXJECN8XG6-=jF!46d$KG^6>HLg_E1wX{fSr z#Wyq`Z(Y1rGbVdLU@OayKAVi9y|maorJjt%BA;4XiXX`f_F9x#%$_@?;97ogQ1N^yA+F0fiV&>$wB$nuQ{Z7Vf!`=_5yZ{ zTmSx;2ADMD*^jn-8cg{4%m<_)tnNzKTR)ASdu&b2_Kr+4IcWB=hgyb_Lq9w7Kn?ed zZdn|}Of#z3YKKk=SS~wA$N8YS=J~#rq zNNEk*w_m^wXOV7eYa`^D0s_b2ok!d!$gv=~VvdZCmxA#-tP+nL)-%VBwF6%SA)sXU zH(39zT)LQfzCugDkQ+zWS?XFB8Oa`WK#)LeJn{C`Cc#*OoITL>F)AWe=g3(=`0M6! zxDC*AC0-p^unT?u+YpqS-6(MNy#V@ttZ%Wm#1HE&mD|CXill;G8m*FZy1MV-D+deR zR+1Z$p7}nIJD@%|_m#gxU%Y-vsp9D*YSqq7XO;?1Ej_%&JG9}89L)FT$8()seACBK zpD}C<8r(dDnexDI+5L59;C&u`G311k;Pe>~CQw(t)@Oe%$3;2*U)Yj4)Hcvlt^Od) zoI%qp=4dbX!)XUzTk9#-b2RJf&v-j#W(!5*pJ=x2Fpf(!jT(BUti&@Sd^ zBG>P9DsQx3d1HNxP#p)yH(;>O4=^I-pcgfwld|ma@%OiG_0>X)*1LeL{F#z#v^7^b zr^(W90^rVde9oK0ju);YhovMc^ioar1;Cy+%hWwMC2d$pKXy{?U#dhOdMPl#E)3Eh z@7oZ@3mWo7CUIrca@Y^;n1d=MTpHfM2(eL%UJ=g zzM8sJ%s>XTpQOC8Ay8OdU

ks@BO#joGZc0Gp{ynWFFBNR%;2NO9mw%EQ#c#TXr^zH@+w|2O?@-`l}L02)0c>N zNHcZ6lw522?@)#?H!?vHIA?Kwjy1wq_Lxx`*JB0l|jRk=Fe&N&SGm*6dvoqu|}kVQ4x8i z+|0IG1vLxbBhs(4wpet9ZR%p*--|-T@!XV7a%P^s(JI;5>70)dlrDt$QCh z=aPq1cTHEISyFAz#RmfI$!B-Oe%pEM?cY8PB#+bo_%QiHl^hzhW_&bq-*?oWp3MDB zNB7@a$E|w~QcRHN+l1*kM+zRtZy?y=^2)Wq_n%BZhf5K^WpTl6tP z|6&Ofx7}~zHz>;%axIuzxDuyScqymu^ebmr32%u`;Y`?UQ6B&}Ipdd~i$OTGD zOBa-IRT&8SiyK{oJ^0HI={&@K@IpL$YvxpKIn#7yK+VWV$%C!z`SZk>80}QUt0Sgn z#^d21(G3L-!*^%t_$A84t^EH@}up9+d> zPvJT*m^VTNXv#AP?M+jN3opae-ucnCF8l<^@zKZWoh##okl0ep!T^(auIKWKiVTuW z48@j_QBgOHJmT^g{B+N{Bp8$u?2K~%wV2Kz0DK@WjrCzEkZI%Po@>YW2@4Y+pHc6j zH+w|kA`tWN;Xyw5Zs>suVAvY$xp?^H%a`o>8{u!d@X*ufyR`S%eJnf`T6g+BaN-gQ zxO;aD3W2h6SiWG00Jj6p;p>w-Gk9=t!=G3C25OYF^$UYwVi@R-=)N&)H_Y31i0`h_ zzlsj_T}g{w)!aIKhZqk8ac{q-`Wz@J#9*HL&&#F0e(2)X{R}lTSPK`o+{Gf6f;e9M^N=zpi8o;hhxVYSq~uOVNLfGDVdIm82F%F-nY_ubd zgR2vDydzmtdtMBD3F!fB{>t59pO)y5p@tcX8bdFtzgDz3d8l zH(|$cp_gC%FqlwAx;Pl*@48ijb%-aWup7{fe!7XWhKBEe7hQ#dj3^*GnOhZK`c!~$ zD3*?09YT)!^GnTM`&}u>+tDLjh+E(vUJYNO2DO(kSoK`u(50tJJZBGBA_BRN4zU;X zS~p;poTE8&A9f01A96D%NidS;%{XP4lPvmB;(#lnq^QXAVC8f9Uy0OeN+M-r2@w{A zK1#Gr$ceupiNyN(ymxSwZg^;@<6LDTxmWQ##HwJtnkvV@+}s>`@nf4orSkDgbBOg? zwS1dxmNU3XA0c*frfkg`U9rQx_qs#wmTDH$6Ow& zsZIFQTM&8ArPIL&NJkwTpy{2!eI4uW#v}W!iqoJPxANfsgaUckvgVNKi`fOJ{wv_V zsxHpU`^3j(9rDd@fO5(YFmL<&$!AGb5E754OD4=~A9loHw#uFL24TQg(dH62JwVuL zLHnsR<|S7GNt<$jv)mIxKP<`kcsf)p*AvqPKSO5LjKhRxi&lP6 zm0w)IWdqL(W&PuGc0=C>Do(5Dy;#wsZ&4PlGnLi;IC%gA%BF7Q`nA{|v7Dmu8sDR! z5H|cOau54rS<++bsRu+!ou(sH(vDmfN@}&!fQE{mcWMC{2J_ z(BP1U^QTWO;&1OggzyZHPIT3(on&=-DSDYKdi$kyizt6^dAyzuxc#rE<db389l=&eLaheE8(V{Xm(&;)PIfym4R1>ZzSHH4==02$(M3Cy4W{`ZXPA7Ak2OR(QX zs9zXIb~XRY;|Df;h1ULFH|742$$=<6-)Y8M{Nn?V3))A|otcB+sS*ko?Z%B9|MDb% zyTAYD^>?_Vd_`4=cZEtGT7u_yw+^E`Y*P%qO>}E0&z>4fH19PfyG7r|x%1XU8rt^^ z19pHsY)P)!vnVAZ!U*^fn&#`Ys51yK{2$M30-{8gTEz)g_*S&^M!HehB7m;_%(akc z&Oq-*aN!SMYJd<5iTQM{I7UcCV89tRVs*IAu=?$nK8z~awqXO|4uYL+NC4+6+*fmR zABO862zd)i{>-10-q0T!MIXf6?h=BE1u`z+F_kN&rSlt?(S3kc*G?AlcX z4Y(d;q~6}!U$`qk(U5~yLtNYqFAxlQ6t)Qi3`_U~J`hSI{|J_cLj>$}QSEB3-SCUR z^K7^mRw7waxw}Qd?{9}+<%Qu=Hf3x z-n%|`z`7>dadQM=W7)QoImrw?V3qy=AD@=K3j%}*fWzM(4?-UyBaGWWoj5aXDcg2z zUsK2n44Ej?|NHG?R}Tb>PkiI(YqXh5OBDx?02`H)b8?QP5)=`+y;kz+jT;OsdwfbF zA|eph0=%f>g1o(taHNO}cxe4(ujxJr1Ev?Hr3W#x027|Rro(c>Xqf;p^Gb|eJUr;? z6)hqr{dt7tOJX#z6*rBX4tl?fDTeL zbx^83Jq!NjaZCk)D$b`*pW?Vb{((FQAh8bX8tw_jRs)5865ubV8kH;H!EG{eCqpW=LO+?AOjqizR6zS!LhZuSPbxYms!0G8QSf-D| z96u^5-|I4j+(K2H^aZT){~E@W;%s@lZU`lDG42k)lYLCzvAR()Kz;so9B(s1ETJYN z0E9|>zW#SYzkU9EKSHv=q6Qzi1nv!E?a8<9G?mR#n?-UKn>uiCUQ9k8g{^0r3Q_+d za}dr>6BAi9Ccsh1SS6bgJ@(Jjb;f*A{;~6nj=XpzYR_N3sTe9#?NXq59l%%UH6Nu3-m|}7-+-v*vsp0&)lLMnpbq3Yp zd>((G9a9-fV!^mnI13mDlopzd^i-Nd9N|SvW**`HKubt7PEho==%>n&-%%Ej7P#~O z3O)dMxJn?%O>rJ)5UKYsZe#xj`ng@)~>p7)Tq0#AzD-dGC@iRVxo&?thJP zVYJ?=VTr`-`bC7#e-MLE(byAly9t)aFFeVLM`$Uj(VR$i$3pFT;d#9U7AZw;vJYrI zS9qn4r|7y)^vI{dsb|5(Q=mee^ifW9En2~!4ZSER zNR=^3d;FxVySQl48Vd^q-gAEuEL8UH*~5BLc{{_&NJ3IFRl_4uf-r)D*Y#cRlIcY0 z0i(#{<;;L8?>{995gg-6@Iu<)sWg=p2(Dg@;V^qvVq&oT-B`4}0KijhaG{-@Y*p>| z{>oJmlw@CX$O?9PUi|~$_8IM?DbkkQvX9fckxG#m+(!1>y${n)lyAe*F5_`XfLNb2 zvaFt-vqzYGB33}$qjvA%cPMiJ9B5j698Pbs3b7wLcF+}FAvNXK)$1Z&X_m_VwuZ4A zN50RRsAI-FHWW8^lL7w}DIwP?9M;2sDypdDzHQ3Gnd;$v&rxX~oD<5u`xN%>bpY~i z90fyxmZTPUYGaFsL-0E{6CscCnMU+Fm45UT{Ghz9df7JH0lenS6SaoRFXvb0bsyTb zq}V*M#tx&Y?0dXJRK;Lehx#1T$fYAZi7}dZnBp01%dchbn@^1f#L!f|MM$bCfTzRm zM;2(dp@1f$r+5Wynua{7htzYon_LlGM}bd_2=;SyIR;7!NK}#m-;D9AZipTLs0F3W zIw)myO7L8bm3sn-Nt}B?0cBeR`-KI@LPwM?Ez9eBXvBcC=OPXsLK>+IVPz;Mu$(h6 zo;$KyeE!MEWi)?gEsZR7hPt>ayz9L~hiH}u@z7QZLg;vWFGs0PK z;|FWrr`Q*~6@yPW$5eM$&-XoYniV~Pf5htKp(mgB6KdPODy=dlI46x5yvL4T6R!Z9 zb24)5($Z28ETW>LT_Z-w2541CkM^n)67=^ehi6qyWif5%EaPlDDh2B9fJ?Fvl+tfL0nx|cMDjbK)VPh(h~`M{A<>Ll5)b<))rkau=Rwz z;30w$PT_4l?R^(OY^wS?F|;+H?OY$A3{|fPwAMX?#16~Bp)`Suy0t5z$dwydrI%8UwG>0Q6lmwHJf9vnfgC1b$Sjgq#5?{>Mc7iKd!+E3vT({<(X=d{~1 zVL0AAo_ct@(uc~hN%GtDv6AISLo|)&g1e&Px7? z;Ce!X(Eqt}hWPkYB2`1{cz9_62M%2l{hVn?e2){+(Y@ACzK`t`P5f08ovJ9(3mfBm}4|3JS4W;M-Fn!JBgeNjTeiSr8x7$95_%z-F}NIQJc zo#S}=7h!6WQ8av^;GOv+i12OnlKq4YKqde@00!%^BpR8lU!2NGKB!%e0fGjYa%&v0 zp^sw6&fQF6`3HAtGuhxMXVTYSXaI-r`u+bqB>*zN=-`D`m;0W^G^`IoNv!Uih0Evi>#t1{T2ZX(532IPO zJ*a5DUuD9&SP8WR*q(&5-9cD2%kSHF zp#T$%wTA7gvE18+Xqp1cr?9vvoC;MHY*9Ld&yeUefzv>zC;q-mXWJS#EDU96YWpt z9x!I<*(t1EQ!~+{|HClA?{DI;B<|C)VCp_mS!x_OAmD(z+KZ8psq17=28;7WLzc>I z=pqgPgW%?<@00PhID1wpnWr>DMz3C9_n8@@(V^*#NhP1fB=xHG6?YT@rjDM_n>yYZNe`hVS%IBh!a7u z9$o}|3W)@nmYBIsoU%sXsX?@*4mNATkZbb*u{9!v^n&Y{B zKjGgGl98BGzUGWo4I&TJ2I5n^dg$nKyKm-~iHd=KzF5{^`*i3exYeTRqy9(aJMP?|J`9GKB*J%RQIk4YrU)19CN?=AK$z?OQX>jk z4tf3V0u8N0XmVYeas49sE~0Xzthp0^)Iw`a2DXLp0c0~3bTGIqL)l>d+bytjlXS09 z`1Cj#tC_S=)fsq{$*~WF`J+WsEYoXvoF5>f_wAgcjZvZ1=;SR9IZtwAoTQw@ zM6%n4KWt-MxbUZMwEfo6+d8}Oo*Km`LGnggHPx6`>EE^vvcSMhWIKfrJdtj6Iq~yX zv6Hz*=Sb0$F0+2S2?KM29z!s+h(C)Hy-;xctt@GzdB??j6YOA;sI$|)lU+_#DVIqD z1up%&CYZ!jdd#$ubv2BdPv%pHKK|n$H_^t!5-p{X@*$hap{&xnbHW!{%P#ae?#rHV zZ8=Ro`|7%-Q#zBw&`zv)k0~#_chn}STK5tI>953g<6lTS)U^;z^*G&y?niGW)p!1Q%#Kp(oyhufAq@R3};O=wU zo$IMSY33FX2P5<|uTSkbVY_zz*wxzXr`s&%Ht!BEVC;G7!s$&-svJnAu&Gt8MBnCI zJb0$$dQ=MvqBv3V0>&L)PSSZp7!daSh#^N?t0-HEw=t*97TyI5M9?9$u8rk6U{UaR zHMsBQ9sN3;-@BVn-MV?QF8!15_}ji~yKnp0TbHfbxXx^mv`P8R$c8cX{;oG=FF|K< zDqVUicc8z>kCpWuNAl7Xxq@4k?d^8WO@;#F(Y`;7<0D01z)0s_YMV>bBCL=!wYS5$8*f<-|P?{AZD&^2k(_gSurt2ZBKm;SI&K{;PLl9 zEB&~r@2w8CuDh>qt2LJV-me=3};+A(j zyVKVvizda4ToLq6UQkkA{^;&-bMjt?pWQudKcZA})ceKGG$k6T>*){MHssbjNSF=9 zR&XxGjZ;fr%g7cDihV0zU+T~vrHN_qj1O<8w&naB>$OTZ^$DrnbLq`2f$NE1Lxv(; zDn=vJ(BE>7=vgFS#^KsyE+on^5@8g&%qz_$mH*j^uR;1OU&Ka~<+p7~YeTm_^=P-l zhxoDP@P=~#Gs(MW>jTD%ITMvbxo_s^*{7K;e>$O$#l6>{eE;3ibs{2~g}e63q;}g$ zvB16FrLDIqIIvDO?%A#JCvT(q(TV1@IHGvI!$Pmw%M_C9YIZAZ^p-i_uLC< z6e>R3|K7A(vnbHTo+o!wo^R}{W1-E#4mW+6xMg43IA2KT_USq>9dwjU!!wNWvuSdxwh9Xs`F zg{@snTG!5F+&y`_)qgMWnd%}(x; zz|t?X6J)%H>c1{o@zNRC^kSU@W*bfnj2FA^*B2`&Vo2jBp0s(r2Y1bDJ1&Ww_%3D7 z{U3OYm5->+*RWADR&M>{X`3~k+FWg~a@%epC+D6%sLv0m4Z3{YQtYI@+>yhSh!sQu zbN%7Pg4K76ZO1RyxCP|pjCXkNHMyZZ7;f(7?Nv8t)?s1A)v_2ZTPVRctW?s{QU)-k z_d-L`Au}^3ik{>$-Orb$4?7e4BstkmHtM`yINv_wrc?6#(L<7FTT^^TUFCeSD04=7 zHZ;k%uGv?;Zc(eMFS|zdewEUggT!`N6SY=H>L^xiUV4~H} z2!#jTiP#Oue1?zhSC1Oeow$0d&byfxo`+j#gt#Ujm|ELsV@h2G%>-Akn$_yzqwKa* z(!}i3n4uZ-$hnx2ek-Pmo#}q%w*wk~EsJSs;65wS-K|}oMEVqET-F9My(-tXb$q2) z=1AYTc~a1@)%Bc0`}HHwKH!zTOV)RH_*QR(`{<49>~;$+1tv27>3biKO?Vb$>4(9X z=G`?n>}}m;LT=Pu_n!UXd1YnA;|~lzvf2uX=km(W4+}Ip=fkT-M5cbH_aAZ|ttS># zhR5Lr3ctS##o49Y0(Ta>o-MC_G5WNcYoJ}VHdVsiex#>SGhj~crtVeDjwurd7+N8u z`8>intDcUvemTX^;+JKngUx%If07M}1M#)03Ifa#cV(NA?pRF$|EY*Z011xlJ6x_U z;N+A#_t_C4`#_`t1M!JFf1QD=3@%||hRqPj(Bj)D|1`8HfH*Bt>j!b<%jPqNhtddd zs+tNMlOHcTNBeZ#EY)VEndj|-l*avZlYdTh48k<^PInt#c=#!_a!+=5(U-&$E)8}c zba9^rR%${Ncj7%gPzja$8zDXkR^1Ch+VBCLDBdxY?=lD0QV*;=Fo3itFaR#Yo(`8Pw*#v-19y-1P zoGh~#Dl-5^FJ=oYy&?m&0o~e*3JNX)k|;h{7S9WEUaGr;5B6L3wZ?vjAW#KZ$du;G zqL@3 zaU%7MqGT@lNHVkYFWGPv?UnP;BtLeh)D;3-Ja!=ImV0!dCFn(n^eIIz&IOmMst$O= z?5YL~yJL$m18ARS3g1mtVwy!u4j31Zury!_P%y9&*fh6v?6?ZpgPn~{Lqnsrr3FJ! zTvo=`*4C~&dmI+uMJqwizJ2G8j+$C3tVRYqE8$}e-hcSvipbV{A9iXM$^`UDp4rT& zmoaYvKk@iB#-qq=v3CoAl|m6L9yW!>-?PSCi}mc=toZfWs58aoY`U-U%)4yZA>X#s z!^?|jm-U2V$MaXuVxOL#i1?V77fP;@Z6H08^+ahQl57;E;rS)W`yD7czI3H3xNxt` zHPOsa8sDX)5(6lJXa467e!fm^i-M98s~+OZ2Rk~BFIoD72S)H`i1WE}_sU})L^p!7 zBoknOxI$n(+7(+@>_ykWIAq=aZgc*5ck}-JmBgO(kRe{l@ab0YX}V!|g zz_8u>hO4Ww@GKTi$+Hn{POTlU!Y;=;ofUK1!N$87mhTs=XvC* zV>JRFNhXtRF)QJXgjx?FdWnJwPaDva;>^8JjumU}@)>)%Sbepj^&~H|WJXs(|B3?N z%9UW^{2M|tV=+wbzRWJCmh0%<7>@?OM1h!%E+d$}wc$G%848DOsk@iYFD3kOFAy+9 zVNuZye=qn`Vxk$R)Oq0p@mxAf)P|&w=wdcmaK$QkX*{s%)bkYP=l=`>2hg3Xokm{3 z=wKnHtf+V}>vY)Hbg-m8zX}6G8rD#eLrA}8zNs0=2UZfgD;Po#5V1a?YTmtz7CgXk z2(FZ=Y|F30cmh3LZtCwd@3B+OmqWOCU~t$&Auu^T&#T?6E&3KRbdXJ8U=uXl+s^y75zFl`-M>RBA88XglYCCG zVwHmF^MK2YFRwsUb5w0Lo?YR3*b~El^Wx?q{P&7olqRtoFHa) z&kzJp0x)Ko+!S`oubn-ipk4n?m2j63ZTn0ALN|S$B|hvoaWaXE$e^y5%{pvO>X8-4cYI#y8F#eMI{dg3oi|i!wp@`uGUn(wn7-xgq|gml zx-Yruy1bCzDs}PL;jqhg3$|(@v`D-xb*vz+jXaCAW1;-A&J6Hea**?t4HgKY1bReFAiX@)F@nOMPqV(^#TXPl{`|{gX9y0K? z{>ul>C3Br-`e?_+s}y@9x4L+8y zr`2?^k`wVa$bZ~GJR0>|crGElQ$S@H869WTf z<~e<)7yE4wCq^ai_;~My_Np%d2G6gkj#xH{iYkKem#Cm-y}EGks~bKEeP$Z|RAo(_ zf@3{n43zg#-fga29qGI^<5YuZW##?RVfTPa(cDe1vn~AGw{12!$*-7S|4meMkJz2f z26)GmS5mOWW4M3$-Hn~uI_67GO@6ITq+Y}J09(%;>hT@w=JCiAI zY(aVVirYL=LE^1pHb2IW?qe4&&i!<^q*}AOZA`IVh(>*CRd_J19MupN5m6~bcjIH% z$9p1qTh{VL!M(qRO-RpM`K(0)&cts__F~TVx|t_5o?KfCDNOsj2hy#^T1?Vg(qU4K zGxDB#bN;0T#yVzL7{RHE)e^EM9cSMq*3bS*zC>lV{llEKtUgcc63bOnPJdhwxF1$4 zArAIWkGMZq+5yyX{~qm;)@m%C?Jn0@Rd zkyutWcB@d0Zk3kIZU(9H_^2vSfVh=Na|w&FYem~gt<87qVmcY=66A)&705PWB1jZwKTQ*QROd^{OZ#F$!g?c|TjziybHSoOKnl@M^9fO*w< zfs7NiH}oQu`_M$n^UM7BloOQks1s&u5T+zFOD^ygD;+X_l%b=pSDT%ud7WC4+r%kN zTWaG9xAC72oXa0}G4De&Wt%#!Np;bDqgGRQlsiF;4lq_;{&MHcwQr zCFHgNg4$ooR!Z*f@#}eZX;yMWR(EHSX1IUm9f7Q&j@(D*?F5@3X;IHM_1&r(_PTWM z1A^P-vANj*={mTaq2-GIoKnMYx`SkaW&@MwTguOA z?NmxusIGXc|0#-cKq%%n*Eh_OxinHXo;Pk66cmuLtyb7!G~v)AS=$UiqZC3y3&(arvh+~vQvEGID$m-3d``&2n#shL$-^Mfx z0ymyF*D(GV%q$^$AR$;NIo|DZ!1^Czt{XSRs9yE)c@dR4ws|8P<%FPK(K)6y1fpeA0(4)4Zn-0;#Sq8G19{w}#X8CBw*X&QX z-&|I_mOl`yr|vD3lqD!NY&v$sdZIUrQHnp+@bqw&{M)kRbiOg}IPnUN9vvWin_X?L@l zZ@I{xHy5O28#G%!j0TeydMtgHo8x@9tGs+k5Bm+5Q|@+szJ6|K&p$D;`@)@au3ho0 z$DZ3GC2ytE>y@Z9E`Cit5Mp=Ur%2}7zP8amgJt;`s=(>iupC^g>#-INL?*$~?Q~tl z_RO_5g%z0=pG1lpUOiC?CC=I_d30Vj9XNJ!drIR2F#=i#>@QuDdbCWsix$Pb>XIJ$ zG{9VPnJzDQbKgfePys`zKUcB)LgM6|+r+nYX2q19JQey_Te((pd2QuM@XS($DCe^3 zLYre|Mf?Is9MU(;_qXv6vA?h_V^#am7l)&xhBxwFC|}J(g68A+?9nlYB|q*jhqgrC z_)WxcYaY96Cx6Bvevx_qC zT8Jf2iA#@%Wp*WD?|r9^FO=eDR}wRrI1yW#p`KgZNPFqx)JHvJOjyu)MOUoAapGP) z+^wt&3_x!C&P`@AYEi@v5J^!avz{%WnYD{cnJ zWu2=%AVredai+A}-1|RV%u|79kCchk{a;+p!e}D*#WO%T@*giKN=2`0V_v|K<+4Xx zza*C(mpVsMn#!+7ALLn%NN%(GF41;i$?55PS#}2Za-~a9eYNO7xx|m3-?thqm#1&- ztN8)zj^{HIbUQfhCX;&}_L*;rv>j^qlpguWM10f`&8*vwl&seoS?{VVS^=AF2+NU% zaeJy!<1;UUY%B$k(SwG1C)a7?*lC!#B6o=O%xWZm|Sgzjl zG#k&*iOBos4|C$)!*YncA5Qc5kw<1u{5NwBvS#9c><~qfMEtxi8>cH=eyQYz#Qm$p P|5wDM}YIM@fdvQ)Hehk|ar}3z;ud3Yp57lG0$F zi3ph@W9Ge1_x=3#^X~n=pU>X?bNBRc4#)8w)>_|noc=0G@=OdI3^X(}OlKA3RB34F z0%>Syr`FNpU)K0u62^b{9ZqXI7~0snSQ=k*ppiGWHoktCYP{nxI6XLi9C<@s1j)6X5#Im#!t z$Equj{`ZV=&XJf2)gyUEc|^8a3&QG3hg#O2JKsutJqiHdoJ zS^b*xzKKUK-Y4Bxcz&4PUB0TyYK}ffo=3(&nPs*1<0gIu<4=b5wp)^qhWf|H6=c2_ z{qa2T(B-L#e);!JS$=yq-Rsfq+IXDSx1`Kn-=&m>dfeb>343Wy_lZ8`#m>IizU^P5 zg>F#ui#!7k?~T>)SM)y;a*EYtJ%8#CW{FF>WeJu%H>QHsJ#RH;ZPV3wIhc}qps)AN z6yNgN?G_;!*QTSAYQ=v`znocp{I+N3W!=Kmt6C0D?5hv;wPrW&nK<*sEF;j`gn8Gi z{2-iH_{?jq5so&nQ0?Qu*V4*3Ib=pX(FyRo@TCw>_BOe>FM&_ z9d}Z0_KY6hw&r$SSDUzxDC5T;FZw&%$!`b0$gOKPyEyFF-#N9(TeF)(YrTNU_brmI&Oe&COLDR(6|5`Iclu54pnkqL zo>2Bu5W2*ylKwL$*4Q)4R<(QQty8w>HbwI%gJ%NMO?g} zw~fVujqRF#GQ+)?T``;K1mrBW<8B%3*?jtfq1-?M#OORqk*34g)NUf~#ma zcGCOFpVnVTM?;fLkKYwD>a7f|ik7PS@#x{hhqvjOYp<};#Ms%{I;*d_qk=_n#eKa` zxx2gn;tgNz?%^>Y#6VM>pD!-KPkZVB4UP2WSmjlvyW1o0zSPONw-iT16BrQjE}rMG z51zJu%N!fcjD5_4U&{!6cjSg%=Z* zr53Z*l9U|cXP!nxaB^~Lm0Z?(VzgR1B+bfs_mPhtPo#OMA94z&DA5w>W05#=s+?aMZHb5qlgehpR~ZyMgciyy4Gb3a65 zWg|_+i0w(p_5aH(wNTpEzF+xS0-bnE=+6-58NO5-A?0G9vm!L4*R6NtFGk;b?ffTB z;H1#y3^Ap+^&OMdWomX(#A==<8ThQj{6CCfM< zG_;{)d2!UHc=p=2NO27pE025i_4Rf=A2MAQw61vc_VsDrNDVlG)!-DdM8Kr$<~*F0sh2N{=LVCaJvm6Gn>dwP#typqVA0&?29kz@MXlQpum?nl+ITK4 z%%;|wM0<#MF8sY*;JAJJ_DnZq5%OIcZ)mF!$oi+WR9fUuN3Ip8pt}7~qhRjd2>Z{T z&oh<({QYAnLXJLuBUPZOvGF%vt3l+7`=9dO&*8>Wn#69X?-mz-%5*VZC+Cr{w%M$Q z@WvqV(K$B8t%r=5#}S^?#Kgt<&Skwk>&qI^-K%fwP4!4hE>70H^J9M1W@l$NylSg} zcB!?L%ec?UveKKYjU)E%-79SKJ+dRbL+Skah2d9KcQ$P2IcRKT)!~x%v84Pe!o7K9KbG^eb8gJH(aAXI?Zz<6REx-|I~!WYzD`a{GYi2rmvS_qq`5BXSZf@>y zMXF>u{o0ds^K6I+a6qZ~^HaHO=VmyiQLGO|yyz zJH@ZBygiZBTS@8Z%67|39*%DB?{3a|q|R@=`ugbiqLz`zj~`b_ExXqyoXx7meqLNp z^a<~^vP1R7>nBm^Zr{EwC@9!6 z;?KIj^0$UzG*8kvuf5lNTPG@m%Sda^F_UlV9;|mI>1arj##4L-1_sSyv&bej{?NXU zQ+(IWxhIWGa@MV1fA;LzPbo#pZ?$!Gy`~zp4r;w9M2#B0U+y;ZJ2dpmmoM68f4a*f zM6ArQbjKp)Sy4;h{->6Thx%!IEicYw*)X&eIE}`cbiR#@vPTklb2O{{vYn;zx3E(fLkA|g7cAIlfa!I=X9c(zr()bHWW9j|1 zvXVz!@porQba1fD_3ayCaf2Ja#0^O9JTDlC_u*GpS5HVv`uxq_Wp>=yF~WMc-~YaU z#xQ*P^eM}*CG}^2e_i1BAAMuV>;CJ4w)Q*^hz25Vy)o!s=_W*qiWX6R)`{-#UTK3p z|381hkpIAeyMcjBjErq)DM?95At7orzdLku%tN0(J?pn$^1p6!Hz-J1Uq6O99DS9M z$g|*k_wJ#?$;rw6ot<@Yb=}A*a-JtR+oI`PSy>s1`;RhTO9ct9B><6yM|&0XMgD_7 zPR0=UL$Vp&)#sp)(CF`u0@P#6=bR@TpTBG$FE(#4Qi;Ii*oVouCI7nN7>!d4b{?E@(A?G?T zcgGWp&>c?zEt*aLi6HK0M*H{g7qw`7u92oWT!n_LvzBH_L0MVq#$bJx@#n~>r~=24 z)cE*g*SeU|kMolj+q;-d5r*i!otFK9(VZFSyGahH}m72ALp{lgX1eXbDF@xG!OlV zEVQ-dc}Ah6e&ppuY5m48AW(?rK_y3Ax^yW!CueGE3eoXvbkwW=ThyaREN_Ih2q68C zXJu_ZuG~FeWV14v+)!7C%G)fz^%${W4D$=mj^8jxIh0x$dpFbRCDdlt{r69gYRY5l zO4dtw0pjNW!P+|_?@Bq3l>(rZmGSWN-&=Zf9c9z>y3mzk3HQGlNl7NC?I&&wPWA*z zy|`R34Y-_IY+%~c)isv93olJWGsu9a-}s|X&K+0|PmB&QF*f$GvNEp3VK07y^8RzU z5cAICBmh1`L&IPNl6AY7m)9~;xx>Tj$l_=Jq;c5WgCcOs4oI!V6(!dZSG<^Ibk@;P zBNL_?E}80Z;#*psMxfMT2`ZIZtFXPcw$?NuBlSv( z`MO1#@(4mkFeeDn#@Dt#%3@FXeUJX_xg%ne(?D%6LdvQw_v@E03B7Cek69`!S9N!H zr*@8^^@)gx04V~0hVIP@y;Hb=wmq^+ny{Tt!(tOi|Iv^pp(|+RBk) zHSgc^9zFV~ktSvpy1Ix}>(8G*>r>SBpEyyl<)G%J63-&n3YEiyMRJ`5PA}znQYv<) zWhAxM);^++X1x8{*ce7-IC$W|6G@LZuV26BDJZI+Ka1Dj#EXD(u4-*P&d)#C_4YR2 zB~f_G2~_et>yCZO&mt+5a~3o)8R+d&OMeYN+~02b!^+(JxYO@;{3w`5?TAmZr{W~m zii49AeYINlvfP<7$Hm2KCZop3uX}hbuKitFcIKLumDTiq!NQlG%3z+}Dnxy-xp?s+ z2L}fLEZ$bH*j-#OP4DW}*q1MbBJR?!T|3^(vYKXx9dcFJqOrN9<;L%J7eM~uQweuW zRG(L{Lhz*m92x)_nf_x&O;kLko)tKmdyyd0=6kp7Vj!>ntoR?+xtUF~8wEa6td1bF`#K zcTbO5x@y$3HMsp-qPleUeT~R-nYiZo?$f7%GGE5*_WX@I#7g@nzkmO3o>g+(yZh0j zN4Ykgk`BMB5pwu5+VZL&_1$5Quv$|ZM|fBmHc$NcaefP*tG65Eg*eP@Y`D3&l=~imUccLVfT-4E7nrgZ-eCO%YigtK*fOFNb-c)B;*NEVTyyJ} z_I7vdVb!yf@xnB*hKvKit6!cRIi;xhxw6u{{N9#4n@%dH%;lebeaFSb&ObeRTBMyX zpr~jOwF38DSa2tkzh-BXbdrTcRDyP%$h}hHnYGh=uzuy%tSh&clk*uini3ZmM{H%c zCxEt~FMn(_Lq#|JThl?)9v&XRF#YID1y;|qp zlP6E=9n03a;0fEaj2X$CAF8U9<>iw;F*mM;va^rKo8hJ_UYGN%cNT2ky0s}yOGu~B z+obAQAct^ed;7xN)KK=?UF)#cD9kq;9UH5ww~1f>S?n?Y`1(EhhXCM5jvdp@wcIXv z033EFTZ_w&4}qMi+w@!B4Gs)|Au?#4L$2&1KzF9+;@qdk<>27pcXycLjlYSxj3*Qq zFMWA>41dg+yrXOD>Sl&pjyaF%qjqU&H6aE1dV6aEW3D0!1MlC@wQ4)VSgDfKQ4PGM zVK=5^Zk`G*@#>X5xLP{)E%^xXLVSk~Sp&;2&oz}ilW-~XlyDx4DJVG6aaXaK#ro|n zI)hB-<)y{!wWZw9cR=Uy;KquVL`Cz)#%ymCCnTRMfB#;A_mS)UZI;fH==+lH&Z?>` z>7QICe+55%x}DsqHKhVBv(OuU#q{F#bBc;vh4d_qjM#SWBwHX$h|cFtP3Ur`JdAQ0 zSza1lrW6%C=)g*PK;d$1f5*-&-K&t0kUMui0PcVoq`Xg4 zlD+}vWRRK970&dCDF_Rh%E4tZQPWZVlY6kcJOG?tP(UDolkcpy_7eqO1_p*WbZ?p* z5C!Rw3+|F+@HBuJ^bU;&lrb{m)y;k-WhS#K>&GAbF!xR^W@P!93zW*;%)P_IkTI^l2_Ao6 zQK74??d=6O;~}{@rmfSYhxumuAw({NrxZ!&u##Y)YyhKObLB zVl7r#-Db#!zzoJdEG_y+|gasF8qF-J(1 zi@FPoi>L{v+hZ=E`Wir!JLx*9&%Jm0&UqknUGG6cl51`j+r9fH`=C;=-3^FIn>TMJ zrJq@fCCaSpl=&N9hD*in7qzsUAV6eejbpe7BxZ2$OH$ei+b-|hw@)?fB#>C&SI#$^ zy|5w7oFZQ;D+gbeEX4`agz^ap0I`i>`5+K9v#4*``fLr|?A#m$d?`^?Cwc4X4;m<3 zPo8X}Xzp27nHlXA6%l!noE*cMB8{q3;<>m_De~@62Q7^^2T1-uZ~P5lF8qpTa7QMv zKGYKjMlOScXZ+>LmdsGHve(9_qwyL<#{gU0-*$w6ndpxWjHUv;y}kB*Um#n4`uH&> zXHM1VlJQH=YuEOX({?i(o0)-A^v;N02<`4RU}k1!WMmxf!X6KUnxfb|jCpNg*C$2IkG(lkeZ( zFnvf>Q|q)0V)vl}FQ=$=0+G=-iADcZFSee_+3*uZ9;=-`7c5wM=D`j=t*y7RvW|Lr zc?k-pg92^Yy0z}8w}D=fYmVcH&g#{-K`=)_HZn3ETCXDe2u|(XxwE6a9RDIeZwuU zK79CKZEcN>&0afJoSmJ`#3_;?dOs&eST~^iv&qIs=MsUUz#g-!?}h>3jvl-Zt~L1U z7pdX3;A&c0Y$7=F$|gz^_uxio&5rt^9ygbre{o3K*Vh+xuc5JVy0o#*G=?2)8Exq{qS=Dbe!ssACu$aZn1NGp6IWFh-UJY;;T4_~XIxa2lm&=K8qb z9E`LQpsuB5yGe-_E0PZnn3t1NzME^|`uNYYnc80@GqS7Yki8!or-7t_7g33R0!qln zW9M1@<$$ddiR}7L=$0lBn_2K=(Z2=;iri;aB`j@ zu={H_?%2k~_286*vk_nfi@%Rr_?;rqoZGiolZUL)^XND3h%r-xfO8Xt4n#l_@3LzH z0qZvChJ?fipKu)h=sP+|sm2!KL9DJ_qgq##B;TH#oCH-3kc$HxhX@o9cC!ur1GtC4 z;IU^%I!mtb`B_4~I*`~I%LYk*dU|@;@Rr3NY(EVVZTnSI)aB*nCHeUH(D(!0<8sU1 zy<^(2p?UoF*CsP2=evT|Kz8Y|u}4h4Mf&)x(OLUVH`CxWfUKITs%dOW<`v6^R1H#k zL2a!n7BQ;lTeBBEpd)tbXP5oPf4lA2CyWH5A|ro>pnV3&@yyCap{y@rC^Wnt2)=Bo zYT*W8bEaWMR+AmbKd@u=hR6y@4~#K}+VX@%uN3pCQFk17xJ#YN(tk^vm@V=6BVZ{{ zaC@;w1Uq)+?`m*u$&2VcKsvo4fB!l|OPyU~U}!kPpVB{Y+GPY76HG4t=1m!CY3U0W zHVdxiejFP5x}cz~t<8Q~F3HkXf0RUNR6KwFerD#8rZ;hT?=Ajve$3odV%wh)14m^r z!}HW zd;ri(_*->NP4KxyQo0cOC#2`<>=gXKk1rGqSg#Pf?GLcnBHsnMe8*9vyY93az_%S8 z9l*BAQO8ePly1i^Y(K0|<7NZV7>{3bbWC1PkBjpG9_&l6lA5QdCm{9XeAi9@UsOud z%2gUBjRFS_#1MjnHBp{L85kK`CMg0m*l5UbKUsIZxb(XAm5K7SK#}vGTa7UT8NLQU zh@qjOiHW^`dMZNmt$p?d6SFw4&VC#gTN8!B z5i}1>F`64rZ)-mKL~tow;G!&JJ1ZBLr0b+9MdbdgR};Z|i3MJ$zVy`F1rb zCXE)6?wrWwXfZpU^(fnYAYZb{7gSYip}3(a?A)^Dv_-Y{A-%%p5-%^TIv%l(V~lm) z2oGUZM-sX0-4WVo65FjOYg5=&96+VfDwNjV19cyAi$72`J~%)HLcdyXD3e_ zKKzi%q^7OijIM$u)9HFtvNWg26a066o~ZpaGekCWTAJ--VUd-+a-|cG7raSw_-lkH zQogCCM%;O9SNctc_5!D>mKI>;CntZ1sZk$hBnr*%So~ALon3krqy(9tV0Qa!qY8ynxg{ei8{UVCo* zS4}+rrpWsU$k%?BW0MLq^dEMAIiy1(o%Jyi>HN8Kab~wKzrLP0H+x&`fT(CwOUrBp zx0m}wAJfXVuO+q}a>f;pYXd)iY-VGVlT}f1adCmNjxELz?CRCsf~Qs|P^np>N!kL_ z6B7py9ikd{y#|>IR&ZFHyP?x1GOcNeSv3FjJ^;AGBoc2^VBfy!s+sZetc(oj+3~$A zcUp}*EvTrg^9C!J&P}IBM6^L7HDkE(RW#vEIpuN5QnUt5(=UwYiybm8f>^wKgCpdPK z|Ij%d-@w|rxjBjB@|N1#+qi?;kt;X6u{BbWkXxa|;|7hNKAqjt@1v%S`hY@FUt0@^ zsa5{$N15Y~GCFi5dHD)7w_1*M<$$&TR}Ox*^62tFL~ls&cx1opSi9?Af#H)BlkFk%r7tE$634Fc^>^&&I^Xm4UA=Mn8J| zSdPF+fs9x@E-Zxw1}lN{4V>Gyfdt;7#;6a^&dkg-0bIPkzISx`m*xvJ*nzsFp@D&` z+^jcB*{4^p-S9-%BJ8lzLC!5(8eU$JqVVe~DLuGzXRVjh(biWcL2^9)4;~P$%=-*6 z8e~>TM8iH`cTS*x%522hr-%U~@x#Kx=m9+GDL1hxAPH7hBYPFY2o!X5-9}FBxyga} z+B8E_7A!2FJCxMYe7l~FToMXuOLydMNxQ8wPc6*BJzJixzW_8dDSa**2P1xM z-+zvmC3iATcvCV)dB28+=+~^NrmbS)mXwf?h@|qD-nk2?XLRjaE$vHiVKjFSu`J7JG>SHeikVId2-B@A{PuM~t2=k>z%%ae8Y;^=y;Jw)5_}}hCh{I~^72E2gAC&f zd+yx116d|E#r%BK@hQwslK46k5))Clku~dj*6c-V*+X2NM)z3$>(@2ep7SU5y{WnfNs- zA2TW)jK0ZEp@ldKwC;OHyITlS1sMTz7adECQzek3LBZ+Vyh1bCz znp;*IwmnTp7{YAXmoLK;RZ=z`Z>FH*8SQr4VPP@kwa~*2f+U3!Eufx*9o(=(toqxx z7lTbS!gfDDZr-^w3RS+Emiv3&y>$Q?00Lx*9wnN}(_&R7Ne7|~)^ zdoBE_fM#Z<^IF~-KVrr}PRP!70MLXUV=1WB^K2bT+ogQl*x~7g*$LzMGQcd4iLaty zx#!NGmvEc5#4L#sa`=rKH`1R!$C$tO_wVmS>Abr36&|>kmtJ50RlVDB z9>q#SBT-RFDK{_A$<|h1)Rf7`dU0+F9eue}v8rXpDk?*nfOcl7=Z5(Vs)9-#rNywm z+5%x-HE2fatB5kBAL0pSKmovxit0#I+)AOP_wn<4wYL&&2Cy`(jHAiT=Af1nb(#N5Qz~#2jw~CE#jMiB+4(C9yM1f_jDd2qJ=&@A8WnZF_T6 zSUBCvZ*#*{3)K&{uIm_`+H`sd6+!z*Wm1>n58cQu*^Zf2 z&7sD1?HBa)e*gIK=N+@u$Biw2XQ6(weeSjdBtu!Eu!1{mDXF0vNox5nKA8?4-?s7XA2I8YL(p=zMbknT$ z?r7Uu1B-!F#WayD&^|yT3d8Be?@Cw~Zo;C%%(iuF9#MeAr0AG07r8ck`C^IDOQ6>l zn%sxl5WZf#_&qz(Z^l&r4%`A6T|dS+w)@nbNOAi+)WGuA);VBG(w2LG2MDtK{QLv? zZs4`vJOnOSm0Py(yI|B*XLifUIkrMPc9wO=acFD6?V_!(cPFR<@K|soi|*87jjAh-IVR`_SZ7E*Vbg)WnS3@sf&8+mBTzbslg7)@HHa0fU6BC8@u(GnIr>9p0a%%NF-6%tD&$l}zzz+LJ z&8^mEK#D?_3DeemOt?K4r?e;xHI3=Ikh)k|SO_^T=FrNuHPdx8I?YOQhrDS<0W@Ah zhlC9>h+B%9<0|ep{Tu_14I2{ZRQC5*MVr{%hE`W|>$si0eH(~5nNtf`R<}rNRG6_A zFqN0(?D_K>Rx0oYVoglJ9Ht~sgG{4AoLwhTuGb0YBkB;?0X!-?n%i_4)AfpUu3TA0 z(aK&s_!Icx`0?Y!5RXpS@ak2&nctTwB5$s~yOUD&Lkr`FO#$WGZvD@?;C-}8q&={e zfO%)v6^2nLC^W5@CBx!VL!td%=tB5Uu)vuWvBE0*k;52rmWIDmSAi80*&1-~o@s0i zdPmjg&jHl38=wRrPT1&`YCuCo%~*$1r$)&gWALst&2)uzw6=e`PqVUytY_U)i)-Yw&e=yR@bum@JLE}etfta6&bFljp;>d znwot*J%&a`4l6b2hAJxfzyKO;1ZENzgOwOpVJS&gJdkUq$Hrn(s>?roILG^ls4BoD z(jzNR+&aewKH!1uBFktukDtMW1bw36m%o3 z{Zep#vsSrg#dt7URaIF=*_p`!HAs%=rUY}B7W~h(DHIB*If?Eq80OQHZn<(i7<(#c zJbCn}Hc6RVSy}n?#to}hK^5E~Y+nE5h+)2MnZj>j2=H0*F39zn{b(DJiKpo0FeHkri8+94CI* zEgOZmhruR*N`@EcOGif(br3BO)(d-xbt{)q@=H6$IsYQv!)L*HN+V}f6 z7dy^i@hL))GwU8?@ znAb5iAKqHm)YRW4)c6FM`)+As4rAWxRP+cALY`tKCb4#sqL$4W0b7M?+1BhocI*|( zmDKWrePBTYgmXo_GEIV}&dp66TMXETvJ}|OC3y#iP1;S!QPUdxd`9o;6JsnCXOzU zpByRn2Q`jFw+fY#BqH)1&H%xB-ebq?;f#TnG3XvAx$1;nw~w~KhgiLPPoN&a$YEB= zWO>nAU;kl9$SKCbq>PN}PoK=je||F6z}iR4vh%;?E0{ z3cKVl;N&9LDGp(Cwig!<^5S(2ZSD~4+M9wwQG20F2sIMI^o|W3Mn>XB}hW1rOSG{E%y{Vd^5vDC5>A4^#cpxSr!3d}rbqkX-qdc?ie_?fi zCvau98nZ7e#FU+#y_VMG5*`6WH6i7V!OL*Py&E*4&EF=F1;GqvI-E%9KZk}2(Dx~{ z%Y410H3&64N=8OTX)tXeM!-kmRY*}k$EXqj9y>MC7EZl{`bDe@tTc>+=NePDop2P; zLEju>M_lS15EO(m$wWSA)tWs3Y!%Np7I|IyR4Er(S=pxXIRr;2j_sNkE*x?CeF>ym zz;wt6sjH`_N9uh7C>}Dd zWHMa(A?n}Ah#-3aCP)evr5ctwBF2?$^z`)8<24-a)eyG;pUuPFT#=2Gs9(V`HVrga7@@9sZ>#W_O zrmp^;-4Y&~?(wtiVh}=6`|2JWf{Nb1f8SP&84~VM*U4Yeo^$K9@Cqu#DGQM0sdDyXBsx!nmsAu-qI(}uMyr#S_Fj<~h1g3YL-A5Dm7+G-gbw|Hn}`6%y$P5Q z&O&ol9|?W@`2G&@>o}jW@(zM4?||VnkS!_Qp|^6&u(-emVh9jWUQ<((9YYJ&0(|zn zF}-aCFH&?cg-K5zK@~&)F=Jx0o%~gUIZVyt5TK)D`lU1!*63%xn zSb0b4Q&`Cd(LjQFl5*%zgKf$Pu)jLZD3}a4P6Fga*bFoK#ho&m;s}QrhLki65pePW zP?=V0;P<@XFCfQeY5YLf8XUZ*N%zmFeFa*RNF-AoK5=nEB&L=ggwur0Uk=?pj;`S# zKfg|~`)hFg2Rlz>Y%{%%@!@dKmv~_j(U#U${vjRlz|x8e6BGuL?>S3v4oUZXH10F| zp--*^JP?6}xp{52Dg;7kJ!T9Gb^sm03ia8aQ~&<`i_C3nZmu6l4uKYjzLa}U0a~%} zjfRK)#Ju3&td2Q^xF7~vjd|In8bFm5l6KssdgmbKVFdN#FbumnD;feM8Q54usi6o8 zXqzaxvW%tl*bAOu_FyW>-68y?S+0LV}m≪~%@F=LJOv3Ckr5(bkQ4}5W@uR{t9}fS} z3QBjtk8cO>5UDp8GrE_0MHK3;{X#-jfbVT>#L!AQhUjlMVe0}arWDtK-$UN0X3HM| zdqBGM_3d3B9~aj=O8xkjk+^~0<>(MZ;Jxy0>d7&A1-N@9Ta9}t1m+={{aA5iPm3zztH-kB=>Wr!#^Yy?Qq;J7yMc>1RXpYEzp#B>U2Za}-&6|%V7IkQT7 z^sEo%rd$4C#YK32Fu)Leix^ihXY|I!#_lF}K85uY&tS%IDaZIT`@w^0g@qD2U8$HE zfIUK~GP!o`(W7pQ>r=5^_F3+;;~?JDgoJ8ZQYp^JeEV>UGX55`9{>j>wPb&Feqqe$ zG7aeg`n|nZbRkr2!2bAw6Oh4&2rYskk{Cr?zI^%nNcgkx@I0L8%G54|OL6wnTjAF_ zDXvO{zHdQ9C)V?Mdit@WM@^YHJ~T8;;eZmUcRi*}gfhiuKHgon}w;|FpZSE9PVQmDm?xG1spjCA%1)r)~SR1(x)LmoK?@>^Ki7wQC(w zK1;CxZj--c>YQ-UuDQ|=3W4S36Xx{?ild(w7Z$oh_-Ji~R$OI0O;`@!)Ri$8lW)!|J0!<;#$A}Y65@P`DkVz1Q_%UYnn~bQz@AlQ@ zL}hp zQp)SuNgMRy7)T~vD~$;x8(Tx6jy^^tn$@j65n>+(H(Yr5Rx%y0q~v#0#Sb6u6kSM@ z#oQZbLvG!oea+NBH?LrBX7*{0ZTL zhRUyB1Fe(RLJ>_&Pw&7a3P>&2u@!{7gZ8l%lrVQGao_tTB_)1-^kkV;!?&+lT3%W_ zOu{?vSwSd*ZfiGelU5VQR0VAziH{_lYamJ@6<+UU5L~AYO+wcI$*>dtazrY;TTn+w zlQty#p|^t|6k|UPGM}8>lD&cdFpM}?3+tMX>MAOxB_#N;ORvJq3m-f7874AfQ8|el z?&9Y+C+2yf$IR=K;W47fszm^~LO+yMi#4>-f|dj^y(N>`+&PW`E){lRv!)jv7|sLt z7`oD%9$pn083(WWBHrJW;oiku%ctGua6wY)+v(I-Np%5;QUT0U=wQJYbvQg?G z)4^a-Z~q3z9JZiFpsD93534~ASKIl(J=g_{>eT76zw?=Xl{DBGyP%HGOBW5f!~2sS zu3xv#7B(}!1D1&HVXrT7aXbX$Un0B-^oMZJ!sz2BN+nznML|K#Cy}sF zvab=uR0&==2nmP~_<7A^t>NFfZ%==~0IVg;3p&^fZGqo4@fGlZ1q1{PIL1ia5*PP9 zZ*Fc5Tf^A1l)QWQ7(_)yw{G2fNgRNqWF-}lgoNo`T?u|9*Jl|IU*UO40FM*~Xe_Nb z69v%uxv`%(qDLat<4m7Lda5Q}f#Cf*dUv+@Jiu2AGqb>LM|j}z50jz$5X4>eL7FoD z^!Dv{DC%Ym3CBh@;mrYgJWM ze}6Cf9HtG11LcE)1Hmvm1L#nx*C6N6dBxpB=YXRk(kJdnXjoX5QxkMQvzt}Wo2W`r z=hTt|aO?t+k8Qb6q&)M=d!i~n*dhK1es@+@h*20D#Ky%LlzOkiv99dWlfdK$VUv2} zkfLmOG2eD~ppP+HKSu1N-aAB!IeG6w?RrO~u!P?!smCabgj;{rs#OFXk6h_=u<5|E zaff=n*&!D|+S2ztWA!f_@&f9r2xu~Z#6p~iUp2Lfg@xziDI3I1-_Vev+LFD4!+VWL zjt5M3U}9($#1-4`5WN$6JyhH<>L_bKInXOH_lbyrZ#6DH-t1-w%IB4!P*+ zwqep*^LUwd^=i9ceyZ?4doM2k{nxme@ZoesU>s%nBr@W>F@4FCYHu>pJU_VIuxvc@hy>BVkO4WcNVlo}QUW;`57Dj8`_*eD#5)bMSU-L1{(-i>HfKP*kj|uYZq6 z%Emo0pCTjxEckueEjLU8Nv;XG79e}yL35b=MFb+^mKQd-kkW`ob(Iq9}rfddvK6H zx;_FPf!th?^)0T~!2fw4!+EI*_bui6BdiwQikJhZWOP+CYv|w3g>wkrD`NM>2$L4q zItB*SpXT9kU!o_*@g+CoBv=wT;*6T)Ci7^X6DM?+DpE5(TsotfnyGwYr^^l;^uhC2 z?vLD?AbA?Z5*KfXJ$3??{~dF&4yq~j)zxEIyp^aYTolYOf650(spE8|e?YTv*5sr^ zZk7iK6WkYLb8H|~JF&J>%d=JRJGZvA>9S+=`~a5Ly;nS@kRQ6BbpqTFU@?Qyd~vA- z+B)icUwv)TL#urSmlyv)bR!Pnq7M*9fYJF!J3`!i>XX(nGn*)jk$uh>;j9jN1eGuOk<(tvxDTEQz4`JR2h32V=6CH7vz2Clz#%+H z9KZn#!P`j9{tSTvTM1k=fsX`q6VDD~EauC61#VN4bZz&0v)UTCmtiqRoT6?SowcNDyrVv zag$@8KR?gQ^2b4n>bec{3;;v2%ywiO&OAKE$tnb2b;3$nEiEl|ndpOa9umxkZHK+7 zF-L#@{*CjQv3y?ZUMe2}(M53Pm^YZCccI7%h}(6qQPjycjlDd8?>7)0Axp#AwLV|u z=h+&#rRY8GQEf3GKX~vUg`o*^P?(oZ8O{+yng2;uZ|VwbS+izM1|17I?bDYph@cq0 z0J0&JbsBK%a;>C9h;S(mCnYei{9= ze8gl8o4P*0AsPaycZ=jSAC4O=H)vf+q*5zA-2n-JUf-bL%v#~|DR84r=ano9^6?FT zashDU!Hw7{P4)D+7dgW%g^ylb$O&3ov7Wl}@e9JI&(I2ki|sGJK}c3`zVrQE7Qp_~ z68o=@e1cy##*DmU#|~hK^J*%&z}K*z;5lYvaztBvhysP?%=&IdD_y_5>VQd-$88hR6{d;0u~376>(O@ zlwqY{LAz+yxl0v>#_p)Ezl$u>^5MbG&ofbc-^X7mLqYBx9Gv^KKbn*_S-$m(`sI>6 zs42ianzfCM-|>YH0p+u2w?l!)D^!kGNzOmVKsu`(rBu+#IM28_D9bNB3ye7RtGU|( z)(%XB9rJ!TJkULCdJm zgC!f9*2OE=0Mrs)S)Hk?I_QjT&j+SUDQq;}j6~wBDxYV=sNC|9qMAx7b|6E`hbr;D zQ=C_#F2$#I%+-iNB?0aI*2$=}nr0ngnUm;(xlKQs2T6|WljwT=0|G)6 zcwuSJEarv~EaYd4-=1#0EhvNdoGp&Bz^q!siwMG->df4qcP+2ZE$H3fJWoCP?i5V!VmND;{lvlCZwX!m1>DM6}*)H zkeUOF*gSag&}5DmpahP894Po2)(t~$R+}Xb$6T9+poJuwLwU$L%*Xc$Q*3-0LLLG- zdM-aBosh6F67vPdRoSH`_)3B7*ReOsc3q{b%9-ajjXlvEJtehfAu_oYR-oaL5xZGt z?AeN-4!bH&V$@|j0t2G5#hH!hApnodmq?=s3?oh>_`dmJL&QHBb>UCcI-ir&hS5~+GEXJ-z(pZ_ zYiq1+3DF{x2`{Te2Kf6*mvTg5j6Q12K(^58S(viwwbTFwC9BeJ*jC!O-sYfF(Y62f zzU{rY)vvo+x82AO{Wm52_( zzk+1YqrOC)2&d*iwYd&isZIHzLM3xPo908ce{XPv)7>=I@fM)S>eYChb9Kxt z3-+~QAYXISBRC?c0F)4;zEbg_;4Q%zRyTS3&c>atOA9WP#%`=7oVr#pZo#wB-qB$^ z(F8FZbSYzO)NA=fL>SJhwR`~YLsnQ)KA%Hb7A_cd3)(9NjEwJ6@sR0YbGq@aPO=<< znd-Pkg|n z4yFyXDSHBwY@ zF|kNV4+@o=_iulK9e4&*cq%92G z!^*MOfK+f0NciYc%w=QfatI5-@hDxk#|r$R7=S~MCUR%*O737A23-$a#}U}DFm`h6 zA@Gt7Ov~JEPFz}sOUpr0pDn-4pF9>l<0g6P!{PHO_DVPS@5u&R-51yr9A(*ZI*SyR z$=X6SQrI`I6J~izHt?{V!oGyFaT>Ww0i8olQ+CA_uTCebH4Q~pEHdZWb5*6)HQ2qV zn{s!2F=VdyBEEa}mbh>34?Cr|dWk3kaeQpKmC!^Od~dPGoWtRH9Hh7SK9#zPMvm4V zA5MVXvxK&(9F8O$Jdh;EenFEd^jvhMm~Z;Rm(Ap4fA7|_j6L1oY|#W=Y4BYK5*-=Xio8Fj!}o_AM&%Xc3ZO z8ngv+czWIu*nsG(%-#@Y=z+KD2m^4jvW(2CHkWfsN>n=MX!tSUV5XQy4o0b6DsW6k z$pr1lR#^)KYtxXrh5T6>U!uVG5_mBH(;!Q}N9QgE&4H5>8K1LaYYIGc!RL+E*)3P> z?*Zr#IG8$i$jfVaTrY=%e`nhmPL~PKi^DOUZRdw?V*ZYf9oP48n6m zbs`HZg?{A&sKD8lv&ct>C|OwI64cpT*5KP(XdWr`pHuN4^t-*E;FM4gVNfKKje|sx z0gm&~r*Oh<7E_l2+0)54Le~}du?>?)Vd^CLI$@O4*^D=f* zoU_F_6%31TxHVZvRn_BRT#yR;>81pMQ>(`JR%SF`+VvQ?0H!gxjtQY247(j0rPWoWDk?L{&Srh@u8bnzW*0p z?;V%(-@pH#BBN{#GBVQ{$tYwby(6NbVU(5GL?tt1WMoF6Q#5EQq)4)gjA##KM94^? zDB0ipv-kL1zdwGT+x5@qx?MWY^YwZ@ALDo&$MK+L!Qv^*+q<{~!O;b#nY3Q{MMaCV zHszVj$I8({ebq_M2Uua|S+t1b>|aAM$T%~(_{VlRULm8&v(`~CVH4 zGhSMJzwb*@IVzLASlNsG-xw7z{5W2>P*-~^ueJDM!tMPkq0OpNI{sc}p(u-9;OPgN zQ5s>?M(+R%K8i#36sLPI4;GxNJ|BxaC%9}C4fGDG$_%2k9*_+ zjsE@NsGm0(i2*=u&8)<%j`ed^eRy(DRs=giX+tycN>Jfd3o$bb@vgmxsKNK_h2-QT z_bbw0s?IqS_qC0D$-?v1i$NNzx+Z)aw5{J*CHoz88CA!YUke(uwiXprk8v9x#KsnE ze(+%G#bud8G7)glR-KB|idi1G%~Dy%Q=$HL#>P*#ZW-J8yg2vp`c#dZOD%2zR%cQV zN~Iz@ga(VSc7v-6E6vGnc-(u%wrwM&0rLR~1&$T7J@!WM3n&FWJiQBouBDbz~cXvoegrz;T-?oFFdgA!A)x)95+GZ8Oy?giG zvf-N$P**eK-EZ*y?&HU)0eaF6nm0yyBY3#DF4I}su3u~U?2vIfPZnDQc$fun(6CC0 zlPN`9v(@rDqA$PR*5>(xv`29OCRKlqM_P6-K07a`?Cgr$?TK33M6j6Ibjjky6AI3k zQn_b0pEr?V5QS`q3^+iOpOkeqk2U55$^B`8xyA~%Uemr4YDZ9I9 zD6*C0cAx*8o_GB>BHV!0xK|+-+oqGFRTp;G@;PPasE_6=j()uMV_$rVvsJ+N=`osv zUMn#b^+=f=W|=D&P(|F;(9n3aqJG{WoZe8zzchx_px$^bTaNyqt39mvvSZHDW(LN{ zFq0~Wp2^6T2KbHrK!^PD`k!BC@!eQ4qGwOTH`U*yB`$Fj_o`*|czt7?SH-iRz>aeu zu@my2dcS94EC8Q}XS$yzlAdqj5dUNJygwiMEV}ymfMUD5D)U`BcIy_*&stgis1Dc6 zNs}jc_`o-ValD@MAAA2?NCGF>H4rMTW#(W0VUqQixq!opEVdxQNNBP4W1V$Tvgri( zAyM-Od;>+wRVs^uDM)V6^>y}Wde0lbBr-80-s8 zBe@^#GfdaW+9q9!y%H@ih4**4Tbd4umAL@&n9l^(dwmuuJKZgvGhJ9C1wL#ebuvTV zTY8W|H3W(hWbY+=VM0LDU#fhfo;dA=?^x9t`1%;MXm|6o%KuBby8?p0^OkGB0<~1F zr^j!#8po8EA3mHR;E+6Pa-`c9o)voGCS`XZe~9|lw=$7i#JPO&Gg2Z^-YV`VB80qC zlRL={cX|JHh1KP+3(S7-qMTy$w1!8`k3SD?N=-L2`GMVgLPhq8vG$s%>Kuu~aal{| zHRPG7w^H|?PsNEIe%4(zr(MQ^dHd(<3SX+YnYJ@UMvnsOsdAWATe>u)mFi2I4b4`; z!UM8^I;1p{!=GxN1GCdZ#P-nq%VgPL09^XK?0Y$Zk54?3c%q?9XX)2V)w z09^hdPXsg()!yCv_kZx@dGoY6m_N|z=xN`ur((U3CMJ~fd#8U74j;JjNA-wet>vZX zC+K;jks<_?T#t2_Ufx74_F=r{9O&+difcc2*y1tPX!<=D)Lx=eq(%CYH?y~Q+*ZwZ zVLQo*@87?Vii})_HCS%$;2}f&2ThZ!i$AEv3reakIh|R=*@7D=Gpchq78Mio?jJU8 zSqq9~1MeTz$?6`*6QK-jgGa4YHi`t6m^jQ#Z%#&IT}s%Xq)-R<+60~}uK9(EmA$kv z%fZa(=I^VB0po2)_~%H4Z_eJm7b^M0it6fLqU}O%44mmse-6bV#KBRi>gGl z(*;AZQY>PO@1(Gteg;O>wn*6-GBLsWeAE<;L%6hhmz;CJIV)_6&&*xk=HN;X1U*qH zbC25|x-)P-*DF`A!b@49ry}w35QSPh$U;CLk&6Kuyht)KqcAY6%!=A}-!3UcapWW$ zcda!~o1SyyhUB41gCUh7f_jE>b||1|QjrTb-rq%p-A`$_YBc@&9KwN^XDBQ$TeEhp z)0=tR|LD1yF8nSVuBeB%15r>S3| zg?yRNvn}?3VDz_IG%Tc>7rQs~`YO)YcoD}l$*tz|Sm0Y;{&Uhh@R?!V;W3W9!2 zF$hr(f5a)aJI9{H2ksT_YZnRcUN^Qad7nBy(71OO*o5&h;{n|_$nU(3%%|pq%`6NJ z#MDor_h49sjqsL4;wLV)`bGp%Li!n5;eYHH{eHvd7W*B0v}mydUmw|)iH!dFEja>c z&dP$?eN=cl*x}^W>PVmXfx8v*l#HMAkjS@$E}<{f6bZrL3(tkZA+myU;}Yz7nR9|b zm1*(HyXamBj()B5fX?Vm*0KJF?hyf!J}qd&6qo05XUWW2XXaf;s4~I2eT(|*@Ow`k zH&K(51ke~syx&r+iNUa)xp2?K8^G*B2`XpzY<=y%7xjIg(-7ACmb9@ea3lqynT?Wq zOWL}I!_{B(gPfUL+47cj>DQdgIF{=DP(0az2j4}(l{M8&XR zm#2A}l9Ez0dHH*b&I1CC#ZT|BULJip5$EvFbGF;BZe$WW(YpN(DpDdb#wC)_m5s+P zD=Xe=-?JXNj+PN)_B9{rRT+SdIH&xF2lv37ngO0>4#| z?~-mOR#mwMO;u4>w@|d~f?VHm=~5Hx_J>e!B)gXK&kl(%DxPZkojXzI_q~9^yN00b z6uWrlLsdln*12uHv!u;96u65W({(y{+q<(fS4c2XeN7LBge+gM06XHbc9J2x_Us9` zUm^6pB=|b<+bJfyZv6disciaAqcAK~9(n(&=S3tfdn$_z)msy6eMS27{d+JrNNYUc z>6Vs;_h%!l>Gxy&3OV@;&}r$Ywavyaf(SPFTvLgrf_MZ!1#=0GwbO)z9dKB6uR)zDef(Ge8pWA$U*1G1ocm~igg|B#F$!lw z1_zD`y+3oYm}T`b*$2tbXVpy+Ea|elbLq_nX!Y(LP9>vT)YdgB_r{H$m{_S8T7x7& zgne6Cd43a?b(8N0=Sa(x=4O>6OFeRL5!dkSjXJrqA3viX(+X91ti9mv5`XZ>kvnty z0-q&GdV9h=LpmaC3mDuj5O1NJIW!*>;WUAG>r!p|9*OC5F|E(-so>k25!0A4S56rO zf7SQ(@zO&t%jd48@sAIzyqdHBG9kzbs=2Pb9uxYnpFf|J?#w}HG<(h*Ck07pMq_%x zfgoNv(M=R5{8w)cZK3v`Ksa#jSZvNReu&rLbT4X1w zL0`S(dVu@X-gv8s_kV6xI4FtkufgPA3|)1L96_cS*M~_R!>zurXmiZECH_FLIN?R# zUz7IK>V$gTz3lAUiw$B+AOLTos*r8bB+9!ACV{*p*R=7;Q-<^3oqD%}dGV%-9#eX6 zL`q8Utt)S4W2%0}-%}wC=mtxGsHs8d>&Cl$)T;P4Ed;a7J?i65M24CZ#NQU3Ry7+R zprkMX?LQ>j3A8AW8VdI|D&b2JLJrY0T9#UGkt%nlk8o@4&+lW8LvD&xK4I zbc8CmK+aLP*&JUjn7v+2+>Ua?ul!trLxqjj9Ds64rND3NL)5+2e0kf!{O!y+aDT$x zb~Lz~g;^4^#9)E$AgL9<=1D{O4s|%e{2E3j7?zH=-b;ZK#9hu)N;-I$W6GeOoa{<{ z9J_kh()Z`!7RrnQaj}TN%W%ELEV&o%@ACVl%svqqC|-nJQ%=vab5~Woe(HHp%P?v= z8FO1`*MuMA_yJBu!A63L2M3lHtU%SEmraLm@(~Vqp3T;CJ)Efd zbmiS5j&mMi|1g+vL2}CPw6os-{P}Z+xUVq)m$T_r{H5~!`*GM!s2JYDc#p(i2dz>> z8adAUiko?PH8dK!@vZ6U^ac-xogF1_2JxNIp@VG8#r)Tt4=0DIi^vOp?J~$Sg-`Y3#%WUDmqCm&28Jo?QH9I4yd^3N<%1G~Q}JE*a)U@fs43n+Y)3>NDSbo7Jm1wdSm2W) z3~Orj>$ezI0)8UM=3B(u-i3k0lSRflSbz8}wp=RU1@O1hInl{E@UfXQ(+7{A@ z^Gi`m;|uG^Z5QO=PY-A?k)croY}cPKnIAw!&A491n8>BV|Ind@Zf+Y`#bD>-9EhLw z*|RynS35Q_-d`fSz!tp( zE-+%%sy0#S>c+M8^|z&6GwyMa5Hjn^=Pm5I1ZLoh)_o+7?Lg!&CD1+KFO{2Qm2mM^ zW~LTYM3n|5JYJogCR^vOBRI@ph9m5&SHAs3XPx)x2a;3Vr}}dDS81MHAclR)-#rLzauxH%E3|793 z0u{;TGhBUC4BtDLPg}(-3LMxY<;ot_rlJ$XR%LzHF!}a-iAv?4nwT@3g;G|pLpSHx zO*{g33|x4N1vYJXsiaO5>oQT7#mx(s60$44@~gdYiobVHYG81pxY6mqqLvaVS8nI7 zvu8hI3E-#@{Hdm~@iqg2j5G(78NlD$nGpJ;I`@(P> zbma4oePM2#3XlOa>*sd_S1jIc0-IpkY!Mfh%t}$|6gwRIgM{SdC~1F2lt=&#t$mD+ zT68rdA;1KIyn|&$6=IK!;ZLYJZwG7a^&Nz$8|@02T3{)R*-jf?Qy>nZInI zHe%U>M@`{nydTSSXax=!cI~est}e#0l+$R~>w#2D(PcFTB~0d>mMz=Y$Djclw5`KV zc(~P77V)i4N+mv#H#nUA=`YAlVKI+_$F48V%rq5c(52%%pJx_Z43%#Lhj+x1QP-vT zL2m8}+Fioo$;ItY)4K!phD6@jkKP0{Ja}m{iLNqFQmm)Y`gPeS@C+kZvYcbN3z4D#6p(5#s=DHpeEs5wZ=J^+zhBH7?W;$xmse_N5rT@3}bC- zDvT%}orp`vkDDnjh_KWIjS~itO`dD>WAB4gQ9%W^ILXwH`Y9VbDr%&U16za(OMgLs zlAA$lCgPg$ettLpUAns+J9ZSR-2$vLJ|`7iEhao0L)(z_t+1vXIKViD%Gdxa-WKkdj(zmALow|KxAc zG((k00MwPY+^nCm1Lu%Ly!`1*eK7`_Oc4z=f(+U%ezT*n6e1QO#lKDV1;QZY1&a#5 zKkg%skgJ##EeB&@{2vB%a05YG| z4(2tRc?FAHT?OUcPV)twKBJ`r_ZC4f0LMsbUF61HF)%Pd?nleFhS?^S>hmt*Nr-Fh zwc*NVsESCktWFHJ2!^PYih4&TcSX_Dubuz#|`V4lD_pj*q=4fN#-9a#wWYwRjGUm-Njh^g%mD6+?j#A>a6=d*QxCRGwHc zlxMJmBn?^fL0;WfT`JZdKP)CsniMMk+|1Ily@7d4iA*%CCtOJ(nE_J%ESNWh2u?^+ z&$iHbR-<^78g}4NbbjxP68R4en4RV^MjRY&^yl3nFc*i)rXC+vBuv+C9HR-Or1ssu zU5F_{M6+Z0CsZ=ufn}gzq+q%e zQj_tVM~7phu6$c?TcV)oK=_+G#NTZ7STUw-NR!7+s6EB-$G0-F@nX2Adul3jEqaa~ zee8mvFqZUHaOhe^+lge2AYAHZw_R)72n)0H`u4+gOE%zS-$+E;BeVRHYV*MaCl+|6&m5)FgBy z$^Slt^Tk6;1>robR;*^B^Q=k*zfmTn4vj9QJ_6~XTo~kPF{$qk-FdhHL95W!PR!h}#PFxqn5f+JBc{-V5x-M`JC1L& zjQBL~EmdDqb7zLsI~mLsC^hJU(c_+!pY${7Q}=d~TcWPd)^#nh46_7USO+>`1lr0f zi#|{2vsS>LGWgx_vUwXdvY<&zf@3Z*N$i7T4jbsDHs&^{rjTkEInZA~H0ZEwcX?0~ z|4y%!*2G+yL34={7KoaOqVvt~;dpcfO&tz@76B-~I}7a`JSB>hPV289oYWWiBeqvr zjl@Ssloi{ny%|&|F$|@3>2MHenOybBth~G(w3)i-X(w^P*+hBGexwn;$G7j=HJQFq z2u|1)rtqgdZNjKNLE?e^`{uOXIZNuP zaK$D-xB!7CIFDI6o(RJOZ{Ds)@X@1_Ttb^uNpQK5h#O* zg4ioXlyu)W!Z%fwZ|r(DoCzxF)8QV!y!0u@X3{gnP9Gn)INgjX(YfSgI@1W>Saf7h zXudT+`n?HilBc!Uyr#KMpb^;e(4Z>8_OiS{H@1I225qx2qSU)~&#_hgsMTIx5z-Yd zoL!0{%d(8oJtUvx#qk+AdNfs}ta`AyKhi+iWyL5u8KZD(2LT8P?M-Q(u0rRt8>$P%JxIEM>_e;LQRTm($<- z&x>Bk*@%M+U#YAu5eEDHI_|19o%w%{0vjB`%^^|6`J-=o#5}R&_qKC4Ye<6^7pAQ; zMa%Jsu8RzKT{>p>w%LQ0t`8xQZen`!*oT=kK2`RozQ zxK@AMB(61eA}p$PLaiQM3ReIkceHG0bx@NI9mNGxa>)yyK;!me%w0qZk1<}kT2%EU z3;jUkjdc)8br0lOo8Ln=0c zEtn0+AuyKC%?5dM8h@NRMzk?T31f%#9G+S5@MVM%OvflxqD5;yJU9<6NdUsslrdMf z_qI9ALxrb(u6m1#k3Ge(*xj-0C6Q*Ns6m&qiEOOUF#6pDtP>17>kBEXKc1L9NC!Vy zc^|9tq3bg+cN{u&D2m0C@--M1KEsQMHj-&L4U|(C14G~kvMLqsbnHOT;ofc|xzU|S zIr3(GHu#c}wL81T#L_rsig-NKAX;eTt4Tg?)t@j8jDfi27{X8HSDcio$G_d=0EZRRd&ong!g)Q7uvCauGr)(T_^<8hV38)an%0|)Mj6n|Kr z!U3+-dUK19n;LPD0rh8gUhh1^kNLk^moDJeS>^r$#;YP5L?Z%D2Ikg%q?dN!&sPVbl;Nf*^PDQzR2D$-@m^ZF4);>e|!$r(< zgM)*0L$6-v4S;K|euX?y1IHdjZg;&k<_$&C4nTwiNN=O`;1D&+`1+RatK2o z)=4>q9Td(cefw^Ulq~kq_q77Ag4C+vr9+xOaKC~gv*46^tREhh;2`Bn8EQ+YXwapF zQt{6eb#D-(N8~FqKMQsrB_<}KAJw+m4)k8%_uM8DXzRgI?St8na^VYX)TA3JOpPcB z(Gc2{>Tl4qAYdYn){)8O{N3@_tnVaQBf65Myd+rJ8wQzs+`jA!MBW^a#q<`6ty&>v z9%t4hv$>~&20l@G+T5}Tc{6u%A5nAk$dNyPeSMbH{3Ee^L2$O=XK)K9N%V)3aKQ@M z#6=EZ;AA~*UBjm^(heB1ws+@?i6nDlYoGIJ!CTypdZhg1)g*<^LbD`Bu`xE67u`EZ zhgC2%po(4=IjOFEHkLT&pWQ{nB$Na-B4&((UBLN188Z`&?@e6NJL>d|rG{$V8g;Od zqGa*O3Qs>W9>Q}`tf}Z0(*Bw3RV$*a;0WZZ1;imaWo8^HU9k+`Ie^+Q9(04q7wW|e zKjEv%yf(%r^LK==LMuf@%Kj*+VUW}3;NH}$JP5d}C*{rVl#Kud(PO2CfRVSppytCb z4X>{hMnZP>_AmR!NP2D*mG2I(cYzHx+hS=?XQ3ZNGLvicjjeQy%T912A}@IQ5j_dJ z`#TRY8l4&-noRqPEUY6N`0uv*qEQ!}q=SFKRW8K_mK__}w+*A0P?2=;RzGF(+n z&3VBBsx}kF3Je&wcY2w&BlnSh1_Mv@ApmQR^wag~{BGImS&+Piog zkS;W!JhdyhQ*Lf|)~ScDQLiKSafB4W=mHVeHc?&^+03lX87o}?H&!-i7tIV?tE@&J@N!oW3-!hSW!mTX` zP=^b-^lBPlm}6LL?j4rtldXMfb1&*o;N(4i@u|u01;Y85vJ_sQ*xaEPAN6B*6P#qrXacKUad3^ z1+KO)(5lkTc=jyhYVyE&*Jj_hD4SMDJ)HEW<3+m+#6#=|5)ZZUk0!4E$U@o~vRY)@ zg%~*1R@_grJTLBz$U>5eQ)4~-XnQXP9!E&761tOfRe#NS@nSE|ja|V48Y@o^k8tTH zv6Ybc-1$KhA4d@#LP(-cx9?ph;%gteC*aetW<0rety+ai4fUPw1!K!Km#&==ze?z$ zs;5Qi=?g#yM;_VnoT8hWNXR!OKRw;u8#%U3B)6In9)GipB!#@ITTuXuVA0T0p}7d# zNm+_{ez~*!r}88RbN{19ONfyGtC%YZn@bg)xdQ`DakXOWpT+%0OX1-{c?p$%(iu1~ zPK;G}7%du~Fu5K6W^RBzH!ARcg}8;jtLeT*jUHW~6#7$lqq#p0TsRWaujI)Eun=lC zQQ$J0r^WUiyVt~4rb?%zj?GZPaxd}#NSlceYynaF+BE~SwTBNJ$fbYcgb1q0BYT>0 zqi6DgMu~5Pr9PnyW6v;o&Fg%7Hr7ze+8-NtFJt4X`mX(H!c=@V(JYIeo!i#3@wNfi z;49JQhv86{GwbTBunD^>!quZ=BdT^#gW$t>O5Ufo;JLoMi-zzk#eW%wiVYnHn*Z5@ z+R^Um#ScNf&loyise#-Jc}i9;7a{2hx+Gb_#^wEb^|}>oS<5E(Qf?a_wjU8$oE%(-sOQaPoX5-E@Yod@BoUiBF}V^B%!I^7r$! zrn1_zI7K01#5SDDCRSe&v-WVA#OCP4Y$*X^rs`NA?>0Y91+IbC%&CBeP8X!5q+nN! zM$C!-CSzksn>DMEzca$HYJ0hvBw9s$?HI0=n)j+?Docj#97gFOko$S;vRT~0$FJZD zkK-6U%wS*|Vg9kz6bm0+mZ&feWr$fIn}`ycjs&e?pL5U7J*r>VTv8({3Y<{QsW2j9 znx}YwJ0BEO3T;+VL1E@X%u#A)EQlVcHarSfp6){z-DN6W+QzPFoq+7=TEHt#k8M%E zoOxv9GGViGrquHcQ zsuvD)=y!4MBDjCF_=h89FxTEN2|8jL!N5FB&qpC|k3N2f1}@rQZ0@UWIwxaY0dEg@ zh~mJmpeJ$jvoMWv+=fvqeJ)dkfBq&7q8F1o-6CUJ48RIl9E>N~VuQj;d5&CYu=?oQ$_5^&6*YErrg(M85UHsDKD z6IZRe2R!~O%w%>Yu6Q4DW4~5Xw$Yhtnh%l|Y@sZ$f8e!!&azu;hb`L#; zSwQg=x~_$jdYQx4;6Wgj;|qNpyL^(7(H81S`qCd?sp69cYNW^hW{b7TpID;|)~ex( zBVc_wiJ_N(Tc@y|3k*3l<~C*c+`Ro=7)0X1npRY#oN8@3|FXC-+VAte?r2`g}IWd>WmvVoK zVb_Wx90Lp!>#SND%CTdw<}YneOkKGC0o2)%n|_apZxY~>s?Q_o%!Q>~7ez@M@vOA* zUT44&bHdGJ7ykoaUwLhxNX)kmUKcf}Bv#|&V} zo}?0m>LSp5J)h(?LDm>m$3Y9>{{&3ie9RAUcWw>_EBG=Wkjd2G63hM&Hjiw)oKh-L#85)<#3m#ypLea<9dr46{Wz@IcE0~`%L=}qIH*+$#J_KDT zO)X8GXLB4T#NF7~-}jy(k(5d&FLr;9_u)~&m*T}S){$J15tAW1ImSxij*nvpEL2pN zwgkSK0*i6V>x)O_b~IWVar*S>&mVSFo^~~#malN-A>1caVS+!R7&;5}#Yo58P}&m) zANgckuGh(FdXvq~1q0r;Q@x@XRHj$+GJk!#*^b*Dt0=k7D2MC{rXghOwk-)xbF+ZD zQjSHhr6LxZqXG}G`F~L6pNQw}nrh#uzc_1??U(0&w2oN^B*{gH9dMiiF(Xn84a3dR zdD$`pR)%B#RrKW9vrTmMv6J=ucJ34c(*+B{SA1nuNo+}XgS-ZJ`%kjwr{%4#68C=;XKu%A3rI`ajtuHBTBwhimx92LHB3*Vxp-x)(e z?xd-_28>`Q*(?0bsh{sH8d`52F($u%pFV7c{=|TB&FWI;P8~Y*@}GoAla7eyF8=J< zki&;@5~!!45{npCIz2BX{h$gq=74C4X6L#kWqQY=+eLPS82!eSw8y*_@#zmXUhH;^ke?RYPFNm3heDn{V~BFts=(h+P8UtTt~pxx~g2{7{7b{X1i z#_R&E33r;k2o};VO0}4|XF4WX(jc%_YpTXE+_|^_!jZP#qo3--=((`Xmgj~xu^+&? z+LYPZ%T`tvzT?G3-f!{-<)fHP%j6_BjYzRFTstAMs@-2539GSj1MFf;O(k#~vMMO5 zPz5f|HRj`c2V29*O(+idHAOKr5QLkV6DlC!pJ{ab*zFfh+XzO|VWRRDP)3okeSJJp z=N=!sez-XO3gUPA?cKY0{SMuVc_@%*!yWBn08#v9uM@*cK8ifz<3uc!cVVxx@K#DC(jyIUL-UMK4N4 z-{jzug`PfrfBJ(*kJPM(XB`R&(ZTyg4E!XarXpt#xTteFD$2zA_b*PO*u!Fbj4afy z%g|fwS%o}tsprn^%v^HUKBR>%i+&*8_Fh$Kv_Z5|zj&W~#$?+TdRGyJ)TMo%UBinO!&qX3mF{$5d1ByiY$@7}*poMSJm zWfxt%-NtC(GFswU_Vyp2rm7Yw?7gKnrr2zPvGJ9)qod|0^G}5>jH>Nc^rc|Fr!@%5 z0K0DsW4Npqww^weN4y@QX+3V~w{D$+!zm;<4Ds<*8@h9@)y%IF9u+g9z`VgB#PRFAhFyK%alGdpc^){Vg~k2eFq zztvv~hjE|Hn@}WVLz(T|VL9Ia2H4-Ndv~xQ+rx62!q;r&N)|;PL#apX;i<2FlimHY z<%Nz#yM~2!glC#7Y$geeg7v%4>s@|Cz@g7IRMXnniA37IC(jWy*c#EUWy>3D2k1_u zoMY<)uS@5U7)L$i+A^t|o)z`B^z_c^_XFN2F%jTn&zw24#>>eEpk?69bMqaPW#cx9 zy{~vq+5=DW5-FMA?vAsAUfyj+ZF3)IfkWM)xdT@+v0lcB?A)abJcoQEFZ?*fj%Tx} zQ(10qm@SnA%M3QGgC~fhPN!RS&TmiZiz%vBTOm=xWSDr=nyD(AmlF(zjT;v-sKu31 zKpuMKM2S|bA9Y*=)9<5BPbb|HKm>&HT{O=L*a17|7d_`%Ik>U0z}buZOaVlCZ|H^>zb3d_Z45?3?9e3jyIx&1Yu&Q=Qq!(DsMP$ zJD}XB4^bytohZ-^7MnuLmKa!~bs5d-Jei-NFg=dNPz(l&<*pWw_`|HAAd`P&;Da?e znud7}=9K1qy|#AKw^I9|G?k7^+kAbhbH@kL(EMF)=2#dM;QjpH$H3?pTspIqidU~z zvK~+7HxUq>7WkD%3Y)lS8=X>uw+)z%Yx((21KjJIM2HrXW7<{MvFD+Cv9G_hXX_b5 zh8kSR6CPS&%Q|VF*Opqcme%o-*Gg!+=mH7If`Pk4w0^F@*L<}|X$ah+Z)|3u%nDX9 zhIdSFdxv!&^n`@H*iUt8B`>jxrO;exJ}m>hoHZP$U-$fkWE0=1qS9Ny0na#74mY=x zKbpN6TTazv`R>;6sQI)ujr2U0pNp<=A=Dhf4z4I*%0?!4)LOte6S9tLaa>ST)El5I zrxaHPpX-Pazv;dRxK88Sz~kU)V-y2^t$E}=)-c#ZQ9l_TX==bZ2sGd3>Bp2Dc89nY z&Z2X^!;ySbRW;SxfFB+|D{*^d_z}D+tE;o@a^dd#Zri4*q;T07Sw*x8h4LwXHG(O- zkP##Em|om%yO;E8Gpa+jR7~at%l6-&KxN38JtYmHLG1*bVQo&!O=v4&hQ+EGEXWpL ze{^MV6x?$q?JEQ5`XKVmk((XF$!)Z`%Yw*|k0dGo;pyU;Tl6RNa_C`lkfRc-VL5Ti ztr1al9m6T}Ipng&Lyk5n2y^%Vb^}Zv8Z@=3K|2ua96M`FySX4ApQL=|x3Ao_x|OFN zS~s>H1QwUA<6v;Dn9aTYJ6Ps?~BEnZy#R8FmMYHj!iHWm3m4`9bZ;;^9+;vRHQ-_n8@Cw=53Qx}|78a_t+|#dE zs>17Nqo#WlU&{8*%I?d|$Xvyzc84~VsERLlEG1P)s1e2XgBYZqyIDqyUx4hstGC7hNJ1LgggQQZFd(WsDgei^8 zqXHu>A=fk0D}=D5Pic;=#>HdT0F^k-np3zx%V*k%M*2W`W&3hFMGL^U*yeh`hCU2!L3hrJp8k3!ZBQ) zJl`Bq~396ha%g9D`=jHim1 zj=gwARjZ4MHjR7`n%Az4U+4Af+m~m{JR-O#SN7X!O%1c`hONo3{%UG!Y|6R>;s4o& zuiYPS00mE=!B}CS_{FFn9mu|&J1-#y%>8NT)#0D7v}kA$A`E9M-WBXb&5yh~rduq+ z!Yd^qHGS>cl4`x>m<&&w+0j!WZG= zi*b&*J(1a>1#R`R6_tIAjh6o;HC@MCLO3{a{@7XZM^2o`J~0H?f=Y?7pPG`=ohLfz zivcAg?X9kFZ6~*-5%4}+qTxcIPnv>vkpO&{&=p9GCMsL&%Ef3JYOt@8IS`&Xu6R}k zRgj~QuF1x%^A^-x_65`z#;MCBq5k6XJ*Eq3oS$yQ#q<0s|HwzJ+QGiTROfhMh)HDi9g$g4oH^ z%ZDx+VjCM_rBX25?(tP_0#6eZB9fq%{^pnvtX9;GE?JUZ_H5fh8!hIYsRt5ABr~WX z_aCcJ-|%G`QED4YjSgS!qL6&ykYjS>^XEcgEEv9Sjo+JWhQ!I#dLw#ej<7wt5KdHj z-|&@uGr>7?S&s5$q6g0e5}nq^9-~)10F9w$gDUyAmOq;TIRn)UQ=UG|%?}t;JW#zFYmFeGGc7AfxGtZ?bquwXNk5aVUyGN-Mdz~EVv#+W|%^*yC9}@ z%Mpk!g(2pcxr-e%h-Fai`p%7>3D25H%-6E1-UJ8ZmQnGymaF*|1vrMU!l4PAW=3T%dGOSNJRaB{(oYSP?A_(UOp{xiCKmEHeeDS)(^ONOr!7{Ix+Uz zRE@-o7XfcRT>o9CQ?LE|<9e4Nd8?*ZZg=aXb({xJ zbt{bL&wmaQ>!|S2NXI6Q?J7{;S@4Dl0|pQAMxB+FGdhBYtQy^`S2;+=@e#{=r2fK4 zZKl2bp>dyMdwlJnsyYJ%0uoTG)e%6=?pz{t)|ag)1~Su<=_(L`5ae-5nX+8J_M(Roi&Ew}_*Hg1#}g z-}w968|0yoDB2rw+h|h~^O||A9!a@_7 zQHQs_Wh7$@eI1y34Hz7PI1ozM`w@S6CZ7W3#^?hsq>IA1J20k2(t?d!j z`Q|lq7kr2-RCugmGiu0kGdjCZ_4T5H`RC(IgtJRzI7+tj^aA-xeug?Wg&YIyyFD1B zfYY^74?Q}1^_lam?$BXn<*qKu%Q09Q*_5 zY9VeH0Ogdf40OMI{@kfY8&AKl9X*#uOfMN8mcMJQ3k#{cn@i;-wju_9K%*=Cr6a?? za@cAvJ+f_g)p8oolHi{wwISC~pTwN#Zpf?%h)W8@4@uG*!Hj1obgJd(Q7= z*iUS|I+`5Gcro!;n}1Kk6NV+m!d@+7?}dG&tVU~~mJg(U8FP&oMeX0YbN+})PJ~>} zDO{NC&JD0qiv}DO(b3-PcFn&5#8zeV*Y^MO1Yo()Es84k?-zp6jgOB+=J%LcIXjRY z6*9)_*bGXK>K_oY-AAkE>ul5bb8bcvojw;+uN4Z_`#;C^i9Ov3xxrCu8Lc@9NZ0p8 zsH)ZxkTE*i!KoSp1bs)d?Yds=_5D{*uiPpw z*4^YtDoxU(2>xwE@GoOrN$7RbT0q!hYBUcj+Vv}v zjVGZ_VOFLQKiG!pqH>2#DpRaC-j3~C8}CGA1~~lRpA{>Vf~HQi?y&I3S(qlez8%j! zE%x#8@s)%p@x8>)vM$s2J$v>n1JBws&;qFkY$}yadZhG?(5;LJFjei`xxqdR_9dZo zD$W3x=s?Q`ntkhX`XJ8&MXEM?nneR96iTcOu2mcEdiQsP{ItvHWob5@6#5NVuG7pi zL;MnpwaI4K+R;GDRQwUiR=E`&c$Hz`k(Xi9wa&_POZdFGqu6Ib{J}~f*T{Y3uP z_!wb8Cj1iqc~QEXr)sQcpMlwgdqBF-C3Srd1}3Y@MK9?6F|IIb_G3XnBIf^KUo*Td zhDwQx@M42W&>=RxniDzw*Z((bk^(|TuQs1K5E%|Zl1jbkzjQmds?Q%{0@zu@SKKxJ z&Q`ylsaA*2>{kGP;oKbyQ&TJLR>`}64SE2x60@Cck0)R?^8CZnxK+KM$slhJ zLrE*nw{Sd=`BZQGJ67q^8W2)tM)xv{6r0$LZG0tX+z#n|f;9uYKp{KUrT%=G+p$u& z;vI_G9F*!=H^Fpfel;LCZu<3pUgq?WtDDXj%Qnm_e#KW3yQeY?YB3_6xUX9mC8bx- zpWoxa)^y+ZG^Zwqp`iUuX}Wf8qafKC{_mGAb34>6#c_Eb*rU84-^Up}I;Fu|2pX&OzS=jnDz)(RjE@vh>2uJ*;&84x zB|S5sc8=)`n#zyk7Am*@Rtyz@6lw9_lbnxXlvtJ*(*X7?xH6HJv9eX1-*3t>%+ze3%$3rn;kXJDjL7+b$Zgl;XPM;a>ZL zfet=?WHsfZ80-G^{TM|Wo%ufJC}EoiJYdL>X%}oVS4-#2daZQj&mLRDSN7JpPapvL z?}-g&ZXl-AkuO-Zg`V9TZz;cOU&*b%{`qDI2^CbYSk^(BU!?pl>Hg!JY@0v#gyl_H z_K=R04o}Bj zWJm(ThX1Zg8Z-C_*F5{YElqqQR0j$XS{GI2+P522=3N+e<*~;5B-=mB=9TsMO`A%z zfBPgQ@xW=T4X=PZ&gp!ut6Q85{#@!-aZhzpJDnr@KPM&)#IO_OE@rYB$5~dx7 z)Xy>a{Ph1ml{aLB2-0FA#HOuOZ;pAt&V?&8(D^jCPgRBfae>+*(*sx|E`8!t%F@EZ zfPOsb6)RVIV}0?dW$XaU{MFz7l%#&XB&+???s>lni-HoS-Y@LA-f8@j1A0SSFS$Eo zk@qyGNqvkRIyYbVOEy*W{+@vy4sGbVuvJ*lkZTKf2PE9ml)lT}m-n-5|Br90Hr{zt z=6Sj3s@LeNCpLW<`R3QRU{8aksb9Uzj>8OhjE;!t*R?naz$MmV!$$XW>G2CwhW$>A z;nWnG8=wnce%D%}nMPU@ew!wH9|%iiq_hSK6Qs-LwG7?UWm8V3q3Nn+;`okza}WqD z1(MINiWe{RA;uqjdchwm(OB>Ar>(}lJS0y8p4LNK`j@kG@n6pGOzlkK_xy3K{q%|b zv^~@jTaS1pl>|KJjN|(D;^ag&8DHblXsi2%2gH##mh8E{baBs-BgTIe|E#vwbn@i# zlM>1I?PKJ9I!5pLoj1KO9bDT0U8{~yc&JXZiP;V7r#Ii?+38DmLrx_4e!u?xKTnfL zHvDx0(H8ilaKJa&dz+pOn#VWIw~`IL27BComN>M1@UhUJ&XoAC{#vO!bgbFG&} zlhF1wzZ8kyg^mCh!uZHrX{FD#_MP=#ew@{%Wwu%F=$GS;!3Shv!MFeZ4N%`Td{Wf) z)L_~q^DVb(6;2J{`YHLb6Q7h{VJ4&ZCX5E*a`_;sX zPC{mbJ)nAByFO#>T0a{0;^=8NjpKprlVsj)TJ?MUe2efLgVzp8z#o+UCTTW0(iW@+63`?OSwl zH;dQ4H{<2W{J?JqzI0pkcH}+YI~kp!#tl_RSIr^c^zR>GSm%57d*x}wzTV^A-<}^C z*0xqDxOa}3&x@hI6P*A?;0izg_oNzuV&>p5yI*Yw&qy$>_itI|SEY#1$ZGjF$_gD- zVHt$UEQ_cZ3%L|Vm%n`Z85Wp(9t9+$bwc7m<69AQ>MjM5Sp&{q>4@m^1@Hm=LejZ& zj-}@#sNyOs#`qT6++r&?fMdGmX=rj&KF82BvJIWRE_(Zyl%XsZ(bSm{30os|PgA`# zYtaJp<%BgfuvvSHcluG8YIizyNbE%8oGi-?O{1Qgbzlr01&<7O!-6%)h)GMg9)3#2 zRGIkZt3SBV=25Lp$ZnTq(FfgD1iD(Eos&9o$}@y?U5g&2(?qqvepJxoA~i5tfBouJ zu2uAq!bvh`hG<6J-EZQibn9^0IfuXOE~ljE*D5WTaN?LGWAV?W1zdr*own|mlf3O( zt0YnIr&NMaVX{|JxA*w*WX}FYr}~_NvdDkpZBHN0oh+7ac|CHfyLt1blkhVeXg=js_9}1hF?tKB&xVSe zf`JVDaE7=?4;yt~uL9Ga-CSL=Hc=DP(%AG}c|Af!O<5W5r>yN6aCjVR!B71@s^nb` zGd-7Pd)`d2s@SV?V0-SP^vQ=brX8n!O~`A~w7KP0+sZ}86d_2M#o`29D`75RV>o@s z{jp39S~P105jpSX&A+a!93q0$B>y)WhVH};rEcA>UJ==%%%bPp|mRH)YGhyrV8f|*V3&blGtp*4rQSE=$-bL zZ-_Ku^(v*6$`(1g%bV>Ydhkt z6ZYwL@8!A@KNA{v-4##<{6OnQ#{k2B-aDdfz89Fxgb6lo_YU?;KW%uSIiq2MHT~CH z*0e^TF0hPw2K2-nf3cTM_?McA6HUo$Vp$Z;>L>XQC8utli*uzM>s;GHFkcbu5?qO;tEYkc(jc8)}fYiyE z!$)2Koag&3H+Iz=t z3^}s=+9>WVB^%k=Cob7*$&1}rm@=z0w^Vz~aNj=Gx7cwZh?0VnPXId7Wo%GUfHXgo z-%g9op!5Ik3G@|CF_mnZYQTWYA9S;;Cd*qbnkNqbi)#t+V!R$*P;u`N!;gLXOXb;u z(EB!pW7s(bG1T$6sg{L5gwv}oLF#(By#b1yS-6OwaC}-r!y1_PbGeO#=7`%O|mc;roZ& zKA_uf`R1wqB|Hl-*(uLd!M**XqWb?(KH9p%t;yz^5JZaQKq{~QO=%v&wdwmd@1)t& z=D8yP^H%aZdH33ZsVCC8f9QtMYzOIkYIqF=(brN641GM+ahdLAW*3#WDh&en@3%-! z@7m^)%xbN|3(R(ZePS+v6Hl^e8~>EBAGTfV)=!wDFy_2^6wC!eT2w7-BHS z1%~6*+A1h4@QfTZYVYOLRO>fS%F0e`_r2roJV!GuNDzS>nshJ2a73Rl1AH#kX?xxspwE2qHch=O`pRtb0ChelI%IYyx>*rvT zCr3eJ1+nHek2aHmcC(y3?^*tDB70;2(fv4*t-9*7QuneXYXQn?c3*B|`t)w^#2KSH z>ey_5U9NpV+A+8POz7-_=WI1j8AYHo*W5eeh}2baCxO{G#GLBN8%*ihfhdV(+si#J zV-%>aJ%g)oX?#)urNX^e(&*)r=gih(Dq2@l)1k+((yQxNe@JQmV&|HpUdL#F?oDKM zC&UcR^xC$g%qMJkM>I{`^x9Kz)(N9EauFdRA+%0iBYXVDq8nchQ{@L)S*7ECB6x!7 zF)hMWS%GN{xPY0~B$C4ESo!A7>)$`zZ^~YzGgi;W!&|Bw5#i9ka#4!2Py^5N|Bw^$v>+7fZ8VyU~PULG4UQ?!k1tju>1fbYGNF!;rq>Pel9aq0R@V>b=gKTKE2_R+ z6cb1Zu7zqA&JnH7L#MEa-Ork8b-KcKuGEv8M>R(UBYV14=UT&-@A{&1Z*gIe%>Y?B zbbJOgdT-*i^0puBwM>kLVt&|UKK)K%_edk%OvP^6JK|!+$D1R5p9tKnw04dg?c13rC$^D|>u&d=_wYC`DMh69njfuG;K0TU4826ttqWq9uz-_$w0kb0G=pFM z_VbQ^OS8-&%w-s5ea@@>YmPDdM+_7)Y>1G4um99!K4b(GGvk5D{ib!c+go=z4?f?{ zpdpk{kI=KN!Y3(MidLTY-oMD7V_M#(iPZpb82T-GM)4lOwW!36yj2-~)TD z-aJF8s9B*oUvUN9s6yMeWfxpj|7&8mULHiF_3~uJjzO_swnR%i& z2j7o%0yFXKIYc<_TKv6fvpMVD6?O%03@?X7V_6}}tki{$+ZlMqzR(F^$?@hT6Rxfv zZaRhCVb?bP8r2o*PTi+Z?fqshJayQp>z!8>$vM%5`%e|sxL;H#k?Y32U?(3_^Sl3+ zKNT|*7G&UK`_1uND}Llfx322G3$)JDj$dnR$F1JH=8bkeP0O-#T_Uz`WX@&PVd&rI%f^YI|$LhiF^QWk8k2o>w^be!|Eo|I+uUmL#jda`e zf(H-w{L-APdC)GC{?p8Ozx(1*>@FUgGr>>pqT~)aSx^8V;{8vMEIh`J5OwWwu!{ht zD^6NYg{RYROK6oe?Mai`dqc>fduC{whKvYkms=CBZ8Ro(`yg1EVbKq1+ zhvmuDdx)Bz+qN&^G27$g5&NlXNz{*~6(uN@&{cgy;TS(a;nimHl=Mu0~^g8VI&t{YCI zBiNjN=)aib{^$3GmnptNe;%09w5h~z#)~l%sBTuQIJaX*3$NMxyXjj+mauPxuMLpd(_Rp>Atop(t$qjgFr`CfjY0<)TC2;;+rDrpp7M;R(luhjW7vrf z-Boc;v$rJ%oCA(mLMWAD`cxU~056t=?xYMuUioR%T=%A@4twxpNV^{&C-2`Ynh)eq zu1B|R-)?7Tr*N`cV;0J>&dtQp;y(aKAF1!z5oK$(?myfKtr6?sMBS-0;k9&S4U4rb z&w9b*d;y;)8$+PCXGczgALrZlT-m$xxeSF8yN&|WjA>`F$w{n{T#`omIk&?kGxu@; zm^+40V@8Y+^Ka@FEf0<6;TPOuhnC98z09$`QdexhhNe282?(5$@1VN3=XdQtoB~+T zCFgi|iDbJa4|C0$1_lX4-}VWe(X=$4;zx9qVUBX18usZ5G7(vB-txo(sB*m;< z`|oE>8#8t+c0ybLN|M==Cbi`3Ssv*4rcqVEIR_p6pEwwLe(3Kp6R1i~j9HuhZy1`; z1xr^z33Y8xN-m&}mlU50RxilkN_?QMQ~oQ)*8hPl;h2x$RCZ+lVSU^#c{ZYVkw+V! zrnvR~+*PZFt6QPl_2yr~ImM80%fIKyZzx4JAoAzD^IouS8sU?vjO)Z)0!BAuS z-B9wqw;W~D^VoDt3aPx-*QxSxZxPoKgFBJrrl-_TKz-zp=F2?z3YljvTcLtW>H z<)=)3f*K|SvxTC9#3_3r(gEl*J$_t*LJkNY+S8u5t)2j741@&PW=d%s0{jGjgJ%d) zptMc0=Re=>KK(To6G$)?#X`qOY42X-;$$T#lf!6rU^)*$2+dMS#6Ye?#3Vle`@lxQ zNmOq`e*-))c@raG-mU|WwD=)WC=7IUK_$)mBkfZOOdH{VlJ-BpmG&852Qb2{U2JV* zW2%M<)`eophDI^;fSUpC!|(XO{|g%yDTM^&aqvmeo!{LsKl2er<1GG$1d77Qph0z%w4lsyM;{MB z_Jn`mWgCzXsGg0tNVeeKLJwf^L;DdBgJ|&+`f{jT3D4iq*3clQdbtk{bt|d3LW;z* zeH2_PD1lzwv}!3up$qi>K(yqmP@X&lfC{*isGI#bB`OewgUM^qX;@uBSJPcW33hld88B7b@jauEwuYRM*NooCEkA zaXq=26cF>0m5DST%*^CB0#l!#Bo+M2Bn)o_j2219nC?>jOasIUShMvO_>hj#kmC^g z`R@u{HjguT%%JNE*Aqt;cRAU@stbxH&jc?KN+G9gB>p!g5;6P<6k}1c*sPso0qws* zfV@a~dhyW|5FTYP~ zp^iJ3Q9;KkJNYM)q9mIA!o`9T6?&>`Ehsh60)*!~O^l1g;$s0d`|H=QxeP0W4<&G< zi^c)s2$URL%B&iP z4zUrV#72zL5Q0K9n6_?`4nfHkoRDa87T7`okA=zJ30Y=wN>3y5&BeA2<*6mP%y;tK zZTEqk1h0sLJc|!dj^?5N0;BY2(}te*_WlOkhFt$YpFrsl%Mx*I*wn*g9usEjh{*`i zMz2D3lUKE>;tGs2ukI0`=-gQR0d$>EbGv$N_zgTKSV)WJHRPIlngcBTks~}7lspLV z#!1Xw2& z2`kf2?x+f)c@phbHu)3s|dK%;+mLAsB$Mu8RgaNPaT-yFfu(#uGU5d_$z7CezybRAx9%d)8h{h}km5l?HJt9nYaKK|fO%hX9ur-YG71g) zGLIZOf{49ggS`oYO2%ThZVG}Ye7JUttH!K;=+JB6S?2_p=E1f_Ch?M-W;$H9nq=Bw z)C?zdcOzg|)71PxR++gT7x^6uPUuFAQ71lvg75wN66BRE$yVMdFaM3_nahwTR}Fvp z_o`*sVRC>fD{C~`{^Qh%7an)Qh7iMck?hbR+>}|MS@5xDzFP>g$^K`=+z_{r2UXeE zm#QqW6|xCn-{LS(BqYeKafHalau2_15MPfq##E5AEOZAmI*Pr2FQDk~iB@PgYV>dI zsVFvU$;$*`%KhrqgDLa$=-^|_BiU0OD*!K}=Rd$Fy{8p=0D4-<*QJztYO-2UF)=d7 zUrWemtws9)atEIl-`*JHo9O6HbR}nf>&bN6@1--O11up&o(VES1k3H2-;SyBU%q`? zbp1l|Xz@W#%I}(yk%i|NcwWo?^8skP0QZRxfYJ&PphbgO6CEA>>D#vpXjYUZ>cwq$ zG69MG-;ZP`CPLom@b{VA%U7-ps2v3<#sJkxg1mfJsA~v z@)}P(YbQvzUXm9>Pl%lqc!7UCWGaq|nRvzq)Bq6ElfbHe8S$|QLm!dCg^AwF+j}sM zas9@N&=rr`hmtb5Nhod2`l=`5DC5=0b+Dl#i$?hL(3ILFnh9#o%uowy-BAQO(Yt{h z5@CRrDYPKOZ$(9ooK3vypH;y7dNhi7B2EDiX^@*C9!+6ixsfB{efQm6zlcLaKAQXkp1R}LLszC%&9Wae#H|uH0+kjgR)HczKDNEcp zB(!>uAvMKEeW>_*8M09@{RU~7hA*v^fBmPR^XGTWP*;afd9E5PE-c&t7CU(vgEgR{ z5S-s8!we7{0QAKf@X7PV)>KY?@BNJ$gJ=FMswuM=k9qUYCt&R+rl+q42M^FPsix^k zJ9SUOtsy#4FeXO1kCb0F$UIdICW4z$)12dY{}1S9gP#-hd({WDY;ib=6RD@iyU@&F z%1;ioh_10%pf85X5b>`HHVhmbNP2n~jVw(bx=C=?IJQ2Le&pGdm6b&g-S@f1LYR;M zEdHJySc~#!xP<- z55vP*(Z}|z-%|39mQv42p6V<#vk4r{Gd~6sP+Vy7OqA2$_@J9Vfw~7Wo-*{Y;eS9G z9L4w8EdBz@$6tVn*d$82`M6z+F-*M!Y%}Hodgk}B!bXCXh6u9pdclozVO zb;zVp`yzXvm^Tl3D=6B!qN@f>!A)=&fgXiPQ0P*^0?!dwi%e)t_ZEifK?FE-abHe= zHFF%zJ#@w`biztOO+{WuZsu`fSv>(r5o%ic0GDC_gibsFMW_@r3@j`xYUG;w;4wjY z2=e^4oMIqCPGxVR;w8ih&sE*FBb^)?vRgEhpMT-WmM*6|1aPp0&Q>Cw3rRcteB@5z zFU4hK&Y}F^X>bgA713-UTS>t^fec(kgua7=kcG|?FVq3>m?TfIS%YmE`~l=Nnt4sC zZe(Sp?OXj8NEAUyBqQjdC4xfEI5l$`Ec+{f7^c5fN3Y!Fk@lFTAB9cD5K{-_BjT z4i=iO1Lczl?;xNgdC=ezcN!n{iiQUGCI4$IHn^8i6Qc)vAEaK`*U(9UiE;1y=`v<)1K;qtwrcQF44m zqCig=rJai*{E*&epe3LYQ7aGjvR165e{Ooto%dkW#Q?4@15-#Tx+&vw1cLLMq~%Ff z9b5-uqxUREGcrHO09LHdgfxwPlRhvekYNelj87#NBRflj=OFnKZAc@00cxx`_zH96 zhaXgTt(bp5CuK5rG*(+06@rjuw`h?+~n!0bArUZ6Yy*M!Xk< zfE>H>_$*Sc+a~bfEJ3aVqt26|6GqWF4sS;&j&m6;C=a7HwR7WvB@`8E+^CxVytQax z&BJY4+#BB$=N^RAa&CS;C<`A{P{SU4{hN(iSZ=^Ak-~sfvgY^5nv0127=2~xOtA3+ z(8DhGw=&ZIIiC-DF_fAQvEelNFkr&ejfe=6V^*`WT}0o8lm^K5`(yj5U=fiBL;JP2 zy7~ilK}xgYPYQ7$<1~<|_iQ1GmaPT~k?qfyzp(Hb0sv8h*XrcACl}my#u*0 z(Z#X2m*y?mP=tE|GVrL35Jh4;*;FG`qs+Zmrl8@DOV7L-WBv;4TKW-z&;8DF0MOCq zyVx(#+EBgWsJ@O}9 z6on@wl6o-Inu@><>7dQoSb&WdQh-at*8r&0UVPTMY+4cc4fD29fP-mQ2X0G z!>ZoO&>GQ%>cea|*=$V&XEURtNW7cs>svho3b>mOK55JY6CHnEQscG~r=^Z4UkHzK z@L(sZBB+_n|M;ODBXN<3G;*?m97c5ykUtfW}dk)x4E4(#`LJuNK{&_qHWi*BP62t4SMN_kHzVoJsk zuzzSIc=w+FzIz@|vI_*=vW@umNW$^#Lg@%j(XNS;E#Q?+T575*q?I--p-3>0?RX1J z2N9ola_RxQ2J`{;#D>jf;oZc+Z`g3R0~G46P_}a-ZQ_Z(ZU0J&PZ%kG&LIMeh+r&^t$gv~z?W;A71e^$n+n?gPJDj>n4+ZZC zL~t1$zGpHCt^s2}FyN`W+8QTPN`&e2FVUpq#-ycV17SLvhIv%hy*xb+-=n2iir^hH zM9_VNiq`~c9uw3&aQ_$veD>6-%AI)&nq z2VB)}I009_Chxa62J)UWJ!cUAm(_dcTkZRqMl}3J0dRY#t zOSyk+oK7U}Hb@Z%agj@56&8-&_Il>s5Bo6&T)Q0Rogn)`kjvjL6`qBo!gYho5&d$BK>WD$4PrQw}JhkxQ0L7{#0kS4}733aT;%$l)>M5`FU^p~s$<{xW;nq$Pz@hWGh~NTe z9oYzq7%pedoM_Kj*T6+4Gn~BEifKdwqBz?35UPRO{XTdJB?JZKAb4;J+e%my%H`AO zL?J0Cuy1>YAAI)A7B0|p^={+BliZ@o=pB)mc0I+XMFDS39&afe9_4A`0s=pXxq&^J zh1&Y%^O3fCdabBPyaNGG?gkYlWc{C?8LGiBZdQ>)PgSKM<%2Zx>NQ^_#HtjX<)jq> zbAZs3JSuclcanRnf^bn;F(Enm9PTL?ShE>RCK1)axj@g2Wd$%X5AmBY_}UwoVAf2b zHvak~HWIHldur}?v*u#)N-;^uJpmGOWKtAfy1p7!VfncajPhAqCVQH$P$=~%afHnB zHBo&KWU|>h&cwVAmlycVxr~J7u8k}#&n_dzbv$weRW>mfYViL+nRfBp{6gRF$`$Q6 zsn3JszgzgUxlhm;*aZu_B=n=GLfG=<%H%dBxy9DH!p%HVg=#$d_(+Ty)!SNIvkWrx00rg_&*cxvI{ZT4jzP%rqoC9=z7ruaKZk3h zm7ZiYx(A_V`aWhEenY|!V+P=KTn<{)>I)!YWcHWQ-s;evfy^6&LUVBUa!bb50iM?h zWkx2oQ&yJ1r=LIngo@4Gfcf8>JV%#slmXoYcqbV@QuQw~H!%Q%hLxdzejEdrM*H>} zxdQ`kP=8@^9VcfG+7u|lfI(o1anx0_Z;p zqHYAyS3{IM&@w7Ry2H=Uj}aF1LH~oB6=Kk%An`;+_h=OwH>t^hV6}~+41)6mzlFTx z7SLB=z^)1PKn)|CptR(@=I{6Y59oCmllnqyYTRkWj)8Q#5rrd&VIjni+xPcn?AE~8 zOaXiJ9 zn&F~{s{5f|a7lI!w)26GHEb=0m~Mwy%5Yy_#bw|}ghFqdz`vG^*9!x6nBIrUdO*q| z^rA^?#AUHtQ+Z7ht_Y;LqmT)+uBB(ekoN~bc7L1@EHn<}*gJApFRdPx;I1Luk<6_I z7en*pY7ixN39xa%#^BFWde|G84}wB8V%pri)TnJJ-TH~Rz>Z}dL;=t$fj7zyib&VV zbUu?|l*6u72%shVEF6%r+^${c(G>tE^xeC6QdiInyI=T9t_I7Pxu)r2jiLCS+e!{b z{m;l0w4iELL1xqqB3C!;VOqKvyWqzySK_oHwPRMU8)qU2h5C)6x_9NMHR#bv3i>#W z#>M^jzyhH5@&%LVP$*l!-qrBZxMLcUwL1;sYvdmftm59bwMDFkpn80Re#zJ~ zj^iJ({x4f1W0^bIoSmKHs{X7m#Mq(JH?vXWs4w{XPiuDv-_JT290aj3U8X zgLcijxOnAS992OcxvFrCnajyyVPks@DYb}7>nnw7{e8}5b9ab=$-!bExC8pVXw;J? z)7T}HAgob|w=);eL)MRrl2>OaF1|8^6rU)U@1xx?e*kSq0gFVf3m3{>S-D&fc3faL zNXvAXk{J2tYBQ-!Km>G<bb1t_A~MGj+`b+{+Zp5vdolx%>G7jSXY{g-AKn?w z6BX0On1E7*bx;<>RbUJ}7|yt8`nFBq)KA*~|M|^)+7FOh20`YAH>(-3qcJDEJ}S3h zMnLC)^t&-TwoZT9vSm7-QO2oOmP9Z^!fx0e8j1uxvAuMP;_iPyQfXgo#Duj`Q#k+bw|AjlM;EUyWN8`Dq}>=7ZK{I6KgqfVb5IRz~Be-OwiU3s$* z_OT1cv9h(bg;5W`{0DXXesEB^3cbU-?4lrT#0xs4NnALfc4GW$=eF~(wE}=OHxk&<2(gCZ$^VcfSf^~A;Cdfv^9?n?mHC%cArOS=v**IwqsX<;I!cB&`68RPy!JAZyMT$}6Rwz` z)c0?kO58BYV*W_d|9&L`r)B@MC;#z>f8%d_W-o%>{~up+RhD6qU`840Kq*4lJ%MUd z4n9q}tk4-tY{@qgE@yslr@3&N{BNIx|Jg_K4}BILz~AGG|G`Ez&O}2D$e-Z+KkkxZ z$%O+zzJ!~6iA_ZMA;^@2wmqA18Syu0J7X=a?kKz<;DUY%#^=$uKiK^&_ef4HQVGoQ zn6;x$9k>{WF`~~=W9h{CsEl6U_?JhZx?0oW63HX*XYrY$v=Yb&8KB^&}V@lafb8w@moYe6tnA5=Xec>W)leqT0=@|U36mln1^Gz2Sn<1&7m zVStUz2SL}JI*6-H0oy(E6|K`-Mz?dhlOj!jpkM+aYp_eVTIe`Pu8!#b-`BmJzH-q8 zwc;r@cf45#F(XV(7)W79k@KjPmE!Jc=#QWsOxVIo*j9&x_JWvooM2Pyce%J~JtX)oyD5o<}Sg5VTeW4k! zT3BeDA~yI6;qn^J>3^AhdK{_Yp9GPe|NbrAOBOG23mU`waCm|m^>wbn&~G6y@as2n z`LEiI9H8~9k1OSDGG6_M$JZaAZd!2mo%@xdAtW&jE2#UYPcqUd=D4Wb*)N>=gs8!> zLq$WkOu>UeOrYG#=3}m!+_9YCSE)y(86Yf&?l*qzq)X1}W_G5b*DrXo)tszU9K-0_ z<#cvp(~?BXt*VxnDfClp^TiCfEQCNtnFeVJWVTW2nxuyQptoF6a@rNn=#e4qWW=?& zS1YFsy_KoL1!z?VU4k83Lr2G?Lh3^9CB$u_A|iG!P{m-v7{32Og*R?gBEA*(8=S+6^-I@c>ef5ji|eJXeJy5y9dG zBDWPo&IGHo_x2576uyb*-n4Nersxh14D97Vcj^V$2Vrrkg>Nbl2(pW}r;1I&{X&fs zlPzo=9XSB1@|D`LYuB#sa&&}I-)A0X&Az2<6wzHNnazJXu~k;j(Lat(H29I+h=MgT7{* zR3@5#D03Z6LE8o5Zz&i5Co#E`yugsn_3gmvowUP!a4>(Ua+mnmdF(Pdrfhx!=n4*w zoA4Kqn$@vJ|Ek?Pr6BQuJzP1e)P}>Kq+59bZLoUSy3gr;US1ZcBEZrRltq?i#C@Ke zhN#=t(2!{Fy>o-e(8zx1FKF(TyZB1Z*I=n#imtXK5wk`GVMIjWxaM}@SADE@xAr_1 z&v?^V^aa)-wH|%n_B6;*oPdGwJ0Q42&E@gZsSNub<1O(?zYe4s+&1zn8p4URssLIJ z8k9L0m*~+0iBbX~AIk z94Y9u`*Ht`xB8O;!{Ij@h9;R>=}k-p+-MrUQ=7jq+xlP0O<_1N)DaQ>hsThSW<1aH zoIB-$U_wlXdN|~PE&_S95t{u_FR>a!wF)C5?558kd2+sqJU@NSNgzKt+%N`X4aaJ* znp$~bSZrLh+LsT9z_0{g&g4*w+Osfw^xoBvLUy-!!TsyzdMk20I(o}pe}jo-CKD^E z?k#DLN)y{LHCN;I`WXaTR*Je-`mO5ciK_nj#7mKLHZ_%({Z8y3AiSzX>zPN7A9u=< zRpXSaY)KY+D^j^lD;8mU&=%5MnYy02`nbW&nPEMx!~wBaV+wr>QJeN+w{gOXnmr-07{L=`SWcCVDni<6?_!T_^s&%nTzWF ztZ45+F==6!9p4dN86cG%Nmb#jB>iT$i-M#*}3>BM?MbWk@t_IHFAMweymhgMG+K z@_3@`L{sCoG{>o4cX*20j9okMeXlgmz2qwh;z2wGg>&JV6b7tU!8ck%tLJVo^1@7>9A`_phE;oLNo6Nc>s!!&{=#_p7TP5f8+$+9dh9 ze~|db{;22aekWZvk6mB)WTPxKjrj-irva|BwoWxztHWm7wQN}9VWE2ao3PlZ!kdo~ zI0_}FsV?I6YseHYm*F^;7cpBpenl8#Rd5UX9fVp;_DgFg#;RVo_fh}FL(;JO?s+Q< z$mM$W>|;Ua;bJggbRt^f%hiuqWLWQ-){7V_1g zQB8k+a#gpWp_VPJMowJg#jIe^-76|9lTG{D^d`g8uXlCRImr?(;{WB{3CMqinwD0M zUK-7me}*e?U`%AJO&=mv!@k|al>=<~XG$SUpZS|0tygYC0x$Gsq_#2WhQQmX>!1&E ziZ=atlc@^uk7FE%+qx$_Dp^0aJT%Kxvn%||8dUzeWy|r!gV4CSR>~)-2H42fOVT+ z+o3T&Qii(q{T7CN{j9h~mK!E8D~76YL5%Ez@;-)qP5QORouXt}_o@aEO5%Us-v6)& z^vlle&(du&$1isOY3!Hj+UIZ>=Lf1)5|mnKb;k__R_yn2{DcLNT8q| zk2=c_QG-d;{U7GuAZ)=QbdFK?z%U~_83BR)8JPuNI{wd0Udckk)(AE|sRbdA-myRx z5UVpZw&S`vqb~vLUiteRnY(tY4rD@E~cvI=jrBThEP~v-i9}^QUU?dp=v|_j#RO?ly@ZSwVg-Z{W=-in!y?H}} zOsYGQVq#kBdVY?{=yM6H_4WW@-8_=quSag3x6B-uoKB3_+kO`e22|dyt0W(W3m$=1 zMd8P-1iwV$z8gP();K1mFlZ(Rim{-4oGq=*?dBaJHq=%HQILJ1ufn=^^{zm_v&?M;o4tP1q!qOl(OP3x!6SqncZo=5dQ)ZR^~C7XM8mp| zW^twbDb}Ha8hr0A6*d2;Gc}v+Q%hgIse`f4T5zUAYFXxY&Yo4D44yb|;^SQYm$Q0) z^5%uQe4UR2>yWGnYbEf=%Ekquf9Hovth1r?u)z#rHFix%Ly$o1r^#WtpMSZBS%|&~ z_i&P#Z$p6ILr9Gz>0ebT&iql@-USjGuVG36`X;007EwiCz6}l4mi-)R%|iXPvP!zz z$+D*$e3m@j%)xria4@nL*^+&qKApwn=y{zOX-5{}aQg)HUsIZ6=*R|MGT~5Q^~R)) z#GP#d=KJ!lmJSaZ>0Y@_TF2Ts6VctQcaMt8jfK6cK`-s0N!_ERQ?d4+^1Qnv&=z!u z(B5%3RBgK)jnK!&tW|LnYR0LDTL8MQ70Om`KM?C+@>pWW&c_atD;&@~&Y|L9Io_SG zRydmX;6c(-?b!>1Yb?iNZLX9WgurTL!4gD~WJG>3hgE#0n!E>c39%TjJB5}BI|?o?7m8nCywK`Tyb zJ>cdRiTtP4wp^3n{`p}tf?SY}fg3glfz#`12TC{y=nWIEsdrO-9q9x#Cdt{5CEZyT zSt(;nnv%Elb~6!^vlk;l36Pb1Q{Wg4HA<)pYzmxgsSbi#Nb2}Q&CfHwk>O2Gs?TdB zTn&Y?$ol>E(}_%Deja<=gM-)D7TFG@c<{uF43@=R=9(%^+0_>>G&7QtTJ;`JjRZ?l zn)6Xj&>W%I63Y)O$3Xp_rHWmm`+xlot3we9U1TwOb~W6TfJ zt{b**>vpk_gNSQ0-S90$Y22q19h4_ZpcG?1<9KW5SxR*HIY&%kD?mYk04If+uZW#j zjD{!mXDX7N0qwWQJFfalXyK|&JXWmV zEUgySzz`8z&Oa7kAZ8MAwZmXIdNmgR)(=^F{?3xr2otXt=f9U8b8x6X99vDSixJTS zw@yJYb4Pc&OPRI8AhyiP&|iC+4|iKXbI*p?PR5mt=kMIJs$wR19cd1Ll=x4<56qf|GgUkN4SP4p4-qt@28$;PQq zbeba4N{sY1zwq+KME$&TH2;PEN{0mf!2+)joyxZSamsPDqCcv*L`1%V(a=$G!Iu2_#``JZ=d>#p*@a)rnw->Z|KeSZmc=$$e$0p|yzRKwm}yyucRBYagMP|eAy zyEabSKvcX|e}7n!c4*lwtX?+)H5@TuWTrLs&oC?PRypJ7MOr(1WMzx6LdfX(rFRy9c{ATDJ4qH;Gc zvy6QHtR`HmV!XLa;wE!WZc55gfJ`vV9+Mro#Ew*%MDsLzxbPPQBD_X0x4$9z$ph0O z195Rjl$7#aF!xtPGudsSzreBzr4cj;Q$;nm*uyF3Xuty_?DhnWB~vY^INferkn=6D z+SX-vK}97C&SutyYtEW=T$QcD8UZtzAT`uiq{{ zYSaMon@B2J3c9$V|C?BO2{fl(YkyELXH6ZFITl-b$8DhYwwB4`YwF;Do)8n%JFTOZ zPiE9rIy0C59M^~|KWRD$l-l!9j`SZJ+dX)*rKazG^b09Fa5yJBGyL6x$sW1SrxUhw zO2>4o>4V#K&@6S1nXBNN>=~UYXa`JQu*~4yeoOs~vE(PFqeCP5YHKbbzi9bMU~eh~ z_uSCvz(fcC7F65X^1z$3d1dmplILt1I8Z2KB~OwGH~(_c+5~UixbdtrW5a#UdOiQw z-Q>*F>o>D*s{v7gAnS_8-$8#&-HZ8%jg2xZ4c@~G-So^#lyMII`ZvjZa3!$0V`*@M zrqZ@_joZ*jI)OBBekXtOv0$C+_x9W6wiwb*?ete|bSQnMSL*4`D?NgeiQT%dr6pkd zxAXRiQN}(<9k;hvW3~QU64v4|yYe}YN##pTY&(Cld#jDUr{_=54DB5sCf*m>E<9H3 z?3ehH(R)btn)yE96(fY&)~iQ*Au&(8S9X&6nU>z$-O8K>CTIKHrG%!e_C~v)S%h*2 zriamg*U!m*d8QsQ(IHNU7+^3&qkV6Cjt5GZUS?NunfD{e@$+B55iw51uRDwLwKHE3 z&L;p+!^)2#`>bNmkAD2|Q<>)c%+cM{Qi-v9xdAXR$U#S z*lJxhhlMPg3}ZJnIX<6pQ&eKiR- zJ@nxo(|;8kxs@FkdD&vrz?TcH$!fQFH(6SS&bDEnh6A}h_g)}97B~?7@wkBl!?05; zkDqr9^p%Vc9lD?E{mAvzh(YG>-~*+S+cl%t@bi3qcOhyhOUc&6qz#^@E$t;?iC=A2 z8vAfO#^cdHB0R44m4*??^te=?>esmYas%G1D3ofF~vfd{|?XtkKlC}1vf-NO673CbSV+{ZafGWDtW(L4u}cpZJsl6jz$b_g~u17^%1 z_wcU>ZF#HQ)eL9u`E(!En~mQ*UA(r>zA670AWIrcL61zIZjRzJk3q$Ybme{tn>xTO z7%GoYX~9(iC;d2Z-d(nGX`li7j^AhXXNbP3@YP6L@!Dpa7n0|-YzJ!Nwe+yX>PJtj zg~eSmxC!XyX-2mz!?-$Nl4Bkb_xTRi^Q}97^xeFAUMF$R`1y!&4&(6PhbR-R^>Li- zB!^#{g{ZCd4qM`dYlZCxeH2djXf!KIS39uxKYd?zb|@y=;zr|6K7rhkl#;4Mv}q)r zw;3?Y^IrARhV>3U(}Y=CFamrINn(Fo3F&c?e#ey}_s|YBfc9DR5k7ll&$K77#1WO= z!hwO};)R`MI@iKvZ~W=i@(+8vHfUESY`*XMSLPLa(SfgRVbneXA6sp4mjqst0cmfEd*I#-OVjx@u`)Rv5# zoDl%A{Zt<`=LzVcNrlRw!@J?TZVP&j+*9@3v1+bw^^vUaSXUZwrF(A*z&5RSGs6%6 zLSomV7z5S4;KbkyMZ7(juWp#=C~qZC_hXZML#B&6jR}pGhWS3msa!d9`;?cuc4+*1 z28eRhq*z2yc2GC9NsCEyKcf4g@aP`L#MYs^4u|WbPyJ`>GE!gi3l>SKq&;|&y1z*= zs|gSp{^7EE^e8`PBrfSzCF6M+%}RE;c3sj_&HI?pQ6%QE(>={dUu8w;nqj~w?D+c~ zogGBKM5=pH50!lzEQq@-BVp$wTh&RsYNt)6O&A{z8HPn))t8{Ge{j1y4QKB+;R)Zjr;Ziw=x`K@J{!pKMmS7y$@TR2 zynK8QJ~=}@xw&)npGre!8PPEw?(}c z)rtImTi72yy0ucz`VJo|RGZKL3LRZzsWO}wNZL|fXBslFdG^IJ5ncO)rrKKGwg3_I1PN0W+qLx@>f+8DeJL8kWi!?iq^<1vaeha!_G0@ zNJq_+n#r-J!BKj(i>2KOSrrGk+{na|N7p_U8BA9B#0kA!!R>!04O8U39yS*}6gQ47 zFbXtDYxrY2(PE*$&A@kF@q|mDMTw@xu_>3eH)bS=HYeqPy-FNjy5pbBT&e zn_C&}O4J7wEr!2NAKaSRkO!y<`_;feUFLTSS#z7cPcX0(SSSi*#_NhZZr{3uVW;`7 zIcHBf{N1iJX;4>kpvv^4B4?C$Wz?iig!-=tw<4~AAnO~Ic8BBZj`LjJUW+=_m-7LMMa&<0WN$$hic)*!EvUq_skims;CWye+OYW$rTmg z*^H@)qddr5K>I=WrRwY2cH1%U--SyebKCycP-@;pe54w!jd2R|AVD8UL8;DG zm6OxN)9~|dfz!N>-;8s3G)ZR*xKuB{e29<0e{r zH?YOsyc%Zmk9~Y1#yl^Pm_X$vzQ1&@fkLrQk>%2MZRsN~)uR6ArcJvCjWU#S9ZVb$ zF4&b}QBs0(6JXUX4~SqNqtj#E&pe$H*hisUrvGyz9TSw&E+li;WLgl}vp+=)Ej};f zGykIt5gj;WaaS*bzGz>fE)H9f%zX^-w(1KEA?jvhiYbr-9r^v>Y_E$h-{=0(V`sj< z?dm#tcIM$(+q16KTbrr2H}6}rN+?4>O;K5wX~|M9ehFHE#DG->%l0X&zVQhVSbnl` ziH>Ffn?i-IBGZNktF5QJ4!^jyFlDfUedsb{!uL&{aaqGBUjQUB{CODkqgxE#H@SPB zC+{x{EA>}ZEX15&Yv065(qfahB^>43k#W73I5ekWB{wA&PQ{B)?3@$ zi&v_&qca2Z2#a`m5(Oj{Sxuh685lLT$q0ZEtB;-vyW7dC=A;~aYY(-y?!tc56uN#+ z7i>c}VIG|#pguRUvZf~`jnz0GwRgX%y&n2EtWD*f>wcH;2n*9r%S~Pbe)|_d6VS9g z*9#oSN1$2^mhc?lc1Y;@;a}aeBlB#SS()NH?ucly@AOak_ggGU`o4x4rl~kTKQfLx z4|1+Tw8IQPF+x&tc=~+!kJ#3Q6bzet4Tj=j&mFtA@>v+a(`Bsd-AVI;KlX=e>f{yf zGtrVaRZ4tIUeay)8f?2Z&N*ULDf>CPOL{^F>o#X3@@s4|K4L16CF{<7{7&O9=kA{= zPf{3yf`hNntskHH=zm_^tWcqcQTOLIvCkR`*^kV7ZgyEQ??pcVih%)4WzoK;gOb1f zstR+UY!Q(ggxPK{AAe-h{!>L~{K}>a84FGxg}ymAej12wRNoq+f8Q+Fg=VNiAv&Na zJ2X7CvpY&Ym{;%+*TMNT>lZ^2Vz%=?uDTHksKcd+$yHr^2O=-r(B$ZNs8_0)W3CaO zJUhblNjbG1A+yWhLvG^2*~|JLVXBS?QaK@re#SS56M|Eqf`@>#w!dM6L)wwHPr>aWJk)P1{I>Ute?Crq+N-vZbfpwD!? z;6u8@m`;#Yyzih%2)v_qgDLC5*bc8KGp>UlHPmuLM4jC%aBb$DTA8LE*pwAE@(m^h z+h$&l8t${P5tF(5)1<%sgu#fzXub)<`UjL}g5Aq6t2B48c>hj3WN$AxRlprm+Gkw9 zjHU*S)@kL5TwgxMKC>5Kmzb91HNEsdvA%#A)tR6nkr`QWth?Bn^)x{?+9bah+MfUVJ}FSuPoHp2b>P6-F!dyg99 z)^_qAQH!4Dx=Q7FYUozO+fV9xC)@XBz22F__s-nuUH*1Y+revzC2=AV4r_NOt-dLk zQ&M7fc$c`>D!YzH*+G-GXRK@NIBGscI%Ha>upL~DY%wJ#r>Eb>WGl6)=$#Kq)iTr# z1)>MIoz2Z`jArRhQ_2i{@<+&v&TAK4bU&BV2{wYC}$(Wg*x7O+Qn+6t}}d(m8XpIw~5Y z8Rk7kr!JcHr}26(BwD&ze3qdedX;k%5I$@5V2%20`!tW_5?;PehV*_WA&b=s@)|sw zS)R&JuXgGw0$?WU7($tbTqb$}v=680e-{li~qLHT0yGg&iH|5(l*GW6t?25Ky zYSz_MZ0QOsx&7#sh6&6rdB)#`#wd(69XbmAk8HtflXw&o5RkaA8*LOr1rKvGzJp{P z?kn8$jSk;%Pxw&JLD>UgH*eDV12cc`eNEb*?Wxzff1@xX$0dm6;HC7JWOE8Pqz8nA ze2wY7%2UlWOPjJiqU5Zg(n@aKiTru=Q~&*8`iQyWwPAPNT%yc+4*r~d@{{@$b4lcf z`q$V1zJ4Zf`Y&&({DS#&h84jY;)1zlQNvN(&Y~{5rUOhJH2Aee3yWWqIs45l`@k8$ zL#ys35wUj6(>0TXxV?ly%W@!JF#Bb=SU8n;NCexU<*9MXk3KmaFh*SD_RdbmQgIvs z^_v4s$sfl)u`+z=7kW~Z`{AfN?FXTAf=6tQyJ!E1TX=M640#5oHaXhbPS-d)vI?Ga z3A@WT*paVS+DLsR%1pzo{gsUW{=R>%bMycc#LmuMdzJN>;2~SXUHwe0 zc(R8@x#6@Q>d*gut{_(71@QB&WSov2+j7|9a7A#iwWwh3ov7iz2Bwvkzu`@tLA+93 z$NSF@c_oirG<KMETz6FE^t|xTdJppYO zfX2D>*C_?8!j%vbx~4A?=gT)}4BuLUS9pY1SQ3I4kcUzwx<{*NX*nb;Dc7D)OilG5 z%myC0?o>t&RI666UJbO_ep}Z7#FLO|kH}ofUA>Gg-I6&(f4^Q^__%{d*CXBg>~cz3 zxCefRmM(vZI_SwcfU$S{^nVU;`cF*3GG0@ljiKIVi4gOs4Y^9CdItW2?9kRF*cR#m zrj^{%6*AOHAx6f=pyXf*K{KR{fFy2iZbq&9ReSsO!Rtbvm?t7D+YSC58Y0$*SD^W` zijI!=-?zlw!+v}irE*(t#%0bfJfoIF47N3Nl8I_BG>FmD;(GJ z0Wc<&1(|_aWANmXJ?fY)*b0L=1O5OouE)Y=t$tLK191 zT%*=nj06aTDspWydfrPfrJ@3J4kMnVrKITS=;Gt!A(M|rTy3%g<$D?W_<1>a&Q;QG zR4wagc3xnxR23BXfg^Z%?DyNcOTnOOG zpaQ`A@G}TumKgJ5?XaQ| zpP~VDjDY9DI_c$9fWZL`8buZ*P9AA#_?6qc&);YqGSJ!jeth2@9zXgKt9UAI=5t^c zVAeh4D4U{BgR0(+eXMQ2YG`8O;NZZ{%BpI6zXqUO^qIHefi_-arKdj$_|yEnN8a@y z9ET5sgHFH|0Zcu520qFh3{c=Te@>5>=4HrYbO0H3IRqyCPdt}cY$&~60nR1l{K&*W zEEaMpv>1jaO}S5Yp@g(~^JXw3@jP`UF9;{Zz~J9UO*%7&?lR&TJNZy0O#!Cm)YM^_ zocEHGD?z#B;qh&>WM$h95wC`h4(8g2Iod z2CQ~zncAfh-=pMQhUlMUIgs(00_D8s5HNyimr=2K-ZOhLj#~D)&OnyT;!|bN7XfJs z735nB!W^-tvbK#eP*Tx|gmbcmZBueuVSW+mt<0`n(Kl{{yXWU49YrNevS1q$QxB{V z(7BUqzvcIW`%T6P_xC5KrAgzU4@m-o9qw;HGd+w18ZhB4nlXu)nfAb^F)*CM1uHm{ zvh_fPu}qRm4q;P4vI}r#nP_O4$Aa)O5qLg7`CC0%8)&dMLf@z-$0PWI(`Nu~Mwjn} z<*g)7S8>;#=?IZe#1OpLZnbw9%jhvVgt?L#Za0?XK-t9;;XQ-{bWVfw3MI^4iQ`XA zKYaQWe3S+8xmlid9l(>8qkCDLHvL&G-7ApV0#*XJG#RI)Tj0qUI>v|Pw43b2@dcnA zo~kb71(&l1CI_G=%1eV2x6Lx1D#_^RTPd2Y=m3FeAz3g1H;QNn><;hQ(Tj~o3t*Wm zR$8Odh527#WRhtW#!9<0Vw9oP2&K_$&mTT`0Nz?38W=*t!ga|xTYC1W#QQQQ{(4Ub zu%rXfIUvelt|c-x2!!O8alAcwMONq&m?Rk5OOicXSE0|Mgbs}Cbc^mXZoil%FvbN` zd((9TR&SDzKk?Yt*})+WgUmwnfnyAae|@iw_|b?RfLd;Dm$Gbqz51+0fJ z(P@a05A~(O+^r;C58Fj z^XHhVxF?NtZqoq<2_Cdq-Eta&l$W0m-NX z!0F^-NcqG^Ey+s}@a33<5E>eqlam9@`c7lU5Cjv1d5)sW_?#z5S4d~lQ&Z)<<_+@b z+-|$8nHBe~oELHQ@#6*PQG}bjqOMNO)bu>?rYO0jIJL)k8R+d4H!n&>%aMtuj!ri0 zT`SBO>FC|NcOaPw4~2A${!*QpkePpV8zID32G}zNon7f_2CSC}%D~mbdY&2$;G#N^p-VaN z8rBSg_8Y|bU{rvu7@DLO*{N(8bs8{KTpP&ESub}Ic-;yU)MxT&CHFJL8ApWNHT<(_ zq(dv~>M|deJwK7da<S-{BZ4CWz$M&mlv*49=dD0+gORbdlTQ7x>+`-wS;j~Lb0 z08>||TO~}fs#|CtxmE|PbG>?>%kR1-4!b6wbLQwYF%0U#yR0D| z1M|(RZ@)@@Psjxr%LBjO^xtuz2{~hV5F_AKH8f~FZi5P{Q0fvznuC>?~s$6oQz-?Q)qDLxOjO#zy(^bsy+m>JUB7e93Q@( zZdvq&AmI^0i$SLU^)Z{6=Ub*z%hC425)7Z^h#f+*o68(J|w%q z{sONaGinh0op*P~h~=$Ywx||dWcD){!p(zW+PL+I9}XI*84_|8>L+V}u)3O)wza4?QWs;DE==F=zDqm>B9$EAa0LGN8FZb8vaX9bHeOBUebTG|9q9 z|0WAPJ>}-|loOw|_KJFdxq}D`5i!_ke*ythx7+0`j?r20(;$j-zEFow#YKh0?Cf2L z?GTNFx`jS_c-lHWj*JPN4xE!7yy4cP&#;Om-oF#@P$YFh+Z$p%ISw4_m&oo!a>{10 zcjZ=ESW11tLqa9WUvH|6JxSx_VF-jj-RHuui$aSblmL-xgQ6@#zY<0=^5>E>$2h5G z^AY)6d}$BbKEzmNU!&XTyKVp)8MVnPGxu9r^`Vv8w~P$_#yL3*mwZFvZbVd6&8G>N zw>r8<5|WZ05alDQB1P_%D1JLBwZH!e+>B(@MF_Je?O1j6pybj5JvB9=i;4ClrYu21 zcgfLhdCQu}xOWhz1O;JXURG8r>FZ-qNee(H$UX&xg*R(#ZddOwK3ci{0mxF&#tY}8 z*QjvWAtlxL^5vFohpOx9R(;R#r9Xn|5!V{4K`9zOBEEzZplNdlm}V$a&&ZF|v9`|vK*x)l}=iWK`Eym2~ z;6X&{md?%=y1I%VA2fjX0FR+b;{H&?{Vr6;5beNl&i(iikr`rWWMu2)#0jn3vP}$U zlac5_8=7Vrm8t0)h(Ds#8!4iARH6||wq{RGrD2XDq5^aikhWoc4kXCo*l6TQ^_L(k z80*=J{l9wl`3Ek$^)N0-tqM$hMiYRrT zcn087Z|^2m)~qS0Ti^tu6gxBWrn9AGEBJ(gz)-KJ;h?Mbo1sEK$s;jrNIHC9HR8ki$7R@Acg+u;8{V$`rxXj&)qX|mc z#MQAASH~T%!rj!-A-!wYO--9%Oe(sl@bp`8L0bjREhK9omF+I~4qDRyfPeY&rA~>? z0Mtw@Hf}le*JSijC`+7T+jZtRj57v$Tf6jq`to%Gy$FP<2wf1VA~^?iEsT%;IfzA? zv63~2KC-fc8jlu_kDmet>faOLbdud)6Kwcn^|EW6P9qqWzrEJGjxKdM3J;4GG6!K6 z>LT(;RrK{4jRWf79bSS41X0J+A2rcJLeIZyy%elcMn(qkCvTwx$+?8x2(ienbEAov z;0PCuAdcuyT}{^6}YN9u?Jr zXavY?(DwRpUf4E9Xz%6x0)vRY%t%}MwUm?rWF|2SUwBiMP;~Oi-iv8nu@!vFmoLZI z^~Hi7GpwY>dnp>~#B$)gv?ZfLF)9!WE}SeZmoH|mnZ^&ietn4TDaZQt&>G5Hc-#wT zi&v9D-wf9iL#8Dm0*&{>3@%JG2ZQN2ju2WiN546##$xc9ErM4-Lx9NkKV6=Y5g>B0 z5b<^>DhBdiaR}{YR8M-qnJL1Vv8_$l&CkH7NfjMyA&tO&JU9<<2qozX>4hkq0DF$2 zDb)T^dw9aQ!|yWYXR1ON3`PrYIgNwiE|-Ad_u<3SCr_SKQmRCNuu0xCz$uajT2ms2 z?o*~8LMsueX5r4;n*=H8Z!jhl69XhXsDb4poMLj1&0)Z{avVs}QGs+5G}dD44@;N< z!Hv~;Aq0dR1)_WLA{9#v4Gm#pAVsSWOl5j{I#MI7LC)Q~s6^$1 zvI;C7ShH!6koIKP%fR&2KSOtMb%^$;ZHJPm$M1#R@pdp7C@=F*$gDC+B1IsWv>_Up zv`m=Ed??Aqt0aX$FircGY?P)=G2%spcV~KcM=rd7TLO-fjt*E8uRvoUx|?I~b@%SA zg73lw!%RhJh=2L;VOeMl5;Mr#-_gDecA1HcDdx%H#Hh+MLc9}E9Vx4AyeVN-i7e*+ zpz1iX7gv}g;62ZM+W!FTeaK_}`&eNo*_E>aJV9UMdgg}v*d&}6Lgu~z3~Z+D(sFWkMuwUm z9c>($Lj=P(t7{Hz5;h>hv$+;6TWoAB6q!fY&IUg-u?G%gV#2Z{c{#tRs2?RFI#Q@u z5mEP1Mp!(Ck_A5!jA86f?4!9&InF=?Uk`w_FZraSGS30KaT~1LERlEs?!~lOvaHj9 zgyX#P7H+6!A_M`9Sn#Sw{fjPS(3hTtY5go=%Krb-Ho=Mi=hlWat}it z(${?ibX*re3QfzSwz1lZG`rc@df}!t&E0GaP}AC4@!z9Ms+;8yg9?e*!>%*R$jaE@ z)!ooQ>hG+mfk&_O@X32)286!cB@h&cSp|%&%ehlTN_W=9ZQzu**^8qN1T`L-lf$i@#2P9dQ<) zhiVS_({;IF@FliJ0TINK1Q|d|ILr>L-+f`1fk`a(WgHZHSgp@8@$?Gs-5bJI18Ew2 zu*g|!Ye2oa#3R{@+x+gX7n_=)A>-u}eLCpwcAU*pyc8IKe}gkA;M-UH9Z0|8u=OY@ zxkkyF?vjgN0dIlb2)6j~D0YE#pr%Aog3c7q#?VR>&a69+^WiE1nr{ zF@@Ou?AbHrjM#QXLsTa?d+Pswi5+N;dwMD%MQB&iE-WlWn3mPe-T`$Yd)iwV;`1J$ z|J(oUl8B_FF&91ISIf4eD z^bv>62W>ApN6Z@_t=Vk}wkWf0qQeeCnCVE6whT{ACC9}n{riO&5aTjXO=0y)LVmxg zv2hn74HmX-;GXjBixcOm(3wmy&?iOUNEeMzBTskUxCrlYgLHQYk% zcOWdSVaiH|ZAL+mvjwbwz!8c{knNvhgt+Z05T?ECkxczMlw z$+60%A(oN)<<_0);2L;-^$>zP{Epx!1SqPkq-1tsA*e!T|9-tB2LrquU}kuN@c%-% zwUyY#ouhP8;?SX($jFy|%FY~zFWO;o)^0#^kr_7Gx zbRgWqu(%_&!^6SZ*~s~BJb&yJ40XcQ;0)}#0hWJ%mlcZm3cGgPDVWZLN$o)U0aqLp zr?#h0&t9*|OMP?iNZa@VfHTxWWGSb@=ugu}8l}Gp?G)@nY!p6t@Rp7mqqS?{!-ut~ z2PH_wk#DhjGuisFi-Q9zCnsIjnKClNWE?txj|j@XSXd84cN!lJ0KmcF8__O-b`r_Z zKYr?zp8VDfQ*9j`W-79$r`3`ZZ{NnE`i)-yD56CwZLUFH9~>y)x_WFsg)+Uvz|U)j`3A@FR56om8Jw?oHw zI1yhBD4dGOR^D?G+k}csOOX>vXDlP=Pm|%7>IQWR%DjTPHA-5Q`#eJMh685+-tXxm zzieF|2%_x$|( zj~@@h7V^&@Jzd@F2dQ^#QI~*E`HsmJ{2Qg$^MYY*wB|~|{gMh#nPclSHcV-kwY8s!f2~UDI^}0;dAvjhNtlTJH&|1Xdiv1(Fda8Ou+t|dU_;{(ZhK4=JQgDKH z70PHCi4=sA0|XdeOK7MDoU)Kr*hR|(hqD2|J46vh)!Fol`Cq>p|Ke~FkDTroPCama zq-q;$KEl!_lCpezmmcJ!=tD;IZ~3C823B(f+s-i&JUD1=$&>xMpr8OVet9|SX-BTA zpMAo}zJv89Mn(GT>od>+;HF`?SQ`BZj$upYja_(J;8|I8-YT7=XJZ3`tx4SJzhDS1 z(c^=K?kV{1qo-;%&JM;Wc>`IIk$EA{w?Hp)^Y(4`j5Fp5 zJOyE$7~AvR6o@TaQXoXpoJWY!8Azu=kE20fgfAaHJqli2SO|#uiTlyLjc%CDMFFvK zp|`yf($}bSWKJE$@5UA7H;Q|2&5qmU4?9~4($Z$+H$Y?n1n?wL2I!lbs^3zq^+vw) z@_LH84G50x*}aK4)CiIFNzyhi$T(wQI!G)X!s;wquCfn^fPi|(W@cgv8}d}(sQjPq z@Mn-4b+#1>6n9ir2%d2|YQ0hRzo8tR zj{=ULlj^aoP2FMBqGBJhNp6pkfe3aIkx)E<{7>3-G!XwCVE~GWYn(oKMeVRvE_~66cx4g*CGadF$uW- zcVL~6CuC;w2+t7-7{FHA+Rt2g%ZX!5QCl^fNVDhx?S!2uS-*Gp_EM0MDGuCiPavH- z>k;;Ua8=eRrSH$U(VFsZP<^wyuxilRlz0Ez0b+q`igzX)o+!S3b36Yw_nlc!2a82UHs**U;w{mnDb!B^IV8QTQWb zUFi7hWX!Y1p<+lFH4bH{%3-Q^Fz2G@+p{NrXKg6HJeptX%_r*!zKtdS1>(N-ox2!%KdV`P z<&7!ICRAH!Jb?+pAqwhsBquxWQI9M90q0N3l;IO-=OyDEyTlqX=lZ& zaOf06#thXC#QCPyR&C85)Dx?Hz(s0m4|~lHUf3UGw}R+>sQTnB8DyAGy}egnMeam{ z&%3~9eZ>AbgeKC4=%&ssa2%3-5?@DIQCbRDxk#^QPv=WN#xLX&D=QYgwrz_+1qm|y zq1AIX`HH|aZo!y$RcgM2)9{FfsA4}zp9MSOdm?rsw5GW=@dSU{I>Mayoglr=f9|a~ zAyO}O5!tzG1Z`Wy!??6$-epkzi;$TT?yqla8|R0jUXtraSk?IC7Zx79&yyIq*~!&a z%;PDGPi6406xnn=z0Yn&T=W<$FDfaC73J2jH;IR*b7NauTYGy^YJ}3|kK<;=Xa*1$ zQ5V8>7wHJ#0j!eXdR=vH$J4hiJ$nnV0!UU*@2x?Wx=?NVfgkE0TAQ0^fBpI!DZ8C} zgTpx2bq|aIiWZpXh}9*dsJ0}@cjlvA9kf^kua3-y$N**2Uw8LE49kDzIA?I*kn3le zS-#Xq7ZW~>&d&G&Qqo`}(%wSz^r(G~_M!p1X-ih2!d>_l~yUz1rp=8_=C zF(g<~tCev&kJWLrLyIo(GX&;;(bcsBKC*LjJ*Bpx@lUcDYzNLe3Uudz+y_3AZo>4} z^-#e_1cY=`|5qFl8?;Bdsq?xdbt!sn!bX>HG2bZ5xGqKcfCxnuz%>WgR!n!6EdHiO zBXXTn!BU%hDs6pL;L;Ak>^cChN95#?YdOW}FQNSP^n?j8d0fb^lr~6lWq`P`enZ!U zXbwd7iCx%P4s)&a&$?P#0R~M7FL;4kXP;JLKRr<=!8M?^Qkp8YxwSAqDABElq{Plo*@ST%fONb^seuX zSY__V0|oq)(F4||rTX{8owoxMg9pI(!ndDP{R-YTI8Ny+Kl1`*V=me~d8{eOjKW|e zr0diDP-h7|iabssl|xQk!wOu(n>jBWne%J`v8bx4#pP?h27L=15vXa%c3R|KdUv#i zZtg=$yyW2l{}c~YzGcC^;J6TA=9g9hfyH{~9m87&$#M`|zM<~{Mg_OoG%P-N@E}^W z>71A_K0iM((F8i)q)?f#fB>Zk1$7mwj5mNUvY8Y0vJ^S2(WC<=uoE^^V2yy-2QyyC zHnHt0c_^gcqOt;f2N?}0@7y1|uQn`Jg1JFw3~<4Y)9DavIHvxvr-O6fO_T(eJw34| z(jWV>%%iWSiw8f)!d&U3Q*W}~41fD3SUD{SNg+LoA{ydepXHkWqm-!_vum1FkkVMJT2~{i>*_U`(=Et}7owJMhpQMXGn~uY_WGx+KG)uYo3F zza3}h5va>hx5VY=k=E~om8v8>am&giB(`yHK~zRcyDRT2vq3dp4|wo%t7xw^+7BFI zh{6E%*l`*vJoWg|TTVllhms8wJ7z`4-N05yukuV|zpVZrqQN=K#rD5+z`A(-b`6fq zqSokI!39gOTq;6I4F!yJ;_UrRnna96X`2Sz0L&o%l0F~Oi1>I$1SP0<0sTsByCgjs z%8k+m>)pN>Gqua;PjPOpY?d6Fu{@0Kg25$ghbphYw0h;(($^bou;@WxTI5R+A6F zj02XBZq&I$=-(h#!S`&r*xuFMO_hutfr_KfqLW^LbBlWWv>K-4#2OR^E>Z|n7r%q|zP zN0s$KY<}J&g!5g|5f2|eZ0Db1h^Kt@02f@}-AnEZ!ZX^t&)waE=7T_8K?X8XkwFHL zpraAFsR<9?6CEl3fS3aXV}uX{0i}8LE8IaGL(>PAOLHR{65HPCczai(``f??1Kp^9 zuH#ityRWT!qu`Wad8Y_A0}CZ01uy~EA{T5i51^Ubf=iE%AJC;ceZ0Q5_bwlLmUBBVf2 zC?nH0a9g!aVGPu@K55!MdUkOhLz!?}8e>T~v!4HdTxsGr;+N$TyG4K#u%GAaC9 zc1?{RBHF0KsO8G^+4z;-Nul4in(forxV}$mat%sOV5$)yA3iR(q{I~xuOB~t z=-rcpiZMP50({u~>gmm(jyKkZiXT|6F>JSru^kE7eL#VW9RY)bU z%@8QxM#b5+NjRglbPk+H>5h7RR70+f+ywi75He)!`r}9Mi@xR;pj2diFc@rCp}B-3 zAz)hU*3cW{?kXxRB~}&s$gd+7+1^jF|wAbW6=*lo_9HMOt+Y}OkTN0E{Z z@D|Ot9p`WbdRd6m0g|ESjrE>aQo}&loeiB`@{y~T;n#p)PQyM2n=l+?RK!5(i5=nh z@7G-U6)yV86fh5Ro9B;y?gR8$?D9TdNWTC50#8YD4P1%x1IY>K_a0z1Ay1w>$;siT zJ=iSwQVS4Urr%CJ$f)FUz(7MH0O+o{tIGp&8E_7~N4Y+FgOf$o4e|$Jo3J~8p$3iv zYMA)Zn?@&2Orbl(`Yh1T65GVLc9DJCPN;>6w{ER~x2^=0?Ufum;nO#Pb!-T!6j}Tj z!tdlklZYpa_0jq!c7#3`cpPLF@Hm7}C8S;eKU&w;7UtVOz(3(IuKb+94FB!;`1b{B zaT%PweSMTx~3y%ZbsBa-?^#26Q1vEV&|Ar%eH>6x|#uq%l_l78` zpNF6Ukr%#}21{E_8*3>844kpb_QAFn9FVf3H%P{2rg9I>B&jF*RxoEPy^j&P>>25|D@3FLRjGf%|(hL zaMT6kNl5a6MFAtP0E!;qPw7gttl zeOGR^8zm$1z?mA@xigSd46ZcFR$iozGz(GA055~@1|ksY0-_C|+}O^AE*Y()R=<*PdkS;NUggEiSRGl!z;jhgyr|3g~cc zF?fqt`TpHIT!>1@j`2DzkX|7fAM8j@N+O12Ad^EgQdcGM=sjwAoTm*g;)r!hpb64# zCRz@t6YlA#6}f_8K8(?%vHQjq1L`T&L*>&@{41s4=B2PGufuv`YcsTvOh zKFti-1e!zmI)USa#8Og9>htH%3GwkIJvIqgz=O=3xS=%iL*rz#tchxiq=P9$p*HzuH?LEzeuNl{{CWwUOUA{qD;w7zlqH%_8}-^t4A zU~TRCt%DmENgLTtQ}YHyR|o(}8oL0je8HMn{Gz0!9za+BQPmK5jC>k&8RilrhY$kH zYyF;QWo4nF!q+o2G<5xLcm2f)bMT{(e6*u-jMYI~KtPkir?YU2p%Df8$T-7Wrw=6x zFgg?;I!iWcNL`nzUTY=nNtN?v{3KR@;>B=m z(v}Ll!;i(%jg1>j;}tyCAS5`xZ81%@t#>HPcSr8KJoBZvu&@d-2>Ptpo*S>|cFVVq zFZeG{2uK9|hSnXJ809Cf07ZHh7DDS+Mt1rpfjnNhf>AN;D<|J?M^j>nl~t0GU7$iC zj+2%qHk&^vF2?A~-GDDyNGlsa7Qkb5vZBAH;>8SN@3bMk2P6T*xKXKkS4yNyf z{XLc&Kxf2})T9Fu8p;=Nsi=&xtfhk*I*pT~U%!5vnE2jbnb7XAJFgE)kb79i12CH? zlOJ07qN6OMpLBs*pcv_r$a569px{+Wghl|gfxEO59*zgp2?-9GGli?aBimI{x4v5F zh(w8;+-@C$s&IDJRX#1IQ-oD%qvb02RnyjS2_n>1__;uD1+gZ06I@kuBO{etDyj9@ zZjzo3h6lP8yjxpbne6Py$VlkdWAks=A}JxrJuEIp9L4Uvs}j2|QLsM7zjTZ~_7A!>sn23LaT*_dqV@t~}X5R7_Xy}A+pY#-v` zT@MaMDUK3&4$@VxEm>RQG{64%K^O_Vc{VbScnMo=Mpjm;OAUY@{8`?cgJgd=pSB8R zthRNEawEF-*gJQqKKYrvz5-m@(iOB7QRW3~2N`frG`z3}j|@A30H4!=qxE!iD}D3` zOCh-zZe~4geV68>S9&1Nm54a1@pWv>4|d`xzOY_k9rlMnL|YhZKb@9JKJ0!LlA)w<>HS!5 z1V*y2ud4iyv`cC0yOdVFQqzE2kdgOxbkNVZP=m21-^v`*1Z3v?%AdXNmrkcvyAA~c z4Mc6wOv`rd{+4G)pv%DRz!Vrh9&eS8CO>N9yPB|o15rqcXC%i_-6y7-p-u1(EG)#5 z#dS40lqjJ=K@B+E`ArzjSjU#2;>9=adrc2OzluwS;V-HEt;j|cD7*6O&lkqA1g z%3}aAY+Bmxn5Li_eS#-HT^3uA?Y}A5{_XzEM(pGVfE&ou;{6THSrFAK|w=i_2@r z8Kp#e2`3JP@7;qzl(P@#i%oYuwiobZWiibFBn{q>m{?HV!J4aoWTNfbJYM>z{wmLH zPHkZA^Zn6f4h_Kd;&07OTIzx%bjDE2pvCedTYe&OX*Z|Z?-qXh-6 z2-IaBzzXmb5Cr~^(VSZxwMdRJYnmFAfqsIJbMM^Qa+k#)NmhuN`k&#R!{8=>S^%*q z(?3yuPQX*_gJ}ldue%ciNH8PZ`(Jie6wD|mQwT0DZ!apEu37}NYyQxAtl*tD7ZN^3 z2P7nT7#R#jp&$Un0}NU$n|r~J_ux>iARf{wf+6vw>b>Mcql9f~yrV&sYhp7fzkdZ1o zL|AJwF*B0|os&4>mzZ@pG3_*UU5~xBH9ZqkP?Yxy98ceT{(O>){$*n$WM&d4w0A|D z*-wD08e!PGk$88a6tVkIc8ALsm#*`o6Eu=^NzninTxy&1*Gz@ zDuQ@~>38Z++X<)3sLX_ErZIPeMqt>VCAft?ejE%g-bsjoCv=8gdK1Ebh8iea<|QAV z{jSjXvQNbQvIimpt{aLyn`^3L5N<#bc;iOLyLU-gTTS#9pLJw(mByX&3uJ^IDZila zLiN(r6e_J(dB3deA`T^vAp$XadsnyMTT!BXN?&yE3m~qQAid+FPP%Dpx1#jRCw^5W zew7uJL+D=Q<8Gire2f%Y@%hrWXW1RTI|lSbWMrM@4xn@R{{8z9qtIt@+q?>s3@Ai_cN5kcUA2H)alBUh z`|TkLeRy9vozt$mnQ+87omjV?X2BD+4D3fS#j< z2oDW`muQgtv7}woyyb!1+aLSs{~4UOFf-Hmiu&w5mh>ckU=+4P--~6|~ZD0X}YSuC-k`l}|xo_avvJ zFH~_e1GPJHL4MS6(@;^x3brxgup-onxO_(411s@#U10@|O)WpstY9G-RK1)r<6~nK zR~Pa5b{PYT+aqToInzBWreS21P+57ni${2nJbgrayE4cLu=nL)QUoJe(Zgdc)D|;| zr@d&wvd;q@G&Un$Mb9mrM3S%P>w84fSxgiFLe}<5FQ}^}uXK!l##E~LU6yqIT-^sK zpzELR_`S)TIT=;x8tx((=VJ z*R~eGLwKzQkJq~6GCcb@xVfrMro6uLg4uTG>|7pG)&nJ?N-6p1* zQcL(ev|q=M-vP*ng51k%5fZ+}Q?m76fYQJSfUp#pUL8v6TZQ4c6cjfQ? zYZGEz2z?LMF(Y+NPE25ZF>>?+C@&xp(0{nrDc1~&MRtjO&$aI`hA7#Bk`#hKhEEHySue%EXj_cmHSdgY)}rEj+OH)S1`ht{%h+T=8!IyDCSKdF;3;p1F-& ze+t-zV70$On|EaghIa z3B8vio{_5u#6f1+EQ#!-yLOc}~gQ*%35}aS>Jd07q+U+LIA*pH^~? zVJTx$I>5@np!C-va2`vAf1`hQs};Kf7+v!GV%D}``p*d6iRs0mA|Ig)$21h+i=si@ zcU1XdKLg{a@>wK3kmZo2kW3*1x{Jb_z*(n}T;4ogd-fQeJI3AEx4z%a&LOStnw^(c z+d|5#rEYe#DAq&&Js=OY%+#GF00N;p6JTE1&j!j2Pi+h{EA?ut`m?C}URMMo|mnMp08Q31zAF5qS z$#p%yv_E*y9xXH#|p-CHr_GQ%XY_eE<=Y`pZlk z2m}eA8~-RNzU;$CzEWaRGS9>(Qfrr!=u@Qpet&XW+Io}1n!%`mbyGt^h!k_A^^l;7 zXP}M=!(7iCteO(@jxtY58hn_`alJg9Jt+93_$ZgR)P-a)6g9ppe(z}M4zZ6yz7-pC zGixyid|wSHV~Fi>Z1!MjeE(&oMt2X7RV=#Xx6+ET=(iPhHa@)Z+KMBLP%14f`AC%e z@>Nx!_lJ`4_sqh2j9midXqCrA85lNH!v{FOV7g9BJy+o_#l<&+$}k@K(c@$r$7 zlZUOF{O6bQ3ZKjEk`&Kuy)>-xqV=IgtMQs{m=Saw*CusTKAB6TuFcxnh>-Ihmu?kX z*>?OcUD0$qxum`TiLniH*t~CqUE*W~+oQK@l-* zW|X%54{IBn$;R1EbQ)%EeRAc(U9J0?p6B?(XqZ&wTi&St$E)t|>o;$<3uxEI>3pBK ztyx<$e2BjcXXkNwIaX*0c}c~kSmM|vnKr}JPv59S> zVa+cRLW*$+SazRDs*2-D<@ddjqbI|P*_Vv3fBLXS_wQxnOb;1cKgA*0L2)~<7ctAXGgnRN z?c@#SI1^UQ<|gjn`FTP_o?Z2p%zqw`N#6)_!k%NqdV$9=9VBZDY3t0MDhNW;Q&S>- ztw32p2!hZ<<#fT`{*S`?f&yU?2`NA$Ip6*-UCxFvfJ=r3h?j&GjpODz8aHNIqI#r^ z+W)IYVxSoiAe*P#5@?r2V}#j6KcP(%;H8GQuyypGu&|(@q%>NG{XzW*)PHj^{;RfV zHuBO^piz9^*SG6;!@&BQr@#L?z)+)*{Jnt^(1ZrAJxfkL0X`yc$@x|7>gaw#P`Gt> z1Db0~!`1C23RRcCQ6r(HzQj%?$pSiXJ%E1}_T9JeYebis*mT$s|Eeit@tE>gbE?zAAI`!B~y}3`_ zTT1&`_;AY$Hfr?}iI}p$R8c5^y)WPR`cjB5=7MbDlN$}T0^}OzN&5mchdx-2(V2Cy z5fTyq#fIJ3sXpK5yuLfn#eb!5Ag^iO;&3Lp!(0wX|1HM^yF@r+C{1*Ku1JSqIc1lL zaBxQY>9!TI%!(hSDJkp_jyv=W3W3Zu&TQ{IR)3zky{_7OFWx|`0Vy<>lKg`K<(lg|y3p!!*V1F?&yrmdro8 z9-nyXY)+!*;-H|)Df)|O>b4$HYiSjI6v(h&#L4eW-UG2R=*~k<$8*R}JS!gjKKOE{ zypQy+#i54K*z)tAW#*;?-T#kMaKe#X)_jcHbbgw?CCrF^-0^C`|8@$#(B1yTR_Cm| zjM0XCj8WW=wK6v5iyvrZ*sB<^{}P1U-|Ff{&>k#)%^b7X+IJPJ=@#o|9UB!~_4P|f zeOV1o{9*N>fcO9;N4;rX3y-dyQC4e@`&RC9C$kh1-7&BmUbInEDWxcZGRK|@$=!dE z0;0deC2W^;E2{mBO_KCowJ%MQt`GwxUc-=4tkwR0bMR%s#fT9Bsa;YNK}o}H+17mg zw;YpH`?U?knYuI$R|jc?8M9yTg~#65|Ad0}{80Ls2+KjU2XZ&`mZGhaq8+t{b-(Wwa&9g~Zl?D%J^mTXNxD8Fj z^3~lnN-vGP!)#UV?QN6JLV=cCHEnfefj!XDK0Z*n~A?U!2*tUGp267&aL8OaDixt;zIs>sTy&IY?Wnlw`6IhhEv6(j z%cuXopv+NIH{+6_t{37haeID`%+hh|rez+P|IPeKmrkTfYYV%XdsA><=4S05mP45{ zlq)Y5(KsKmzqz1sO*%P##+N7t=5HxnhK5&a1uo(PuRmNlPteTg=I zmAGrF=)@DXZYBCU!mV}PH55>A%VIB8zjrwJ*pWZ|?zPObq3T_Kd`P7F1}+uq&fYf-)mb>OEKN$ z=-ik0TE26CFX&+Z9d)A}&QZk;yzfsCQqt;GDs05*$GzERhms2e@{x5T?Kij%(WS`y z_PVPd_9wgXDBm@WWOvg}8xHnet&7C;LGbs(+wN~YK!Mr*0MCr>xAH6PKAXjCl}w5s zGQL@uU)`Xk#*EdUR)MWvk^NfQfW#temQ&hp1Y^jbau}eLxnr7Pj#a_ zc`E-dY2ogYM2-Y@$Kg9)xaH#ILsX3a&&PPJnuOQY=>SjUu0wQ*3n=R3{&RMz{|L1& z2xa?Lqj?K0IWk`V*ya_P=8jNqBLQ9;&jYHuw%JXG+YP>^7kvCgrFBzvnHi+lbVo+R z)uowcl!b3aSon=cml01v|HO{QG34#MK#vP2);!upyLLUzO~SgOs`SPX{$y+wE+c zzR-{?1p|T7CP>Yj7ZD)coHUn73%xTOcXXXi%i*`+uE9aAc>KYwdvl8#XS~MTZLVUL zTJwseZJjG9i1pxEXw~}q70=nwy7se;$nL-XVs%M%(}EAqa1GBthZ7ayu{7##In{+ggiY&?xj zIdXM7_uTUrp499H`{*}Y^xw?V!#3*BC-g}iFMg*`c3$6k!20ht`Nd74!j!u&AF4kX z6~{R)rV$rZU~!6<&wz2lsJV)D;?u){&#QZ_;8RlH1{4SwY$WFqnenOk-UqFOEw+)~ z5$yFScv!PsfE`kQW_i8EFhg2}@ff}n;KyXXoUHMw9PekiBjZNor~F&8eEo%dTDH1v-=(Dew^L66)`P#QW@;J+Av0v~!OQl+HGmxN z?tO_j-!O5xj%SGyB8FGB`M|b)ued56!Pd_EO6+<+B$E;D4~vShKRr(_VhYDrYL|yj zRj%}kPOSs){uXh#gOuhJM>o)EMi0NG#mn*UIV=Cw>CO=FI_{%W1GNgbMney?lN?As ziQUuifNEzVBhQX!t-k5cV{yE%;B@@qncnaIAsWmd`$;Cb5!@HWD9{;BQ@4Ldd z4=%$&H})AZ;xgFpNX&hD`Qq`O?JT6{ho9c<+tbgm6)4KK+*f{}4M7?cqu#2Oz>rX* zs++p1Rw|M?xET$}H-g}b+dCqS>O8W5Q~P(yy9PJ0b9YJ+Z!sb2xBeI9`Raj`Ou%{b zD#D1Ndk=%P>OvZ~ts{Bw%oMx4+1 zyav1(jTbno!9p~@=2&lDzkGAOA8RHf6J9KP?WnSEw0!U*BC}K><4v$hJRkC_%il z9O?Cs!A@QUn=#RzrA;dR8UFaGO)p(zBV_Xo0B7;1CAzeTV1P6-c8xCJiw%3s!NEE#@ZA%)WCS=Hb^1s7791ps#drw zTtS*Q_;|;(sGz`2X_}&QEP zIMvuZDSPwAi!RZNlfngI-kY(wB`nOs-oT{3;Q#iY!`UZjtZTE{Q9(cD)0rR5jZI4a zImnKR8x`R@-*C_*5cg9)kIg15EsiB0B!8Vx8g6>{-`@uG=2fFn-S6H2cgyK0dRcU=r-dw_+4s)PDSj&EWu-YyHUlhs` z5wEek9o9H|-*6W~%k`8t%+!hhF|_N><$|&L#{Z#dVVxHEpMR#}b`0>P{^$S4A7+#P h7W(%;ir>CQ`CenqG<0bRh0xGI$;^zBL{{UpC3|nmCZZiFqs;8+lyQ<#8HI+7Y_c;l zLPoaV^WEpV@B4S(k8gimpRVgu=lgsg$Ln~#p6hT&O+}ubj)jgyBGD_HJ9CjlS~o-@ zt-ZN%E&hu@QAiU0huc|B)7i+*-p$&?)R`o2Vr$}P;A~>dY3Rmj?(A&uB+kcYZ*5@f z>|$em%*f8>TJ>iRe1wq2WliV*`tPJQ_#D@$2ba$~wH@E~ZbW1BhjH?a8#f2KKONun zYRfvs6wztk(Q@;BU+y0$3RYS5F!8rJ9?^U6M~9t$SH`TI1-Hvi`(DSio%cT+{I>b? zQ+b!eJzLjIdENQ5c9imBqVDs07vd^yvgrz_Er6%bqDh>$SGCK8_tIqf zqF5=Xx_4aoz1sR|QFn{WzqGHby}I6=(P|!H6+rGBWwWiOmRjfsCCPm`7sRqfB{!wc z#?|}b&THb~aavXBaZ>kae;CG_s4>#YEmwMWnrraWzt+;I`m9_re{Sc{kztpijx$TN zLt>MRap|NK*B=^c{Y^Vx6$wQ!r@j2pS$p5IeKoI_HXz*k%5VQm&%06>ZeQT0xuM?o ze7@FJQd{=Z)!XOIrA|%N*`631&=~r<=UjuZp|bpz)Z-z?{LEa#tao$mwKP^TqLbeL zyk6Xlb!Xp-&OzTBx1ata7s9lgFPXOch2FRTz0;F}44O&`92!EsZJPPd&6;l0cNN+h z8_pU(ITl_c{ByS{RcPexpXeo;gyoeW*$cE%B$6*l;moPau2)7oHfUZpYdbM9>doJD zpy<;TErtXu-gCR3eLJ&l=j}MdQ}UeLjxKr04n`z+FTZ1)KQB$q4C{E%R_o$%ue||?& z?RHmesR;6GUku=mfyR_%y%Vz zz|YSwj88u%HdfV+os@dq_P%tlfiwPkz$ts$>bnmgb{6~ioII46oSdOs5Yl;?q(;_d z@%iw6XdQ`k_eM8eRIc;Si{kGunvD+B>TD#X-8Je9a@`e;Z?R^Z?u{H#5r+>A+hiWt zTQ6Fy9Hg)^M2md~eRt8VoA?;B0<%2nv|EkuRNtQSN_jj|55*_&Q!&NEPu(rI!&WJOTw`sP# z(0WhaL7muNrxlJ1uT$I4#`^EO()r?Dxx^ieb4pe+Xhx&PuIu015zQOIm$yadG3C`h zCwV3MH4PgpD>x>Pi?1R1uI0>MYj#J4P3mn*c0uG;v+Mz7&p23esmMbGI?%tL81q`>8ScbQYx|xT0wJFbI>L$bEyK2W&Q)x4rpkb~-QW-nJ_@@VCed4k!7E7fKUb z(S7InG|YI-fA2=v#D~f61y0EwRcFi|=+ul~&8bj1+s3MD-Ra;~<6C#kx_9VL``T=l z_OP*2<}tI&qj+?U-ujO;LyFRxp;ZZuDINq@p8)n z#~=6WjD_=#w)40Z%baiYN6ir zO`grKX(>|Kk6u>fnRsj)eK0vQGcz^CkijN#t*WZ(ezE7`>{#bpkDSAc<;?od!wnYW zoo|=iAC$Vxj<$ArFOC(jE{|K(C!3g=ZC1a1=g$1EqVbn6U(PWS<#1cKl0)QVRpbe~ z^1FT}tCkOPsfT&6BqtY<+FlB_blibQ$lKpaIrdfY}CO9~_z-ci1)SYE>_Mlrt z2cknCisF)Vuy;XBYR=|d>>=U=PD6D5X z^(fXmfbTc6v$M12_kKQUk6ERO1T7Ws>7ngD^DS9MMBj|NN_3Di2Kg&TU%67}(gG+> zs()AT_ernv1g#v?@vdU#jBRGsQInICyG8AryPq7n)Kcb0yLsSiYVaq#LwN_`F zbvxCf{^d*FmEY+auWnus`2U~fmii2{2eJGk#;G02?|p9a*s{NW>t`C=*pg?x)$eV; zk7SzJ#fu^K{bTK~dwP17`dvnva;=(e$J%lSYhqPZRG6wJ&M<3J%}=f6j-5yh-inPR zt7&SsBrCIOGw#KXN}tTk>Mt69XViL8UjEi<+l$LIn|B+pV=i9$eg2fa*Xqi0*Xqjk zm27)^WmQ#qVv79N395c7X!b4YNIXNOLCpS^X)6cULLGrNB)y1 zPkssKW6sEourxAyuWy>8Q0g&!Q`+@lVaeKw<;6eqU&=7CE^qTVC@wCZopQ+LHV*Or zT^vfv$|*`u_la(Pc$wzBO=)9ot=b%=%ujI0`RBL(pYnPrr5 z3~Hh!%q%*ToqKn=2@iKk=UIQJD%7l*-Qw?_JGbz~_U%hK4Wssusl)HQmkVWYZ7D4+ zwLTag7M5r7CCu*K{6N)H!6n8cI`ShoJ-HE?>%pF`t(}q@Fpf*^r54k_6Mb; zq`adaSd4DS+E=te^Xl2Z3z@$7iqH2Mn$bXi|IARUpnbhzok9LF}L;=NNT=?s|#yWj|eyzdwO{- zZgDh_;W)pT2!{fI5x@J#dj{lmvYJc?gNy3=BRi8fX7I!w64qqvH zHO3r$@ZZ79=UK6ls|>?bu7NKgHJhk{3)*t^^u9SHs+ok1M znxGYdONhTUkUsUl|JnXr-y9oy~2uXlHcoGFaKroSZ+4@XbxR^PDYwn z#y>bxj2FhcKc_tWZ^SdaGO{@?`GXSMlr;O`6lSW^K$U~N{c#~7>(*?p#p*DvfJV8X zy)T{rzUlh)cvH6j^QPXtsn`A=$fG>#&i?-gg!wOcwT_myZt(c^zrgJ;lsb(<3pm2Z zr>dyfmSt3l0v{V2L%(?(9jzQ&!S+AB=HAz&viI-9?N6UMvknhP8)(fjLl2FT_Ia0( zV1#}*HaeQD8vD+sJr5%)JLRa^e<2)00^#&9YLJ4D&MLjJ?>TL5K2-Z$HkV4p+^h)V z;9z13i-^$F)#ZJ2@PET12kTzV!3K<;Oyx)sDjkV_YWin=N6~fF*pnR<70F(Uvl$r~ zIHM^l(VstkdY(?#(=xaJN;CmjWZnbYn&ATuds}`~w|91a@?$!L#CgTd&CSrTH;|t7 zdq+oZZtmBrDoIJnef#!>Jbs*>mNwLu+l`NinIl@P%)#SdX{&o%K3rI82>wcW91?;y zG@O#3FM90QF(Dym95Zy))%n5L<)tO>)#X3e$2;rDT<;0kIZ1p6U!|+hHb-Gc66Rj? zpdqzhU#CI(#K_24UQw~0mUd>WJv^Y%dwC(Ne>3wj&$)>k8Qf9?(7nR}SWGfrTd&*A z`%syU>nRHk(`^lHZ5C$c${6M9>T2GXTXr4i6cQ3Tc`~N)XBz$AXDSe<$9H|15VPn# zBL;becf0PIbywbb78q4NuBE>->1kAAbAx4gXdhBh}u} zK*dK)4SY3X?qA3vzxYceN*M{%ORVEDWi~+p0deP{Z98_vXQ~dZNll)fp2jx>q_VKG z+PYi77=QQ3kt5Drj3r5vDJp-*{$Jw27AaaCE8SIJU;pu=c}Pf0v?{`3xZy=_uVG;fH&KY}emwuum?ogK7)iI&W}3q|YC&JyS|1bw zN%^j!866!xrvFaK?l|f7lko6ZX&>)}>7VZI?xXxQF>6oQbtdw>;68?u*hK6tsQ{<7 znwy7bYG$Ut!imvV9H~fH!chi=i#JrQ4nM2z9`}_9^mr_*x z*VDHZx>%up^c4CV#a4hsYD0v;*Hq7ke5$HSL3z$*X{iefj+5%lopjurF=E zm)g0OHUWf z9~Ko!cvPh?(&$vp2|DziVfy0l?{6V1V69}{oS}E_+(w&*0Gn^mWpB}LW~vSR5Oz%O zbB5R=?Id55DEJWRBMo4B1Io|B((<#uZAYPSWQ=#4M%4H3-wEXT^QX=C{0nz9XyQ7v zb8`NSwhB5AsoB_!eR_NdFRWWG{ie-+wAIqu+7qa_Ew}~$z2p0LbF#piHEXPE|tE#3*St!Mx^g=JBazFhu-Ze5b zBs4*Xt;iXLg^e8%{|Kyp%&Fdi#tR{bP2v@TSXTUy!&s5{~81IzB>!nE{s6d$OTGV2Zle)9C2v2x6DgzIgGpMlUs-PhVS0i+0^Qp(S1Q*R~zmxw%PX3u7}g zyyHjX+pe>tPotyvu-dakRA3K>Z+6ph3X7b-_weBWUt~lCL;*Z68+fVzOL)$mBb!@j zX=$nSafcfl8v&T{+E@lO)klvWasQrOM_c637x?^nPj$3}MZy&vurOY&)9Dut{b?58 z)>^)O^5jWX1pj;Vq`Cxo>IM>tQv!$e;t0r}q2WHC*3X|6g=-WZ$HbhpX%nKM@yF31 ztE+z#@s;G_;-X!@o`sdQy}jM;d;TQaw=?|%0wJ*nU7zfgYfF6<>$5VyFf&5sPI~i3 zQcCJAP;&iQud%M;*bb%HXks;u*Ac79OHa4O#?Z_xJSu9*LO&pLWMFu>?XAc4-PMt6 zEYV3K!IreNw4O#r-nw~H(re*K#&ZMEvZ`-I|J=G=Ri%WIy?d9gEx2>IG5wHgj8Z!N z#8BOSE2|N3IPAZo#^BXsA zSa)^lT)zCFEHgT~11;2iD_D*J@x-Zx87l?`hSKs={_FJ$9OY79#dC9W=h<~-ym~c0 zHbxPbf4tV^&qR-`kB<))2vdba-1!`XipBmrAt52ylAOf@($cZBET&~QH-Qr;G%lc& zSwT%HBANgXL6s6N!#i!Tl0uMpe4TeNFhoa3(=yB7-{mk+wfp%yMWgzmfX&Rq!^0qN zEOvwb?u%%18G1$Te}36mTfYIk4~%*i;DPhMIQ_Hl=TEIGS5!RcFKKDLpirV8JvzlY zL)O;*?CtNfG`Yb>s3ltBx{{I-YRGSE3k}KlCE&=p!HqZ?nSew3arm+On zs-^MQ_ktZ3`Lv44!^p_?xKsWUOjyz2P3ts#3mKW1@+|5Di{Dt(AH<@avcgt+ z%#Lo?Q=Z9Eut&#mpBZ);YZGpxnY(=UYz4}%2s91FG`sWT=g;w0C9yu8Mb~REeJUUB z$=*Y^&cnzJ{P}hsmwI0=Hy_^#Vd1w9ed}MGkFVH62NXj`PcIA#&K9@_d)i5Wmf+af z@u8u)RNO16R+wb`*(c*3% z9(}3j4L?*={C0g45wWXv3vHPP$Z4Vb47Z-FfMG@>Bo?3fer9dTy@)+Ka8%6xD7m_d z5_@|t;g_@+iKV)#iucG7h2zq!(%x?-JpBFr{F+{B?Js=Ba)gIR=e2EgObir7eOudO zHvVV1j~+E~s{p+D{Miys6e}8M8|?l1`V(T(^2ijl#~;WKh8z1XzZ}wc3fDPF^a05Cwt?n9a`$I zU%#kF`6ru)yG#8+OjF2NAI8-#J2+(Bx^?UATd6JmV81i_f5x(r=nqB25?ji}C8xG^ z>sB*2Rr?FSEut(9ACK$%EQfYfFdR~;Ww-A@KhzTX*4U_*d9@T3XwG`(GMW4}TB5nS z8f$w!k*oc=@7UM+dM8L{)V)b<8H`1HF}<>~vZxor+pcLw0&f2t8R_HL2jaB#+w!M1 zwVHnOT0l{Bbad-xuy#sM1?226wBgxz@7*(Unp|04B&3*GUnl(g{(bwbt*t>{O5?Y8 zRvmecC0JegQw&sHM&sveeQRyr2{h2aV)Y{f+IytjsX(|?ZDxLnm&&J4`#pNJeU*U; zdmZw4L3N9-X>UzU%g$nap|TkiOV6M2MkAIKV#v(?>i9Ac&d$ybO^He$HPKtX8OLDH zo@k&;NKf@54adMGeO6bXlcbG#&7j0vI(d&C#T+xtAiKEaqCZg0l9+O2`M=fIAy=vh50^fn8Ir(_tezbcD_;QRK_Tp+ttDWaASr9-VnAAwNq^0vv%yp=k%8^CEce}qoefzT@w-#c(}QTSU7K>*s|leJWs!D`)E&q zIzx}gpNcF;-l*dRO}6g%r0+~|y5&*`8RXHUI?yF^tabM#`sK$oaTl(Qwe^pU9o0Po z4X-6D!9Jk9I!esQ#6;NmV=!P~EqiKWc6K(}F8*LHwv{)mR^;3$q%=u()k%)^rp3Y< z8XDT6tQ$6LSb1T)a{y!bt^3UHiHQ;&RFljRL`fhQh&lA$ zeEgV!@>xqk;nR;#kN51^12Aua{@lHvc-GwFq8$M3PRve6N5^xIrhZRN!SblGUHlx% z18x^foUqPf@IK z7=7l!g9mmUg>tNTCjy^56?d_`e0k@QYzsn{I(I?#jrX$qw?qZ&i~^rk?@!Xq8-Bm{ z-jDz5SHp|?H*QlGFI}==O}u>NN_AOrPL2~=x?|I6)1tlTL~;Os$y?%ueMaVD#Lm7s15MJk`uFuiAkNv zxmTH)_8)`yqOmD@s+K<7BLU1~K_)oHQC{Absb?ZPdx4{VQWE1<{@ZwTp>Wzo&QkJ&1)u!_xQPd5;r)S4>^!4?R9;INGTXq*U^&b!vtj9U5 ztduW^y=tbKIy7Xi9a@ad585plsLsg6$2T4hWej?-!-6@9v<*&AupdyiIX4`FHc0CV z7X(AY!vWkbsH)mwch9NO1q0<>|Mh*#9`ULesYO&hm42o?W&po{b>r#F4OI{08;p)x zw*?o2nXv~Q690ZgNlq>RQV)ePhUy{8KxhYm$WBYiE%jvqn;mwXHW)o-SQ=Wc!DQH4 z6`6O6sU@0i+qPO9WC&;mrhGbt#w{dtIbiiHu;tgfx<~4aCau{f5HhK0nt-8Z#rJOB zT-Sz;|LPAU`~p3Y!)NKjw2=nnw^7Br!66~Nzkb=;+CpT$(B{AXFfXrefn!owSQD6> z@NDYU-|wYGYaxi6%kK8`_YXg&rBs4UMLOHtdN}TrIg9j$X+v^f~;U6W#eha?r z?d=V0U@=o8-FjbfQeO1}GjR2mEnA3TDqg!e9OTljJ@0{Xulz$cx78J|w!roG?%x*@ z5GZsS++uV1Q;qcM%kRvrW>pc-KVJISG=Q;*SJQjrnl-da4=n0LfF{i62g;VjL-=&_ zy9Wl&rcZ4MmmI@7t<aPe4pr1#r%; z7nf297XC9|y_y!zmmdjI}E zc6N5?xF}AZKS>92Ip?A#ppKbuHNNSS-2}xEjrMC>G!bQ1wR`9y*{NWKE(_BZZT>-yPEHV! z?2S#`zI^fu zex9A}2tL1l{d!p7*zMl;k`(FEzi?hY*Bv;Iv5%WaLp_w|@P% zw2&VI1KEpdadEyPPr!XNaAyDf`BV8ka1BWal8$d8w3eD3v=r|TYmbh6<32a={?=A> z4X8-ZpFfwAlcVbK#d^*9_(xuy2ij_)9Uy}CSGQeSTa=# z;8`mC<+C!yu`>CfH4oFekJ;*bie%JDueR^sJ-_EW5QuFsy1GoB0?VEme2>sk`o z82b77FJVXLnRRk4$$cIIT$^^yTq2WmT}IUP^g2+@4RZ;n25@c{XGTuA{WktIZf_!$ z(V`wL?sBm-;Ym)V4NeDGhcYX7AC8Xo2T_OKb;N-^M6}XjbcAcyu3>3_IIs^Ej4Zr- ze0-doz9w&kt(pj-XI5VL-Eua14T=Z^{Mm5>KhCR}jPdaV9iNl0?_qAG!@&g??VwsP zM26pMO;O6cbr%rt-o5jRifDzNZ`@}-gG){JmS6NblT%UYyOv!;BSY80(J`Lfm#cnt-SN+<9eK@haSXAu!+Ox&W(jNEoEwy0oo}}*-n6y?z9O)R^y-q6_fj`=4%j*Lt9ZG4ka2R(l=3yrS?bVa zQ5kmaN`-G^*LAXureGe>ZrH0#HAym~#ori5fttqBB2)QGiBbBdowoKfDD>3T6f9aJ zJYmiwA{@itk~ULTl7K!4c1RA6#+*$FYFRt>;th{RM#R&nZtm{AEh%@MSC-r$PJoBB zsTuG(XJsm_Nn9!}xX_81K^u!RrLiJ9%QWuy-Iy{%=_$hub z<>ckj%kS@zm<4dBri4Jn066ZzScY6*%l`3_v2h|`k^3IXAZQ#cue7C$JwUyXgDuE2 zP^t2Zii!#fvJP>MVNSb4yA8g4>eQ*fbDB>!@Sg(L$$b<*qMkFfa?WaKoZ#f-ggTr@ zR?yXrdhz1L>({Su%4gGRY2{fz4G0Km^9ptao`q?bLT2n68j6UBIG3K5f;J352mE}o zbiW=ZwG>faY3M(MWrDYnZ7Xm(MDhEM3jg{{_+Dk7O>1^i#rxOX%{Yago}PuyKmB~n z4r|KEmBVEQ;I7OUfTY?eefZZquf>BZQFw^u{O^83MGHRxT;{urK(li_w>T_4n7d#y zGVxteO6N3#gUBvo9Ra|m==Bh$Zs&&&AKKfC(CBAnVz72vv#k7vXD(dWKK4TLTEE1# z(bNTwP`)Ea_>UiV{qt*&O==p>ErJ>7m32fNG7``nUnx27aW>mYPuHcnNh%$k16m!s zl>0wyqG~_obD^f|Q_Z(Wa`gqMmt%4Q=0=D)nVOhzjlJ*(#m+A%s7q6%`{y4-S;Q!5 znWzW$AZ9du0xO>+uyQSGy6uWA1edUcg#8r1c<^sRo8>yIs#*g9zBcbPq9h+WJ3Bi% zq#$xkVB`zYG-vXmA)Rj=P)x&4$~tKQ+7j}{QDY1!^2Ip zrDE#M_4Ns4wU_Wlf`hk#04JRf=bkf11A3PBS&5pJSpijhzc02h*5)uje_eI;Lv`}5qIM8$3vz!_Vj@luMZY)( z;6 z9GFd;ya94LP%ok(mr5iA@E+>K8eIi3AIQ%Ikia@6k=62k|Nf1JH#{;@^GukBhv#12 z2-p7o?;9IuKtTvkL@HQ1>;(MhJ#1|G4y(m(Q>cemX=!&wF1MqtLBYJ-J~@0@7upZx zK2Y1nk!_cNTmNz+*y(rf+@UUnW0=6Ij8;D-{9|yCPcu_SL*qK2Cyog9DE&&izs5_= z=hqbcSzBJ&0sEpQ^i;`zz7BTX({n0)_$rnIE15_ZF5Nd0!EXc>t`0Tc1EuT!w{(kr zeE7#VzlBx^C&`@g@+U}>=q^@z$f*o{7PA<>ybrhr_(Yy{*uUeZnA5=YaN~JpA4q4O0T*kl8bEaONsGe4>ObE=u(>ZQ~t2z{REDp?VT3$NBJM z$dOT>55Q_@n0zC!7JPYja`HLZg<e&3lM^-+=&>} zY@&j<2EZ0g>VeTaU`}Dr>Sy&;VkAHHO|D(Lwk4bDu=z|hh=uBr@lRlmFj6ptB19Ux zFyFD2*s}dnQhGW%MR1lx8onaM#mme4*O|eVu_Q*EAeG$Q#4tPFrJ8=4a0|Oj)?hiq zLPIg}dBg6ZgcVPUX#ry(DM{!#k$aQw>Tm}B_;X;DV*?zRWO|j%oE$WWgOoJJ>(~EC zdCbH+BX_t~YMsh{$KUJN@YJJY?VEC8)~ZecT2Ge=RIJOT+hp^gs?O zii*AZO6Si`$k3rB=;zz-rFdKRez+4QX|Z7tUKnOTJ(SJq zu~H}*znWihSi$HCpvLWe^Y*PmQflhQuV0}#KlY?XJjSR(7qlSTpd(L@cg3nV>Vj!~ z$#CtZA*HS*M)XU>-&U69sS7Uv0DDWyEK{gdXQG|m+QR50{<+I%wWF-e5IQBH3;o&N zx$jsg&`F+6JDmoa@WSla$l#!cp59U2!8BB5tf+&ZdZRiN8pz9k9#(olL^swTk;sVE zas~j?5Fkcf+U3`Gu`nC-Jk3+5N=t6gz(UhC`)$kv>hP~PBqk=7xQI4^x(wdeVA}sV z6cOQ_x}JZ2=|NXOL^MFXM_^VHinpOwv`B*%po5GIiIOJ$KTpFXg;r2EoC4JuD`LTT znQUsB48IJv8kbLKkX#dyS-dj}cmHONE!;lPBP~xxZDz}gUpzE4G>FH||26>)0FGGt zsjZ8Y%TRZ>OuFSS@ZM3kQttxl^OazLwkKN%Ne%8NAWI^7JN$p(Jt|$=t$wb}n>SC& z-_7`niavXPS7~q9M3GdH^H1m+5cXJ~Gd^Dryp)@j)w6-XbFenYp{Hehuo%6-jIdey zupQJr-Q{5EY#x%YBQeo?z*NDflF8d47`%goNAbH00rDN{4FZ?BEDH(-b~fwrt0iDe zt4prh)tI(gIyyc?K!xr!Mzw*dX@wt;M>1>~`=1FhI~-kHq^|#BqoftXEzgQPo387y zyx>BtqX{8Sl_5NE5^|+BW6$_F$M)@~(&H4-|0{ogBLr?)cj$_6!whz}z~%r21=Gh- zf;fhm?@XQ>!YPNGcT`$HSQv_Gl9jz4RvL3lbiV7s@86EIb3Q9eVm9`)(nWB9o)XBV znwVPl@DdfSD8csJAyu;>^&uu{X2A@^C-a0gK%=s!Pq)}2D?I0BjRxn;HD}(EX@J4K z)U622X^K@tToUKmS#V1ML=rR+i%=e>W4igSlZM*;+rso(>m?DsAs!d=_i;bJahaK! zX)`{Giu#_e!H33fKQ*At#0SQ49)_g4`Yejk8Z;E%^Y`y>U=Q>9dLc9fD2b8fZ1dpH zk53HOR)J=;x2d;EHQ|6DBf*YLL)FjQ`2;s&dw2~;2!e|Xdx8!{@2z`iWgpkUg9K^& zNKXiuMBY|mpNU`|aMR_>muuG_W{ot@{yBhFi)DVLU)+g$y}f<^O~Hucv%4VO?^g+y zo#^xW64ZL-{CO)V^bie0IKDk))z#AjlUGe=!yMiB_)kxIc1w#U^e_V05s%wIJg$W; z3Gj=m&5+jypku-Kava&vr&ex%4A>P9>2%VrjMy~tCbDa;X&8K18!N#WK)BpQ~b<1(( zxgS&bl=}}Jz|l4Lzqf^5@}n*9E!DN_NO5$;=asD9WT!MGqL+dV^9t0hKOFV?^&e>Q z7G!~q8Q=3f=N%V#!gG*@5DEP8<45g!X0*glKV-};4WPF`O(e7(gf#^Gh|Y@J9jLf( zmPd)00Zy+rZMnGH??f0I1_pa=&aE#EZQseEJKj-bW@IFr&c?WXJHJ8MI_>@ppy=$n z0Tcl7S=oQPG}=0c_uLJ2s~)U}!Ta^vw6veAt3@C-do7CCoKuqXvr@5DnZ6_2m!dps zY4zfLy#yZQYm5h?bB^});eqA944`z(&Lz_S(uPzH!g995 z_&=9Vg12nW;C=VaQh5uF;s4P^2Q90E#tyD0w=PB_KZjvl&=W4 zSC8Lb>DxtwEXxxkEt-FYRX*fMh`g~5k86#vhZ&ByQh0nY;MT2r?i7?yoL$#DLU_dc z(GzlhbgcKnPpFbq?Z;3!S$FTQ<36ki8x@WI{Q2`1vMitJGqhT@`jQ_uj~jNs<_`{N zYIMN~}@y|jz zV=I}PZc7G;hp?bv0$By+GyJ_ECpmiHNyqRehJ#QgG!TbjheytgW9$s1c)+Lhrm`*! z9L01_9~{~zpDq|Y*`-_QrhN6qOiA?qc>Y|ZZUa=^REjoP|J*C^OMDxIT<$>%4S zy7iWC4|C-sPOarU&b?6301}@)dluO1Z{u7~ z?6&5yyFo!Ijcs3{k`S&o-ESfkiBy$VpuFq_Mf=?BT zO3=C`b84`r-f|3bvIrs{+O%Szzs8e4VWv>)NQ#>>3MD&in6HJ1w&hzec!bBw8Kn&| zx2t!_#QvJT6o2G`nn7tu`Io3Dwyr9>Hrk z-!PnBs7SRh8+Y;Mw6?a^r5(Hz6a=rtY*QF9FVMe9-w*_=g0Wyx0B9Waag6iKk#q`@uchQb^1cdcfGT0kg8GscNIMs z$6jOA+Ec!IfoDc$ zgKWSuP6!AfnZ!t}*g9gx`Y>=IETkLa3w1!KS3i}EGY@3EI@hxqntw@IpONls`=nN+d~0>1#&^j;58AKW=rgRgSi@pVkyyT* zWBL`!*rEK7VeoX0<-0wk)Ko&X>s!>t2iVInaz4$;+sLiU+~H=UbHumIFFh!z z2D8$f{2nL)82B=}X<*V%4W%fBx@Hq+mMYltQw71Hnw2F&*J25VdUaoWr*l#$I>*aE{-OZ4}8l z@j9E+LFl(-L$Qx_Yre(f7@E;N>t`${XTm$&weBUW&zjg6=?%K+YEZOIOijUTBEZ); zIP7d~!70vqpV!fmK&oCs0_>y%Cf$yg9NV@{AlZtL*y7@1drQm2$hY;)EZ0~1!}Sjy zIFKo|+O_^}d_?!>U&i3t5DeRDC4n}Hcpk+v=I-6Qdu0Q0tZ(6X#9bqfhk;-RF8pXy z&KG+x!+1QC&bb-FBvg2UX71gL^8qd|B4xcSvOeTYVZU{LXo5=))7N(kl^PFa-NzL~ zIiG2V+vs)Xn5pJ%D7>_N@7}#2A858j3&$wuNzJK6uHq!@jFs)a^X14N!xZ2=DMPwzROw@`w=;QayF* z2DszDSsF`RiRIiQQlkm^n$kq12Vf0Q>9RAC5kz22JCxW4^uCIgM5iB(hwIF_2duhg z{J|E=4(ZcQ?qtwSQI2FH$ka1S0QYa~2Yu7gXq1(dkjNmSAZiT2u|KV$W+2o^)eeX5 z3G7kFEu^WSa0g@$gwkC0>=Q=a-5eYol`AS6ez9$*PZjp*kP@kNiF@^muVZ_I3V&%X z>_|s0L&o;%a_bxfK5@lp{wSn2~m@=_dbg zm>LPd!1|1EwE@h5WRmctIpY4NGl=g<_!De~p`oEUBTL-Nmr5!d7?{)y?Z2)@=mB3V zD=9PGS{^UGDObFuW6{fHPFqk=utzY#@8-^Jx|oeuf_z*YB9S?idbqR1V8a%+tEz~q zb=6~G39v2LnhsR66=hqslFA98+ftN<)LBeh>t>qr*Kg_K)4IywTeo z@5?NIB&Aa1%e-hz+gsW)kDYARmZsa7L8z-+Ig-g=iTjyIk`pp$?N#1Se;_MRsRS?R z<|7IjHc&jlbridUq*pStvYwMuUxC-63yaVs(?7i!(EV(6QuIB#Mx>zGLuBcnKR19e zNm#kuFOPlVzxn*^?=2al7t)fFLUCz_m8Ayi{NBAc)P;B5n}ne7va8(<5f{Q+cLu{3 zxmrTf4wWI3Lt|n((e=z}hD{J8BCLI~)}=??bdLMRyWRg~vjNhpx*%7Oc+AN;p$A^UNMx$KlIXD8TKvW_=&2t0e?DELCT-hh}AE zWmV1=@`Sc|Vq$`;L~i@`?T+*rSnk=`*<^B-(D0^eTR-Gjy}ec+RgNv*m2!p7I^Xkt z1F(NBE}N3R^{D2VlMSH>Aru+ks6E*;;tXL7Tjqm;d6I$ z!x?-PA8&}#z)gW4%oy~oopW9Dj4nc`WKhJqG*8}Ao{Xr2&E214%mL!!$$MS>g7!#+ z(cb}yr+@PbZXj+&F-~!alSsJ)lZytE1Anhg`ye1F2rrgP?7$|SOBxz~;9ieP=nODh zMWu_0ii%1|5O;%8Q_s~d*Z8cwKWORW{aqE;B=#7A85mKQJuS1hwApuMk(=k(~7h>P*<3JD&(SiiRY!pQvmKR*Vqg zxU*odAdnlbE_XXN{jJaH71z!Rc)Q4QB;iu%(mh_i=DF;|;hM$|=TueA>UHJ373o2i ze=zIf0tL)?3-ZR8ZcjwRtj{Gjs#^T^3Vref8RI|1Z4kVjB=L4e^|x`oS39%?+B(F& z)9L#xJrC(%V*f|T5dzaL)qOzO#>hy%aG_NC_@?5I>iHgjY%MH)LVGN{HpXolYiSId zAI2e-Ta`FofAq?m zh>nRs&oi_nUm5~k!nK{jbsp`|3LXS^)xy+jI+*RZ2sX)F;Oo)*C=% zB2P#hX;2{}#$fP%X=w@ZRGG(w^ZgaNc1ZL2azyi~IXMaBR6P@uq!%wNXvSyVHT|aY z9mAul`_NGDYl+gN{D?W}g{wkU*}H9gx6S5fQ>pjw-X);r17fNPL(dD7v>>xs-$iJM zuwiK|9e#Y={x`f@%;j1hTK{9aE)l_4aV_Kg+}Vjuj#2Nq#M_f2&4%uhfDigg9HU%Z zDX1(juST4Di_ z3y35CM93lqJcddat3AD)!VS#&`jbe0wiz`kiHqWAjLZxbBXow3JNI#LFn(k~ZHeGr z_z}!RDdUpT&47S9%eS~1zTUbbjL=LFhho=B* zBq1)|OVdb-6C;+HiH(gn{insba~}y|gK=dC#4g+KqS|Cm+6~QrrGXDD*_4V91A9nP zaDK?W(psXvNln}LpRMI?utiWoltmB;?Y{@B;d3?*F5M_9-o@OOlcTl4Z4Pz#z=(3( zNU5?RKCtn^smmADty{^F%yvWS;=4ktw)cr^5C}((PoKSKS5)vy!OsKV7by0ZR za$S6A;9~=Oljk5`57bYwpizM!0^U*AtUYZqFYN}6I%_~PAuw&wpvQ%W>ui#^3OCd#E@MU#mQZmOQ_KH)q>F=tnD>$> z#qSA{A^A>&D%t^U9mPJem3;^g5Yq41s1B@MEUOs4qe_%U7Z!J}a`qS9dG_cBB z7hBz>m?`k$e<=%4e*G9N+qdcr;wK#BWM>;PW05hRj6Xt8KcTgiR zm~3y7Ra#Pl#HCF>8ueB-(O~scyi7B=Fg36>2x{`9s5RYDMO{{s&Zzgsp7TO8T|8K{WG4#;*OppJh+wL z=svV{_Zoo!Y112bozyyx8P9nBjrG&NKaR%^mvT4TRUcx}eWhFQ4Hr>~{f-I^ZG@|i z0LI|?*?NV3)Q8E1`TFGiW!<;#WHn~**yH-Z5z*sJVfCSVjd$pN`TW^cvXjUj1LaoS z-~AT~Y)g-eD}e)ztTj4o$zEatOL#3zLvOIiUDHDC?CgwD7uJOCy_uZ|wm!GdrENC7 zw=fq?zjIwP7qjfUD+0cFlP;>oC2w0}IEd@&M*jN;eayM^Q1dVp07*9;%kBr>SP{_C z-)2aA^ED$cvK=m{RqGpEQaFO%7eZoHxR;F1;3@M93v}Mph~@wMl#ukS_G9@UGjGlZ z`7Fu)yD19xQuf^?$h=xG4v)YTg9w;RPW^%sag*#Mg6z24#`Cv*F*E=9!dF~tNdp}= z^6Ar_n;C0iW-%O8LRd5PX#NWIoAMl^Mvc)L;di|YjT-u!{6>IG*VUyX4k(;_q=(uB z1FPpi#l{dbNO*8nXsv#4vg6Twc>DI;&y-lr!uq;8WL~9za`%K+N=+`tx_V zYycrc|DC4-t6DgEaZc5%X;tL%K5hbKY533eK#N=hxGa5RW6J3)cgp90`3@a8P#Y-F zz@#h77vRGx>ASjHV|Mvg?OtK;iqO^7jVq2yO7}U>WVwm0>J{C*O54=W5vEXU_+oT% zym-(@?UIhpBF>s0lm3I!P`NXCv5;55SG9v(tQLQQb0TuTLl@o)qnE55(s(~!`;DX6 zye4}C?E7J|6F*+#=HFMj9k@Ybc2QVZn39$jPjBvv>5{Ye5#}Z6pXdoul075w63A>B zuT)=Qx*(3=keZqd>$6+sj8D7X&Zz6yo2ctQ9L;ohohq+>aNDMLWaJAIBDAm3m6=T5 z9O1*P55HyI1*<#QQ7P z6mx_yqMah=y`3?YVBcRN=KkF1bnz6vfZLMZ_+CVV1HCT-eHKl=N#5V|S9M?jSo zq6i6j6WXk{O(rxP%$ zJ~}b+I^h#ExzS(0RMJT#%fFZkA}f#^m3uSZ6vB%*#c~JJPUd5}=h8pdmvk>I|LL-W zYqo#CKdmEfC4nb@6BeQgs>I!pe!d)9r0`T173+h|ae>Iz*m(Lc-O$R%O^4iEVL+%B zf852{`=1Nq4ZDdNMdls8)*cZ6kE|~NtGV0T-U$(vp+uxa zhLX@kG?Uqv{ec$!H*ZW@Y zIp;a;{om`q)^E6f_kAxA_(5C&qk+J3*c@-k(h&xAjJn{}O(#X?e_S(DYo7^Mutj$Z z{zpxWirC%^Z$B&f%Yak!wJ&%2NljxoY0j~2-R8{|o5Kmw5T8Sa?!9l&q>;&-zzVGD z0@10w3J?#VEqaW~mJB=H-0OW9@d9nfH&Qq99s+cL4WGtLUk^el;ovNyMD2h?ck26} zD?m~s)wQoo4u`*Zp>J!u@8acia83#e3OcM`bZOaQO;*93JENR0bBkHl5@9-rF<|Ik zqSa?!gX9D+4v37&97GJYwK5Ops~EUPsACB1;y@~DyOz5fMCudILvQfen`&t(Kt23n zIcN-M#`ewzp5}#86mluY`|jlg-B|&GB$NhlQ2J6{4h{(EOIuJ{)!w{!uN?T4xw;%c zanaxBZcXyYG{<`H*!*RF;u0M;S{KSebvu4q-~!ZXY1?wcdCq|qG54Nd#Hv2dB~NXI z%2gC5IQ?=gzQcQsKCi@=>MWrsOCSr5ws&`5>8jw?3FLk|Px=f2XVf8JRMQ1^DnTy> zEU~Pt%;H!yl%r@H?badpu@FmQVGa*n1AbOz3I?g0}5e0#XmDQbiA9V@LBFTAW zr^vd7W-Qui1ojp{=Qq)z7%P0PFSCfbB28MvQH<{Z z=H)@9#$CmM#uD)coPaP!-bKh%_7LAkYXMLJ!u7GXmb^Z-qRr-LP(i#z%%?Ji>R{a6 z@NjS@cB89PQr9So&K``jx?hoH2bH|ep0^0I+}Jdm5(6XK=QcHzh4<->+>@j7iNlhzXP*s%`5GHbSXVDmvkIo<;z4h>6H(en&vKnZqxC~BK`cSB+u3Kt9J*X_uA4Ntm>eiZx~ykE^xA6N5T#O7(is zwg9V}$FM-p0I3L~2jikefbqI7bDWTqo0^=gW{=TC*a3_EG#(vx1*p}q0x-$-y0x$> z*olOO7VW~mZXG;7mX9|1U)imfF|=?tZkX8+9x1|&}eZ%{OqKpsyb?@ z}&A7iaZ*38VEP8ubJ1D!pl1vML}M9Jw%UH~g&41}*!C`ZY`|BO~7 zHuY2r&CJFovDxz70XTN#p$ZpWLUo0)2jo=~kFaz3=0*Gkcb^2iC_SB|G}uHQEiwj$ zz}CrW4$xK)#r!CKKgu3iRpok|11gnTL#LC)*-4)NdVKL%Z{3}U-Zb}Vr*l({MMXtB z!0?O+JqxB0-sE7;NZz;)*r+JdZfh5um|`v~(is4XfZTvKO;=Cv%uT^H8#XjWD)G>~ zeQ(^j@deOgM5y=B&}9T-+9JxWfY*cL6y6@}43sY6(UL&jQ3mvW{)qjaZ3gJ{g1wjJ z4}>6q%q5$(G&CY2BQ>?OcJ6z6Oa8pUiRN6_hRVuB{4FMp4*eH#iVSmS(JnYpL^}aA zK<5^|D=IWBtN?5Z#7GB>o84l@JlH7D0k~v>RiIXmgIcghjcF`A`NGFVZq|H9F~=~? zJH=+qcCdckwzYqvhL{C!Nd<4>=Dx|Y@yUx9ibZpT4+NSx&07vI!;g&P`H+cdI{Z>91Le3}$+)W**PcU%;Q#bEqSyJy zXO{Y@w5jty8igJe`)@t~fmc$}-jd_ikM|@z$Irka&%qKv(id>hDixdT(HYs5uo>y? z??0oeOojc8tJ&(`Z($p?DG-lr38}_WSo6^|?jT@Wjm*wsD{XrYLw<|Z;w z)D()zQWxgu^Fb~VQP+X@1YQaB#IG1Td|UQgEa}-ifnl!Sq*WbVQ|kl-7^u6SKYjWX ztTZtGy7!vvT)mnZAAb?rG;T^Dl_q*BHqUPnC5!qUA58lM;Q&A=(fB=BOpNC_e=~>+ zIzT?CpX*Z1emoH{Goipo-#1hOL!kz`l=}M~v!j|Qj_QqIO498XdKQJBezM^b>JbwZ z&%jP6ARW84)=$tY048su+1DRJ4Ep7z%*zPAUwwTWL1j=~l?%|W_PIGBJc+35##q?eT@ntg zthZELT(Y90d!Rb#rrgp8fT$!hdtCKg!Ha6-OjN4d@=%K6NaAtOMp1obw<1gbvC9x=Tp8MC`I_*%l~$nwmCbdoodyNwA~?h69tpLMOK|#)%xP zty_D%ilIaM+Smw(j61Ae;(&j=BO`ZE9a&@J5K98*Z9@MMErCaZ0~J?qRgYAfo11IF zyr>6x4FHw}GxQ>;l@z$(B(t9NDzU>bH64SiktFYS5JgRv1V@DOqa=b|m3fRVlC<^3 ziyX}p^Z3QE-m-IYx_{@+8zbd&s4hWrz{IJCvaG#6UKgj|ur=fWrB;@FIt>FU!oG-E zE~pVV1Z_w3v!wJH80_AQ2$jOQ1EjB@%ANn>_(GofsURod$HFvFKqtr7sGzoEVI3;Nc$QvdMAsaedh;^O0f_BSrCeFZu`K*y6! z>O5ncB`j-qB1xDpBYPTV80y+h9L*TDx{mhpdp7K^dvK2DW5VZzfZ3oIa-6-MM)UFF)1w#4{mqwsQJ$s`* zB5l8)pL3;oUxownJ7lmLEcaTn+{mC~sBEg#-jKY8ax{j`P42;Fm`cdeyx$tI#UKk+ zsZDcBIuy6G+8~LxN&CIyLo(4+yDuz|^V1=X31&j9#3(IQo(~s)GJQqoXE?pGB9nZ^EN|`gE-5#T+H{9{CASj}LZrom5@@46+nd6BaSc z5%M-kxrkDa90Fq=-~BM+D<*{|kawWE2W0`<127~??IT69yrgo{H>)i#D_b#-*nRI9 zIh)8c1(W43aoP}q2fwD@VO2YX{vIV+6?>X0Vh5TI^O$s`mkWl5!waWNbj(dJ=gPk9 zIFQOYI5}$!l(jL?1RrNWHy!)`f{h@WHzfK{E)rCFuwRf#BBBp$+p!~(1RUu(QR z9DU`56)CXXqRSHAlh=B+%TsBOhYJdfbWq~3l;|BN*%A?7LG^FKmcw7gdYoZx#Zg8u zL@?-6NLw&cI zn~?)fF<;x-UPkanLDq&ajCP>vnxA=fECa=SHHp+F#>QIO+O{>wo-;7r&S=w9Y5ykf zT4^e%g_0Fx>Z#!};mpf$E5k`Pv0_A@^itAMfD^Vw!9w?@%lQ@7%XrL?T3bg*%K*a1 z?QMN)yK)yZqje`9ER&DEPB(z>myT&~gmkFU#e;_rHy0EbqXFk@x=mx1r&8f{S}?}l zTMyF(0KzoO5%O@H9=I#r~o~>z4@rB`4_i4YZw9q)r5ReoZZ+svhuc z?9YKTLQkuGe=J_2CRkn8LP4xiJi5Z*r+OKyvAYgoe@LQOc-$A zuPz`WVh^Ga9zPEfOK!$+hwiF&!~)SJM?z#gTcHHCj!|wG(bUyvp~z;F!ykG5yax-;_mavC^FT?A>NZ3 z>-Muje&xlwx+byDnk8e$=EM**8)K5>ogTQ2^=rQssC==TbaO_^Cr&@v9kfuLn4>Fb zg#WDZ>)gbp|2935|CG4%7pIYH18myobDHit0sTV_(XN;>rrYlP`-aOmQ^6vn3etJY zUL0u6wK6a`@}8N0*mXHOaE;>Me@?s3(~xLDALplv!Fr(|G2WoE3Ovj2w~AsioPN`u zhp>7nH_jq22~Ez_wQ9m3M3Qv>U=SG%mU3LGRYM~I)m;v_^_aBGd=n2Qy>(o*?R3=l zqvD^yhdrO`lJ4|d2fmnl;w}d%7+HPBcnT$~gRB%BOW48h&u6yrj~d{Qf_q6DUhcfV zZRMT$#0}t*WKn&rN@#@wRuCe^CZfJP&~b~7o)jqJ3Ds3P00A2r17)=Fl4i)#ES$Io z93ad?=2ffbeX;+VHjbcA%P}qIn!7j+Edb~;gSq3I$0I6ya2BT#^s&2bV6)vCnVFP7 zZxHJpzYcYS=11A6m zm$C>B%}>-`R@G)(0ZySdVOhTX6{9zoq(fAvhH>a=z+!2Cr%fd;HSdMr(36X-7%XI( zSM#B8!I8Oh`IBk2z^+~X(#)Ju$K2d$ic z7_hLg#QrWzQ!YoBjeTJu;DTo((n+79m+YzV7Xb?*J0ruq;m%#tdw@Gosf#WVyHF?w z!AS&h!t7uU%|V3&2Jpj(4nhTkM&J_XA@4i4ZXv83rXJBuTG|NU1b$|cyq7Sb>cyr2 zKZ?6*X)|m1QWh=(-AXQ1Vcm4#dtV=V_UqtU0weeR@6*AzgRR}2h}Y+$uvT3X0=HP>Q@jo92_D{sgLFq)vNJ%&>r(z1ii zw^6)fBt9V57(O3@hb3#n6;u_VMr8eMW8SBmY*+}xesk2h3z(oTQU|8i<}vEX6jorb zARyLU6Tnp{pT&*D82YYZkSNL#4h*+#C>;8H+klH8?XukjA$2F;u6uIleXfB&+NP4|A?vwOESN+r=Hqt8Sw0@k^^Qz&U%WT`>xar{xHhAf;63Dned z0tzP4efzG?PKj|-&efu6^S60by4epCo^KfOaaWzibk9`C9jBML4;hKk0l~oP+nl+V zi2R`N#=HZ3F8dkaMq_+@PL$8||3Q@j9s-`&Oql8r=Sv(3U<5%uA_X;7 zl+by1rhhjICd6RSRjUQVy~WS50RTIlp{Y?DY&Z+%EUS_Lenh3x-B7BV}Mv(5u)X@P`5D5al88@#=lMSXo)|Ts8MPO52_g zf24iN4`7N5iw*<^Iw+v+-TAugUJ=mAZv@9*Z3pati2w+Nz|*`pPZ12ezYIjn9_cq| z!?vPX>R4DrM@E{#1CKlEkK*$K(3>7Qf4&X-i@tC90>tF_CS&;B5~imKiXc7e+z3|bSvvv(D-r?0<_>_zQ{Jfl~VeRX)5DNlSl!Am;>w`Ef+=JAQun z7KPKNF?a-n4~n;wMRSu~2=f3Gz%X~9IE0`qLpZdEIS7Q&Bpyzc_gKAdpnJQ^BLgR6 zor;QBhq#QXiHYwrR&~)xQE~4{m&uzovTjM}>bT6FnRhN2Hd|i0^aAptVQBwIoqI!h zEwK7_FiFFsePI9u-r+@rJ_m|`9ZEr*9Aw^E)Q1jdy8Qa^|8XSbF;>8M;QFCWl-iTd zfRWA9`5t|7BbgyrNkx3zvm zjGaQkfg_7{4+NHgW0D$rq*yCAey6#A$BrYiKvY1kw|jqX5%h;GSMMyUT80SBrP2xu z;zl$rfCKDLHV~7eL#NEVX$FK-3<_`bcH+5NTPrFh6~ZcOqGiIeY}tj}JpuxLiL>~M zra`oMxI^FtTT|K7zn{1Ah9W8mc!-KoyacL4-tDB^oA?!M1HJk&Rc>`HtpgyyCBC2P zMM6b!aSrzjg)ll0`(oIX!)ML0o~irU<&4v>q93D6!jfH3%8$9=sW8R|#g`*!L7ooD z8GBr=v%#%_7|G0+FFp#w*?QLl)p$S4{&_zL82#?F2+50R+7Oj6xk!0Gh?C^#N>nZ3dpgsIN91SCP#jO`HCCY@h$gTzxCvXay z#kYoTNA-YHxiG@O4O_8p<*?_*FmeJZ(mbXQGvK(yL>Y|b`c*RIa3ch&QZCJ1NC9w~ zkndXM-5Fl|@fYUg!~l~ql)e5mJdRJ|q7lrvQR>m#5f&8{!N6yto_H|2)9Fpdy%KQZ zp&C-^qP#N5a|av|7`K7q<%R=B^d9(52xvgR1?#XLoj)zfM&SD%ne*hRx7aJm3e zLIYk?kTPs{73hfY<{CZT4d75D%Gp$$D=@E$a zlaBy~;TvmUDBw7E~a2z*S#UOBkaMN#znxng~ZDoe_#&LgXgjZJdA?z=sBZ-EJ*e)fSMC zO)p+7FO4xSuD5EE+|#$l+T`qhrjP=4g|T;=_gsD&YbKmozv3sUP`O=C8r^uzGJaXFGh zYzNj|xe8O3MU0FVG1(}WiRI_iXM}{1=g+sFc?Pd&r6Spzmjj3KPUB?h``U{I5l)zg1$xPh zS=dyv%s7%DFf6TcBbFq<323T1=2HY+-SCVJpFjHwCIE^M!q=MO@B3%HQ5*|IUBKaD zA4fk_`#hxJu;(21sjQuI2!|xHO7; zv)S!-79-)+%OY8A+2Ea(Tt|>nKY=ix+2x_~Z+8O>*Ve9$*Z} zBArSpC+84OCm*5bL3aG56hpAwfE}O+`gEMVh$3x( z5Ie5mUx5>elCP0R9#bvsOR{dl;Q0KLcP-E}qY)=tBLz5`TEO$?g!!U+&H*qJdTsu( zH5<6OG3O%{jolgfDmk{zhxhK=*PhjfbcUNuMk|9aF2ZCT>K%DgjY3q|*z$H5V|cdq zzp8C+e(uO7xpt?ZgoHCnx42t-l$%JMzD0=? zo0L=wfRKnRb0h}^n<&_xogR4h5NBCI?fj}hyc66G&=r@B1*^r74gGRS$?d>12JhCQ z6A{z>1z!*lBoL0W0T4(sMR`euG+Aj%dl@#S>SmVbgROP>nJ8ryGfF`P!VS24*F45v z>ndhMzY%JCWYuA>WrO+|y%&1=NTY>DjW{FXMI)CyQm^;ldJ<6;)&)u*e%}bfBsvXP zC}#A)EYSlB=1m(q^&q(zr)OeI|F)Oq*iGyY)>1MN>W=fsF++pRJ((g&@uHK3&#!;c z#C4eJSb_Wv8HucF__poa!O#v;UtQ8N+B--r zi4Uu&y2jP3lQ=LKC&Ee*Q-d=%k8Hf+;xc^b8Omo)r$g3Q+ zM8GZ;<``$Xd}EH;`oyRtWbE$`f3fK+Ge!0w4qObz2V}5DbzBzv6AhgApiXo~#uW_w z;+}wq<9kSUr@23Df#)8+0HT(EX~zrzMd$uTf8o!7JzysLxguzBm}{Zf4v8I852R$y zZ0hM8u(me+vRS7h4Nb|hbq8DJLRNvb1p zvUvHDhq^>XSvd*0Mq>`p*uANkb9kloAdqUD$B#Z)qy~DlkJn8EeCT3KS;ZXM=^)r=>rOYZ&XyJ zcws@7D62!@1GSf&DmNXBD1y{Qc)Oqi!q6de%7vf+D-BJIjA~w=SV7)uPEHOEc4Gi? z-9*d&YhDf!8KyF2o2BQN>~-%n#a`Fe4jla?CuA+OLow*tqesU$8T`&>WxPkHMZnAD z1YGtbJE{)pAK|%LO_R|3H*822W0MSB8uvayC%qJoqM(U^S^4@CuQZ$!INc5zj9n1f zyLSSptX5H|5$~#&oe3zm`o4}>u?;GojdYTKsy_Vb*Po$*=2#^g2hE>5&*=rBFY0f} zeu@aMPQaBIROUp*5RpYjoggBMsz)NXVq6Dd5^RWmAgDTMEs0zIj#grJ)}E*G}@>v3&EpP)u03GCB9r z-*FwYxxAa^6L@uYCioq?G7%bbN6I2>W5>Ic zdP{SYw5bPkY!|2-N7Ol7_#PB||+t9K+#S&u`)X*i?3 z=Hx@kuSW8N&Ta0_)c&Q?2K-~wCD(C~Zhfd`xW?e{%H~l*H2u`Q*M_$DpeQH!1w~d} z?L8|KWjG#{Bzh8jCtwcT{uUa2U6u0qM)^?{>N(ZCuLLWR~pL|t%_Adl_ znjVT5!whYKt?*@6{$Fcl%^yJ<&(@V%%C>n1jCH!&8En~xc-@9q$C%8_y1+s?@t&cK zqXFCZ;LB}&mbNX<7hbBmnjPYtHmEtd`&*`+(Tv91rIjA37Ec-vemj)$b{42tcT;Fq zXof&V!58Bn$rr=!zd!#@G4jQ^FsqoqY=;sveGZ=M{?^H^S+CPn<^dQC#mnE((agQj zhl4eVd=H1~+)c?Ab9yM(`|El@$KroWSngVfHh3<_qfD+RoR%GIUJLNXh$Euxl-XSGcq3 z*2zzDIA6XG=C@31i=SH@#p4&-p_68vJd!`y$uRSBex}Iv!#g^gbq|kID`GU==RH-? z_F`>RHL_sq<}dFSZhGocf-%VDwf%aeT(kcjZfHB(RlcthS&B@-_oC8L$HU{)KZww| zgrtM2EFwAsd_+sa67iguifzWWL^A@6h<{|LFfiVbMx&ude=jxX3G5)H{wo3=+hE1n z$nI;$!aN%fZ*C3A8k?cDRjrO;!4sePLJgO(jh{DgcOJY?e_)BH)khDMRrRi9R{~nv z3pM>qj8PEvPZs(R=EBLNK(;3A(S6$1=uk&HN;f<5HGSjxhi#`$ObtPA508EVCW&z& z9vaI1V2(jt@Awr|k+!yZ{43D(fA~&xl*VZ#zXl&0Xq{U=l9Z&$*T;&jAPqQEhm{(hYe z*?RJkbr!0q8O*_yFunO!U2Ti#t*3&i2lI*;2Znl;7|sU74@@ga>}MuPt_~~gX#H|6 zX6nf)DFJgCDt(7Ba~-7vAOB3J+hNp-G#GGrJ2CnPXo)IuKVTP-1V1!<5slz!T3fAS-V^1HkYiDUE3~Y9Z=rEu31P8mZrKS=Jy+X(dn2e zzmxH(@4=FWr7|){GiXl|9M^s{d3!CSY(jv zrp6}bkJ$dSZIf-EzqbtcW0OK5%X8iXvr&tf@_)xesuwZ2O$O+V#lQ?1RG`54>+5ib z*bH1op$W3YI2oHr`@v7s`k)Tl)2ChaALH`}(<^4KDz>;d^1rjz<9T<&ZmH9rqA^8e z=2w=NVPwcvCy$VO=gu9gzFzswb^be?-RfVLOgr{D^tVRaCnokvSbrZ@Kh(n{Gi}jT zpFsbS0k8)ba6FfC6&DmF;ub?;a{KHrU)TlVj*VeNb^z#joIfM5lAPFzZk1$Tuot)lANACiB3kncS5YSq5dnsPw)Utu9Y^ z@mo4-{^Ly^cd&Ry8$`0hc;-)w&(tOxojftO3%(=yo9p`jOyWXkNDBWPbTtJXJa@d+ zwRylN^I@*b8JcL%BPHo*&BPZ^pEdwy&fHX}PKV_Sy3&)dgDoUYMK3lf-rMWwdf1)h zIarr^$DSZ2kTH zJMYyYb>)Y=g^nc~$s}zh;weRIq+LR^&IxBue<6KW<8v@^M4e5ON8ce#{GTq}J-HmKYCw_A%HOTVmaxgWQEf9E+w>PHw5^et!ON%F5rUh;kxweL1t~8Jt zY>2OkHskDhK9e*;dzM=#6TV^N##GixTzM9dos~7vlzLMp)3QzgHI?|si#kD%9;Kok z$H!k%8(!OR>((v!l8h}oL#46+imsW#~CegSU;(UQ}8+XI%{=;bu?|{%b=9YxUrHO|69|WZrA**pdL+46+yklj#(Tp zrT!|MKb2I4*w?Oo^X;bK&OLiTd-FkUdHeP$be~N+{eU5xm^Z}Af}WS@HaQGP-qBRm zp#Foi{=_*KmN}XE$p_#1p@%rNg)A&*O)Of%i1nk<#qFB5e|z* zjL+2gU>@}CwBCp4(KM(QQ{o}J65{q~Ox(7bW$Vj!b$(n?QaSJ5VR=b`Q-B{##y~pm z=c!j~a~;gZbu%eLkYS;ZJ9Kq;Td=f4_rvHO&!?$y@z4-!I#t5FMO%8KxOK73!7rGQ z-+Xz}F4e%J5`+HI>Y$F&+qheWEzjxqH|h&1lkyj%x@$dfv(bLrBHw4_HC>A{GP9G< zx+SWg@MdrDY|S~R50xxQN96fsfu$f`pHRJsdummoz``ngr2++V za&REbqNnmtDglz2nV9_9aW!D1m_}AR2KTHYwi`XjLQkQqqa$uXzd@QrgG|2ZRZAyt z2qg61hBqfGrb9c)IE_NY+;*MIFkl3rf?2}J8rn%SL|T)Vn?%*KGN$fr{4muzQ$F94 zW``)r_2xqGc_!}8h2Vp$1ZUt^IcJQE*KhK86jPCsg43%&B60)nNx-+(Neb&X zR#tu({LNElI8a^VtX?1vn>xRmEh>CmSs+Y~pBFiPZwGM8u{g~VOe1#i6$p5zOr94+ zu0Ak016X8EJ*AJHl*o2@I~_X5#N+YzRiskG`O1DikuUn({q-Mn=`6cJS%n)wbYdcg z-M@jA5Tra{;}m#Z4>`)vu}K?H8^3(%N4ELlB>crEZUCap!Ru_&#hxSgn&6A(K3uY6 z_n+b6EO;tPJcvv2>xkLJt{Elp%C8T+b>MHL5~ZLLWdOx|9Fn()Xbo-9I$^0`uCuiV zPwSal!^OmO^LM24X=lxYGN=i(zBNU?7YPQ%C;d_jErOTPPw-Zda$$N#Mh2*5AO(;< ze?NI)80p4W1j3OaFc47ub~0G!I`z~~Pz1qlbFS<0^AW$*>MIjY?|aeaGC4h6vqT*U z{sHPSVwA}w>)Y$bVo>Oa@zx3od#XvtUJV5E*9#A1)CEhT%D(6Dg105!b`!``N7 z)g82YHB5}KZZITv{X393a%M@91HTMl0*Bvoj_2Fn$M6iKplZTM4{6$gVjT6WLqT}6 z>>h?YeG+YMZy2ZBnY?;$;thHsRWCH~UyYywMkOm6AC0Q}S6)v7k?LK(td)Gwy0UJT z?jATD#FJcH(W*GSELJ&0S?|b~#k&*mOX`0!`Z9Xakl&XP+n)6V(oM(Z2L2HFYiO+F zj*50j%&>z~$svdC@4p7b-4#C|e)!)$q;f2HIf}Y@hNIYh0T<3@ddScT> z>l)CY`}q1|SoqH>%m0fSKWR)gV`Ek1J*9caYA$$oCCnrMS^%hPqSI5b7eE;^U0x>G za&vDK2YF>)g}`j>2o?fpU?I=LxV9?YN|R=}99fI|z_NHRhl~vGXRq*o%eC~eOAiE1V57>3p zY8&IA8jN)o3}@Y$5W4!`-vh1#@IKI!YcMX(1VFSHrX)jPiPP0KIt(;VV)88---Kn| zniiFj!pXuFE!!A=``SRuYqukJ1dS{$X>c?`V*lq)_4QkEod`K@yq5sGrz9s=XT`=} zij%R1)`me=4EGh^S;x@;T>s@ukFF5sZE}ydWQuAVpYw~$Q5jUb!QFnAO z~`u(qB3-)Qom2fSf`9gKkj%};BA=>8j(Y>(_cY&fnhz8x-K8x^K*ei>;~+R^r1 zad;B#B?C0|Rm# z0?d1aRMz5wP@8DaM*{rU!-mVp?a9)vW4oy*tg&BFN<{1m&G7c^mbFFt69~RC+_^j$ z?1k+jjZIAe%Is_IV(b=l?LygAv$*_343al#WuIahL@N)C zj4bMEz7gl6sW41GrP3b%@c9$RSG3#{mVDN>Qke8%9{S(@0jubZ(D@DJB_+7H1vgBD zG7c@h|AV|E=l zk6V`Nn=nLzv=+mbH(l7VuE67*!4(o>P%3r7H zWDoOdrGG=wjbv2Hc$ylu$C#d@%1}_9Kol{*v5rGC>Kb+)KuGw>lS%W!9-qLZ9g|gA z)jz~(JtzqGP%h{8@h6G8H zfAHzn*MK(sx6vSLYjYpxrWPVA`~(;#x@7tPA~3ckaP|e@``<(G1Gp&q1W}G4j9vjF z*08t!7u&6EP5viJqEHZ&8E*VRCBpOHEtK|s6n_8NB%H?%CNVmr&{d{ zn8U3kMR`BA6ilEqJ>1snIq&X~MGp$Xtv#R`&@AKs6>uTrfreb)&_L<~-SVHl+Xgor z^*dD#nTds+!KVVMu6ywx%`9rZ=uCIs82tyO{9ycPZTqwwCuOXDHl`COc+e4A}SJiVq zCw=Li>6e=;vQpcuX{_^i>H^@wIX^x>*9H)M<`bI?!~{1gQ4Qg!5-4|I+e=uWq@Vzs zpRDu*n;r`ILZ2K3GgBBgLkgpNi57ejiGf^&2apLPO<1|eOm%N9nGEvsqKJP&hb<1D z7ff<(4UCPq1;>M)23AD>*V5&%0R?ZR0VCDAgmd3u@Aae$y?ciMYgn}AU;tV+ zY4t+*#~OaKhib^V2%2-o5O8G+O>(q|__f7u($=i3uHFZ>Yw(lz8gYjuE`I%sNa+SW zgb^l&PRDTKXJ==FMJ@6Z?9rP-eq2%hLHI_w2==$rr=}KEnvy*}U2ihHGq8S5A|wp_ zZ%gfs6K{sOP(%mrN@^j5(W57fIW+6lf`xw{;@iHr+kEeId4!3hrp9Tlml(jU>^m1% zc^3q_N=#a{uE2gDYnMuQL`ugPKY?%fpv0@>g=15F}fh_WO zJpjmH!`E)FP3z&gZLtLBFj|Wgh3h#C zer>e&#W2TSWM~E3^5sDgH)aRWIZJ_Yk`wdRs$tJRU|I@EWS>8M`hgZul!K{WN834k zm)da++w{4sok?x8T|B{+vq=_Ds)AZCq~B=y){F~n_X}Qd^T7C}q-o+ds$0!xn(H+V zh%_la`$^;uYr*O?sOh(SIQef+KMAT~#%+)(lM~9i?2ex5S7~)0KX-{HMD{}SU;J8u z+~eBl(SZ114DuT+tE9kRSk$3ooiC#4xdMH?`yf3Xez(qad~aV@^T}>7$H1!1fv{&T z_=1u8S225qGUk%-$BK+J&D7d=10-} zB))g=higpi+hQ}spUs!|zxn89Yf`iOl}PSK%TpLgNz5XzVQEILLjTffJ+nACK0hZv zDL)A9{?5tvZDsuL3X$i3L}o4*pFgw)q>4}EBC-oRAoB%eRWZ0SI{%@82_140sbTF; zoljwYdCsHH+$j*h`5?(%9UbtZz^Htv)pd|e49g}>>}u4rG)>M)`HuEJke<3FqrC+e z(m+w2vb??%e6h?SICXRlUKIb>CR(z>MCsV2DNr*4{(HGu85tLZ$0^GED2BW@z{wm0 zICFtTL`bwixLK-QSZ7^VwWV5hvZFLY`>2`A^|}C1F6?XKwkFf_yXJ#W$sGv{)LgId z!Z`Q-pkhE~oP|at|MZKn{|897%SQk~+P#U`TvUYWBjo%rY1}0~VIIB9?zZ0rr9CB; z36pyD+Fxw% z?anM)lAMqfz+J#E`S<5waWRC(&jDk86wsnM^L~(tz6lqK={Fm7zpyxR@_Lhvc=;O1 znvHQ!KplA&Ox%NUGA3s{MRqAC3&feFm|g-(h}auuuU!LXS+i+E3c2uUT(D#acS-z| z@RWir-OED<4qVpVC4!{xcb=~r=9upd_9G$1+1u4{wDQ@hXzanh1Vr6D_pDd8c?FvAYFa@0_8CV zI-+%=8m3wXt43^H3gk3wP56X2?bn-}Wg5v&{x_*0}q zUj*=eVtJw zw>eZFFCUu#4@Z#+>8kikOmdFeb)7*yuU8@byya~FRO;EWC}?kYG~5I9VYvN@Ej(BZ zZIu3t$DrUE_9cqerGdzkI%-Yxwzl(&_0|$H_}!f2gm>8aNU8C}6*!gxGb+Q8(pupTkxGWt^0MVfdl(o4cP#U5 z{2iF{7y?9h07|5|Mu7}IZ>DlRzeZ!nGYB+5`$=*6@?;2N1F$Tgw9zy2U42!1xC4cM z^#06iIz0pmVupowgTQ>bSxi42&K(msT11^bgW%+WW($o|r%ZLA-ZH_oevPEyJlyxe z%$e}%pMpi@fn_$Ye^kXc!7H{LBOVhBvd>BP3gu%(J=G${0?KF55kq$sZY}+Raj;Ij^(IF415zjg-H1QJ6v%X|BHk`tO@%pg3A&23ZX%u zdF$!u=xqT16I3~xMmBOk8VhMiwsFlj_6K0!NPF|gaj``Ml3<&^>x$Qq)YB7mlT%wC zBkylgN;|2s=hSehs`b&ikB^p}cyeCdZ?|gw;S@V<9AtlbP zh~N@~b^uIKI(sL*wS$YB`!}dtHI~j`CISlsoG5;&`3fv@0}g4eVMOX{am0WBs%xty ze?UjpXfw}tgX?{j^PgQti_blMP}A-SAj1Pt7J6kO)ahiD=H(5=rKh;#w+WSFrj$_L z)^^XX#BPiH9oB{@bF2^c+knCy@%{UEgxe_i1;SN+=1ZV{75MDPM_)lH1;>6P7uOur zPBZzSRy1Qaj)QmQ%9SA|h9^1F^c9t!shaVaLl2Mag=K}U?R?9z;J@WtNYnhAAHO|r z%nUq-ZM zMsrNO0dwCbrEJSQpRh0xsKOW({`=x=!N2T!Dl`m=cUTiS2kEpc&}rYyO#tV1FYK7w z_C4d{H2$Z|(74xl6@(m2E%PgZg%A=Rj7Sj2M==9^u34WCbpMq8CJYV>j+Pu}jnB@# z@x3rG-RiB@e>(=h+{M+kM$H~PPjGz9nFCRU-&=LewvKHy@UYgOPMKfd;x`;KE3L#} z8?3ec67G1B?-wP56dLlfyrAGl@WTOX4&Q(i_rHCtLq=&N6-Cf11MU- zU)AgaB0vllXedxA{7sG$Px0$x8hQW1UG$l7g8dIpalNXLipMX{lWe@U4_&}8M-*6- zgYr?Tk*rTO8xzBhNgJ%4SsH6Ci3?P}gnnPbebBC;tt}5x9QDN$y$N*j89j&@*akxf zCAL_#?>3Wo68tOa{do0Bo>SZH9`&cF!B=88KTx&9mkD8|2{V7E02Je8B;}j5{A|`z*OKNHWT|FjwtxX z%xt-{&EJDx@NvHm{Z(fgA14GO0=QHO<^ROQ1mMoodk%|;JPJkzB@)Yp4tNfAhX0^v z%A?(n&vaI0Ej%B{<*h_efkwuMG%~12VE2HNnc_UCk7+8++YoPH9fR6a*g+vscWM3@ zpEc%axMwyluHSrp`hMRt_f*}vPR({_J($Q&7}cQ<9_A=+Zl1v?U_N;8JUt{nU-=JT zWbqRBsh&ub{T&h5tU{SXKZ@pE-!!fSC*G}sTC8&gj2B33b_9h*MBvzK?e{;{cS(2) z8cFr0{Cq;fT|izUu=9Xy68uJ`bzw;cuXOi6k&3|Iri zxN*B}uU@{q_q6oH_v`Z^=hMjo7JmMWh8Gl@r|Adk)A%{xllDPhycUF;9;q!QItTiC zJ3Wkc>^Sr61NC&_HW@CHXUexl=TaL>w@* z=ieu;PmEBkVAeW$at^CcP;oPn<2w&%73RDxI#CKUg} zJ031&-E;*PFX018rbk_lUq12FuaLu%7f>yJ`9He51*rBRHt9QbL^KUypaS3-ST4iXgr-648=4v$aqBn0XfMz5mohR47U0Hi0Bo0v zE);*vU=<&iO|&`-zY-SJ2Si05N7TXP`ox5UIHef=Uc~hFtD>w_N=k}(m^$_xc=V{o zs6284&-R-rpuzs%qSFEKq7}E$Ifq+PaL@{pbd4yhGJ%W;GmPqHTz+-!8iSyRgRCnY zHZ+EEXIVBMp1`8~_tI%C?F9gthWITBOdkL{QOwoAn}N8~T<1E3pim=|=)3Tv__u9Cw5dwdfr&YGFpM!?!Yj;6P6{_` z(&@wC=sSc);K!9hVe&72brdW?VvtCUEhH>c$38hc&#G(SA)?bE{ON17NE~q_ru>25 z%PE$N$QEgV5m8f9P(+;}23zQ6K%b-B`ULD(EMx8BKUe;_?*U6Cu<#o&K8EbFT5T5i zH>M6ya45jVL3R^3#Sm}9C;Bv#e4PU)54!M?@m4#dOZbtO7Z`ct1 z@p{oBifkb9WP&}>Yy_j&^}M`!q(j0JCexE^?$FD@mnSk>5~%bF*J-?GzPL<$A7+bq z%@;rhzf!q~!cPWGUm6<5(N2h}2Lpvcp}c7o8%6dxR_JWI;xyvsJL8fyw0g>U_t84k zXa9Z0z4iO}h)0#>+SRMCjJ2mJw9#Y?!W&cT_&5+WCE?F~>n zMx7~445NgmK~$2clkOMMYYWR?ycIfK1zJ%G-{pxRgE3w7P1^xKn3S^9dJ_=O4iG$& zBFnJ<{3!<6gScsG#k$?0(JnK8Ym`vOM34=1`+3I{F4~4y2azZ;aC7kRw7s(-##uXM zf8m*Tn&Gve6B1QtgIxrKVK~f`g5!#|CYX$ySy%)G2A*JYs0PI__P5X)io@L;O%;mr z!VQ(gS|#Qqc=(XPVDTt?Tk|rAxaQBuh@h}=B%|aG5Q+~UevZw=9Mu`fPKoISBMWLV zxV!dXgghtw1lMwK zpoEO<=rEKFJ%+=B2`QdGl;We0WwdSH_tQc^6uz-;)MXUeqLsih$(W*!1CC|TiM+xY zHzWl;w=k)(Yfj5t9^EGJ#Jn~ynN!VA)Spl5Y{C5{t`eVp*ISv( zo!#xlUEO`B@j6%bK9D$W$rUDCP_s_1R=ZF)ks3NFBmC&gq2?g%b&Vg-O?ccdvLDZM z9;gk;WXnD@GM5VpFPf7kEOQm!iUpDe@E21-W*?xXSYRVCHVprp)HuEevnJ=gjADz?*+<6++c8&c&h=Oz%0N}@UJ$M^yayZ z|9hr3jNmW{ZH#(ycl|y?fS}gcl*~^-6VlXd0ND8Us7$qAZLFqJ^+s8WY`ZUcE@a|7 zT&6A_!y*ufP~43=&KjqWeGfuoFASFeT{JS!62XkCtE)I(_r7fjl&@Vse!QtFe}v9v z3?6IAu3c=La8=SF)145<)`6dRmLN;Z6i}>wg%xK+k3}+*v{(%{Nn~n5lzn zVep1R;W`F}zB|#+tlW>W(>S28RPs=@C?|Go-kn?^S*Yo6x+2{EHg=#d3(!vhj1 zL2jfRV*kuw4)|JEkPL)33*=e%)eZz@gnr`hj+Z5CB(KMiCJeScQh>FnCqyB{b_!Ri zkT>b)g{~0Y*btCUYaeNnyfNLyZjrsjOMX8-2Lq0z>KSbisF32wyL`O`4K<1d%v((a z|9%AbQ4+VqVT~VdBwsa%Q&Kxs)B8Lm1X_hM?4;0Qlrz_`rIDcL&RK6Do&fL2#^0%c*Ypdv_VC1fd-NT`bO*9Owg#^RSq2`HXBY?54PRtJ zDvvT?VclHFm3O(>e2w3}K{x#XucUM78cj+(RN{^x_-5eNXn%$9QvJmHmvxd6-FUKFl$&#@2CHxD| zlx29#f^5HaVNrUKx=}8c7Z+a;bf9B=2u@N3e!Sf&m(Z1z%o9PD5VXB?1DvUxAC!B0 zx2cYAUY@72@+$Jzd|xUn$rbn3YCGcb>M=tkzw>DrQz_-4F0qiCpX?-dQV_f~=@c79 zaDY4Z2u`;s;}@1H9|${CW!d=msT^5FEiLYlkS%<~wx#$8Gq>S`xWj-*09{R3x2-gS6zMzY zmvA?mC-i65J{1Qr;0~`R&pY0DZ9k=x>7^UIAK^qNgU2nnZ3XTVg3>cye68@ogCKPb z!?4lX=Mshypk_;A1&gJeu*#Dkcf2I-RDb_|(GOyzjUkcb7vsG&#A$E6i$C5AF?DBm z_XK>g-yUUx8eLy_fOiQciw(zC{LgJd!fGfyqsg5-39b1{&#QQ!NXLJK z`Qb~!#l;0jN_%0Hr2W5sJ;_~;;&O56#$6}w-ntcBmxqtrk62ZkRAA2RM! z1qBS0VK1pd+@%cXjbP93#N7zkadF@-t8l?_yps6_HF)aons2#)d+)IgO%jnYA3C+? zFA)@s1+aoEIWsa2*m6a0$~*|F7xTRD3d%#C{#{Ec!~LKz;374Y6Kcfb6PL7&IcwDG z04s%(C@DT%6lA&JUf@soJIupE?Oa@@uuxMZf{5YaKft~d{8A{-{qw>vO+?}w_7vwY z#uNLJC-xwGctk{^r?j&JCuQHbwiOB?Sp64@2hyREq|M+xA?j~DaQOmQ=QnRMnIvH| z8wF#vjmPnHn8(?+)vu29S6Ew_>^VP&Lwsfxh1aH0btU!+3l|8vAVyp=Gt+z{#{wUl zDQ(fo7ej5@4ObNOdgc*D2;XmeSOWN)rEfu|d`PY%#WZT_{Bt>hdqF>tS}~H!Ok_oq zd;ZAFS_*S6DkJ!jW}`tyHyv7i3}g%Z#(eRBeW=D1^q@02A*I}*-~+|%+tpZv95A*O zS_Mv7eAxt6^d@d@pVbtvnVsE_xMa@`A#Z3*KgFx`ZCkq?+})WQkJIa1FU(_Iv9DCG-Sh7yBO!0n`)qTVS{a$lE$32VuJottWmO z5KL61hVa^=h#s>Dd-LW8!oAN&e9(&XmYk0=#BnV<$Xl!AD3oDFY-<&uYuKJ|CdY4_ z0&oB607it5> zW}m=Ent_X#iq>FEG@=gT1S>PM3zF8n4kM*=%^FP;q8HQ4*vrd%L7M#(B(28B4wCBv zjwx&5uKT2}WfThkxs1ynVdaFiE5*ipQ=nem7V;KdEO67up|JkNv}9s1?!ndQ3%JUi zKaE1U>RX_$4RqgSW+E99%5Wg4obyu9iFy+c*nwzk{E2@OQNm<`5xN9CD{6bk~B4k`fOPl@G;k{7@|+j4`3{fy<>?lcvp(rM~!x zG=E`Fn2<9K=hKKePUodudWu|1-}IcI0*0vE@3~kxxEC$c*qmCJTF7g<{|lKxb6?f* zILFcI2k6Nzt-kSYl`lU9-6M3^=r;)d&hfq7xmHP|%h6H@XAM5W9cJ!}-kIwts`)vy zYLy0zh4Lmop6|_xwsS7h{&Y5S{6w*!b?XF7C_MOd%k#YB&W?TlMKgYZdkv2xPJ3b> zM4TbYjA?!B%(3-CjrNS(>Gkr~gX3RYipFS{HN!}&_|}d93M$o`Tv<@az#ZQNVP6`G zptz?`pJHbgRX>*U<2NH}DT7HRorANGyLi-u{<#fV5MOLcWc)&=O_G>@yj)hvF9jO1 zuU9c!ZJW-oy?GzN>9lpFpnUjd8^NiRbzh2#lSP8O(bx^T18!OLv(3K`g8oru<=cmB zRHi45J(jE@6pg&jtTwL_6SlKV6SM24Te^Om(Bi#K_2GgU77kAj+zq9{j~RW6xOm>y z3wLIRG~ZBD@S(hY<5Bl6+O_SiHTI8<%8)8J-$ot7)b&X-l+cUiUjmx1qg!Ph-BS}{R^fRe9*!uuc*)_dRi!S_xXKCW zk5yn(w`B1%vo#@KCnwnH<+y6p0)o1ck%sv2AZQw6d7X{zohvIXtv3DyI0}ijNpRZe z#BPa23OdS*ixL-ynif*G8%w+pJt&_1Txxl8w9T!4$f<~C;+R^M>GxF%X1;gSkD7#g zKTA?#iWNWQ>LwBz5FyO-@l&Rkga$o1$!ed#z7Eaj+xOlLtH8(ftz3`hC9G)1327IS zPvB*%u13U&-WVNOwtz(+_r+nxm0{dL;5iAm2pln+49 zHTUuA9uyZJ8I=5?fSAv?b!*Ul3pC=nGH$WRDXqB>a#`QIBloBqgTV$(ISTJjD{Fr3 zIw_uSXD(iQZ9HUGUHcKcpOch=*4x8*&vf@R7F#^eyhdIeL_T>G;s-fd~7 zHdV>5)uoId9^TmgK(^c}ZGlY#N@aF=t>d?R2OxOMIY?+q)IucyLMs+bLi@d)R9(H< ztn#eie+A!b#B2ty5A{J~c*XLGlP7y22+R*}jD+a@Dmm+wAfmW(JqQl7^$!)vN6#j6jj=w028Ly#!mN zEDaMKNOl1=OGiU7P_yWH^JXcGdF~y-1{lw{*>#$<4CaG~TAuv64=~zwW1jX;QtLdYLg)H2U$QncLYryN%b5{33X0e4tinXxs|=vB`k3dxAf8oeu-Ap@ z1HJOP%bViqg!J8Zn-$M;?=_?gt)Gv&eCEs^Lqfk>G{h>gwszz2Psxj;Te%|i63HIF zzKP2fW9=WyASj@*kpvT&>7fu`8`KwU@1CvKDR#T!zV(oiD=t&Hox;X}=h;e*Gpl$q z9$(S4nf#hFTPrvHUSo#s#iJgV@0>34WJppT9N4`b!OML7$=2fz$EQub*I$q%zLOBVkl|w2_PDvVYR;8yv|m10(5H;g+QIy6AwqSYGzEnz*S}Ac0Aij;Y^gsO zD_Gy#mS#|!c(Ew{o9R_o0mBDwegT=~k(Yk9r)lsvBn+nQbxLjnw@mQB0m4PTrz&L# zrWl)OXbAbEjQ0@VaKO-b5#64gDJOcG#}{4Exwzfh!Ni31MFOWSFW=x$$SJ5L;^9HY zc9QYBTKB~Q6Phy04O_M_e7cVXwR<)Q<5qvak=tl(%VRs{n%);H3#|fPIqNFcmIc_+ zi6y487)w(*Sei|tc&WIJ!rkZJK$0W)Nprx@^~BKah&bbLUc=AncgA*Bc|ykI;bC8}5kMvlcQ}6RJgC%lVZ3i&>siQ# zRwCN2jBuo7lst}&iGhc@R^zc{KgL4^GGWe`dB4y}Rz(2nugylY%zER+FG~y)PC-Y}R^^JPAJ5Ru1%ZsM_uVL{ z*uZ|6_TTu$Om^_6zg_*UV9Bx7NA_G~)Ojx6I4 zVU4Qu>*vn~xUR-#D;w>~hG|{5P?}vgZq|eO%_&O-&*ryP4 z_Z!dgaz>XMEWUpq&a>>?t@2a>E8+j-oyMgkE9O}7^U~qFiz_#7Z^x(@8%I7Z?EnF2 zm_$dxAL@B`u3#O8%=p-9nwrJv5uxLeTK`=Eq+w*7kg%}Bt?>511jgUt?D_MT@W?UV zq31UM-S9@VL6$QG&$;qLdr@+hb!c0Kd4m(s-PPGhy*zThY{27M7MbDI?s9lD7+dq( zP*yYlO{sDymOeRIJzWqs{3o3_eMUA(zqBt;cjwpbh7*k&09NZ2!*{p!&4&*^5K2s< zMeUc4=Lt-N9$Kc`f9gKJZY)$m9WB0=*Vf(*bfzq9T$LE~H(ynGqE2f@18b0ZQX@{% zZZ1AsqxmGS(PsI=>)(nue|qlLCGp~capqDMJ$u66(7gZ+E>-sdVX4bcIr_a3} z@=h-nMp$Pgw{b_8m4}l(1;ZC(cg<|((|e+&o`~SDzNQhJ)Yq>7TYN?TAZtDXcxJd3 zz%wx(A2dI_=$&%QWUUJa@}c^RMM*yHS>cL{#Ux z!r6G#KU4jyXa@hiO;bB$cu(`S+SdFS&g{-JmkuxGj4t!ZR?RWNF~qu{&#ntR<+D;Qr4zWwEzQQqT$i4e}c(l>QA)SbR$Pxy-I<@;lu-l>NP+C>!X);2gRsA=ta!_pe_rlavS6jAceJp$7S8>eh ze+#pZOY8Ml?7F0^R^CQ0aT3i06d_XeQgskfF;`MI;$fVhpHDd&Eo`A@B%UG!yFMYI z#EgRi0_q)$5cjk+PP6XL%UozYPKsNju$$v=uA*S){O4UO`Oe4!V=`;}wrwQKdc`}T z(;n@CIPY2t**$;$w*M}1+YTW%iqk7gz)J4ovPTD&(Ne?dJ9UNcY+W_b^o?<%RXfyVlc11{6)Y|I6p3g7YYNYcSFn z!{o`rLO;{^;Ln6wx(5ZH=eMr=Z&k{F9boht%m3B^|2|v%X_MLi{00B@mp{14RMAtc zc#jkSFoQwQe}0u}x25-+@aNw{hkAbo1A34H_Of+rf;YYApI&YM-_~g@#qNIs8ydlt ze-j$T)@}bk{<2z0WdOm)JVcRj%v_eK0`1mldks)a3WcM;zd?p4i!=kj!98A~p@COO z=g)TYVtPb!b$x2|{4sWbA>N5bVKI&6!h@hQIvvVPLHF-|6Q?!{f1N4NaPlso@OP*Y z{J(m!wEskkKs}s=!T?PbptKA1QNa-rmHMfYOwQv5nxMs5p3P}q3O>1`umBf4Xz_9Y zKR(GQw@lTXNEBIeo1x^Qg96YHaNj{E3q!4X|30A*^Wlj$Azf&axmT8lFM&GIoiz8N z7R5#l1^}H;9P;{Yp3n>RFJi>nW^N|J`K*Llbv@b}v)u4_Dd-yEEso=!C>6xKiocJAw4YUDX$ zbj9xsCkWVAybHJLLd1uQ#*@Ro+knIjqlYXg7-Cuc0ZhxhYdhp<(V4%`Fmi^ZP#KE? zDfMz$1WTb2nwo8W3cWq&|Vm^lI?~DG_WOpmNJ?Im(9Tnjdrse(FBXmufBfSL)I!Vn3M+!Tqd0|xg2Z^qI_eYG zQ_gcZQ*LfIMN{t6^XKx;|3MJA#4m|bu}YEVX=Vf74X!lYHL)-1^0IPRHZ0TPDfz+-T05f9 zBR}KP<=^>$uzS%rdY(9gnMTFt1*I&5=*9SKtcf{NJMt_ismJs85|$tISs67tsSfOq zY64n^g0@TH#$XDd8X?dLZkm+rE@-Mf-KMEFj2_=7eTd7qB1&~DK)4B_$0=Jyz z;I;kxQBhxQPBfG7xj+?muBAGbA9g8P5+Me?Yf`lyC>^+o>eqQ17Y6$1_Z%t{Bg)*4 zhe}di8yw6XGWncX`_hAkE%GE^ykme&jS)tNakXHrp;K5A)&-B}Zpfkj3-&lTZnvnG z<|9%CmNpohRDa{6mJfQQ&v2nFSv7oMM3d6}xn+*tSLP?@^5SD&1W6AKJxWPoL$3sJ zM{unP@hJrb3Pwge1=Mc+YQ^mNJ3^R4wYtzo99c=`teKCC@vo;BHE|{48;P3@;f>-W z_wRxrqNn58O3SLU<0d7&@@h-I{GC`zSpGT3tBnoWk5K4kH2GTxZb&|X+h3+Aqq{ZW z5wvv|E(gd4;q7kJrHqG=IsAu(@aPM`V#})E^uhU{N`DK79-p;O%9*nGGbtiiX^407v7&rA=L4c)dM|h zc+HAsdT(zl+{UHqXi>vO8^PsOmecbg^dxoRAnx!=ELU4_5|y3(|7db)v1>Kt+{iS|pZ`rI%?OPF5xm zsdBH&|2N=(jh4i_CDH1jm5mB*Q|3v>bik}0XW+)0Fppn3WRm9@(6l7%qSU#kA80fhIm{9Kv)~*^+24NlH?(10`@7Yg{9-$ zhqrAkl&pP`VlOKrV>uD#t|j;8-^Zb`vk!z6-Xkc0{T3Kh(dnQlB`D_eA*u8#xAa5) zc`_j0U{o^FP0VHp0OdWrdAy>dcQQT_J$bp8T~4r&vn=PF)`^Jjt0bGh?B ztl8&7P517}2odn39*7J{SKk;l#q;ph6Z~{=>+*7Qha9>N$6A0b2-M{XCcv?=%w+SV z|2j;mM$|Qj0<7L8HK?UZBv<7Yi@wJ?%ED7m>Okef&YB8+VP@TMm&nsy1|~-Ksd_q- z(i&npLoY>$ihhVZ#IZMDN0ooC_tV->VizPe`58wn%z`|!{YBX&>AM{miutacG>XZm z!^kE9!a&RoAtUw>pZoGnmyk6`R>dU70eqaY*d?d@wfT8@_Aq%RH}1j2Em?Brc>f+f zaB9m-+Dx({2)(sGr6W_E)abYvQH^mT~w`RMzhar-R5fVlnb0 zH7-WR-}sT5@3XVo1hBZWCF{s7$8cc}k zjx^?)$B&aSg7ua^^1y@;r8--Aub+be&B#+>{DsCd(3}OqTNZ+GIZ5kjSertQM+q@~Bec3hyRk z&iti6$&dHIB>^f7&sZ54l;6goTDfxhvO0G3?X*Xq7+GKqA5>_?lhrqSDjzjiT3Cd? zwo}~xr%-!7`_=bxdQVAAZ|kKOcX}r2P(rNVv_tE$`p#OGg|~r%`%nivV66r?altt+ zKVnzrzr$1q$h14#3Ev6zYw&?TnW~cv@-Z-8y~`Cdzf0m7RLUYq@%{UrF0R`&*9ro= z3rGki-$2X4DcXPk78TY(U7Vfy&5B>)NRg|#=B`uuGOF9_I~`x1 zJDGY*p()4Ckw_D+j<&MIpqn=p0ilzHVUPIB{FS42VPq~pV2*!EILB}9W`yQ)iue)Coh+~89%-b%tKfQ9X>Aa}Kh<`4=9M++ zu9ZWIA7d=HIOD;|4FNGnEr?@_GxJVnNPj211>*KVoW31mze=DQ#Xo z)-!QK1`H6{%vS0Ib2G#~wpe+UQ3D3NsHHH4iVx2%e z>+EI_{Zn@&?28Q0Gi{1361hLwf5atXQ$)QfloGz^sML7CmS%L=@wyu(RRDm zP2NONefjseYS%`>20ESBpHz^tLbZPc1sK@ikKR9$xw~$2%y(YSQ$mFr(-t3&Zv&-_b3-@@C+m{1IVi1?kZ?9^AFnjgO=+pp$Xo(F+V%oBI{Bqgi)~AQXp)UeYzA| zy;d$!=R?wuiEJw_u?%hTOwF-RtCHu4VPs_FUU?v4$Hr9Nv@T@^NvWo~bXayvTJJbxAwK1?NZke16p9091Tklb|r4kD}Qu2dz z`ZT*K-9qFUP^akSFZkqLQFKfsqrWiha2ycB^4N4ZdNQ1KDad?aPbHD4!F<5wKz;$E4@YN_ttMJ z-fR{T8<7)wI(S+w+ zn22A(JAnz@^d1LAD+ayKtxD!=ii6Tk-?$x*(%H3AJb?Czaes(vb___bK+*QGrR-*$ zPq_;F6uIi8)B>~Y^qi->c2pBP^}^;~78U85BZ`TJ=vv6S#n#=@pD9un%yQQi0jJpr z9RZsBOQTIUKV>g{T(95B7+$-S^8LTPr6DoTh1cxdRYoHPQ+$h7T#OFr(|h6;EpK$A zjzmMDeFY?-i#wi(e&SH7_dQBFzR}mKEL{KJcckUs_%To`+$Di>MMW^=!r9&DEuI^u z`SCon?&|td@yIchF*Mq*N7^%Gua5dnjndmWqwS{xe0{aacIGcnX-PF)mze@b*m&2( zSE)-AG{LX;MyAxkNs&AQ|f!NL^zfg%UxD{Dd|7YpJPtdL(#wxIQgYzk86=I zlWNP2C}mdBV!BiN!5pg0?;i}SnPT%oad#`w@QK!gD2jb+L>`<7Xl+^Ds$U2&;o`S* zdmpSO@8Y&51`v;Lnk2{+CkG8ZPJEPp;=}q^MAsws2xu~$zu_&9XPzDhx@+&_ z;5gKCWB<@4#triA!dqqH7J$-}9ohEuvtP!@QKy|{_}4`mz0~df!j7nS!P7#==mA|F zy~Oy!cMiOP-B!-av!CcO$Qj;$ z$`?^*C#Vv-g=;>bM|o=ryGwp4<>Wl{=foP3+sA(C(7C$gW)oE@jWWv|h|N z+VD2>nis)6x=I6yj-)vU@tT7=hh+9^B84sN)V?{XGGm(&V%9mH*>>bEZ#MComU7RK zoP)2aAnxK%cssNhmb>c0np$>xdGOXiHWsL}-ig;&U4Xt7BqF|wG&o&w`WFLPt zx+vatJ-$%%b7%EVCU7nK+MxPeywEWdrAAFARotaVy^dYPFlJGh&PW1-wc1bk4- zluV2OOH0jRe_?XV8eC6Rjx{ldL$5tjvp-RjQ}E_hST|+ZwhbPAoGd4?+&s3L{(PYHHjC6 z8Du9m?68yD<`ipcxavY|9^Jlt>ORODvy*bF^{Qb!rQt|_Oj#K}eTKens9Q8S zIJf+y_sc-V=bDBi6T3=vw+EYCH#Z{Dw{3mrmt=M=nju_}%2u=p5gL=Y1kL^5vxbWI zCxw`4G`KSSgH9Jd;{YLphIs{;#jr}iV$ z*LsYMfL9sPuGX&x3j9hcH)ct0_k~#|PAYFIREts7;u5!0P*A`^9@oAQGy2C)+YBEM zr>O03RmeIXf4Ou>j1r`ALzf^t7S=?v_=ML`kf4-$nEK23cn>Z+h`1X#4qxuwi=u_m zuq1V7829YX$9(+GkMD=_tJ&LqPBt;IkFBeDcBt?*M?P)&B&DQeqg0i*p>Nkv!DUoE zEMm4h=C3!SMuq!3;Y6C=;uu)HD}to

x5k@SKso|B%l}#qU10D8$1yaH#Xd+i-oh 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 PEi?vCS3j3^P6p>wqU;^7+@|Wc# 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 Date: Mon, 15 Apr 2024 10:47:46 +0800 Subject: [PATCH 144/162] debug on urgent function --- docs/UserGuide.md | 12 ++++++++++++ src/main/java/seedu/duke/Parser.java | 16 ++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 178dee8b3c..5cf65a31e0 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -297,6 +297,18 @@ Expected Output: Timetable has been written to data/user.txt Repeated task added successfully! ``` +## Find urgent tasks which happen in a day within next few hours:`urgent` + +Format: `urgent /in HOURS` + +Example: `urgent /in 3` + +Expected output: +``` +Urgent tasks within the next 3 hours: +lec (Monday from 12:00 to 13:00) type: c +``` +s ## List name of commands: `help` Format: `help` diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 7505d9887f..4303729ade 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -175,14 +175,14 @@ private static void printUrgentTasks(String command, UserList userList) { private static List findUrgentTasks(User user, LocalDateTime now, LocalDateTime deadline) { List urgentTasks = new ArrayList<>(); Timetable userTimetable = user.getTimetable(); - for (Map.Entry> entry : userTimetable.getWeeklyTasks().entrySet()) { - ArrayList tasks = entry.getValue(); - if (tasks != null) { - for (Task task : tasks) { - LocalDateTime taskStartTime = LocalDateTime.of(now.toLocalDate(), task.getStartTime()); - if (now.isBefore(taskStartTime) && taskStartTime.isBefore(deadline)) { - urgentTasks.add(task); - } + String currentDayOfWeek = now.getDayOfWeek().toString().toLowerCase(); // Get current day of the week + String capitalisedDay = Parser.capitalizeFirstLetter(currentDayOfWeek); + ArrayList tasks = userTimetable.getWeeklyTasks().get(capitalisedDay); + if (tasks != null) { + for (Task task : tasks) { + LocalDateTime taskStartTime = LocalDateTime.of(now.toLocalDate(), task.getStartTime()); + if (now.isBefore(taskStartTime) && taskStartTime.isBefore(deadline)) { + urgentTasks.add(task); } } } From 960e6bab79361adad4a67ddc19b151379158a1fb Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Mon, 15 Apr 2024 10:51:00 +0800 Subject: [PATCH 145/162] Clean up template --- docs/DeveloperGuide.md | 2 +- docs/README.md | 9 ++------- docs/team/johndoe.md | 6 ------ 3 files changed, 3 insertions(+), 14 deletions(-) delete mode 100644 docs/team/johndoe.md diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 5888fe06ae..532686347e 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -101,7 +101,7 @@ The app can store multiple timetables and easily display and compare them automa | | user | compare two timetables | see the common time between them | | v2.0 | user | find a to-do item by name | locate a to-do without having to go through the entire list | | | user | specify task importance | remember if a task is important or not | -| | user | compare all timetables | view a summurized timetable comprising of all current timetables | +| | user | compare all timetables | view a summarized timetable comprising of all current timetables | ## Non-Functional Requirements diff --git a/docs/README.md b/docs/README.md index bbcc99c1e7..38c3fb3b36 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,8 +1,3 @@ -# Duke +# TimetableComparer -{Give product intro here} - -Useful links: -* [User Guide](UserGuide.md) -* [Developer Guide](DeveloperGuide.md) -* [About Us](AboutUs.md) +Refer to UserGuide \ No newline at end of file diff --git a/docs/team/johndoe.md b/docs/team/johndoe.md deleted file mode 100644 index ab75b391b8..0000000000 --- a/docs/team/johndoe.md +++ /dev/null @@ -1,6 +0,0 @@ -# John Doe - Project Portfolio Page - -## Overview - - -### Summary of Contributions From 84491b1d8baf97a39aee86803e71a94d7552370d Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 15 Apr 2024 10:58:32 +0800 Subject: [PATCH 146/162] Add java doc --- docs/UserGuide.md | 6 +-- docs/team/z-wenqing.md | 4 +- src/main/java/seedu/duke/Storage.java | 34 ++++++++++++++ src/main/java/seedu/duke/Timetable.java | 59 ------------------------- 4 files changed, 39 insertions(+), 64 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index f5767c3815..e262c9d587 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -74,7 +74,7 @@ The active user is: john ## Listing all existing users: `list` -View the list of existing user names. +View the list of existing usernames. Format: `list` @@ -301,7 +301,7 @@ Repeated task added successfully! ### Add a task for multiple users: `addfor` -Format: `addfor /user USER1, USER2, ... /on DAYS /task TASK /from START_TIME /to END_TIME /type F_OR_C` +Format: `addfor /user USER1, USER2, ... /on DAYS /task DESCRIPTION /from START_TIME /to END_TIME /type F_OR_C` Example: `addfor /user simon, helen, tim /on monday /task project meeting /from 9:00 /to 11:00 /type f` @@ -310,7 +310,6 @@ Expected Output: Timetable has been written to data/Simon.txt Timetable has been written to data/Helen.txt Timetable has been written to data/Tim.txt - ``` ## List name of commands: `help` @@ -350,5 +349,6 @@ The name of the file indicates the owner of the timetable. - Changing a Task's Type `changetasktype /on DAY /index TASK_INDEX /type F_OR_C` - List Today's Tasks `todaytask` - Add a Recurring task `addrepeattask /task TASK_NAME /on DAYS /from START_TIME /to END_TIME /type F_OR_C` +- Add Task For Multiple Users `addfor /user USER1, USER2, ... /on DAYS /task DESCRIPTION /from START_TIME /to END_TIME /type F_OR_C` - Help `help` - Exit Program `bye` diff --git a/docs/team/z-wenqing.md b/docs/team/z-wenqing.md index e3a5449020..b9641dddb9 100644 --- a/docs/team/z-wenqing.md +++ b/docs/team/z-wenqing.md @@ -11,11 +11,11 @@ Given below are my contributions to the project. * **Code Contributed**: https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=z-wenqing&breakdown=true -* **New feature**: Added the ability to store user data such as usernames and timetables of each user. +* **New feature**: Added the ability to store user data such as username and timetable of each user. * When the user launches the application for the first time, a designated folder is created in the application's directory to store all data. * When a new user is added, a file named after the user's name will be created within the created data folder. * Tasks added by users are recorded in their respective files. - * On subsequent launches, all the existing users and their corresponding timetables will be retrieved and loaded. + * On subsequent launches, all the existing users and their corresponding timetables will be retrieved and loaded, allowing users to check their existing tasks. * **New feature**: Added the feature to check whether the task added clashes with the existing tasks. diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 0a4d835d3a..2ea38cea66 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -34,18 +34,37 @@ public Storage(String filePath) { this.filePath = filePath; } + /** + * Gets the file path of the timetable of the user. + * + * @return the string that represents the filepath of the file storing the timetable of the user. + */ public String getFilePath() { return filePath; } + /** + * Gets the folder path of the folder where all data is stored. + * + * @return the string that represents the path of the folder where all data is stored. + */ public static String getFolderPath() { return folderPath; } + /** + * Sets the path of the data folder to a new path. + * + * @param newPath the string that represents the new path, which should be a relative path. + */ public static void setFolderPath(String newPath) { folderPath = newPath; } + /** + * Creates a new folder in the same directory when the application is first launched. + * Otherwise, print that the folder has already been created. + */ public static void createFolder() { File folder = new File(folderPath); @@ -61,6 +80,12 @@ public static void createFolder() { } } + /** + * Add users that are stored in the data folder to the user list, for a returning user. + * + * @param userList the list of users added. + * @throws FileNotFoundException if the data file is not found. + */ public static void addExistingUsers(UserList userList) throws FileNotFoundException { File directory = new File(folderPath); @@ -82,6 +107,12 @@ public static void addExistingUsers(UserList userList) throws FileNotFoundExcept } + /** + * Loads data from the data file. + * + * @param user the user that we want to load data. + * @throws FileNotFoundException if the data file is not found. + */ public void loadData(User user) throws FileNotFoundException { File f = new File(filePath); String day = ""; @@ -101,6 +132,9 @@ public void loadData(User user) throws FileNotFoundException { } } + /** + * Creates a data file for a new user when a new user is added. + */ public void addUserInFolder() { File f = new File(filePath); try { diff --git a/src/main/java/seedu/duke/Timetable.java b/src/main/java/seedu/duke/Timetable.java index d2d10bc15c..835086c28f 100644 --- a/src/main/java/seedu/duke/Timetable.java +++ b/src/main/java/seedu/duke/Timetable.java @@ -5,7 +5,6 @@ import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.Calendar; import java.util.Comparator; import java.util.HashMap; import java.util.Map; @@ -178,62 +177,4 @@ public static void findOverlappingFreeTime(ArrayList tasks, String day) { UI.printFreeDay(day); } } - /** - * Adds a task to the timetable with duplication check. - * - * @param dayOfWeek The day of the week. - * @param task The task to add. - * @return True if the task was added successfully, false if a duplicate was found. - */ - public boolean addTaskWithDuplicationCheck(String dayOfWeek, Task task) { - String capitalizedDay = dayOfWeek.substring(0, 1).toUpperCase() + dayOfWeek.substring(1); - ArrayList tasksOfDay = weeklyTasks.get(capitalizedDay); - - // Check for duplicates - for (Task existingTask : tasksOfDay) { - if (existingTask.getDescription().equalsIgnoreCase(task.getDescription()) - && existingTask.getStartTime().equals(task.getStartTime()) - && existingTask.getEndTime().equals(task.getEndTime())) { - System.out.println("Duplicate task detected. Task not added."); - return false; - } - } - tasksOfDay.add(task); - return true; - } - /** - * Get tasks for today. - * - * @return An ArrayList of tasks for today. - */ - public ArrayList getTasksForToday() { - Calendar calendar = Calendar.getInstance(); - int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); - String day = null; - switch (dayOfWeek) { - case Calendar.MONDAY: - day = "Monday"; - break; - case Calendar.TUESDAY: - day = "Tuesday"; - break; - case Calendar.WEDNESDAY: - day = "Wednesday"; - break; - case Calendar.THURSDAY: - day = "Thursday"; - break; - case Calendar.FRIDAY: - day = "Friday"; - break; - case Calendar.SATURDAY: - day = "Saturday"; - break; - case Calendar.SUNDAY: - day = "Sunday"; - break; - default: break; - } - return weeklyTasks.get(day); - } } From 850e78da5f13719f2081319151fb252eb56dffa0 Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Mon, 15 Apr 2024 11:02:40 +0800 Subject: [PATCH 147/162] Updated changeTaskTiming Sequence Diagram. --- .../changeTaskTiming_Sequence_Diagram.png | Bin 55991 -> 59861 bytes docs/team/john-nng.md | 1 + 2 files changed, 1 insertion(+) diff --git a/docs/diagram/changeTaskTiming_Sequence_Diagram.png b/docs/diagram/changeTaskTiming_Sequence_Diagram.png index eda689857ed4f9917b7fcbcfe6af17f81ec06b60..a3513db3a6793e11ec9069259c908fda1aeb4318 100644 GIT binary patch literal 59861 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 IMQ%U%KNb73$N&HU literal 55991 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 diff --git a/docs/team/john-nng.md b/docs/team/john-nng.md index 597a5183b4..fd0f8b465d 100644 --- a/docs/team/john-nng.md +++ b/docs/team/john-nng.md @@ -29,3 +29,4 @@ This is a task scheduler and timetable comparison command line app that allows u #### Documentation - Updated Documentation for all commands in User Guide and formatted them in a easy to read manner. Bulk of work done during these PR's ([1](https://github.com/AY2324S2-CS2113-T13-2/tp/blob/9dbe139124adfecf78f4c94d8f662b283788a8fa/docs/UserGuide.md), [2](https://github.com/AY2324S2-CS2113-T13-2/tp/blob/65c01a9d7d4875eedc494afa923108eec9e48055/docs/UserGuide.md), [3](https://github.com/AY2324S2-CS2113-T13-2/tp/blob/47db8ea97ed3da106a83d75a7ae90152a5e80200/docs/UserGuide.md)) +- Updated Documentation for DG, Fixed Class Diagram and Sequence Diagram format errors [PR here](https://github.com/AY2324S2-CS2113-T13-2/tp/commit/afc1f429c45bda99b36cf8cae4ac14941c0ccd2a) From 30800d15f94db12c90153f5bd25cd98cdbc9300d Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Mon, 15 Apr 2024 11:08:29 +0800 Subject: [PATCH 148/162] Update help command --- src/main/java/seedu/duke/ui/UI.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/duke/ui/UI.java b/src/main/java/seedu/duke/ui/UI.java index c76e02637d..18edf63f88 100644 --- a/src/main/java/seedu/duke/ui/UI.java +++ b/src/main/java/seedu/duke/ui/UI.java @@ -11,8 +11,7 @@ public class UI { public static void printGreeting() { - System.out.println("Timetable comparison app opened. \n" + - "type 'help' for commands."); + System.out.println("Timetable comparison app opened. "); } public static void printBye() { @@ -41,8 +40,9 @@ public static void printAddTask(Task task) { public static void printHelp() { System.out.println( - "**Note: use hh:mm 24hr time format (ex. 13:00) \n" + - "List of available commands: \n" + + "Note: use hh:mm 24hr time format (ex. 13:00) \n" + + "List of available commands: " + UI.line() + + "View list of commands (what you are looking at): \n" + "help" + UI.line() + "List all users: \n" + "list" + UI.line() + "Exit the app: \n" + "bye" + UI.line() + "View current user: \n" + "current" + UI.line() + @@ -57,7 +57,7 @@ public static void printHelp() { "addtwdc /on /task /from /to /type " + UI.line() + "Add a task for all users: \n" + - "addforall /on /task /from /to /type " + "addforall /on /task /from /to " + UI.line() + "Add a task that repeats over certain days: \n" + "addrepeattask /on /task /from /to /type " From 897a1543e3ad2b77c7c9b1f35a0b924dcaf43901 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 15 Apr 2024 11:13:10 +0800 Subject: [PATCH 149/162] Fix DAYS error --- src/main/java/seedu/duke/Parser.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 687890930b..755046c772 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -485,13 +485,14 @@ private static void addFor(String command, UserList userList) throws IOException String[] words = command.split("/"); String users = words[USER_PART].substring(USERS_INDEX).trim(); // to exclude words "/user" String day = words[DAY_PART].substring(DAY_INDEX).trim(); // to exclude words "/on" + String capitalisedDay = Parser.capitalizeFirstLetter(day); String description = words[DESCRIPTION_PART].substring(DESCRIPTION_INDEX).trim(); // to exclude words "/task" String start = words[START_PART].substring(START_INDEX).trim(); // to exclude words "/from" String end = words[END_PART].substring(END_INDEX).trim(); // to exclude words "/to" String type = words[TYPE_PART].substring(TYPE_INDEX).trim(); // to exclude words "/type" String[] usernames = users.split(","); - Task task = new Task(description, day, start, end, type); + Task task = new Task(description, capitalisedDay, start, end, type); ArrayList clashedUsers = new ArrayList<>(); ArrayList invalidUsers = new ArrayList<>(); for (String username : usernames) { @@ -524,7 +525,7 @@ private static void addFor(String command, UserList userList) throws IOException for (String username : usernames) { User user = userList.findUser(username.trim()); if (!checkClash(task, user)) { - user.getTimetable().addUserTask(day, task); + user.getTimetable().addUserTask(capitalisedDay, task); user.getStorage().writeTaskInFile(user); } else { System.out.println("For " + user.getName() From 31d12694d1de9a79df4a5b1e89f00041249195b4 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Mon, 15 Apr 2024 11:18:30 +0800 Subject: [PATCH 150/162] delete unused java.util.map --- src/main/java/seedu/duke/Parser.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 4303729ade..3147973a06 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -15,7 +15,6 @@ import java.util.Arrays; import java.util.Comparator; import java.util.List; -import java.util.Map; public class Parser { public static final String[] DAYS = new String[] From 2827a8d9b000ddf86cccc82076ef080c940ab345 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Mon, 15 Apr 2024 11:20:13 +0800 Subject: [PATCH 151/162] update on user guide --- docs/UserGuide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 5cf65a31e0..30874e4252 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -21,6 +21,7 @@ Welcome to **TimeTableComparer**! This application is meant for creating and sto - [Changing a task's type: `changetasktype`](#changetasktype) - [View today's tasks: `todaytask`](#todaytask) - [Add a recurring task: `addrepeattask`](#addrepeattask) + - [View urgent tasks in next few hours: `urgent`](#urgent) - [Help: `help`](#help) - [Exit program: `bye`](#bye) - [FAQ](#faq) From 1ec77a1fbe070a55fd6abe39cc0b8531894568b2 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Mon, 15 Apr 2024 11:20:53 +0800 Subject: [PATCH 152/162] update on my PPP --- docs/team/zhusijia0711.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/team/zhusijia0711.md b/docs/team/zhusijia0711.md index 7a717e7118..0556783f14 100644 --- a/docs/team/zhusijia0711.md +++ b/docs/team/zhusijia0711.md @@ -13,25 +13,34 @@ Given below are my contributions to the project. - **New Feature:** Add a command that allows an user to add one task to his/her timetable. - What it does: Allows the user to add a task with a task description, start time, end time and task type one at a time. - Justification: This is the basic functionality for a time management application. + - **New Feature:** Add a command that allows an user to delete the task he/she previously added. - What it does: Allow the user to delete a task using the index of the task in a day. - Justification: This is the basic functionality for a time management application. + - **New Feature:** Add a command that allows an user to add a same task to different days. - What it does: Allow the user to add a task which can happen in multiple days to the timetable. - Justification: This feature reduces troublesome of users as they would not need to add repeated task one by one. + - **New Feature:** Add a command that allows an user to change their task timing - What is does: Allow the user to change the start time and end time for the previously added task. - Justification: This feature reduces troublesome of users as they do not need to first delete the task and add the task one more time in order to change the time. + - **New Feature:** Add a command that allows an user to change their task type. - What it does: In our application logic, if the task type is assigned to be flexible(f), it means the timings of the task can be changed. If a task is marked as compulsory(c), it means its timing cannot be changed. This feature helps users to change the task type whenever there is a change in their plan. - Justification: This feature reduces troublesome of users as they do not need to first delete the task and add the task one more time in order to change the task type. + - - **New Feature:** Add a command that allows an user to see today's tasks(if any). - What it does: Allow the users to see the tasks that happens today. +- - **New Feature:** Add a command that allows an user to see urgent tasks in the next few hours. + - What it does: Allow the users to see the tasks that happens in the next few hours in today. + - If the stated urgent hours exceeds the 23:59, the method will print the tasks until the end of today. + - Code contributed: - https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2024-02-23&tabOpen=true&tabType=authorship&tabAuthor=ZhuSijia0711&tabRepo=AY2324S2-CS2113-T13-2%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code~other&authorshipIsBinaryFileTypeChecked=false&authorshipIsIgnoredFilesChecked=false From 6432c4289bd1b3b6d5ba326204c27954a975422f Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Mon, 15 Apr 2024 11:31:33 +0800 Subject: [PATCH 153/162] Update test --- text-ui-test/EXPECTED.TXT | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 7dfa43adc9..3b1be7305c 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,8 +1,11 @@ Timetable comparison app opened. -type 'help' for commands. -Folder created successfully. -**Note: use hh:mm 24hr time format (ex. 13:00) +Folder already exists. +Note: use hh:mm 24hr time format (ex. 13:00) List of available commands: +_________________________________________ +View list of commands (what you are looking at): +help +_________________________________________ List all users: list _________________________________________ @@ -31,7 +34,7 @@ Add task for current user (check duplicates): addtwdc /on /task /from /to /type _________________________________________ Add a task for all users: -addforall /on /task /from /to /type +addforall /on /task /from /to _________________________________________ Add a task that repeats over certain days: addrepeattask /on /task /from /to /type From 2e0183e4189485ee41cc41009ae369be0fe1533c Mon Sep 17 00:00:00 2001 From: Leong-ZM Date: Mon, 15 Apr 2024 11:33:53 +0800 Subject: [PATCH 154/162] update test --- text-ui-test/EXPECTED.TXT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 3b1be7305c..f658c87e1c 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,5 +1,5 @@ Timetable comparison app opened. -Folder already exists. +Folder created successfully. Note: use hh:mm 24hr time format (ex. 13:00) List of available commands: _________________________________________ From d3374f8b18f21b802ca201b0007870532fa1664f Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 15 Apr 2024 11:41:08 +0800 Subject: [PATCH 155/162] Update UG --- docs/UserGuide.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index c01209ae4c..be86bb5de0 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -22,6 +22,7 @@ Welcome to **TimeTableComparer**! This application is meant for creating and sto - [View today's tasks: `todaytask`](#todaytask) - [Add a recurring task: `addrepeattask`](#addrepeattask) - [View urgent tasks in next few hours: `urgent`](#urgent) + - [Add a task for certain users: `addfor`](#addfor) - [Help: `help`](#help) - [Exit program: `bye`](#bye) - [FAQ](#faq) @@ -312,7 +313,7 @@ Urgent tasks within the next 3 hours: lec (Monday from 12:00 to 13:00) type: c ``` -### Add a task for multiple users: `addfor` +## Add a task for multiple users: `addfor` Format: `addfor /user USER1, USER2, ... /on DAYS /task DESCRIPTION /from START_TIME /to END_TIME /type F_OR_C` @@ -362,6 +363,6 @@ The name of the file indicates the owner of the timetable. - Changing a Task's Type `changetasktype /on DAY /index TASK_INDEX /type F_OR_C` - List Today's Tasks `todaytask` - Add a Recurring task `addrepeattask /task TASK_NAME /on DAYS /from START_TIME /to END_TIME /type F_OR_C` -- Add Task For Multiple Users `addfor /user USER1, USER2, ... /on DAYS /task DESCRIPTION /from START_TIME /to END_TIME /type F_OR_C` +- Add Task For Certain Users `addfor /user USER1, USER2, ... /on DAYS /task DESCRIPTION /from START_TIME /to END_TIME /type F_OR_C` - Help `help` - Exit Program `bye` From 29cb5da8539e794b94ad0f2bcd0ae9318673d73d Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Mon, 15 Apr 2024 11:42:32 +0800 Subject: [PATCH 156/162] add urgent in command summary --- docs/UserGuide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index c01209ae4c..6c5f0014d4 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -362,6 +362,7 @@ The name of the file indicates the owner of the timetable. - Changing a Task's Type `changetasktype /on DAY /index TASK_INDEX /type F_OR_C` - List Today's Tasks `todaytask` - Add a Recurring task `addrepeattask /task TASK_NAME /on DAYS /from START_TIME /to END_TIME /type F_OR_C` +- Find urgent tasks in next few hours `urgent /in HOURS` - Add Task For Multiple Users `addfor /user USER1, USER2, ... /on DAYS /task DESCRIPTION /from START_TIME /to END_TIME /type F_OR_C` - Help `help` - Exit Program `bye` From 6bab4bdcde56445bb07c6dcf57f00c965f65f0e7 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 15 Apr 2024 11:42:34 +0800 Subject: [PATCH 157/162] Update UG --- docs/UserGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index be86bb5de0..67610c7080 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -358,7 +358,7 @@ The name of the file indicates the owner of the timetable. - Delete a Task `deletetask /on DAY /index TASK_NUMBER` - Compare Two Timetables `compare NAME_1 NAME_2` - Compare All Timetables `compareall` -- Add a Task For All Users `addforall /on DAY /task DESCRIPTION /from START /to END /type [f/c]` +- Add a Task For All Users `addforall /on DAY /task DESCRIPTION /from START /to END` - Changing a Task's Time `changetasktiming /on DAY /index TASK_INDEX /from TIME /to TIME` - Changing a Task's Type `changetasktype /on DAY /index TASK_INDEX /type F_OR_C` - List Today's Tasks `todaytask` From 9dd9cd53bf0ebeed23c10ab7dea98ffb50289421 Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 Date: Mon, 15 Apr 2024 11:46:05 +0800 Subject: [PATCH 158/162] update on user guide --- docs/UserGuide.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 6c5f0014d4..9863d9500c 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -318,6 +318,8 @@ Format: `addfor /user USER1, USER2, ... /on DAYS /task DESCRIPTION /from START_T Example: `addfor /user simon, helen, tim /on monday /task project meeting /from 9:00 /to 11:00 /type f` +* Note: The usernames have to be separated by ",". + Expected Output: ``` Timetable has been written to data/Simon.txt @@ -346,6 +348,10 @@ Expected Output: `Bye.` **A**: The timetables are stored in the folder named "data" in the same directory. The name of the file indicates the owner of the timetable. +**Q**: Can I delete a user from the userlist? + +**A**: No. + ## Command Summary - Add User `adduser NAME` From 41fdcccab3f8d33aa5ebab98853204f9b9cb7a0e Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 15 Apr 2024 11:57:15 +0800 Subject: [PATCH 159/162] Update DG --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 532686347e..a37ff5c651 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -10,7 +10,7 @@ The saving timetable mechanism is facilitated by the Storage class. It implement * `Storage#writeTaskInFile(User user)`: when a new task of a specific user is added, it will be written into the correct file. The following sequence diagram shows how the operations in the Storage class goes through when the app is opened and it loads data from history: -![Storage UML](StorageUML.png) +![Storage UML](diagram%2FStorageUML.png) ## Parser Component From 4dcf6e55a81890e982313ea8007c714f6a2dc5b0 Mon Sep 17 00:00:00 2001 From: z-wenqing Date: Mon, 15 Apr 2024 11:59:43 +0800 Subject: [PATCH 160/162] Add storage png --- docs/diagram/StorageUML.png | Bin 0 -> 57216 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/diagram/StorageUML.png diff --git a/docs/diagram/StorageUML.png b/docs/diagram/StorageUML.png new file mode 100644 index 0000000000000000000000000000000000000000..2e76f759edd75288a5ec94f9cc027ada28b83be8 GIT binary patch literal 57216 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 awh5KM_EA&TQYun34f-Ecn7=9j literal 0 HcmV?d00001 From f3a0af5da8d9e36cbb4330274aededf2f95aab14 Mon Sep 17 00:00:00 2001 From: john-nng <89668122+john-nng@users.noreply.github.com> Date: Mon, 15 Apr 2024 12:08:44 +0800 Subject: [PATCH 161/162] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index a37ff5c651..b889dfe6d2 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -72,7 +72,7 @@ Step 4: It then loops through the tasks on that day, starting from the back (the Step 5: It displays the last task it looped though, or a special message if there is no task that day. -![NextCommand UML](NextCommand.png) +![NextCommand UML](diagram%2FNextCommand.png) # Appendix: Project Requirements ## Product scope From 9e792ca56314e8f69713fce51bc8934c0720defe Mon Sep 17 00:00:00 2001 From: ZhuSijia0711 <110603075+ZhuSijia0711@users.noreply.github.com> Date: Mon, 15 Apr 2024 13:00:39 +0800 Subject: [PATCH 162/162] Update README.md --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 38c3fb3b36..35f1e5bcdb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,3 +1,3 @@ # TimetableComparer -Refer to UserGuide \ No newline at end of file +Refer to UserGuide: [User Guide](https://ay2324s2-cs2113-t13-2.github.io/tp/UserGuide.html)