From 848bcf06947b15249efd98a49cdf99bc36d6d030 Mon Sep 17 00:00:00 2001 From: Mayank Keoliya <49546368+mkeoliya@users.noreply.github.com> Date: Tue, 15 Sep 2020 01:36:51 +0800 Subject: [PATCH 001/326] Update README.md --- README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 13f5c77403f..04edcc7906f 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,16 @@ ![Ui](docs/images/Ui.png) -* This is **a sample project for Software Engineering (SE) students**.
+* ResiReg is a project built for the CS2103 module at NUS. ResiReg is a housing management application for residential administration staff, such as admin working at NUS Residential Colleges.
Example usages: - * as a starting point of a course project (as opposed to writing everything from scratch) - * as a case study -* The project simulates an ongoing software project for a desktop application (called _AddressBook_) used for managing contact details. + * to manage records of students and rooms + * to allocate and deallocate students to rooms + * to generate bills and record payments + * to manage students serving SHN notice + * to generate reports for half-yearly audits of the admin staff +* The project simulates an ongoing software project for a desktop application (called _AddressBook_), originally used for managing contact details. * It is **written in OOP fashion**. It provides a **reasonably well-written** code base **bigger** (around 6 KLoC) than what students usually write in beginner-level SE modules, without being overwhelmingly big. * It comes with a **reasonable level of user and developer documentation**. -* It is named `AddressBook Level 3` (`AB3` for short) because it was initially created as a part of a series of `AddressBook` projects (`Level 1`, `Level 2`, `Level 3` ...). -* For the detailed documentation of this project, see the **[Address Book Product Website](https://se-education.org/addressbook-level3)**. +* It is named `ResiReg` because it provides functionality for "__Res__idential __Reg__ulation" of dorms at a university. +* For the detailed documentation of this project, see the **[ResiReg Product Website](https://ay2021s1-cs2103-t16-3.github.io/tp)**. * This project is a **part of the se-education.org** initiative. If you would like to contribute code to this project, see [se-education.org](https://se-education.org#https://se-education.org/#contributing) for more info. From a068545161d74e6cbb145739b02c3a181efd4af5 Mon Sep 17 00:00:00 2001 From: chloelee767 Date: Tue, 15 Sep 2020 23:56:35 +0800 Subject: [PATCH 002/326] Update user guide --- docs/UserGuide.md | 396 +++++++++++++++++++++++++++++++--------------- 1 file changed, 267 insertions(+), 129 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index b91c3bab04d..a35ac43f69c 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -3,176 +3,314 @@ layout: page title: User Guide --- -AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized for use via a Command Line Interface** (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, AB3 can get your contact management tasks done faster than traditional GUI apps. - * Table of Contents {:toc} --------------------------------------------------------------------------------------------------------------------- - -## Quick start - -1. Ensure you have Java `11` or above installed in your Computer. - -1. Download the latest `addressbook.jar` from [here](https://github.com/se-edu/addressbook-level3/releases). - -1. Copy the file to the folder you want to use as the _home folder_ for your AddressBook. - -1. Double-click the file to start the app. The GUI similar to the below should appear in a few seconds. Note how the app contains some sample data.
- ![Ui](images/Ui.png) - -1. Type the command in the command box and press Enter to execute it. e.g. typing **`help`** and pressing Enter will open the help window.
- Some example commands you can try: - - * **`list`** : Lists all contacts. - - * **`add`**`n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` : Adds a contact named `John Doe` to the Address Book. - - * **`delete`**`3` : Deletes the 3rd contact shown in the current list. - - * **`clear`** : Deletes all contacts. - - * **`exit`** : Exits the app. - -1. Refer to the [Features](#features) below for details of each command. +## Introduction +__ResiReg__ is a Residential College management application that helps residential admins (from the Office of Housing Services) with their daily tasks. __ResiReg__ allows admin to deal with allocating rooms to students, billing, generating OHS reports, and even managing the COVID-19 situation in residences. --------------------------------------------------------------------------------------------------------------------- +__ResiReg__ has the following main features: +1. View a list of vacant rooms in the College, filtered by COVID-19 zoning if needed. +2. Allocate or deallocate students to vacant rooms in the College when the semester begins, depending on: + - year of study + - faculty + - major + - room type. +3. View a list of current room allocations, where each allocation includes room number, student name, room type, and date of check-in. +4. Add attributes of students staying in the College, including their room allocated, student name, matric number, faculty, year of study, etc. -## Features +__ResiReg__ is optimised for OHS who are fast typists who are used to MS Excel, and prefer typing over other means of input. It comes with: +- A Command Line Interface (CLI) which allows you to access all __ResiReg__ features by typing. +- A Graphical User Interface (GUI) that displays the information you need in a grid format. -
+> __ResiReg__ is currently a work in progress. Here is a low-fidelity mockup of its skeleton. Stay tuned for our progress! +![](https://i.imgur.com/uqEO8Lp.png) -**:information_source: Notes about the command format:**
-* Words in `UPPER_CASE` are the parameters to be supplied by the user.
- e.g. in `add n/NAME`, `NAME` is a parameter which can be used as `add n/John Doe`. + -* Items in square brackets are optional.
- e.g `n/NAME [t/TAG]` can be used as `n/John Doe t/friend` or as `n/John Doe`. -* Items with `…`​ after them can be used multiple times including zero times.
- e.g. `[t/TAG]…​` can be used as ` ` (i.e. 0 times), `t/friend`, `t/friend t/family` etc. -* Parameters can be in any order.
- e.g. if the command specifies `n/NAME p/PHONE_NUMBER`, `p/PHONE_NUMBER n/NAME` is also acceptable. -
+## About this Guide +### Basic Information +This User Guide explains how you (as an OHS admin) can use __ResiReg__ to manage tasks at Residential Colleges. -### Viewing help : `help` +You may refer to [Quick Start](#quick-start) for a short tutorial on how to run __ResiReg__ on your system and use __ResiReg__'s main features. For a full walkthrough of __ResiReg__, please refer to [Features](#features). -Shows a message explaning how to access the help page. +### Command Format +This section explains the format of commands in this User Guide. -![help message](images/helpMessage.png) +- Words in `` are the parameters to be supplied by the user e.g. in `deallocate `, `` is a parameter which can be used as `deallocate Jet New`. +- Items in square brackets are optional e.g ` [-aka ]` can be used as `Jet New -aka JJ` or as `Jet New`. +- Items with … after them can be used multiple times including zero times, unless otherwise stated e.g. `[/m /ig ]…` can be used as `/m mod /ig ig`, `/m mod1 /ig ig1 /m mod2 /ig ig2` etc. -Format: `help` +## Quick Start +1. Ensure that Java 11 or above is installed in your computer +2. Download the latest `ResiReg.jar` here. +3. Copy the file to the folder you want to use as the home folder for your **ResiReg**. +4. Double-click the file to start the app. The following window should appear within a few seconds - this is the Session Screen, where you can create, open, or delete interview sessions: +5. Type the command in the command box and press Enter to execute it. e.g. typing `help` and pressing Enter will open this user guide. +6. Some example commands you can try: + - `list rooms`: lists all rooms that are vacant. + - `allocate A0123456X 08-108`: allocate a student with the student ID A0123456X to room number 08-108. + - `exit`: exits the app. +8. Refer to “Features” for details of all the commands. -### Adding a person: `add` +### I. Housing Management -Adds a person to the address book. +>**ResiReg** allows you to manage rooms in the Residential College. -Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​` +#### 1. Viewing a list of all vacant rooms -
:bulb: **Tip:** -A person can have any number of tags (including 0) -
+Before assigning a room to a student at the start of the semester, you can view a list of all vacant rooms using the `list rooms` command. -Examples: -* `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` -* `add n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal` +##### Command +``` +rooms +``` +##### Execution Example +``` +> rooms +``` -### Listing all persons : `list` +*Action*: Lists all rooms, along with the details such as vacancy in the Residential College. -Shows a list of all persons in the address book. +*Output*: +The Output panel on the right should display all rooms, along with their details such as vacancy in the Residential College. + + -### Editing a person : `edit` +#### 2. Allocating a room to a student -Edits an existing person in the address book. +Each student can be allocated a room in the Residential College at the start of the semester by using the `allocate` command. -Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]…​` +##### Command +``` +allocate +``` +##### Execution Example +``` +> allocate A0123456X 10-108 +``` -* Edits the person at the specified `INDEX`. The index refers to the index number shown in the displayed person list. The index **must be a positive integer** 1, 2, 3, …​ -* At least one of the optional fields must be provided. -* Existing values will be updated to the input values. -* When editing tags, the existing tags of the person will be removed i.e adding of tags is not cumulative. -* You can remove all the person’s tags by typing `t/` without - specifying any tags after it. +*Action*: Allocates the student A0123456X the room 10-108. -Examples: -* `edit 1 p/91234567 e/johndoe@example.com` Edits the phone number and email address of the 1st person to be `91234567` and `johndoe@example.com` respectively. -* `edit 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags. +*Output*: +``` +Successfully allocated the student A0123456X to room 10-108. +``` -### Locating persons by name: `find` +#### 3. Deallocating a room for a student -Finds persons whose names contain any of the given keywords. +A student can be deallocated a room in the Residential College in cases such as early checkout or dropping out of the programme using the `deallocate` command. -Format: `find KEYWORD [MORE_KEYWORDS]` +##### Command +``` +deallocate +``` +##### Execution Example +``` +> deallocate A0123456X +``` -* The search is case-insensitive. e.g `hans` will match `Hans` -* The order of the keywords does not matter. e.g. `Hans Bo` will match `Bo Hans` -* Only the name is searched. -* Only full words will be matched e.g. `Han` will not match `Hans` -* Persons matching at least one keyword will be returned (i.e. `OR` search). - e.g. `Hans Bo` will return `Hans Gruber`, `Bo Yang` +*Action*: Deletes the room allocation for the student A0123456X. -Examples: -* `find John` returns `john` and `John Doe` -* `find alex david` returns `Alex Yeoh`, `David Li`
- ![result for 'find alex david'](images/findAlexDavidResult.png) +*Output*: +``` +Successfully deallocated room for student A0123456X. +``` -### Deleting a person : `delete` +#### 4. Viewing a room allocation for a student -Deletes the specified person from the address book. +The room allocation for a student in the residential college can be viewed to inform said student of his room allocation during check-in -Format: `delete INDEX` +##### Command +``` +room +``` +##### Execution Example +``` +> room A0123456X +``` +*Action*: views a room allocation for the student A0123456X. -* Deletes the person at the specified `INDEX`. -* The index refers to the index number shown in the displayed person list. -* The index **must be a positive integer** 1, 2, 3, …​ +*Output*: +``` +A0123456X is allocated room +``` -Examples: -* `list` followed by `delete 2` deletes the 2nd person in the address book. -* `find Betsy` followed by `delete 1` deletes the 1st person in the results of the `find` command. -### Clearing all entries : `clear` +#### 5. Viewing a list of all allocated rooms -Clears all entries from the address book. - -Format: `clear` - -### Exiting the program : `exit` - -Exits the program. - -Format: `exit` - -### Saving the data - -AddressBook data are saved in the hard disk automatically after any command that changes the data. There is no need to save manually. - -### Archiving data files `[coming in v2.0]` - -_{explain the feature here}_ - --------------------------------------------------------------------------------------------------------------------- +The room allocations for all students in the residential college can be viewed to check which room each student stays in. + +##### Command +``` +rooms +``` +##### Execution Example +``` +> rooms +``` +*Action*: views the room allocations for all students + +*Output*: +``` +Here is the list of all room allocations: +- Jet New : 11-108 +- John New : 12-107 +- Jason New : 13-105 +``` +
+ +### II. Student Management + +>**ResiReg** allows you to manage students in the Residential College. + +#### 6. Adding a student +A new student can be added to **ResiReg**. The following student details are stored: name, matriculation number, email, faculty and year. + +##### Command +``` +add student /name /matric /email /faculty /year +``` + +The pairs of types and data (eg. `/name `) may given be in any order. The student will not be added if some pieces of information is missing. + +##### Successful Execution Example +``` +add student /name Jet New /matric A0123456X /email jn@u.nus.edu /faculty computing /year 2 +``` + +*Action*: Creates a new student named Jet New whose matriculation number is A0123456X, email is jn@u.nus.edu, faculty is Computing and who is in year 2. + +*Output*: +``` +Added a new student Jet New. +``` + +##### Unsuccessful Execution Example +``` +add student /name Jet New /matric A0123456X /email jn@u.nus.edu +``` + +*Action*: The student is not added because the faculty and year are missing. **ResiReg** will show an error message describing which fields are missing. + +*Output*: +``` +Couldn't add student! The following fields are missing: faculty, year. +``` + +#### 7. Listing all students +All the students currently in **ResiReg** can be listed. + +##### Command +``` +students +``` + +##### Execution Example +``` +> students +``` + +*Action*: Shows the names of all the students in the panel on the right. +*Output*: +![](https://i.imgur.com/uqEO8Lp.png) + + ## FAQ - -**Q**: How do I transfer my data to another Computer?
-**A**: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous AddressBook home folder. - --------------------------------------------------------------------------------------------------------------------- - -## Command summary - -Action | Format, Examples ---------|------------------ -**Add** | `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​`
e.g., `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague` -**Clear** | `clear` -**Delete** | `delete INDEX`
e.g., `delete 3` -**Edit** | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]…​`
e.g.,`edit 2 n/James Lee e/jameslee@example.com` -**Find** | `find KEYWORD [MORE_KEYWORDS]`
e.g., `find James Jake` -**List** | `list` -**Help** | `help` +### Where do I get help? +Just type in the `help` command! + + +### How do I transfer my data to another Computer? +1. Download the JAR file (`resireg.jar`) on your new computer. +2. Navigate to where the JAR file is. +3. Double click on `resireg.jar` +4. Delete the `resireg.json` file in the folder +5. Copy over the `resireg.json` file residing in your previous **ResiReg** home folder that contains data of your previous **ResiReg** session. + +## Command Summary +| Action | Format Examples | +| -------- | --------------- | +| rooms | `rooms` | +| students | `students` | +| allocate | `allocate ` e.g. `allocate A0123456X 10-108` | +| deallocate | `deallocate ` e.g. `allocate A0123456X 10-108` | +| room | `room ` e.g. `room A0123456X` | +| add student | `add student /name /faculty /year /email ` e.g.`add student /name Jet New /faculty SOC /year 2 /email jn@u.nus.edu` | +| help | `help [command]` e.g. `help` or `help list` | From a95aab9498cd1090ef1d9546d527e965edcb6c0d Mon Sep 17 00:00:00 2001 From: chloelee767 Date: Wed, 16 Sep 2020 00:04:40 +0800 Subject: [PATCH 003/326] Fix table to work with jekyll --- docs/UserGuide.md | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index a35ac43f69c..c585e6726de 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -305,12 +305,22 @@ Just type in the `help` command! 5. Copy over the `resireg.json` file residing in your previous **ResiReg** home folder that contains data of your previous **ResiReg** session. ## Command Summary -| Action | Format Examples | -| -------- | --------------- | -| rooms | `rooms` | -| students | `students` | -| allocate | `allocate ` e.g. `allocate A0123456X 10-108` | -| deallocate | `deallocate ` e.g. `allocate A0123456X 10-108` | -| room | `room ` e.g. `room A0123456X` | -| add student | `add student /name /faculty /year /email ` e.g.`add student /name Jet New /faculty SOC /year 2 /email jn@u.nus.edu` | -| help | `help [command]` e.g. `help` or `help list` | + + + + + + + + + + +Action | Format, Examples +---------|-------------------- +*rooms* | `rooms` +*students* | `students` +*allocate* | `allocate ` e.g. `allocate A0123456X 10-108` +*deallocate* | `deallocate ` e.g. `allocate A0123456X 10-108` +*room* | `room ` e.g. `room A0123456X` +*add student* | `add student /name /faculty /year /email ` e.g.`add student /name Jet New /faculty SOC /year 2 /email jn@u.nus.edu` +*help* | `help [command]` e.g. `help` or `help list` From 8379fa6541122e754ca5152d4a9f70a425114fec Mon Sep 17 00:00:00 2001 From: chloelee767 Date: Wed, 16 Sep 2020 09:49:51 +0800 Subject: [PATCH 004/326] Update doc title and github link --- docs/_config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 6bd245d8f4e..707de9a8ce9 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,4 +1,4 @@ -title: "AB-3" +title: "ResiReg" theme: minima header_pages: @@ -8,7 +8,7 @@ header_pages: markdown: kramdown -repository: "se-edu/addressbook-level3" +repository: "AY2021S1-T16-3/tp" github_icon: "images/github-icon.png" plugins: From 43c58269431265ccac05c64dd466fba3c15d9b1f Mon Sep 17 00:00:00 2001 From: mkeoliya Date: Thu, 17 Sep 2020 01:54:19 +0800 Subject: [PATCH 005/326] Add githooks --- build.gradle | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/build.gradle b/build.gradle index be2d2905dde..456e360180a 100644 --- a/build.gradle +++ b/build.gradle @@ -4,6 +4,7 @@ plugins { id 'com.github.johnrengelman.shadow' version '4.0.4' id 'application' id 'jacoco' + id "com.star-zero.gradle.githook" version "1.2.1" } mainClassName = 'seedu.address.Main' @@ -69,4 +70,14 @@ shadowJar { archiveName = 'addressbook.jar' } +githook { + failOnMissingHooksDir = true + createHooksDirIfNotExist = true + hooks { + "pre-push" { + task = "test clean checkstyleMain checkStyleTest" + } + } +} + defaultTasks 'clean', 'test' From 6f5372751eab0c7e0a073558ce0e7feb1b869974 Mon Sep 17 00:00:00 2001 From: jetnew Date: Sat, 19 Sep 2020 13:42:03 +0800 Subject: [PATCH 006/326] Add General section and CLI sugar commands to User Guide --- docs/UserGuide.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index c585e6726de..dbda5a7ab46 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -292,6 +292,50 @@ The semesterly fees for air-con rooms are now $1500. ``` --> + +### III. General + +>**ResiReg** has many general features such as Command Line Interface (CLI) sugar for more efficient usage by experienced users. + +#### 1. Asking for help as a first time user + +As a first-time user, you can get a walkthrough of all the available commands and their syntax to understand the usage of the commands, using the `help` command. + +##### Command +``` +help +``` +##### Execution Example +``` +> list rooms - views a list of vacant rooms +> ... +``` + +*Action*: Lists all user commands, along with details on syntax and usage. + +*Output*: +The Command History panel on the left will display all available command details. + + +#### 2. Checking the syntax for a command + +Occasionally, you may need to check the syntax of a command if you need to use the command but are unsure of the command usage. + +##### Command +``` +help +``` +##### Execution Example +``` +help list rooms +> list rooms - views a list of vacant rooms +``` + +*Action*: Shows details of the command, including syntax and usage. + +*Output*: +The Command History panel on the left will display the command details, including syntax and usage. + ## FAQ ### Where do I get help? Just type in the `help` command! From 5ee5d2e6d056b2df2683dfa6e0cae56b1af24f22 Mon Sep 17 00:00:00 2001 From: Lysire Date: Sat, 19 Sep 2020 13:47:48 +0800 Subject: [PATCH 007/326] Update user guide to include editting of rooms --- docs/UserGuide.md | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index c585e6726de..2924b88c1f8 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -173,8 +173,26 @@ room A0123456X is allocated room ``` +#### 5. Edit a room allocation for a student -#### 5. Viewing a list of all allocated rooms +A student's room allocation can be edited to update room vacancies. + +##### Command +``` +edit +``` +##### Execution Example +``` +> edit A0123456X 11-109 +``` +*Action*: edits the room allocation for student A0123456X to the specified room number. + +*Output*: +``` +Successfully edited room allocation for student A0123456X to 11-109. +``` + +#### 6. Viewing a list of all allocated rooms The room allocations for all students in the residential college can be viewed to check which room each student stays in. @@ -195,13 +213,14 @@ Here is the list of all room allocations: - John New : 12-107 - Jason New : 13-105 ``` +
### II. Student Management >**ResiReg** allows you to manage students in the Residential College. -#### 6. Adding a student +#### 7. Adding a student A new student can be added to **ResiReg**. The following student details are stored: name, matriculation number, email, faculty and year. ##### Command @@ -235,7 +254,7 @@ add student /name Jet New /matric A0123456X /email jn@u.nus.edu Couldn't add student! The following fields are missing: faculty, year. ``` -#### 7. Listing all students +#### 8. Listing all students All the students currently in **ResiReg** can be listed. ##### Command @@ -321,6 +340,7 @@ Action | Format, Examples *students* | `students` *allocate* | `allocate ` e.g. `allocate A0123456X 10-108` *deallocate* | `deallocate ` e.g. `allocate A0123456X 10-108` +*edit* | `edit ` e.g. `edit A0123456X 10-108` *room* | `room ` e.g. `room A0123456X` *add student* | `add student /name /faculty /year /email ` e.g.`add student /name Jet New /faculty SOC /year 2 /email jn@u.nus.edu` *help* | `help [command]` e.g. `help` or `help list` From af892953951c0efa5659ce47adf27d7951969543 Mon Sep 17 00:00:00 2001 From: Lysire Date: Sat, 19 Sep 2020 14:26:51 +0800 Subject: [PATCH 008/326] update ui mockup --- docs/images/Ui.png | Bin 14607 -> 173357 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/Ui.png b/docs/images/Ui.png index 5bd77847aa2429edac366ebe3e00650b6dd909d8..39da3f3c98555440b843b4bf3111a9dcec75c8ed 100644 GIT binary patch literal 173357 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

O%|QGI;e2mv^BSXYEuq{9w7 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 EpL3D-pa1{> literal 14607 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 RAXge19gVx{rMDi1{6Bg4z)AoB From 7bc97504d451a9ed5b28f8abd89a1af7365152f5 Mon Sep 17 00:00:00 2001 From: Lysire Date: Sat, 19 Sep 2020 14:57:07 +0800 Subject: [PATCH 009/326] Add about me information as part of the team's About Us --- docs/AboutUs.md | 10 +++++----- docs/images/kevin.png | Bin 0 -> 11630 bytes 2 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 docs/images/kevin.png diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 1c9514e966a..e5b48b5f448 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -29,14 +29,14 @@ You can reach us at the email `seer[at]comp.nus.edu.sg` * Role: Team Lead * Responsibilities: UI -### Johnny Doe +### Bec Kyung Huhn (Kevin) - + -[[github](http://github.com/johndoe)] [[portfolio](team/johndoe.md)] +[[github](http://github.com/lysire)] -* Role: Developer -* Responsibilities: Data +* Role: Developer, IntelliJ Expert +* Responsibilities: Deliverables and Deadlines ### Jean Doe diff --git a/docs/images/kevin.png b/docs/images/kevin.png new file mode 100644 index 0000000000000000000000000000000000000000..c1ed3b7f042e05826e106a9bc33c3f23e80c4125 GIT binary patch literal 11630 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 literal 0 HcmV?d00001 From b65f9d27fa7c313e272f21f01fe334348e2cd30b Mon Sep 17 00:00:00 2001 From: mkeoliya Date: Sun, 20 Sep 2020 00:23:17 +0800 Subject: [PATCH 010/326] Add value proposition, target user and NFRs --- docs/DeveloperGuide.md | 174 ++++++++++++++++++++++++----------------- 1 file changed, 101 insertions(+), 73 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 4829fe43011..8f21854a28a 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -2,16 +2,38 @@ layout: page title: Developer Guide --- -* Table of Contents -{:toc} --------------------------------------------------------------------------------------------------------------------- +- Table of Contents + {:toc} + +--- ## **Setting up, getting started** Refer to the guide [_Setting up and getting started_](SettingUp.md). --------------------------------------------------------------------------------------------------------------------- +--- + +## Introduction + +**ResiReg** is a productivity app designed to help OHS* admin at Residential Colleges (RCs)* in NUS with their daily tasks. **ResiReg** allows admin to allocate rooms to students, manage students records, generate billing and OHS reports, and export CSVs for easy reference and sharing. + +**ResiReg** has the following main features: + +1. Manage records of students. +2. Manage allocations of students to rooms in the College +3. Generate bills and log payments for RC-related services. +4. Export records of students, rooms or transactions to CSV files for easy reference and sharing. + +## Purpose and Audience for this Guide + +This Developer Guide specifies the architecture, design, implementation and user cases for **ResiReg**, as well as our considerations behind key design decisions. + +It is intended for developers, software testers, open-source contrubitors and any like-minded persons who wish to contribute this project or gain deeper insights about **ResiReg**. + +## Setting Up + +Refer to the guide [here](./SettingUp.md). ## **Design** @@ -19,7 +41,7 @@ Refer to the guide [_Setting up and getting started_](SettingUp.md). -The ***Architecture Diagram*** given above explains the high-level design of the App. Given below is a quick overview of each component. +The **_Architecture Diagram_** given above explains the high-level design of the App. Given below is a quick overview of each component.

@@ -28,22 +50,23 @@ The ***Architecture Diagram*** given above explains the high-level design of the
**`Main`** has two classes called [`Main`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/Main.java) and [`MainApp`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/MainApp.java). It is responsible for, -* At app launch: Initializes the components in the correct sequence, and connects them up with each other. -* At shut down: Shuts down the components and invokes cleanup methods where necessary. + +- At app launch: Initializes the components in the correct sequence, and connects them up with each other. +- At shut down: Shuts down the components and invokes cleanup methods where necessary. [**`Commons`**](#common-classes) represents a collection of classes used by multiple other components. The rest of the App consists of four components. -* [**`UI`**](#ui-component): The UI of the App. -* [**`Logic`**](#logic-component): The command executor. -* [**`Model`**](#model-component): Holds the data of the App in memory. -* [**`Storage`**](#storage-component): Reads data from, and writes data to, the hard disk. +- [**`UI`**](#ui-component): The UI of the App. +- [**`Logic`**](#logic-component): The command executor. +- [**`Model`**](#model-component): Holds the data of the App in memory. +- [**`Storage`**](#storage-component): Reads data from, and writes data to, the hard disk. Each of the four components, -* defines its *API* in an `interface` with the same name as the Component. -* exposes its functionality using a concrete `{Component Name}Manager` class (which implements the corresponding API `interface` mentioned in the previous point. +- defines its _API_ in an `interface` with the same name as the Component. +- exposes its functionality using a concrete `{Component Name}Manager` class (which implements the corresponding API `interface` mentioned in the previous point. For example, the `Logic` component (see the class diagram given below) defines its API in the `Logic.java` interface and exposes its functionality using the `LogicManager.java` class which implements the `Logic` interface. @@ -51,7 +74,7 @@ For example, the `Logic` component (see the class diagram given below) defines i **How the architecture components interact with each other** -The *Sequence Diagram* below shows how the components interact with each other for the scenario where the user issues the command `delete 1`. +The _Sequence Diagram_ below shows how the components interact with each other for the scenario where the user issues the command `delete 1`. @@ -70,8 +93,8 @@ The `UI` component uses JavaFx UI framework. The layout of these UI parts are de The `UI` component, -* Executes user commands using the `Logic` component. -* Listens for changes to `Model` data so that the UI can be updated with the modified data. +- Executes user commands using the `Logic` component. +- Listens for changes to `Model` data so that the UI can be updated with the modified data. ### Logic component @@ -101,18 +124,16 @@ Given below is the Sequence Diagram for interactions within the `Logic` componen The `Model`, -* stores a `UserPref` object that represents the user’s preferences. -* stores the address book data. -* exposes an unmodifiable `ObservableList` that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. -* does not depend on any of the other three components. - +- stores a `UserPref` object that represents the user’s preferences. +- stores the address book data. +- exposes an unmodifiable `ObservableList` that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. +- does not depend on any of the other three components.
:information_source: **Note:** An alternative (arguably, a more OOP) model is given below. It has a `Tag` list in the `AddressBook`, which `Person` references. This allows `AddressBook` to only require one `Tag` object per unique `Tag`, instead of each `Person` needing their own `Tag` object.
![BetterModelClassDiagram](images/BetterModelClassDiagram.png)
- ### Storage component ![Structure of the Storage Component](images/StorageClassDiagram.png) @@ -120,14 +141,15 @@ The `Model`, **API** : [`Storage.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/storage/Storage.java) The `Storage` component, -* can save `UserPref` objects in json format and read it back. -* can save the address book data in json format and read it back. + +- can save `UserPref` objects in json format and read it back. +- can save the address book data in json format and read it back. ### Common classes Classes used by multiple components are in the `seedu.addressbook.commons` package. --------------------------------------------------------------------------------------------------------------------- +--- ## **Implementation** @@ -139,9 +161,9 @@ This section describes some noteworthy details on how certain features are imple The proposed undo/redo mechanism is facilitated by `VersionedAddressBook`. It extends `AddressBook` with an undo/redo history, stored internally as an `addressBookStateList` and `currentStatePointer`. Additionally, it implements the following operations: -* `VersionedAddressBook#commit()` — Saves the current address book state in its history. -* `VersionedAddressBook#undo()` — Restores the previous address book state from its history. -* `VersionedAddressBook#redo()` — Restores a previously undone address book state from its history. +- `VersionedAddressBook#commit()` — Saves the current address book state in its history. +- `VersionedAddressBook#undo()` — Restores the previous address book state from its history. +- `VersionedAddressBook#redo()` — Restores a previously undone address book state from its history. These operations are exposed in the `Model` interface as `Model#commitAddressBook()`, `Model#undoAddressBook()` and `Model#redoAddressBook()` respectively. @@ -202,14 +224,15 @@ The following activity diagram summarizes what happens when a user executes a ne ##### Aspect: How undo & redo executes -* **Alternative 1 (current choice):** Saves the entire address book. - * Pros: Easy to implement. - * Cons: May have performance issues in terms of memory usage. +- **Alternative 1 (current choice):** Saves the entire address book. + + - Pros: Easy to implement. + - Cons: May have performance issues in terms of memory usage. -* **Alternative 2:** Individual command knows how to undo/redo by +- **Alternative 2:** Individual command knows how to undo/redo by itself. - * Pros: Will use less memory (e.g. for `delete`, just save the person being deleted). - * Cons: We must ensure that the implementation of each individual command are correct. + - Pros: Will use less memory (e.g. for `delete`, just save the person being deleted). + - Cons: We must ensure that the implementation of each individual command are correct. _{more aspects and alternatives to be added}_ @@ -217,18 +240,17 @@ _{more aspects and alternatives to be added}_ _{Explain here how the data archiving feature will be implemented}_ - --------------------------------------------------------------------------------------------------------------------- +--- ## **Documentation, logging, testing, configuration, dev-ops** -* [Documentation guide](Documentation.md) -* [Testing guide](Testing.md) -* [Logging guide](Logging.md) -* [Configuration guide](Configuration.md) -* [DevOps guide](DevOps.md) +- [Documentation guide](Documentation.md) +- [Testing guide](Testing.md) +- [Logging guide](Logging.md) +- [Configuration guide](Configuration.md) +- [DevOps guide](DevOps.md) --------------------------------------------------------------------------------------------------------------------- +--- ## **Appendix: Requirements** @@ -236,29 +258,30 @@ _{Explain here how the data archiving feature will be implemented}_ **Target user profile**: -* has a need to manage a significant number of contacts -* prefer desktop apps over other types -* can type fast -* prefers typing to mouse interactions -* is reasonably comfortable using CLI apps - -**Value proposition**: manage contacts faster than a typical mouse/GUI driven app +- an OHS admin at a Residential College\* (in NUS) +- has a need to manage a large number of students and rooms (>800) +- dissatisfied with current MS Excel and paper-based workflow +- prefer desktop apps over other types +- can type fast +- prefers typing to mouse interactions +- is reasonably comfortable using CLI apps +**Value proposition**: manage students, room allocations and billing faster than a typical GUI app. ### User stories -Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*` +Priorities: High (must have) - `☆ ☆ ☆`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*` -| Priority | As a …​ | I want to …​ | So that I can…​ | -| -------- | ------------------------------------------ | ------------------------------ | ---------------------------------------------------------------------- | -| `* * *` | new user | see usage instructions | refer to instructions when I forget how to use the App | -| `* * *` | user | add a new person | | -| `* * *` | user | delete a person | remove entries that I no longer need | -| `* * *` | user | find a person by name | locate details of persons without having to go through the entire list | -| `* *` | user | hide private contact details | minimize chance of someone else seeing them by accident | -| `*` | user with many persons in the address book | sort persons by name | locate a person easily | +| Priority | As a …​ | I want to …​ | So that I can…​ | +| -------- | ------------------------------------------ | ---------------------------- | ---------------------------------------------------------------------- | +| `* * *` | new user | see usage instructions | refer to instructions when I forget how to use the App | +| `* * *` | user | add a new person | | +| `* * *` | user | delete a person | remove entries that I no longer need | +| `* * *` | user | find a person by name | locate details of persons without having to go through the entire list | +| `* *` | user | hide private contact details | minimize chance of someone else seeing them by accident | +| `*` | user with many persons in the address book | sort persons by name | locate a person easily | -*{More to be added}* +_{More to be added}_ ### Use cases @@ -277,32 +300,37 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli **Extensions** -* 2a. The list is empty. +- 2a. The list is empty. Use case ends. -* 3a. The given index is invalid. +- 3a. The given index is invalid. - * 3a1. AddressBook shows an error message. + - 3a1. AddressBook shows an error message. - Use case resumes at step 2. + Use case resumes at step 2. -*{More to be added}* +_{More to be added}_ ### Non-Functional Requirements -1. Should work on any _mainstream OS_ as long as it has Java `11` or above installed. -2. Should be able to hold up to 1000 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. - -*{More to be added}* +1. Should work on any _mainstream OS_ as long as it has Java `11` or above installed. +2. Should be simple to pick up for OHS admin (to incentivize them to migrate from Excel+paper-based workflow). +3. Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage. +4. Should automatically backup frequently to avoid loss of sensitive data. +5. 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. +6. The codebase should be maintainable so that developers can easily add new features to the project ### Glossary -* **Mainstream OS**: Windows, Linux, Unix, OS-X -* **Private contact detail**: A contact detail that is not meant to be shared with others +- **Mainstream OS**: Windows, Linux, Unix, OS-X +- **OHS**: Office of Housing Services +- **OHS Admin**: An employee of the OHS who works at a Residential College +- **Residential College**: A university residence for students that offers a 2-year program. +- **Check-in**: Exercise conducted at the beginning of the semester (in Week 0), where a student is informed of his room allocation. +- **Outstanding bill**: A bill due to be paid by a student. --------------------------------------------------------------------------------------------------------------------- +--- ## **Appendix: Instructions for manual testing** @@ -326,7 +354,7 @@ testers are expected to do more *exploratory* testing. 1. Resize the window to an optimum size. Move the window to a different location. Close the window. 1. Re-launch the app by double-clicking the jar file.
- Expected: The most recent window size and location is retained. + Expected: The most recent window size and location is retained. 1. _{ more test cases …​ }_ From c112a409346f25dbfb7706398bd13e3499d50bb5 Mon Sep 17 00:00:00 2001 From: Lysire Date: Sat, 19 Sep 2020 13:47:48 +0800 Subject: [PATCH 011/326] Update user guide to include editting of rooms --- docs/UserGuide.md | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index c585e6726de..2924b88c1f8 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -173,8 +173,26 @@ room A0123456X is allocated room ``` +#### 5. Edit a room allocation for a student -#### 5. Viewing a list of all allocated rooms +A student's room allocation can be edited to update room vacancies. + +##### Command +``` +edit +``` +##### Execution Example +``` +> edit A0123456X 11-109 +``` +*Action*: edits the room allocation for student A0123456X to the specified room number. + +*Output*: +``` +Successfully edited room allocation for student A0123456X to 11-109. +``` + +#### 6. Viewing a list of all allocated rooms The room allocations for all students in the residential college can be viewed to check which room each student stays in. @@ -195,13 +213,14 @@ Here is the list of all room allocations: - John New : 12-107 - Jason New : 13-105 ``` +
### II. Student Management >**ResiReg** allows you to manage students in the Residential College. -#### 6. Adding a student +#### 7. Adding a student A new student can be added to **ResiReg**. The following student details are stored: name, matriculation number, email, faculty and year. ##### Command @@ -235,7 +254,7 @@ add student /name Jet New /matric A0123456X /email jn@u.nus.edu Couldn't add student! The following fields are missing: faculty, year. ``` -#### 7. Listing all students +#### 8. Listing all students All the students currently in **ResiReg** can be listed. ##### Command @@ -321,6 +340,7 @@ Action | Format, Examples *students* | `students` *allocate* | `allocate ` e.g. `allocate A0123456X 10-108` *deallocate* | `deallocate ` e.g. `allocate A0123456X 10-108` +*edit* | `edit ` e.g. `edit A0123456X 10-108` *room* | `room ` e.g. `room A0123456X` *add student* | `add student /name /faculty /year /email ` e.g.`add student /name Jet New /faculty SOC /year 2 /email jn@u.nus.edu` *help* | `help [command]` e.g. `help` or `help list` From 427e87f32cb4e7c04fa7cac564524e49aded91b1 Mon Sep 17 00:00:00 2001 From: Lysire Date: Sat, 19 Sep 2020 14:26:51 +0800 Subject: [PATCH 012/326] update ui mockup --- docs/images/Ui.png | Bin 14607 -> 173357 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/Ui.png b/docs/images/Ui.png index 5bd77847aa2429edac366ebe3e00650b6dd909d8..39da3f3c98555440b843b4bf3111a9dcec75c8ed 100644 GIT binary patch literal 173357 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
R&pi>_jY@b&Dp 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

O%|QGI;e2mv^BSXYEuq{9w7 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 EpL3D-pa1{> literal 14607 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 RAXge19gVx{rMDi1{6Bg4z)AoB From 4a8553c128119eefe8872db5fbbefc8576cc9242 Mon Sep 17 00:00:00 2001 From: Jing Yen Loh Date: Sun, 20 Sep 2020 16:51:05 +0800 Subject: [PATCH 013/326] Update ResiReg User Stories on Developer Guide --- docs/DeveloperGuide.md | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 4829fe43011..6c85c33a0fe 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -249,14 +249,29 @@ _{Explain here how the data archiving feature will be implemented}_ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*` -| Priority | As a …​ | I want to …​ | So that I can…​ | -| -------- | ------------------------------------------ | ------------------------------ | ---------------------------------------------------------------------- | -| `* * *` | new user | see usage instructions | refer to instructions when I forget how to use the App | -| `* * *` | user | add a new person | | -| `* * *` | user | delete a person | remove entries that I no longer need | -| `* * *` | user | find a person by name | locate details of persons without having to go through the entire list | -| `* *` | user | hide private contact details | minimize chance of someone else seeing them by accident | -| `*` | user with many persons in the address book | sort persons by name | locate a person easily | +| Priority | As a… | I can… | So that I can… | +| -------- | ------------------------ | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | +| * * | Meticulous OHS admin | have automatic backups of my data | rest knowing my data will not be accidentally erased. | +| * * | OHS admin | generate audit reports for financial data | comply with internal audits of the Residential College. | +| * * | OHS admin | export records to csv files | easily create mailing lists or send relevant data to other admin. | +| * * * | New/Confused User | check the syntax for a command | do a task even if I am unsure of the command usage. | +| * * * | First Time User | ask for help | quickly and easily learn how to use the application in one place. | +| * * * | OHS Admin | view a list of all students | check which students are in the system and access their particulars. | +| * * * | OHS Admin | so that I can check which students stay in which rooms. | check which students are in the system and access their particulars. | +| * * | As as skeptical GUI user | create aliases to other commands | perform my common actions while typing less. | +| * * | skeptical GUI user | create compound commands | ... e.g. to view bills and pay them at the same time, perform common sequences of actions more quickly. | +| * | OHS admin | find a room by searching for the room number | get the details of a specific room, without getting cluttered by other information. | +| * * | OHS Admin | view a list of rooms filtered by a particular type | select the rooms that needs to be upgraded, for example. | +| * * | OHS admin | delete a bill | remove a erroneously added bill. | +| * * | OHS admin | mark a bill as paid | easily keep track of the remaining amount a student has to pay to OHS. | +| * * | OHS admin | view a list of all students with outstanding bills | remind students of outstanding payments. | +| * * | skeptical GUI user | have autocompletions for a command | quickly and efficiently complete an operation. | +| * * | skeptical GUI user | redo the previous command using a keyboard shortcut | do the same task without typing again, e.g. if two students wish to pay the same bill. | +| * * | Busy OHS Admin | find a student by partial searching for their first name | type quickly without worrying about typos. | +| * * | Skeptical GUI user | undo my last command | fix any change that I made erroneously. | +| * * | skeptical GUI user | view previous commands using a keyboard shortcut | check if I made an error in adding or deleting records. | +| * * | OHS admin | edit the bill amount | ensure that changes in the billing amounts due to changes in university policies can be reflected. | +| * * | OHS admin | view all outstanding bills for a student | inform the student of his/her due bills. | *{More to be added}* From 1109d140c2385c0b9cccbb90eda730e46885356f Mon Sep 17 00:00:00 2001 From: mkeoliya Date: Tue, 22 Sep 2020 00:05:12 +0800 Subject: [PATCH 014/326] Add AboutUs entry and image --- docs/AboutUs.md | 22 +++++-------------- docs/images/mkeoliya.png | Bin 0 -> 872 bytes docs/team/mkeoliya.md | 46 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 16 deletions(-) create mode 100644 docs/images/mkeoliya.png create mode 100644 docs/team/mkeoliya.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index e5b48b5f448..d179c431f50 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -9,25 +9,15 @@ You can reach us at the email `seer[at]comp.nus.edu.sg` ## Project team -### John Doe +### Mayank Keoliya - - -[[homepage](http://www.comp.nus.edu.sg/~damithch)] -[[github](https://github.com/johndoe)] -[[portfolio](team/johndoe.md)] + -* Role: Project Advisor - -### Jane Doe - - +[[github](http://github.com/mkeoliya)] +[[portfolio](team/mkeoliya.md)] -[[github](http://github.com/johndoe)] -[[portfolio](team/johndoe.md)] - -* Role: Team Lead -* Responsibilities: UI +* Role: Developer +* Responsibilities: Scheduling & Tracking, Maintaining Code Quality ### Bec Kyung Huhn (Kevin) diff --git a/docs/images/mkeoliya.png b/docs/images/mkeoliya.png new file mode 100644 index 0000000000000000000000000000000000000000..562891c12b4ae694cf4918229d65cf4e2283c962 GIT binary patch literal 872 zcmeAS@N?(olHy`uVBq!ia0vp^TY&fu2NRGC zB?=Bq>_0qH`ey^spa&esA0F6Sa{w&N=!f>}jx?gU8d1 z5YlRo9xR^715)27X7S^N63B*z#oT;$Q73>xHZnC&P6KHVnVJ?59U@bs0-_USYL1)& z(m66UDW^OR9&}&OqaahW&Tgck)>L=$JOKJ6T>{dxuw@ zh0%i>SB`hB|0EBzvrKW*uaMq(Q+X_o{ffA|>Z*ax1Bpk;Ti1p?-_Wr5ufLeZj1RZD z#BK|GoM^=E}tdw1EFz?2UkCHTVMyaqv!EJ9z4F*A||`7 zU#Yo&cEOGdD)O#u@&yMz%J7BHd=81Wc?TW}1=j+jHm2$Dug$>7I?ihG#_k?aD=^IO zG#$P+`v)+t8=S=-Z+IUDj#dGgUGnX|=3jteJ^$f`XY+vZ_?TIy?9MfyhCSVfo2-8W z!)<%Pjl5!zRaShfKQgvIxDaXa<|w;Nm0%EDMTr>SYjA2UvE Date: Tue, 22 Sep 2020 02:17:06 +0800 Subject: [PATCH 015/326] Add missing user stories --- docs/DeveloperGuide.md | 65 ++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 6c85c33a0fe..31168a81390 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -249,31 +249,46 @@ _{Explain here how the data archiving feature will be implemented}_ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*` -| Priority | As a… | I can… | So that I can… | -| -------- | ------------------------ | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -| * * | Meticulous OHS admin | have automatic backups of my data | rest knowing my data will not be accidentally erased. | -| * * | OHS admin | generate audit reports for financial data | comply with internal audits of the Residential College. | -| * * | OHS admin | export records to csv files | easily create mailing lists or send relevant data to other admin. | -| * * * | New/Confused User | check the syntax for a command | do a task even if I am unsure of the command usage. | -| * * * | First Time User | ask for help | quickly and easily learn how to use the application in one place. | -| * * * | OHS Admin | view a list of all students | check which students are in the system and access their particulars. | -| * * * | OHS Admin | so that I can check which students stay in which rooms. | check which students are in the system and access their particulars. | -| * * | As as skeptical GUI user | create aliases to other commands | perform my common actions while typing less. | -| * * | skeptical GUI user | create compound commands | ... e.g. to view bills and pay them at the same time, perform common sequences of actions more quickly. | -| * | OHS admin | find a room by searching for the room number | get the details of a specific room, without getting cluttered by other information. | -| * * | OHS Admin | view a list of rooms filtered by a particular type | select the rooms that needs to be upgraded, for example. | -| * * | OHS admin | delete a bill | remove a erroneously added bill. | -| * * | OHS admin | mark a bill as paid | easily keep track of the remaining amount a student has to pay to OHS. | -| * * | OHS admin | view a list of all students with outstanding bills | remind students of outstanding payments. | -| * * | skeptical GUI user | have autocompletions for a command | quickly and efficiently complete an operation. | -| * * | skeptical GUI user | redo the previous command using a keyboard shortcut | do the same task without typing again, e.g. if two students wish to pay the same bill. | -| * * | Busy OHS Admin | find a student by partial searching for their first name | type quickly without worrying about typos. | -| * * | Skeptical GUI user | undo my last command | fix any change that I made erroneously. | -| * * | skeptical GUI user | view previous commands using a keyboard shortcut | check if I made an error in adding or deleting records. | -| * * | OHS admin | edit the bill amount | ensure that changes in the billing amounts due to changes in university policies can be reflected. | -| * * | OHS admin | view all outstanding bills for a student | inform the student of his/her due bills. | - -*{More to be added}* +| Priority | As a… | I can… | So that I can… | +| -------- | ------------------------ | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | +| \* \* | Meticulous OHS admin | have automatic backups of my data | rest knowing my data will not be accidentally erased. | +| \* \* | OHS admin | generate audit reports for financial data | comply with internal audits of the Residential College. | +| \* \* | OHS admin | export records to csv files | easily create mailing lists or send relevant data to other admin. | +| \* \* \* | New/Confused User | check the syntax for a command | do a task even if I am unsure of the command usage. | +| \* \* \* | First Time User | ask for help | quickly and easily learn how to use the application in one place. | +| \* \* \* | OHS Admin | view a list of all students | check which students are in the system and access their particulars. | +| \* \* | As as skeptical GUI user | create aliases to other commands | perform my common actions while typing less. | +| \* \* | skeptical GUI user | create compound commands | ... e.g. to view bills and pay them at the same time, perform common sequences of actions more quickly. | +| \* | OHS admin | find a room by searching for the room number | get the details of a specific room, without getting cluttered by other information. | +| \* \* | OHS Admin | view a list of rooms filtered by a particular type | select the rooms that needs to be upgraded, for example. | +| \* \* | OHS admin | delete a bill | remove a erroneously added bill. | +| \* \* | OHS admin | mark a bill as paid | easily keep track of the remaining amount a student has to pay to OHS. | +| \* \* | OHS admin | view a list of all students with outstanding bills | remind students of outstanding payments. | +| \* \* | skeptical GUI user | have autocompletions for a command | quickly and efficiently complete an operation. | +| \* \* | skeptical GUI user | redo the previous command using a keyboard shortcut | do the same task without typing again, e.g. if two students wish to pay the same bill. | +| \* \* | Busy OHS Admin | find a student by partial searching for their first name | type quickly without worrying about typos. | +| \* \* | Skeptical GUI user | undo my last command | fix any change that I made erroneously. | +| \* \* | skeptical GUI user | view previous commands using a keyboard shortcut | check if I made an error in adding or deleting records. | +| \* \* | OHS admin | edit the bill amount | ensure that changes in the billing amounts due to changes in university policies can be reflected. | +| \* \* | OHS admin | view all outstanding bills for a student | inform the student of his/her due bills. | +| \* \* | OHS admin | update a Semester name | correct typos in the semester name. | +| \* \* | OHS admin | add a bill for a student | keep track of a student's bills and finances. | +| \* \* \* | OHS admin | view a list of vacant rooms | start assigning rooms to students before the semester starts. | +| \* \* | OHS admin | archive the current Semester's data | keep the data for auditing purposes, but not hvae it distract me while dealing with the current semester. | +| \* \* \* | OHS admin | view a room allocation for a student | check and inform a student of their room allocation during check in. | +| \* \* \* | OHS admin | allocate a room to a student | allocate a student to a room before the semester starts. | +| \* \* \* | OHS admin | delete a room allocation for a student | update vacancies when a student applies to leave their room. | +| \* \* | OHS admin | add a remark to a bill | record any exceptional details about the bill (e.g. cash-only payment). | +| \* \* | OHS admin | add a new semester | make sure all new bills and allocations are made in the context of the semester. | +| \* \* \* | OHS admin | view a list of all allocated rooms | check which students stay in which rooms. | +| \* \* \* | OHS admin | edit a room allocation for a student | change a student's room allocation and update the room vacancies. | +| \* | OHS admin | edit a room's type | log upgrades like the installation of an aircon. | +| \* \* | OHS admin | export all of the current data to a data-file | hand over my duties to another admin. | +| \* | OHS admin | edit a room's semesterly fees | update room charges when costs increase (e.g. from $1000 to $1500) | +| \* \* | OHS admin | import data from a data file | continue work from where my predecessor left off. | +| \* \* \* | OHS admin | add a student to ResiReg | perform admin duties related to the student. | + +_{More to be added}_ ### Use cases From 75dda0d9dd409cf518810b69340f971189e1b96c Mon Sep 17 00:00:00 2001 From: Jing Yen Loh Date: Tue, 22 Sep 2020 02:35:26 +0800 Subject: [PATCH 016/326] Add AboutUs entry and image --- docs/AboutUs.md | 8 +++---- docs/images/jingyenloh.png | Bin 0 -> 68759 bytes docs/team/jingyenloh.md | 46 +++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 docs/images/jingyenloh.png create mode 100644 docs/team/jingyenloh.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index e5b48b5f448..ad87ec30e48 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -19,12 +19,12 @@ You can reach us at the email `seer[at]comp.nus.edu.sg` * Role: Project Advisor -### Jane Doe +### Loh Jing Yen - + -[[github](http://github.com/johndoe)] -[[portfolio](team/johndoe.md)] +[[github](https://github.com/jingyenloh)] +[[portfolio](team/jingyenloh.md)] * Role: Team Lead * Responsibilities: UI diff --git a/docs/images/jingyenloh.png b/docs/images/jingyenloh.png new file mode 100644 index 0000000000000000000000000000000000000000..47a9f1f22271737663f7a856a4b90c01be61e93b GIT binary patch literal 68759 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 Z4yBQ3N=x2%?gc7k@O1TaS?83{1OU7k8eRYZ literal 0 HcmV?d00001 diff --git a/docs/team/jingyenloh.md b/docs/team/jingyenloh.md new file mode 100644 index 00000000000..5abb102f949 --- /dev/null +++ b/docs/team/jingyenloh.md @@ -0,0 +1,46 @@ +--- +layout: page +title: Loh Jing Yen's Project Portfolio Page +--- + +## Project: AddressBook Level 3 + +AddressBook - Level 3 is a desktop address book application used for teaching Software Engineering principles. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 10 kLoC. + +Given below are my contributions to the project. + +* **New Feature**: Added the ability to undo/redo previous commands. + * What it does: allows the user to undo all previous commands one at a time. Preceding undo commands can be reversed by using the redo command. + * Justification: This feature improves the product significantly because a user can make mistakes in commands and the app should provide a convenient way to rectify them. + * Highlights: This enhancement affects existing commands and commands to be added in future. It required an in-depth analysis of design alternatives. The implementation too was challenging as it required changes to existing commands. + * Credits: *{mention here if you reused any code/ideas from elsewhere or if a third-party library is heavily used in the feature so that a reader can make a more accurate judgement of how much effort went into the feature}* + +* **New Feature**: Added a history command that allows the user to navigate to previous commands using up/down keys. + +* **Code contributed**: [RepoSense link]() + +* **Project management**: + * Managed releases `v1.3` - `v1.5rc` (3 releases) on GitHub + +* **Enhancements to existing features**: + * Updated the GUI color scheme (Pull requests [\#33](), [\#34]()) + * Wrote additional tests for existing features to increase coverage from 88% to 92% (Pull requests [\#36](), [\#38]()) + +* **Documentation**: + * User Guide: + * Added documentation for the features `delete` and `find` [\#72]() + * Did cosmetic tweaks to existing documentation of features `clear`, `exit`: [\#74]() + * Developer Guide: + * Added implementation details of the `delete` feature. + +* **Community**: + * PRs reviewed (with non-trivial review comments): [\#12](), [\#32](), [\#19](), [\#42]() + * Contributed to forum discussions (examples: [1](), [2](), [3](), [4]()) + * Reported bugs and suggestions for other teams in the class (examples: [1](), [2](), [3]()) + * Some parts of the history feature I added was adopted by several other class mates ([1](), [2]()) + +* **Tools**: + * Integrated a third party library (Natty) to the project ([\#42]()) + * Integrated a new Github plugin (CircleCI) to the team repo + +* _{you can add/remove categories in the list above}_ From 8a142b47da4461dbcc606395c2a39698d02e441f Mon Sep 17 00:00:00 2001 From: chloelee767 Date: Tue, 22 Sep 2020 10:05:22 +0800 Subject: [PATCH 017/326] Add use cases for v1.2 --- docs/DeveloperGuide.md | 119 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 108 insertions(+), 11 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 4829fe43011..5fa307875fe 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -262,32 +262,129 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli ### Use cases -(For all use cases below, the **System** is the `AddressBook` and the **Actor** is the `user`, unless specified otherwise) +(For all use cases below, the **System** is `ResiReg` and the **Actor** an `OHS admin`, unless specified otherwise) -**Use case: Delete a person** +#### Use case: UC01 - Add a student **MSS** -1. User requests to list persons -2. AddressBook shows a list of persons -3. User requests to delete a specific person in the list -4. AddressBook deletes the person +1. OHS admin requests to add a student and supplies student details. +1. ResiReg adds the student and saves the changes. - Use case ends. +Use case ends. **Extensions** -* 2a. The list is empty. +- 1a. Student details are missing or invalid, or there is already a student with the same matriculation number. + - ResiReg shows an error message. + + Use case starts over. + +#### Use case: UC02 - Delete a student + +**MSS** + +1. OHS admin requests to list students. +1. ResiReg shows a list of students. +1. OHS admin requests to delete a specified student from the list. +1. ResiReg deletes the specified student and saves the changes. + +Use case ends. +**Extensions** + +- 1a. The list of students is empty. + Use case ends. + +- 3a. The specified student does not exist. + - ResiReg shows an error message. + + Use case resumes at step 2. + +#### Use case: UC03 - Edit a student + +**MSS** + +1. OHS admin requests to list students. +1. ResiReg shows a list of students. +1. OHS admin requests to edit a specific student from the list and supplies details to edit. +1. ResiReg edits the student and saves the changes. -* 3a. The given index is invalid. +Use case ends. + +**Extensions** + +- 1a. The list of students is empty. + + Use case ends. + +- 3a. The specified student does not exist or the supplied details are invalid. + - ResiReg shows an error message. + + Use case resumes at step 2. + +#### Use case: UC04 - Allocate a room to a student + +**MSS** + +1. OHS admin requests to list students without a room allocation and list vacant rooms. +1. ResiReg shows a list of students without a room allocation and a list of vacant rooms. +1. OHS admin requests to allocate a particular student to a particular room. +1. ResiReg adds the room allocation and saves the changes. + +Use case ends. + +**Extensions** - * 3a1. AddressBook shows an error message. +- 3a. Student belongs to an existing room allocation, room belongs to an existing room allocation, room does not exist or student does not exist. + - ResiReg shows an error message. Use case resumes at step 2. -*{More to be added}* +#### Use case: UC05 - Delete a room allocation for a student + +**MSS** + +1. OHS admin requests to list room allocations. +1. ResiReg shows a list of room allocations. +1. OHS admin requests to delete a specific room allocation. +1. ResiReg removes the room allocation and saves the changes. The room and student are not modified. + + Use case ends. + +**Extensions** + +- 1a. The list of room allocations is empty. + + Use case ends. + +- 3a. Room allocation does not exist. + - ResiReg shows an error message. + + Use case resumes at step 2. + +#### Use case: UC06 - Edit an existing room allocation + +**MSS** + +1. OHS admin requests to list room allocations. +1. ResiReg shows a list of room allocations. +1. OHS admin requests to edit a specific room allocation from the list and supplies details to update. +1. ResiReg updates the room allocation and saves the changes. + +Use case ends. + +**Extensions** + +- 1a. The list of room allocations is empty. + + Use case ends. + +- 3a. Room allocation does not exist or details supplied are invalid. + - ResiReg shows an error message. + + Use case resumes at step 2. ### Non-Functional Requirements From d5dc52ad78491f0196a6c8a427c6d504eb86c55f Mon Sep 17 00:00:00 2001 From: Jing Yen Loh Date: Tue, 22 Sep 2020 20:35:44 +0800 Subject: [PATCH 018/326] Add #58 and #59, remove compound commands --- docs/DeveloperGuide.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 31168a81390..ca067e29660 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -258,7 +258,6 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli | \* \* \* | First Time User | ask for help | quickly and easily learn how to use the application in one place. | | \* \* \* | OHS Admin | view a list of all students | check which students are in the system and access their particulars. | | \* \* | As as skeptical GUI user | create aliases to other commands | perform my common actions while typing less. | -| \* \* | skeptical GUI user | create compound commands | ... e.g. to view bills and pay them at the same time, perform common sequences of actions more quickly. | | \* | OHS admin | find a room by searching for the room number | get the details of a specific room, without getting cluttered by other information. | | \* \* | OHS Admin | view a list of rooms filtered by a particular type | select the rooms that needs to be upgraded, for example. | | \* \* | OHS admin | delete a bill | remove a erroneously added bill. | @@ -287,6 +286,8 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli | \* | OHS admin | edit a room's semesterly fees | update room charges when costs increase (e.g. from $1000 to $1500) | | \* \* | OHS admin | import data from a data file | continue work from where my predecessor left off. | | \* \* \* | OHS admin | add a student to ResiReg | perform admin duties related to the student. | +| \* \* \* | OHS admin | edit the details of an existing student | easily correct any typos and update the student details in response to changes (e.g. faculty). | +| \* \* \* | OHS admin | delete a student | so that I can remove an erroneously added student. | _{More to be added}_ From ac4714601b9c6cf81b95b4431f70b0c91cea7e15 Mon Sep 17 00:00:00 2001 From: chloelee767 Date: Tue, 22 Sep 2020 21:47:29 +0800 Subject: [PATCH 019/326] Update personal details and image in AboutUs --- docs/AboutUs.md | 11 +++++------ docs/images/chloelee767.png | Bin 0 -> 1961 bytes 2 files changed, 5 insertions(+), 6 deletions(-) create mode 100644 docs/images/chloelee767.png diff --git a/docs/AboutUs.md b/docs/AboutUs.md index e5b48b5f448..028aa0d2c80 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -48,12 +48,11 @@ You can reach us at the email `seer[at]comp.nus.edu.sg` * Role: Developer * Responsibilities: Dev Ops + Threading -### James Doe +### Chloe Lee Ke Er - + -[[github](http://github.com/johndoe)] -[[portfolio](team/johndoe.md)] +[[github](http://github.com/chloelee767)] -* Role: Developer -* Responsibilities: UI +* Role: Developer, Git Expert +* Responsibilities: Testing diff --git a/docs/images/chloelee767.png b/docs/images/chloelee767.png new file mode 100644 index 0000000000000000000000000000000000000000..1ce7ce16dc8717e182da5f82fe0f7ee9c34137bf GIT binary patch literal 1961 zcmb_deN<9+7`~;Z35JG^)TU((oNJ2A)YREBP%I+UW}kiwI`WWHBi#lhmd+GCe#_84 z{HUR6Xk}rkX^V^$GabqNDs@i$C=)|P)LnC)`eWy8=WO@h=Y8+{ywC6Vo_n8j&rKo` z-Su>hbpZg-^T1=hz$^oRRe+8L7@1q(aUiiO%FEpqsE}-ugN0`3?)|#~pfU}j4%7nc z&q;)XxXH;$g+lT6?c3?;>Dk%Yxw$#DT0K8Mzp${dxVShoGcz?crBo_aDiyfmyVX)2 zm|)RfL~pSB!2xu1=UoO{Ya{SSq5uG4u!L1&q+%BUtQqmZ?migfH{R72+2sJ$dRnJk zWZm(J9_zFv8?49f`}o4+@Mf$hs$IxKC z6Fb!Y)#@<`m;2070TX`)-PJbJGz=++K|iuZ7=2$<`%8z(xK@HC6r7DFg*c2 zz{yNY=VZdxr)Dgj>)^2UD_E)0(tGZ+_1i$Pezz!<5_C-V3?Jt7{Zaf_@N>(7IoWhv z!?qkNbe4F8Jrt-qzEh%JK#hFuW}0QP_Unx?qzbe^G{sahf-s2%$tfk3)e?ev@(Dt5 zm8yVgb+=EBx^b_V*P_gz*>&x!k%e2!DK~2Wkzi~*+QX#OF!Uavp${U^tZnMc(faNe z4r5vMtx7J(^8Ov361zquN|jYB^K->kSlLV2*xKyn+Gdzi?B;xgjCHI zFfGgaQzz?qa z11!k2zZwx#mx~iwJ#6Rwc>IiZ;*S@&xwL?Wov{OSWq!(|@eo;3%;D9L1C2#hohn9e zW>delA}=I|m7ciie%#47=l3|g`M5Vi-@Wd>#=1e$$qF+uzpmRQFW7e{1O4c`$k_k9gd0DB2oqEc7555=IwjJCW> zKUI4jeIOj%dEnK{{L#n1$M2Npb|prZ+CPU4l31_IMBI}T?0ARCPfWiBwCf%@Rmm27 zdo#o%*A@A;(hF=<2C9hAq?oP>~x z7nC5xi-z)ItA Date: Thu, 24 Sep 2020 22:07:19 +0800 Subject: [PATCH 020/326] Update to match ResiReg specs --- README.md | 38 +++++++++++++++++++++++++------------- docs/ContactUs.md | 8 ++++++++ docs/UserGuide.md | 41 +++++++++-------------------------------- docs/index.md | 31 +++++++++++++++++++++++-------- 4 files changed, 65 insertions(+), 53 deletions(-) create mode 100644 docs/ContactUs.md diff --git a/README.md b/README.md index 04edcc7906f..0006f4400e2 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,28 @@ ![Ui](docs/images/Ui.png) -* ResiReg is a project built for the CS2103 module at NUS. ResiReg is a housing management application for residential administration staff, such as admin working at NUS Residential Colleges.
- Example usages: - * to manage records of students and rooms - * to allocate and deallocate students to rooms - * to generate bills and record payments - * to manage students serving SHN notice - * to generate reports for half-yearly audits of the admin staff -* The project simulates an ongoing software project for a desktop application (called _AddressBook_), originally used for managing contact details. - * It is **written in OOP fashion**. It provides a **reasonably well-written** code base **bigger** (around 6 KLoC) than what students usually write in beginner-level SE modules, without being overwhelmingly big. - * It comes with a **reasonable level of user and developer documentation**. -* It is named `ResiReg` because it provides functionality for "__Res__idential __Reg__ulation" of dorms at a university. -* For the detailed documentation of this project, see the **[ResiReg Product Website](https://ay2021s1-cs2103-t16-3.github.io/tp)**. -* This project is a **part of the se-education.org** initiative. If you would like to contribute code to this project, see [se-education.org](https://se-education.org#https://se-education.org/#contributing) for more info. +**ResiReg** (**Res**idential **Reg**ulation) is a productivity app designed to help admin staff at Residential Colleges (RCs)* in NUS with their daily tasks. ResiReg allows admin to allocate rooms to students, manage students records, generate billing and OHS reports, and export CSVs for easy reference and sharing. + +**ResiReg** has the following main features: + +* Manage records of students. +* Manage allocations of students to rooms in the College +* Generate bills and log payments for RC-related services. +* Export records of students, rooms or transactions to CSV files for easy reference and sharing. + +Our application is geared towards users who prefer typing over mouse actions, so interactions with our application is mainly keyboard based. + +## Site Map + + * [User Guide](docs/UserGuide.md) + * [Developer Guide](docs/DeveloperGuide.md) + * [About Us](docs/AboutUs.md) + * [Contact Us](docs/ContactUs.md) + +## Acknowledgements + + * This project is a based off the AddressBook-Level3 project, created by SE-EDU initiative at https://se-education.org + * Some parts of this sample application were inspired by the excellent http://code.makery.ch/library/javafx-8-tutorial/[Java FX tutorial] by _Marco Jakob_. + * Libraries used: [JavaFX](https://openjfx.io/), [Jackson](https://github.com/FasterXML/jackson), [JUnit5](https://github.com/junit-team/junit5) + +## License : [MIT](LICENSE) \ No newline at end of file diff --git a/docs/ContactUs.md b/docs/ContactUs.md new file mode 100644 index 00000000000..6af2c4b3e56 --- /dev/null +++ b/docs/ContactUs.md @@ -0,0 +1,8 @@ +--- +layout: page +title: Contact Us +--- + +* *Bug reports, Suggestions* : Post in our [issue tracker](https://github.com/AY2021S1-CS2103-T16-3/tp) if you noticed bugs or have suggestions on how to improve. +* *Contributing* : We welcome pull requests. Follow the process described [here](https://github.com/oss-generic/process) +* *Email us* : You can also reach us at `ljy@u.nus.edu`, `mayank@u.nus.edu`, `bec.kyung.huhn@u.nus.edu`, `jnew@u.nus.edu` or `chloe.lee@u.nus.edu`. \ No newline at end of file diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 27aca121d8b..9e43c7d4619 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -7,44 +7,21 @@ title: User Guide {:toc} ## Introduction -__ResiReg__ is a Residential College management application that helps residential admins (from the Office of Housing Services) with their daily tasks. __ResiReg__ allows admin to deal with allocating rooms to students, billing, generating OHS reports, and even managing the COVID-19 situation in residences. - -__ResiReg__ has the following main features: -1. View a list of vacant rooms in the College, filtered by COVID-19 zoning if needed. -2. Allocate or deallocate students to vacant rooms in the College when the semester begins, depending on: - - year of study - - faculty - - major - - room type. -3. View a list of current room allocations, where each allocation includes room number, student name, room type, and date of check-in. -4. Add attributes of students staying in the College, including their room allocated, student name, matric number, faculty, year of study, etc. +**ResiReg** (**Res**idential **Reg**ulation) is a productivity app designed to help admin staff at Residential Colleges (RCs)* in NUS with their daily tasks. ResiReg allows admin to allocate rooms to students, manage students records, generate billing and OHS reports, and export CSVs for easy reference and sharing. + + **ResiReg** has the following main features: + + * Manage records of students. + * Manage allocations of students to rooms in the College + * Generate bills and log payments for RC-related services. + * Export records of students, rooms or transactions to CSV files for easy reference and sharing. __ResiReg__ is optimised for OHS who are fast typists who are used to MS Excel, and prefer typing over other means of input. It comes with: - A Command Line Interface (CLI) which allows you to access all __ResiReg__ features by typing. - A Graphical User Interface (GUI) that displays the information you need in a grid format. > __ResiReg__ is currently a work in progress. Here is a low-fidelity mockup of its skeleton. Stay tuned for our progress! -![](https://i.imgur.com/uqEO8Lp.png) - - - - - - +![](images/Ui.png) ## About this Guide ### Basic Information diff --git a/docs/index.md b/docs/index.md index 7601dbaad0d..674ee14c3fc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,19 +1,34 @@ --- layout: page -title: AddressBook Level-3 +title: ResiReg --- [![CI Status](https://github.com/se-edu/addressbook-level3/workflows/Java%20CI/badge.svg)](https://github.com/se-edu/addressbook-level3/actions) -[![codecov](https://codecov.io/gh/se-edu/addressbook-level3/branch/master/graph/badge.svg)](https://codecov.io/gh/se-edu/addressbook-level3) -![Ui](images/Ui.png) +![Ui](docs/images/Ui.png) -**AddressBook is a desktop application for managing your contact details.** While it has a GUI, most of the user interactions happen using a CLI (Command Line Interface). +**ResiReg** (**Res**idential **Reg**ulation) is a productivity app designed to help admin staff at Residential Colleges (RCs)* in NUS with their daily tasks. ResiReg allows admin to allocate rooms to students, manage students records, generate billing and OHS reports, and export CSVs for easy reference and sharing. -* If you are interested in using AddressBook, head over to the [_Quick Start_ section of the **User Guide**](UserGuide.html#quick-start). -* If you are interested about developing AddressBook, the [**Developer Guide**](DeveloperGuide.html) is a good place to start. +**ResiReg** has the following main features: +* Manage records of students. +* Manage allocations of students to rooms in the College +* Generate bills and log payments for RC-related services. +* Export records of students, rooms or transactions to CSV files for easy reference and sharing. -**Acknowledgements** +Our application is geared towards users who prefer typing over mouse actions, so interactions with our application is mainly keyboard based. -* Libraries used: [JavaFX](https://openjfx.io/), [Jackson](https://github.com/FasterXML/jackson), [JUnit5](https://github.com/junit-team/junit5) +## Site Map + + * [User Guide](docs/UserGuide.md) + * [Developer Guide](docs/DeveloperGuide.md) + * [About Us](docs/AboutUs.md) + * [Contact Us](docs/ContactUs.md) + +## Acknowledgements + + * This project is a based off the AddressBook-Level3 project, created by SE-EDU initiative at https://se-education.org + * Some parts of this sample application were inspired by the excellent http://code.makery.ch/library/javafx-8-tutorial/[Java FX tutorial] by _Marco Jakob_. + * Libraries used: [JavaFX](https://openjfx.io/), [Jackson](https://github.com/FasterXML/jackson), [JUnit5](https://github.com/junit-team/junit5) + +## License : [MIT](LICENSE) \ No newline at end of file From 4ce975e7849751400842d7ca84b138846a65a563 Mon Sep 17 00:00:00 2001 From: mkeoliya Date: Thu, 24 Sep 2020 22:10:33 +0800 Subject: [PATCH 021/326] Remove COVID reference --- README.md | 2 +- docs/ContactUs.md | 2 +- docs/UserGuide.md | 19 ------------------- docs/index.md | 2 +- 4 files changed, 3 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 0006f4400e2..d9be91ad54c 100644 --- a/README.md +++ b/README.md @@ -26,4 +26,4 @@ Our application is geared towards users who prefer typing over mouse actions, so * Some parts of this sample application were inspired by the excellent http://code.makery.ch/library/javafx-8-tutorial/[Java FX tutorial] by _Marco Jakob_. * Libraries used: [JavaFX](https://openjfx.io/), [Jackson](https://github.com/FasterXML/jackson), [JUnit5](https://github.com/junit-team/junit5) -## License : [MIT](LICENSE) \ No newline at end of file +## License : [MIT](LICENSE) diff --git a/docs/ContactUs.md b/docs/ContactUs.md index 6af2c4b3e56..dfa16790f32 100644 --- a/docs/ContactUs.md +++ b/docs/ContactUs.md @@ -5,4 +5,4 @@ title: Contact Us * *Bug reports, Suggestions* : Post in our [issue tracker](https://github.com/AY2021S1-CS2103-T16-3/tp) if you noticed bugs or have suggestions on how to improve. * *Contributing* : We welcome pull requests. Follow the process described [here](https://github.com/oss-generic/process) -* *Email us* : You can also reach us at `ljy@u.nus.edu`, `mayank@u.nus.edu`, `bec.kyung.huhn@u.nus.edu`, `jnew@u.nus.edu` or `chloe.lee@u.nus.edu`. \ No newline at end of file +* *Email us* : You can also reach us at `ljy@u.nus.edu`, `mayank@u.nus.edu`, `bec.kyung.huhn@u.nus.edu`, `jnew@u.nus.edu` or `chloe.lee@u.nus.edu`. diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 9e43c7d4619..853f02ca1b6 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -71,25 +71,6 @@ rooms *Output*: The Output panel on the right should display all rooms, along with their details such as vacancy in the Residential College. - #### 2. Allocating a room to a student diff --git a/docs/index.md b/docs/index.md index 674ee14c3fc..a0b6f8cb266 100644 --- a/docs/index.md +++ b/docs/index.md @@ -31,4 +31,4 @@ Our application is geared towards users who prefer typing over mouse actions, so * Some parts of this sample application were inspired by the excellent http://code.makery.ch/library/javafx-8-tutorial/[Java FX tutorial] by _Marco Jakob_. * Libraries used: [JavaFX](https://openjfx.io/), [Jackson](https://github.com/FasterXML/jackson), [JUnit5](https://github.com/junit-team/junit5) -## License : [MIT](LICENSE) \ No newline at end of file +## License : [MIT](LICENSE) From 3306c44f90853ae4a8a16cc8ba31b4bb26a68433 Mon Sep 17 00:00:00 2001 From: jetnew Date: Thu, 24 Sep 2020 22:37:20 +0800 Subject: [PATCH 022/326] Add AboutUs entry and image --- docs/AboutUs.md | 12 +++++------ docs/images/jetnew.png | Bin 0 -> 103010 bytes docs/images/johndoe.png | Bin 1961 -> 0 bytes docs/team/jetnew.md | 46 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 docs/images/jetnew.png delete mode 100644 docs/images/johndoe.png create mode 100644 docs/team/jetnew.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 12a13c11dc1..cba770af1ea 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -38,15 +38,15 @@ You can reach us at the email `seer[at]comp.nus.edu.sg` * Role: Developer, IntelliJ Expert * Responsibilities: Deliverables and Deadlines -### Jean Doe +### New Jun Jie (Jet) - + -[[github](http://github.com/johndoe)] -[[portfolio](team/johndoe.md)] +[[github](http://github.com/jetnew)] +[[portfolio](team/jetnew.md)] -* Role: Developer -* Responsibilities: Dev Ops + Threading +* Role: Developer, Intellij +* Responsibilities: Documentation ### Chloe Lee Ke Er diff --git a/docs/images/jetnew.png b/docs/images/jetnew.png new file mode 100644 index 0000000000000000000000000000000000000000..36582b6b1495b42b868edfb2bb2ed510359ace25 GIT binary patch literal 103010 zcmbTed0bNI|2_;DTDVktaBXoVuyjOm&!QAW6ctcYvc|AXNX@0JtY*;C^0?%JrnscY z;*zDMrY$pOqGe%<%a~eYS~gkMv`^D4&rS20&-eTL{q;PLzD_`%i2I!Pa$VQ^y8V0N z?-|4jI@OPgKq8Td!{8h7_Y}e#u~bu2OB20ROG|6nvZWXuNLNQ&TgOD-U^%qfbnTke zrmI$&TidTQx7=X0Y8BpyB9YdvbN6y{+-UDaa#X(wa@n$FI@&tMy1K@W7ON~A z|382I-HlkeRHGY>&_G%uP%DudE0KTqBGw`hNHqAg>JR*%FCm*W{yuP9F(&e`Hjw_vAS9@;tD*F0w-x*MijE;@}H1S~a z@$B4_r}NK#dA{)G?Ys9MK7RV`^Y7|)A;CKT{rYEN|JS-!f_0&mEYVn^rCt{jbqE|9 zE0>@xh?@Fam|DA%3@jbfmqJ?$Yg=zFvvOknisdE`V+^fHk8R$lm-cmK|L+!-@&9XO z|6SPstZNdXqk#lBPh%xwGvX!M4HGMe-w!e=ZU-e&2!S~a4F_R2L@V6b5L;nx4SkSd z(p1sb&{G+lJnCT0Nd%87Rm8c<3>WFlG*w$+_@0BpzZ78S2A?qeBj>RB*goFv$+eD9tEPe}+od-w54xX}U{V zbuFYMp{0+)4jLzQM~)m~hpS>v3erT8Y@^rgcM9UlmU@vinrT{}UFaY?(6DN@>DqYf zHm72(xX^8BDL--=?-%bN%|sJ4I{1d}q{ZM2dvFdzygqS^BDSz%UT8U8`E~#cbKebHCC}=1p7j=J711$7diO_-b}(P?66x6ATC&FN#9BF zSyV0?iGS{YCXGm5Mn~hJ8G;K!EY!oJs$gZS%zTwbWV!+qOh_U_7ZBj4BE%(q z5R+n#!HWeLCK;M(w-c~S1%w`H$;z-wkCCuyTN7IHs*u`7B3;*;qA1do@3j=`28Gqf zw)G!Ux}lD;G(^={og-NNRA;!0t4yTC^>i`e!F)%#Wn1&DBt_y_$zUU2ar=^%v*Rf3 z@O-sy6784M?--<*q6~qGHB64A6L6$< zhRJA6*kcIA^i3lmSVvXE|y4oe6=f4;2W(I|Lh= zQ9L2jB}0?JJYDX9$mH2SavVPd8?9k|26Y+%$1Wml_z6l zF(;_&cb|@<dd#J`{+^myH@bTU-2#2DnCX#i#$l1L>?NV>&yI>C69 z5Mysau``!rDCUqjJrGsWC%_=2sIypCB%TD8eSrwhp5i4@x?>34tT$9%Bm%SZeYseg zdk|G5G&R=Ktkk9I;+=JM4)b@6-lXGOM%L)ka*6|(VHP_nd)MvWr|aMG@o~43cZ*xM zDsPqY&F<@JAJT1mq?ZJ44P&TWB)t;;ZhaPOe@Y{fw#8or{#%`ZVUWZO z4I@&UfHj1gFBslZ6UDR&lqO~|OW4cDf7vRH7b;}$w02UOA6 z!*UFFHC~VUq=z5Z-hmb0m;|<>Ywf`R^;j&CTDECXY!uT3)^dp#q$7aCz z`;dLWnOGh6j;$I9$t z?q1ULN2$bFY;ihPDlR(#dV>>K`V4_AO8?WKbfmETtP znuY8h(nY1epmERK2m%$RJEXN2A&1F?1zR(M#T~X!BA>)*HJxv*aL)K<``uifvEM3- z6)`@i;IZ}`uYFm~`2&Z(A>Z33sx;->PqSZSZLccaIt)8e`Sca4DE8%l?w$JnY5pgs z5O|5WOq+uG8ep1Wjj=1hp+smF!A_#BZiRs;0bypFJf(~b)~!GUPavQfkWL}F!5~jS z?LdIKHyi{Z9tUz_<;!odG!z@z=#3$*0y*f}n8JMM@h6_Rl0eL72Vsrna4Bgc3kE;P zA};W^Fq=1q-9EEoxerwEs;Jn@ytL+@WbYg&I zCd!_yRt9$|_b-VitmvxeNSzI~`K-(>H(+rqdBp8LS&r~`c!lTb1n>vMOwt8aJCZe< zBNzgeOFEw;;KIb$bhNnvR0E1G*%)FfAp{pDP%LV}-4JI8*qJt{0yLf^Y&&TOfh6+w z3#@|#^gu#ltin?eOd!jV^cfe>c=4QV#sXG)pf=r5dYg+3Vv;$9Ve&E_s+pEUZwd-^ z7E0ocGvI2Xs)%%_sbI_P3u(ozZC1(q4u4vyh}&Wux+--0;hx!x7Tp&&oqv_e&O8Nk z$h?%uXJim9HM=Mf8zIge79sF;q!^IygcPzS&k5x4qxXoe8q;{&A&VZE?nFbKB~7c? z$Om<#Ne&`XHDB&e))vv}Y?_`MONG&TbTMEaptJ&ZmTh=XC4N?jBro0c!HtCsgaqh~ zEF>L|?5S+aDB)92!CxD16sqLA#nlZwV!pZ&CrXGEJiv0bdCQ?U0i5JNCrceEayUvI zZrw@#3{9bFKy2c3iuntFvI1g(B#2c)!6+sOEpYLIk$&I_h5!6X9CNjDg*oB^M8!LpWWj^?w+quRgM{$K8K0Ln*1Dh zX{rn}PIMHechyga$J?@n<=P>3tjkA7saG4J)=;yMA&+*B|;@mIlj|%=?AC6?g2>L-BNMd6yj8|ApB7K4&$m8b{%Fp=6(N{ua2)U=F(j8vP}!Yr(T(OZYW|v65r3+*H((6PZl= z<-{Jr`wz}5C3e2U;G&|`JJi&Z)};}#G*Mic7afjj?M%850RBVh!GK)@qMN2t86 z8hel2(IYjc=w#4B6JnLfq!fQqEGgJ%HN^&(M2<|2Rr+47)HT%3SDMJ?^G4BwR3Y2< zksR|rKPe1!!%7bo2q;1>(j5<5r_$ zArFg-(#dE$kSY>sjSBhS0{l;NS2y^tM}X=p5&3Vl{Tp@vJ`yu6#JMVLPp&Ga{AyXn zn!a)om7gaP`M58C$h^!pSy-3W+4JPxa?s44=YB9FI$t;6J->dllD4xf#ji39wszNW z#YQ}mav9`-eX%}+aoM7}=%78MKI03gCA)CczH~Y-cLJN_6t|6kelaMfK779YWWbZY zR+)&+XfCp7W!ONWnLTi1+K8Z`%L*@_&1EK<_yelb-)@9#YXkk?ULy%$uR17FbEK65 zT>xMJbjvMa1`zWE8PbQ^FdW1de>JYDYep4l`+-hb6Vd??*yLfTQ}TqAl_|Fc?~UcV z!!&-gn;lKRx=A$1wkLM>(o6KK3rB{D5%ic=fhG4`M|F14GSQuT!#*eWxU<^!MpJ4zhO!u@Z}B`Rq@Q1Iggx09Iq9&{N~3)vUWyWq zGp2{vgK_}c2ZT_mkbx360ZG^?ty!YLi*skw^LGlnWHGrzs8_Oin7%~uFyM}KbJ~f( zo;c9JyJT-;TV2;)BX!Br{fC%QolWCaqL|0j*p`viS4B!jO#Op~`s~}^z2ZI2dek0T zsrSKP8vP5u#O3zE4Lf+KPxYoVdLOpDy8NiA?MZce8~#dHWup*~Tdjw3%=1?7Ot*s| z`Wir_5>C8kpOxZ>J=FxzQxV`0SE3PkIUEbkfFOn5Fw~D2!d(W4-9EQqJS3LpVE|8I z!CArTe^HaHeq|+r7ZsF(v)?3WtT^fShEhw zYJ!|rUmuN|ujJ#Jm_A*)(+sPavu?6hB@fFrv--=H9tJhGi+AfziCjVkGD?IAO2IwN+pikTTF{3h21gf zaJ_*e{3cNZ>w;FxJqtw^qU{L)8`-0{xvbgTqpZ$8)$G|dqwLO;Ae0q0MtC9>)I=jB zU>P}rNx~>-6aa#*09QqTuY)?38e1_SZrOr{xKuT%jYUZT=-~Iye+pysCFuqDn6(#|`_C+aCMT3A*NWA`adduxJW89N=@48nn0=Am{b! z8kZok$G5oash=tBUlAtqcRi3ign7G|mxBwsvb9HCLnzNfZ!CQFo5yM9&4lRu_L}i? z_5071dl5g=IE}CS(>6}JYgCqXEz;Mn=3lAw;=7(38f%O%TCkj=+v3h%bY{vv)$dIG z&}$TEmLM%P|QAp2I3#R7GG7FJEbci=9o+`Ck zU!z$70yFA=_3?iz>c5X_AwsPKkkJ-W$>ub{%BvyzDQt&&W!o%cVbFp1V>W1dl5x-sm-+keQfNL#=+0h)OwR9S*6Z8;`s;l z6Cpt$|#T@%+(Y`&Xu;bOtVbCBM|9xEz?W@8@c5c-~|7##dq?c zJt5K?z?k3apcI|l;XnnBFug<~2f9^f)(lGpw5d*Y9@MbX>2qdqFkwOpRhSw;VgcbM zf4lJz;U@1UZvZrVYfRe*dSP(&m?I^EUYnG8o2eU^UCgrHIkwB<OjU3^1R%}HjU!nmQ! z4^e{&#w*a)#x;Nl8kb3B&!F*wV7;)lA}8kOj5;0y8jaASwO+>rIi!ubR6G*x`P3LP zWix8mCN5Kb8QbysHFZH6a5lJge(w#lg&!8SeuzBzuJi=FzZ^bsuRkrwf%#G~7%<59 z>UTDyBkD!RLaAla;LBGF9I%uNUJIMsOov%931X5-f3xf1)h{;RUw328kq?a_<@Sx= zY^*s{zvlb2MwJ2Mj&qWnYr}e?bpIfE=T|R~HbeSW<*kQWB>*!u`e8olrvu#1?gU~| z62*KTC=3;WSgpi2bRhMZmS%0LY`Yn#St2+rg~sHV(yWbag#$a&qLb@OJ6k#_?% zML=56i3ZdO8p)*fV?a%&+eY|g2-y_(@1EC3ufju^!`Ka$pgXB0HE^XA_IL?OeHA4d zyq+SUG)l#4_LNbYp7|d*`VTBEmjaRw==fKF{@?Qb-_orv)#R@T1uri6C-Q5CRb`RX z=fUoZfH94c?8@>bXW+)yA`$1pEzxsXF0Pkd%tDIzb^$qx?Wr~^Unf|mO zmiIW3@EfY^9-^+i)p=L`V@gO7=YZ;8I zf#eEtD`P=x$wCe2<%un2;?mNR zUYF9+(i|a9ErNN4Nn1}h1^Fo5^<_TipL!Y@PjmaLN1vP?I~g$AuzHtmR;!F!_$Ex> zBh5D~I=^cn#KR(h>m8=QmS1AkQ0TB;bWra!+ltmm31D|i6;V$fToniaRU;S{0P04? zYom>UMuj0r1u~N0koe}kLLBe>#A_z0M|`BuV+`N1*EU<<&qYhKiFEx#z4f_u%|6!3 z{g|{>Z|fu95lr5NdaGW~HGg|~-K74jPqNnvA61%Z%v*H_-H=fC{c3(^^ozhd{Tz3V zvWo8r&30Sw=YKGBb_N+yC37|l;IAHiI3|{zKDdm-rBDYMt|V?V#WJ$Ozo6CJ1i-CHqBa7MX4=jTaP}_J4}FgZNBOE(@@dInw{I z_yQt)C%M1LjtKh_Y;pXg%-$z7)hGkU$L&wc6LsV{5d!?ooFhLp ztiCMDJmWmPw2bak(J6BpJ=);J!IyWPRx(@f$el^!g<%%g@&JyMH2Gx1@tcYoXSo1v z3{!eHY>lOfc@HCn-kE6CSGP%;>!z-EJ{TYrk5iLfFqotVZKEKfVL7RLXvt=eU^~#>+Xr_}1OGpE(A{AVxZONMPb@7{_ zPVtNrn87Fz%tSD}sGb--1}5B;q*@P&vI#;(;GEXp#x;n5ak9~AnSx*$w~mrGb(kxk$2UFy+@i0{+0pNj1r45hwIbj z4fT60W`)Nm6Jj+B?r1%du1zaoow>p4<`95r;jlIpsGKMP9#vYn^#Ca5U#TEoTnr)F z{t+G=F!)7(ATrqF6$l_Ws>N6IS7lhO3L~Ik0>fPYpYa9je}VL`S_aQ^#K7BxkE6Hn zvP8T6updqH#?QN;x24XuoroLs*+67OGY-wyJrq46#yD~>huDu^_@Gv>%IV%a8eO7; zoDKBa+n6UMR;xyI*RvV?Lft$*PcBNZo%J@21#zkf?d_YbfQz9rS=s3~RIi4KI_Q-J z7)gw(xuBt1ga8%!@vcq6$7-%u77oM*wVar!1C$-9H0dZ#J*D8(t_0`gSt5-;qC5cBvZ`bs>H7#4Zy72&ceUWr~RiczjI)n9q5zzH* z8>J~?hZZK4=SVPW=@N?u(N6auYx~{VPVm<5LyfN;RxcQKs&R)?Nl4B&4$Se!JIPvU zO?G`LO4gAa(_iG&FO?$~cI-QsmMLF%BXm0U&V@1+?P*Eaoj>LRc+2YR=bPEIQ_M>Y zAVAz379A7MuNAqnou~}wl_`1;8Fv6G%R%?fSO1t+0W-Z<-z9cpQw^8EcUhG1d`9Pd zOM`X=yCEjN_bzKZWZRNxQ5W>(%TKFmq`}`08rZR-Ovyc2yIw???Fi5Nh#a()+zjOV zl~rfeVuCo2M6u86N7j?fD`)FsKjxRjpJs+uT{&>!v|nWrY%!%qhuFp#7tlF@YWPYc z$#=X84p8SsB|FbX1EUsv0iows!Gy@z1i}r%d{I?j7^pM|DU?4Xg@9ZQng*HB9Sp{O zkx}Amw7DF~>Sodj-~>TpO)!Ci3-QIMg*kPSq{}pbbkct!NV5)l6Fj8Qtd^A#Ua*Gx zfs_Y;ezZ@{r-r*~Ntl=~l_>2~X!WPkICKusr2jJ^{1=?70S;ba^WV()3g3Zl$3f76 zScl5}&#a>wj^*x(hgMsTnb8C0DGhz#8~54mA#bknBoXcCX}V<0U_l zNw$*wp!qSwcpys2ygZv#Ke1+P*tl+)U*2BX{MmT>fw2gahppujrC-YkeT1R5pets2AK%D!XErPQ)-~i--z}%<7GejjyJ;I?3csxjzZ6%;=qWk$wn>G zW6=el%tbTn!gtJ9N}P&!cQvU9J7wH2q8E-p_d;?0TbUG-Mr%A6?&|f<0qa7rR4@V2R-=w?HH4YX3L&cr zZ6lCdDCSb&M#ywCjgo8l34Y~;i~xeG9s+CDu>-L>v4=^&@*Q|HqpjjCbVAKAYvA+( z8U<^XwXrb&M|caq4#GKfw1c6#8T@movAYm72?9@tuFe2Eb>OpDDuhH_S_U-db^nC- zG8OCr>!PAf8a4Ulr?47Lp*{og1x^OcgAL`!8*!0gZ-^zgKaQC2qZzw6vY6qB(h9h$ zw7jE@<&m%e*%R^eQtv<>J?bWYti8?Gl*4_Om zUDO&FxOTk3>V)?O28|l^9vt==Y z-bihcJz$#O=eLypHJ0poEVW5{>FOp?Xnx}X`ta0Tdjw6;5Q>mKk9=GI1bRxqG2Uc2B*2$T0cmNz0`{NzKE!*jYtZ5*LnV1 z;w2%~1IaWkJa^DHcZ~YP??O5Vi27}qo#JBL*>*$Y8dWf1K%$B^3)HN%!bxeAAV*tb z+^K^biSHXqk>G-Lcb=afZi^a7=>1s#>+$tlYMIZ2FX7+IO={`7SogX$V=iNL8d!1R zIf5SHreAHVD7i(RNMmFbG^}n6o-Hght&Z8m+Q^C;$un*Y0BSB!(S&`j&Bk(W1^F~t zib{Vk1+*6opM_vm%hWZFNCvF{$m#k>3LdPrD|H3v>1UyntDheo0?-LbL5aT3cPMz! zBqV(s*ics)R#MLGbyK|y*g!!O&f%LoN*_|B-=})akjVYsCPM3YH~Ih zXuq_@IX5~@9JJz=U(Fi}v$^en*A_*pE|LuDtaiVzFXul(LVX;mIz?Ma}WX+gk6Spq#X~>DmW}6?|!)by=c4K;YV3P-7m~sI03VJJYQgRzr zHi+iVKe%*~>lK38F;Q>2i+O!ixLwOSN7o!{0D42jeB&a)>qYoTm#}f-(obtX7(^Z& zi%I6YIJfbvszb|pKwZ(Qto~q>M&vZ|Oz3r7CqvmwoJ2ctsqL%6ifa}VywuTaJR*Zu z&Dy|DVnxFVw#5d(C&d!kUZ9n!g(@%&Rg)S*teO;ok=A;F5X{uUz!~^5#JM54^h9;; zC|;9m*xe1LT+rvew`|$+0^nmLAy(mr(Omadz8=X?;2}|$PjwXZLlSlcFd@~IEH5uw zc3YlP3}1vH))R_t(K_A)d?uxx1~2EdufmKOF`Z!{yd_d~I&xgx-S!5P-%~qAn{-RP zcgEtz^Nppeo1%Ju5LRz}CdIUV8|Ju#;rFzq`HaPJLNls*^v~9B^zP;5J@;>I3Yltl zeR(%%%JTRL$BuUUKCh;LZgKG)X3%8K0gh9ut8~rww6KCaC;wJ0zE{Jh-d;#t)gfq? zD!W;*%SbDwn+~)w=#{4?fntM~^tpj+A+CB5#bgVZ)T$XCS11M{d|z%O2#T%Ii!RjnlYUldA%qTI>=zf(iLeGF3fF z2+#K~=@=Q-4bYeP%vaQ7%1yn)idH@k^1*t@Jj3+s_hVvD4Xi0K>)%FHP;XV2i0bbq zQG#qMTSgyKHX>{*Cv0OgxeBu+mJ=o~&jxo>VUeeBBF#%C861m35z2rK=1*+NrcrkZ z#;!!QVeI6oNhz(nK@)ji%9RL(5QmVkH=klqh}rvFEwDdvNZevY*omItZ>|unSSxH!RY{ z@l{UAMv#D;JEZGraL zNxI+<^{9>qOafFw$fx-D**mki-TwU;!vto!#tu6zq*5Ovr{DR`VugBbn%B zK#w-BK}6qh;}(^m{qdZDkP0e+$WA`*1m@_Wm|KOnow@D@n~QYX&DoAKjV@zTWBHBMApMq3T$SdW!9RhNdSiw|;GIinf{l+#m? zA;i!VrAZS2o&qZ(xF7%vg5fs{I9`xJ+WsB#vS{$5KvXWP^A?CUf0#^S0egl&EecIT zJFpcv1lkiUKOKXHFa$lz+1y}2>p{}wTL6WX#vKOJv|xPgcZ-Ox<^hmW4u+)#NsJAU zJ`HgYCs+n=GC8M*A&VR_s%*w zxW8yeKL7crp>6BdNS@4Z-AcH<=EraEjZv=`R(x-@&Uj6ANn~xxJCf zVd=NgXYRk1{Rmgn3O=h6Y~7w;(QxZKp7eR!I_uXPn~ZOUcTe@v1s$Xt@~yDvj?Wz!?Po> z-e{iL{^&mtAKl--e=?@@cvH0CUee>h{**O?oO$-^ebRZs@4kU=@{1b+?COpf&Y2L6 z?^wNnA7;^>k%v7lRnPpSTpJ(1Y2NSg^@9D(r-CO1m<&fRt-zq29&cC?hfi%+*|S1^ zEDw4VV!f!b`Qh9dE+P5j>N8Rg)=y>6e>9GFY~h!lnb*^4NtQ3j<szje>M}WY*e^rZg!Hd|V~+9m_Y*}y8X5=+?OcPc2ld+HzXW9G~5`VrfM5B6dzEdq&L+ng!(lZ>JpF%N&Y~N(15r=!xsSU|HktqN}ml-O$B7+e-lCmzX z-4dy4YMHOxlPHXHg&zA+3E9iFRzLSHWFSP5rlp1afH3aSk(59T!;E2SvCvybdTc`a zAws!nw_$V&`A$QaJ^#RIy>@*OrO&RU#8^}qWqqItVLN<-vUl)zQ@p*5mUcL;(X`U^ zsypLI&X(sl6`{-NYtEW~&hgB2JxKW>Z#4N7(Sg5XYz1kCf5bOAKy^?8{7PZkIdp;} zUNg&R&8EeTY@{5{Le4Jsc3(Ku z>zckR@ym4~>ur3Lqt*qQ@rBIWnBGd{9p{<95eCP0e4OecO>ILxa4Hd#b-pNWP z%FoR%KW*f6zLZ0+@Qi;#jNH>bXL0JHbC2`AqOQV+*-MK2?t3XI8?yXzqMlh7Pl;mY z@~6+y+fMpjzjk(A{;kQfdm672ZW)ut6Vp%MTnC>?ohw$AWk=kMEY4s!hm*?IAy&=T zr4$j2F7VR#T(FMVX?^Lx+xodUe%I|_;)y%` zFYfbqU*2#9Et zUs+xfmp--W$20V<)px>8mhLPw84PMz`)8WH=b9HY=dxWUh0AzN52^N9s7)&E<3|nN zU-a?Qr);C@#q}ot#bb zI&FH8NZX^c)b_}dLvqYkwH~oVsd<8e;+p0)MzT#}ef+Q!?*g2iY@BvA8xV_j$1__R zOc)ky4ld?)hYD)wP{lX0Y{a^46@a>w$?pXb)=av9MmrUHZ&e+Z?*pNMzvoC+!Bgn5 z!V*rz7RQ`U7A1>fp&Mv_0&%Kd?dx5y_t;w=kjUs2BK08pIOeiCm`pwyE{4RRe8=zZ(c*AS9GEmO}M zYS^s+VWpbEZfata_|<)9@0P{;s<0YQ?gYmBcq8Mg*qdLGSS|7E8*S58BQ*8-V9gJ=b6f+*h z)jKFiN8BO>qp6yZ+(gpM=yWhar@$G{ z2Ubgl-V=EA*RiGY6Tw6J3G$daNP{(WXG;wmDbZ<>UWnB z4fZV+PjHR5b*NdC*wEQGD*!$n4UxSA1jIUS0mehcg6Swr)tMV)aYg|sTWWtF2oGe^ z19AD)vx&e3SRrEcH1L7zIjlVCxF?zxZJ(U>I|lX4?9Jvr?HXQ2&ve$cE_UCM&<_`@ z_ms>RKAcK%-*E5vKHpxCr+qgr+&`N5^4_b|jPDjcVhfZ76EBlOvAc*S?=lerTNkdL z)?DCIDucQyy7)zL0Qtd2)rrjCMaJ*^GLiz&30lt?g9vDTz9N^6c$kSXDoPQF9^b6G zVWM^H1J=-SizI=8)ZcjM{p)S#rQx%l+YX$0o3_h$b3^~1Z;$gU?9t)vQP=XdR=s=v zsMr=)U7BELd9;aj*W(0~Ja^LGY~4hr*HMiB?ZWsPvZAW)T|`+?ui@m$XSMEwUVV&h zyNeb+dit0}zk@zg@`w5n#jpD}2^Tq^?b~s&pGf>hIFS0%Hor=+o+h?A?Y04k4G(iy zRXa_dTdQ1p7jcU>>B|`(d3i3lRA~^$9H_7^Ich)Mx~>D&`bQJ})%f`1m3Ajcu|)m8 zYdP1V`S=%=(VL##VDuGcLRo`zR*7r7$%}s-4Y|TRxf?&wAQ)Kj=g&!hVN>5eG|&EF zWV!IBL2THPHA@rzMg%WE#@@BdxojKL_SNT<%KEiW{tEe)B~CkZ>&zP3k~Cc77x*z( zSXlV-_;>9u$R}<;G5s8|)8BJKk{X3gx6c_$8v1>1{*U#)e2YGuxp7O~g~;|^gmuN$ zE2~`R{F8TIt&>7+kAw?8nK-p=S0ZNygqguH)1v?$L*zk=r_siq0H z!eBOij8HHWx|^hwH9N979@1dti0#afZU0%nr=cmu1Gk0jG5!`~`ANyVGg1I1`;+KZ zm}>5M9Kl#MFX}s~!x&Y)AFmm+_TF`kRQ^eP7VBpb8ABkl)Uw6Oc-dmZ8^#oa7G|Zu z&sM?SfwM-Wnh`<@&E5k}h3VYxyePs@u zc%C=FJYT&Z0gQ)1?nE-_b70KR8cymB0KNqEj>Uwf)Enkl$#x zH9S2_P{_I@N_4ETq>dD93MS|QC?N951c)U6>vPZ~lQlH5t0+yyq!_NAXlt81h{#B% zpwe^5V%R%?gVzM2Hj6b3Ywpz<0oxwlaH=fRfjEH&JKhlNR*KzvVL_R?mIT`-5Wyq_ zY>=SO;3gwkGwfFS3<(3qga}sL67_zEZs5l~J_#_%Yrob^AZR3Ft@Oe9+=8rkz*#Ei zmUQQ05;ZHqeAW!vBq{(qVQO1zc|a(ssigoZP?v^Q*x1L`)Mrz9Nel&Q*Hxfs>4rXR z;nhzMvRgNc2tOo#XiWI+b#Pn%czd2_IlVb=`NlLA>8}qJ&(@}G9C;nqU~={8{JBTh z@6Ksn9eN)2dq|vj;M5cIzY$A+S^vX3+C}tlg-4w4!`2azrJ)Gqux}KBe$KW_>QSj` z?fU`Q^XI(Vno*arU@bnB>~){B?^)9O^Z6OBn@Ws7`+70_io(y)W1N0!Mp(QE`~_`p zk`M&FOk;Q6>}2{~!AX1`-h3W5ck)9&sq&?>;Q(c+xoNch=8{-HLx&(Tzr80u@)Pd# zz|0)iF0Bb`knEBjj@#EIx>?o#zG|f?&kARCpQ(~(y7UZwt4VzOdqL3Oh@DwC zt=K`iJHI_H{yDj^_E17z_vbFHk#%p*f4Qr9r7Jc<^Fz0-?{{;b$7RBK<-=OfjK1L& zZquv7U4J1rn_aYXZu0LMa@+{NefHZADc9bgpK{4P0I2^^>^G~go<00=L#CdY&S3c7 z5#!g}!+sh5<@W<0DK%#YV+#zY4-qimb$)a1H{BSXEmrg(P@lKbdfl1gME3oJ9|xNs z_$TRIi7U#aS=y+~9U;$-?;}%w@p_(eK+6n!Ax@>8leh79_Y>>*Ysj)=isOlO+V@j8 zjp-G}4Lv%Z!IeI_>sz{NP1Dft&)^r&TC$#nAN|Sm`m^c$=1k8@!~P+{+P|(2ULQ_< z=uHYb1xG~qKH|Do$v1U#vwCnl#;&>bpg$+RI8m9Q_xK!lb5;Cd_O=SY(Z$zRg+@G}Xq%UFxRFw4BRN^+Et%6?9+D|4sD)$Q55X4KTZ44gpdlz)&+ZQb4G z3-4&h4Y-V@7z}uKoQ?Nak23GAIvGxiceWoO|1kPF`-#<*UpgC<&3l_zc5P*|0D=)B zLESWNP-{;wo#O2Q51c%ttqUA)z+BgJ>#GAMCpQ6rGO%IhG};be5#Z4UE(B7Rjd~){ z4NQ1of2rGP0#D5#mjS1fnn+6PG|xf^p*WWr0OkPcYCQ&Ph2f}|)Jxwv`hnvDM=DIn zBRA*8Kp#CoI$!{%)y`n#z%h-^#LG_5b#bSXW-DzSc-^BDJmB;%_ZL;@9Jl8QMj8+- zIB-;4pa(r>K#xV>zLGS85Tln0)O%Vx8<5+icIH4(LNKYzq}ud34093;k_m|AH>k0a zXc+8oPyy2xb&ywI^pqQOjJ@$?NI+j5moHqYSG#AgVq>Jnc>Rjein7q7q;Fz}WjN@_ z-H2))G~P)%YT+?XvaXDGYjm8B66M^-)f9dTYmr7{N-oewp4|X8)BIxT0bAax3w66I zE>mBpz_SV(Qo%g<+vfAcVw)ag_hMwE=h%OP;Xu4tlQtfJ)JoMvYm{mISh-P(RMp{bn z(-exCWnB+F$2X{nQ8sS-*OXFxx!zs>fMR^$JjrnY}%o0Q<+~5>-@gV-^ndXl2^7N$m_`dfySNT zRs-1>du~i(_lN#8R(W=kR^W!M!FIth%qP|JZcfa^1_f)MC8(vGd8x zf6;on;{tVGXzR(g;#CA*ImE`zUBWAER^zpEL~iOmUh_IICxNF8Ym}wN%JxIRsbg?2 zJ67pE&pMKEZoQGmI;BbDU$J${x{{nKL$Lqw#|rYEKGm!pIFyU~K+3f&+G8$KdBE3Z>Y9gPpJf1=N!5s))4rN zN-zb?-}Satz=Bh!S<#v${kwcQPJR@P(~A>e(_Jtj+QKe2TrkUN5=S(>6YeMmHN_UYAsxzke8_ZucFiNeNf4XLV&nhlrqe_~NiSXO;J z#;z+sD*fj#@)ZNyTynX?j9Sldz0Ql3$Jhpn+4W<|$<`a+&;C$q@3d3njZx5-Z*uk? zpE~*TCgRAXxGrH`pdkp6xuIQ`A62xywuYX#RtcD8zab`h3eN_NG{;WxYDvm zP@;^}MS%*RvHb03cbGD^LG9!2!Nc#H{g1C1f7(&YW2UcNuRB2ga%=OzrRKSg-6lm2 z52^e=&nG4r7i7JRF2+{YJrJ#%R*t^BK>Bjh4|_UiL(w;ZA-{gVaoa)h_GRzwZ2!>T zX|gd}V|P3-Cf=NTedzblJncXRml&O7<$P`R;P#@#r3lyPsf%d~-yCy{QdwVa#b9$T zC74Y5-H*(#IvVX7iPLfH1#5J&@#c&VqzPdzwE>9&C;Z89^V)9Pu~ulaq5i9eY?DV z@iRNO9mi}PKjvKNyf{_Ze!a!z;LV4nfBIdd>AxGl{&TmBa{tHd9Gw{p;}<_~ex|xs zNVv~g%=A<^4O|SR#+#xzOnf71XXVJr>qF1W8|MWD>?^4CUVA<@817Fy7jri>C;c*& zFIFly(!KacBKYFnpPkJN$OWd3x`r(kovPlDxOv&6u5+=opO~}TED!gNMLO{FhA~<0 zWPx%%ukYMbQNpdDtaF{IYPVO`InuQo9vrT6P2VOkTAF13FfSTMjZe?ZBeT024U z4M~hCUx&}MH`Jfgia`}}&m8dW5MmC~6L<1bP&vl>f)gsKcA&ODU}(D4qhS2t*O6)A zwlZEawFve{vFD8lYrN_en}KH`GO`X>qCjl}?#wv|Xj`C&1%Ls(13+vz0udlH06EqE z&DpQwRWRCf%_uncqyjgYiU(y5SYnbS3a|xFy%_axOKIU&sFkwEyM*8u2224~>1}r5o*e3mN(Qu*Q)mEpU?X?1mDA{K7D6em};)LH}k@IQgY5 z;{~%VqptjNAkAk7Oz7OgZ2RGZw!7DYaJwZNo~Y{hSf7Iom}a;-i?dHks(ULkT@OiJ z&O$FKw^C!l4ho0`Gbufm{|`-X9oOXhzW>uG3Mew9QM#o@qjZlL+kg?$u+c4GfJlu2 z(l7z30b`7=5lVN*ND)aX6%iEc^_}m}@Au!mKeqdR?D4qI>%5Nhcpeuy<%9fW7o{Iu z3yqMFjHboQBbeoxW5K}-q0vTkaHVoqzZtH$@w*%da$?bu7nidrS5Q9Z@KIY&8IOOO2@ zYe=RAVv_!G#MkJ^O*Gg-ghkPGo&k!s3Y#}g(yZ=T0AZSsEaXV(>F82x7eq-SZp=y% zhAR`!=lv_L2vnRBL$?HaO&PsZ+Nkg-cdvSeYDt<@-d$+zV zOw%oUn10+*{v3z_y;2c$C>*PzN1vg_UpBD~KW(|a=I@`^-BPr0B3Ku53BkEm$^6+} z4~)`d`@Aq)FA~I-vg~%94=X<&`1?UN+*eWO`{#ZC((3;xjI}E2xgSpcM?uB^;`0Kh zcL|k$&(WZ*QNeW<~#%q$%l6F z%ex<*9`SG037)tt#5q)#I=_G|80~>)?*;e> z@aLr6{AcqYz)$W<{a&`J&s_Ls&VbBS3>L)Q9l4{r6WuS6+AXoH@N2IKz>Fvaxs_IC?dj>cy(T)l)jsRjdb&HxonEBocI!7@;rJwI zA0Sk%W>mxP!5~vLm%yd3GPV6P#$F^jWO=hwwpw(|FYOBt{SVmqqkj9jTTi<`NYn{M zc&8|81>iqfQAYnh;{7%Bl|aUs^i0+-Z_r1KzqmQN*O%Lq1KK-iLmfL9Ib+{oc)8jbRPZ{lGv!XOF>8Tk{a#Ug z_{)+>WuW*VWPWG1BEF=r9igk+GQdauYRYD$i3|+d;Wsc**QF5Yt z&ZBHPyR(fITWAKAyl%{0va9eFRZ8h=8C9=X&lWC?YI_D*^SoTs1b5*L@yB4_vVYgU zO1|bOzg48Js+R)rWy3{tKW!}f1#km-9{XsDk&di+r=MIHe(Z#L6by2Ote{*$M+ zP#Hbs5dt{Y5ZObA==GwDMzCgFCs({#j9&Q*tU_oREA5K|eKINfNjRQdK0D?tbP`uh ztxhpIraAFX5D2eg7+ILJ)U+XIOEp`l{jm z%jqApxBLG)>Bs)B;G2CI`KKKSQSUNkS(4BeY&T|2Vhs^V#oShHoa7y{1eGuI2BLFP zh&8C>mp<2|d|)M~G2+g?kIppQ6uddNRrr4^hH*F`mNk#Hi>wkRk@Hu`MBxpFbj=Fz z&YWvP@sfyJua8OW=LA)^$3DLLB0 zMAOEYjIqVU{om-8>^}Nu>C0sGAeUuMF;OA3v!&b_OxAP_q{cC(B#})vz9_2>?nX*j(H0(OP=Ee`uMU}G@sr(WuQ6bO%=bK z&6N-&_o=<&Va{eu2|wcQyGh6fT1->fuZ_|q69u(vm;>}oWgqBpjFX?yr$3hLPU#H|h12X?X~v45v%2}M zYWnxb{;;Mm?-$w`+Pbin=H_iAI+@S4SL^9pd$#DC1%UiQmN;{=5uQ>ld1u)4u;wz{ z{_DJNe8y*k^KdEnhFaY9)SfRvS3Wy5trlOmq!`we5U^^yIq9lmQEpcKUjIJ|{)TJ= zDV9c6C=d|#X*|};a)uJ>2NZRN^-A}IXce6!N+~|XDfu{uW%FgbdVlhs^hGButYkOb zgbisoLB(1mTAUbk%Q&`+9;j}3M}<9*0Y4>onK@I+nsoG5n5y;*VPkWg+3Ing<*vB= z=%D>CP2ZXq0QEn}wwJHMVhS#BEO$@i4y?-b3RqW6M`SjLn zlf~vE#I9{|$5X+FSufiqnJej2y&cI5a1{#2nS$p;i>Em|@FgiM62BByG@9x3Ay!T3h3I>beLdCf z-T(J){gTs~?|o_OJ=r$KG;G9B>=xcv%387d2m9)M3xf*p2q3|Fpz+lcxk+cRYEO*q zlX2eHd9_i&_lHhwZHp2j2nQV?;_amw&9w;FvsXu{EoZNj6skObyz*3ho}v)$mn-gK zPuE{~OwZ0IHobl1I9l;r=LOj+@RT-v|(d)uA??j zcY$pel?oJ0$dC3Azd(y>MY|GK6!Q&$LoOh2w0fc(v&y0(t|wB$Cbo=YlS6FS0xIR? zcKFE+sYz2&Rwqc>X{X@^S>PhW^%Con6m#+XnN(;7&>gTKlb&eSLWon*qO@p>%B>`? zTM#u6CCCINW#-i=RCyIyZ)Hr03m{uC^-AtwHyB|wbMg0Er0Gz2Nix2!r_DYWuRt{3 z7aGA<&|&GalfkCsjk&zO7cZKuiB`rM8Gjhdo3Jv5ESInSE9=R=!mF>y<@~-255Kw# z*_SRXcE)nhESHH1o8LfN2HC^e#TJ6~)KI-981fcf$C{Usqke2c{%ui2%DYYolM_CLtY^|z4n+r zhR7BEV$LOd@c7>q8CVU!mAFn`9xz&(HA3X90QL%r|B+j_$)&uDoUp*u=QL}gC!3^q zk2OB8Mu?l7>lQzUA(IFnoXCA}PBNN#o#%j5hMBeLU~U0`m;1esY&Qr9rtBn3yALVo!>Q&94cIV+R-$31GZ zF5JiDKO2=WSwW5hTCfvZFs!$+3TLRE|FvKq*c`e=u<{71O7_`g@)oe@w#oV`-u;GL2@zHJ})+oQ&yw*9Z_Huyu*5v(lzkGGOo z@r9+Q%bPoazoF?{%(v9Xc{7V&K*LpC1}Uh$x-GT<+?hA5UHP6y^mQnwJUwTziNB&pY)20e)T0a zig)$M%u}&SxYgs{uHWj2xd_K*8ZxOaJ5{K)NdE7-+ut%Ej3}V^c;F|4-v$?X`Ew5R z>wV)=xuM86S7zi)oAmU`am_OP+7AqTx=<&A1VXimvjZ*47_#;)qM5|f-`VHMTk?Gud z4?-J8?tG_6x4eyCm@`^)OyHlDh^Fl2Iba)H{&JPKkFYLU-;E(%a5!Vc814_A-MX{= zT;)HCVdQ|)g|MTGTky9LQU$XJRhepKR{E)Z+7P+O=Eb%`#1kem(3Oa_B6oyLp;^KODTdTfBI zU^32RtJ^lf8MA+Us^no~!4Poee?AXK-ga-oj|BK*iZG9YZ?2Zk%U*0tYza~T)JIJv!J8r%@Yp52uW@@$?W))kV>WdP2r~3cr zJudw)B4gE444zTOGmvG3Sv>)$Gg)TUV+D-mz0wn24P`G@xyfOy-6F*oranHdn86+ zO%tAhvKF%$h;1<62ii3RT6mD{oWU7h|wv{Za*{wbk?kKlY=p9AvXs?RW-zr3{F;dP zKgji8$4;J2CEVFSke!OMdi^i`Ruz9i$jUA;_N9mDni<*6$j49SJ(_=mw~`b11;}MP zla)LbOHA_>o(Ef^9`}wUUd)mWNYbnJy~iT~UcIZolBb|v+THGOvrgDmRB$@RU z$hn!S# zLf%Z-XEK|^8K98YR|p~#GJ|CbS|uYU$KK9|YXA16r3N7Rf0 zZE_#TR8QAxza0=?V37;XRBZdTaI0ZC(8hm@z4upNssGL4k##Zr-KYW8j!p@eb`5O~ zxMMJS$vG51ELR}2M?AvKE~lf)ODFkv+@Kx<{yIUJ``}bx7}UJAlSSU>YZ)}m zd%}ul2Np$P7h@?{yHB(D%P!#eLJ-d9zV~&Mum)a#hxOm;Q8xS88j0WOF>!*;(gEGr`D%52lTqoHC#Fna#WNkBrJLKQ z?sZJ_{V+w`v^zX?knG*LVYn97#8UqJX^i3YQw@o%xPH;|l8=axb6tGSU57-DLuTV| zeAnJZIEUXqrl8aqjJRO-d(+Zc^1eAp(B}~kqnKJr?>CLr(SF-9x{)g3%#gHd;#{3ZEY!Gy`i0ifWa&|1kiHID0=f%?}<)XVEnzP&; zo{$(>vJCkv0D2Onw<%k(GaEPU`tauPpAVOF|55aru>ZY#xs?2@PfPAU3XY1l#0mkf z6rjc9;id;kTio=l$y;vz+kmZUTDYk7S;cZD|cPXFj@zEBmhRxH^p!asEI^W|S z;k|?6_+;@HPX$7T?9NL}K}Dq8K-JiGtH(PJ1|-I}PAwVe{-YpOJY;(|Z%)EN8nQ~u zBW*(deyNnGbdi|K9gO(gG$~v0-A&MTF zi7TB73_U&leQ4+Pc)vjyd+phc-v=jE+H~P$MKJ6EoAM@cnuPTSs62f8b8f#rxTq0m zINIY3b8fe#r?F1$-HMl%+dr$VG&yB==ZHias?>)6=9H0OTY}j}U&bK^RU7yDtG8z} zHo;Ed=gh{AqI}~2U_+F01$PzM#gr<>9xaEU7i}*s&Nx(F$Z@v4jrnG=L(f-un>s4s zFS*X>9rm@asDtyB120KWmQeMT%s=P$08@u1AJd7>meSa(hudd$QthXgc#h7r{8J)h_Q5uHDYd7@{xyqcOanGBZmFi~1)x521!CU%KidA0SlYkWu&mK1z8_GXhP$Io zWBowr7q1f3J^S5{Noz4_Piw$tM$MlO={7kG`y6y_0`{V1F7S32^7aNac>8XTtUj4e zvsdw9Cnro9WtuA9Mu~}*OFMg&mqzcgk=-PSxWUp46xD}+5yzqwlR{*l1_cL}49=kR zY{)Db1=;^)Y^gcNL`x1b%1Jk(*dxO*CR%~yO%qddGj04gY*{xeQ?DTcA*-1ek9m6j zfHki;fvaFE1}sKJ+*_O`=&p|Y?fh-oI20(j?@5kmST@LRjw?u9@+YvJ?Vm*2iDnxBY1NCXpB zd0#-9!S0(2=nwkAwsVJ~v9XgL>)w1~y@NVB`U6Wxw_#OQwu!AAae-|e_$IzQQusxZ zR6qBET$&lkn2lrOfvWz(hlksIg%KUdptuhy0!T1#?K4%$zWuTkIP+&z^y{W+YIB?qx_s>Z+GC`BA`N|`*1tk3k{Bjd-xW;MwvvKj~R zrr)dDq826aby8-G@QUW zFARdtrNhOv_>T_1X7+QYoqT7KyNZpUHR8gXT@$<$Ahx;2h6i_b3A{6FTjw+*=`}}UB@#$>N=Bc%F9$*w7q+8V(rltxF&rXPZymYk< zplz!ZQiByREcu+Yn4Klhr0*+Ikk__ z<_Oy`pE&mFPXSlpE%zCo-){k>&aM2k<}S=%p)5ZChD`dZtRZ$BK&J*VTiI3?uGnjk z7zrz&wxpegXAdjWi;(i$=3Xcs8}R3_SM;l`i8+*~mH`y!tg*700+?9?ZIxr#8OA{J zuWN9R$0jtj6VSx^N9{3u5;PwT$oIKfjO?+FK2LV@OEhkmb5$ZOO7qC`2 z`D>4C-cAHLoJO0^c=B1#qqRwN`5cJzn2asjU-^$a&rm8{w6(xA@9P$%pA z*)C(6b2xfs4S9%wkUq2VTlcHs1BjfV00~8V+mEX}GhcOfThUC}OFe7JECJPWM#uER z?XMXkGBigHAr$O%+@!atQ0rNBu4mz#u>zG@`Nt1;r#G)Yh;!#d_1dl~se2A^)?K_! ztg9Oe8<%f<)>&}x09Db5hKjB;Ra9!X%oL_c9ZF2tkfRFCyKS#@BWm#|Gq>fb^gLd9 z%bM~~e9#?Xyn-?|fH(E(q#eq)w5rC886a22)GQ;Vu+{;V%=>IfN0nZ{V7zJjONWV? zlkLM|Q~M&@D*%^SFszntLdnc79*70Z$4wpXZg+?q096(e9h>Lfno9pJK6>@}^;E6a zmOivM*j_#N*qjcN>thZl=mmG>K4f~~UrqJRcvzU&lHX7;pK~zVgb945OY<-JnQ-B9zxMI#P= zr8k1T{6nAvYHh7>V6I$_Y)oxIP-Z`m$#f8kPZAK%O=}rA=M3r zl~p1yi(CTe;rshbrh>osQ5%bXmLI$pc3vBA*C`BV6?hcJVo;0iMZ*-*aTL!WR z1%U$Uy>9uBOon1q&0RWeSej|fQp#ZLcU*`MZycnvo!!**`$4z_Dwm~+sMH2qE^wZt z4k{OOOl!m-6A{;k@7%IeJP=Ttdchp%KwDS*5ncf|*}K<7(f6(giFyUkR1o zy<{n47++%@GhFg6_oIchd%ZK;WVBA<3yY{6%eOC>q0^Yr&D`bYba{DuX1?wzOoW?Z zGU{DQYSw&%v@ojTkZjM7yw8YbKD~P2|UKSJTTBxQnz!U4HgO_+I4-c4V zl-9x#5&UGAVj#5E4=f~D&)PSVy{G$Y02;P%m+^TY5oG6Jv-13bdF0;10bSys55GU& zBDc+5NpFsrr;3_}-mzQf>1-KLQ%>4AJPmqkt*me@n>WK<>$f&$o*$hd5#K^87rY&W zT<91Tk0>^~au~OxyLrlzc;h(Mh__`i@WGQN(Up(JaR|nT?!&D45#o{E zF|G|W)@?JTNkwRNcfDKp&RlTrnRg?(f3K3Z3<|W(5b)auGBzx~1Nkoe*|z3Cy@qxs zzmvOE#E*;)&5f8a3Tms#yEcak8LC(= z89bdvx7ei~Bp!MfG`}A@CjH4Mi)Myn6}hV(r#eLKHB}mMq|tR49%uLPV|`T=zj0Is zE`O+O3;)Ym-73ul3TxvGk~X9B7C*ent{^Oo7S>FTg}zNA-2dy$Yj)W83bH&*m+GdY ze-?e4VA)PSZ3ZvaQY4EZ2>lx0$gFxk(fl>rH6G_g42Z-`!XzUIT-U^Eu?#4q8e;9R z2Xbw_)9E^9J_f5ihH0vN^b}(8skF_hNsr4o#%`Y9f(RZ^p$_x*P+ac9RF85?^-|#+ z9#)G{#`#W_dK}mbV{T^nK)G^8OPk#EZa%7!h01zSVAv4^bijOB?Y(qy$ z9dj&Q&b<$ai5#CcP6Ejr&NqyY%^NJHK%;P~e!!APL|5B1j!9Q?hN4verz1G5i8$y{ zE>*C&_P7!`y=ub^s&czS1+q*1<;jI-HCqc%u3FtJDi~+~$(Z zQUdAKMULP3eUjElY7KIm2gw11_U;iIB+^M`2rdl}L-S~We)H-p-WT(?ET=bsne8pY zL+52{hANCdKKFcv&08^aaqhi*sSkpK%_E=LIFES0!FClPV8?BdLr#d(k#UnF#ssmq zT)9J0OU}iQg8KeI_uC!*WGxj9hFKH5?2cI08XHx>8jK?3VTx<@DQ&{V)ABFOozd33 z@eSO8lW5hXxv4GxXq!m z$qbLW&g-paWs)Riuf6-QioYP#CF(ZE{F1^@fEsGQ8IOyb?~gow3f9+`cVLz6xe$iB z-|>`sZA?_+q2 z)^<0B-?+hoNt3SQJ@ccjC--)8LmKLPVf(yW^-go|K5#sczkaq_v+^S{DmmPz@DNK* zl@NCqT9}jai7ZS*H5Z!Q1uO)1$c!+?rulgnoTkQ9=rON_Tv`Y``FJ+=8oBvf$3O7H z4`0rAXMw6j>UqD7_g}=P=gUdbfZewkeHgXhBfdE0clc5v_V?OH!t*bcF9`opFvHa| za!q$qh`i^|W0EK`yxYF)zRh+M4i#X0P4HB?4dT(y<#^6hUG|9b(a$BZ(`S~C6eg8S z%`!TT|D({`eD=}cYwf%Vo%Q?F^PLAQKui3O4mW)|F1;Ifc}9K>pNV|Mf*kd2^5Kfg zlLI$lF2QX;YJ)S#Y{jetqrkKf!knPL#M{DMUbTgnXIUWXt~k5VcN@P@bHPajqZ+QR zO-HIoOXO}RD11+(JpjeqQ(_w0+(=e*`lniz8xw_RMPgK zmtX|EF5m_AAc99L%jWumnc;z15ai6FiBv7vKxYnbV2PPD;Go%Axa2~7O$^5X0>nzj zTWMkGBg%Azem|T*(wYrVq=wduT3`+%i%*2LiIWx`FXeBD6D@39%$pbb9xv*ep21vW z3N{&XX@*_&3KmL(H?RrjLCSOmKclLq7)>hFZq|&W%+;w$n3+wd^Qu)g4SACl)Zp^| zH=t5M;CH+%b*25n$gc!=l6KE%kq5n6%C)GN?3) zDY9}Pvm3s9&8BX=5!|ws*q-Zj$gYFfLEXfjeN1!Dp~BZxN?`E}{);kTV%5IcjnYo> zdwC3KtY7Wfm5=GuN_m?yJSmZ;uz+%BMd|z5yBl0f*5-M)9|(ljX(kUSvS@Rg<`0|B zflXVS@6Adrvr!gI&uUyS? zY4Q11*e>Xi%q0By#+!*ZM&HZBbk$KG9Y-V|U9)M+VPOeSE@tSrMDZ3|@jXNb4!R;= zb{Vgy+ZPV5F{%RAyGhaiM8f-VxZPdnat4s_Vf3=8MfA+Gd> zQ%6EF#<`d%YPC1QEk}VRjN_e@nWoa_kySmL9z^`e=*#F9QiR>Spa-r6lP_njaAp7G z1S{2tnKwZ!gaF?nDob`m39Jp~pHMKKROE&VbZFDNtWmQ1syd{!msw3u>+yTfxaXmR zY?K{2^*JL?$$l?=!WJxOtnTL`=;;M`arIa7rOW`OJk$2Qypj~`g%<11 z8Pri1ral82pP{0-#A`DSgx1*j$vgu3N#uxd6e9`&Z$8N(r-sr4h&3mQ`svSG!Xlr% zFhv=06f=cs2pidjF?k!$n-#IBE?F`bh|?PjdAV4PY(+DwI9M}c*37aeQXEBJamAT- z{C@On>$L>W?98nFPw$4DU)yJut!+2J;b^j1JfAC{wPo6%R^P^b@FB=?y}|?qa}IGR zM3wNj{|N_2h5E<>h=GJP@vmF$e7BG@#(YeobW{FTr`&5R;jgEfq<(9O78(VkNg99p zx{h_iYnD2$taD20P20~uwqXIR|6o6_?r1|dUNP7|a)e{Dl6!(tMztH3qY5_RYBZ;U znV^hej`Q01>474M)8~WFj^Nzugo1@_%S`s`US86X3-@IvqW!mz>{g$lGIYk560{zD zXtW`ft9B01@tv1*55HYGN*|M9hfUnNYR%szptH0qU+k$oO^AG2SUb= zk`o=NMRb`kWS*f?x$HhiGr)h&$1jrHO~J=r=J9jkxHHZpJ9Hk(xysEtU?{>Bh}ZUn$KX)-TFfy=>Ua0 zjrvZ8fH{QfW6%0pKd$C&y0+$bT2?ebh+C4+`@d860pc9TP)#oVr`eM54!O;99OgoW zLIr^A4b~tm-j3_7&{IaAAHeQO-_Q?B$L!Vm<+GnCV0flF813&2AwJife#gh#EpcZW zuEu^>h!0~yZtmpNygC8dnggT1PigHn`PJD|gO`~W>cVpmC+ z(tD^c+WP08OwW9hc= znq4-UxeR$!nPdv4?QK9+5l;^$5Vo#I7xs=+5%RfvV!qZ==fwMDJDT z(G%Rh@t{5z1d_@O0+v+<9lc@z*L39zto8sYJiIQMH_XTS*$EZOz>%)BE9(g~)_Sg? z7vrpXuk*gVx74c*nJFwx);P0NIWp-)Lwq9cpNlx(qF7Ow%xBjS`%x)cog_KdF>g64 zq(%R&at*&mQI<{36-fz?qNZZhJeA8F(nFRLsWEo z3Sz7Y;jN5rRieE!n z*5^O<5PWIje#b?p;zv`IP&ef zSGh(*e4~rmQdr|^r%iZFx!Uj;gk5vAZInc2h={d3dgzb!S)G=+lks6(mizj*>Nfhx zdvBvbx)nL;vS^`+%luu%3$u=dmxtjJzQFa>=yYr&bxR<*@xOBHAe<5YFn_smuQg=N zGmM>L2c5avlvRshUw#c+wC;b(+40upjo-U^+^7A@AAbQKxQbvAZbF55O|pkZwewqM zZ*qTjAS{#>FKpk(_8Uh2)k&Lb|K_gDgD)+R;wtjsuT=Q9ax)_0#F&zr9WT+E&tJt2 zRdmWX(;ue8%W>~O6KIPn3>)e6ZaR&5^KO6yh&rT-_Dcy>qtrmSfknd;>C^z^H~Hsu zASZ!>J;I<0EB0E_D;$6J9%h8IiDjR06yIRV?#Agjp*zxv5Y!w8c}}Xxz4I0mVL`8) zgx^Ay0Ev#-^DXV}2exeiz9+ik-)^GvVZC_Nt6Y?SmdQ85wMUeWdOn9X`jD40e(|Nf z@Q;{9+dvdn=;c0D0aBzLjSc(AXp^e(8xsY;@lO1az%U(dLGPyI-AGspMpz$FdShW% zAHA1>yFr|R*Vxf%PAVQ)@!*A|3z=ya(=>J*y|Q(=2aN<^eq#5h!cJi{Q5b@tGCU3{ zL(KSctCxEoycqK_5Wcl8J82WYXl@A~6uUBE!v798iKXKv_|za1Udoz8_U7sB!;hBWfeT@a5zR_$LrjFvdx-!JN)q3(<{V+NkxV(HY>-Vd))?N~J zdP6%^G*HVmy1m|ub#oh_=eI%E8=OY)LoQjm*Y^>x;rdm2YuvefBnoNY5L)6n+kDR5 zUB`nR!!lYwF(OvhRqJ;a^g&GfHHg)WjCSDS^7>~>N9%G&?n>ZCPUu{=eY%~#wYZ3d z%y@=)+yT_8r=*2_+tDVZhSAy{Eg_05eI?U!(DatQmN)F3qU=T+P~yEtUi?-=eOw!- z{eb*K!&dOvP^Sr-U8psUHLd&O`g)G7w#|hXC<&}gmk{e{v z2M-fMS}#ro9jaymRZc6b>-bB5vB*qM|vYH#izRQvYMQ0oW?k&3WxG&XBxsX-ng=LKK zocLEW35^!77tbES*ve`FF4W`%pwNfDNm}C!6W#eDVAj3%r6pss%vIT6vx9Dtwa5I@ zSCSm&hSBb&O2yo?6< z#aqJUf<#hXQb=_=_eoQS{fMW2j4Gai>vI`~tf>|6;cTDCGDPIk5I>NjJECc7qoVZe zwYqFgKGO8OVLSWpe-uZM&+5*5Vq`sS&s#Eqh|8VOFdCFlxbIr)e?#p}I3_)G`0t+} zO&JcF`5Xg!4m=tobQn5X`{4V*WbNArDz%RMCmS_2Ont2{GS_of6>}XzA3UCaKQNW3 ze`XWE@`n-95tD5WpR-KN%18bhJfqSKz9iA^CwdTR*wlZK+&|tOsU9P$lNcp1!ZzLs zVWYyO8jo?C-d%HRq-iuZF`d@XrO5mOo$ZjH}LEE7pR?CXMA|eDA*!*hCl<|L!(`U$$riUVI z9+!>Oy$X2sHxiF52p;B1&sIY&zL1PvW@9s13s+$P!JreayMv9 zb-_Pu`3TBudJkSZe=!-byiB|(wIirV=kYRn;?KYWd!@RVS;x2Bn1$wr!Ykv}8eCfh zflM@6V@+_aNrSJYB11_91qrp5?Aw@pHvudJX($GY_1KTj@@^ZL5tcC2{;V^}vBSu;;h*I1TUR8gaFc$>ALmPWn^1cUYN zB`0aAbEXPkUnd2H-SidQD%{`hzGI$)H$;mG)6|J+9J0OqId84;v6}Mn-rsW-+m+6F zfSz3p1gd*g0KF|-S~v!64TaW>?Fu`)h;^p>-F;G%?8XV+6$CiLX-^A>HqYpyY>;Jz5}BO4Eq2 z?=|+X*!NOo=c>EJK@#h(xGMN|;1({JHi6KN%skdb$Cy3WjKs7HX?EjOMk#e|(^m^G zcde+G`DptO|ZhEloO+&vU~1Lni( zcP8CIgX5g^ukIzw>yEOCrpie)eVHqPkk3J?EU5+04esaPXrHI@)Btv8B&Q4`s z@*jn8ss77PAr_xK!4zxgXRqgqE_TbcQdQQG3$ia90|JLYj4dXLkt7zE{Ux2NguHd4 z$j-XtJdbsTY|DT=PKgznV5~;+}e!m8!}hRFntZ8 zfo(vku97^4ijnP9#0(vi1VdxTjMqmO&7(nZR|3rr^w+I8j&G&slwdM2l5e0q21sMY z1>D$5#!<;qK)Kt2*4!XO%^V8IzMYe(5Ks*%H4S9jT{}J z$h4Rj|!S!P52Ay*zxFmBOadGs=JytsIkTK zirfIkpX8(CKC`43SU(7V{3~%1F(GUc@yOxTJ=<4pibho{$*o3}(PE0Aq^uYek@`ko zRq#_s7Xns`N_kTF^gMW}<3(me zKPTbZWgZP?zHL6ko_kSDkumRRex+Ri6}^DZYp=NE`M0<=df2 zaoG#i;~CyC5b(YWtsW0*r{G&zc1am{8s-%(xsH0H4zu2U|8q%AkQTB@0`$IA>F3N1 zQ7eis5;kI%exMqE1lP{HE-^)la8MS`P;n=h7F_Yb0SFQ+GoAur* zS}5lFDseZSM6m0O3sWaS(unOfbvWI`eb(9)0B0+$^zjTe`z_<-BlAtvm2DKAaj|dJ z4h05~0$kq5(7V_yRY>SBt{B#QEP(!C)Qz6Gl?{Ks_2oo;-Zpg=FV{qcyhR7g0iTSP zr(C=YwrtEsdLX~woH_XZOXli30*3Qt5~xa&*ya+ zxuoGQ%bLfKD925{2nYoGTW&PL9y2itOg-_c zwIRBt4#^22ngI^N)me&_*uO zKW(8V6Pj~3eLpEFQsM|Zm+{^j^eTAEmtw|BJSkaOJ{9tG)e`q-&Fl(DX4g#{dt8b= zuYtT{rh#xHBMooE0c**m26MX%didlSGeIOPIYI^Rme z8WL7Z*A-7q5dmIQA0<#A6f$G_EC}fw2>v8DRs|5}Z$nn@dt&dajHr`*Wh9#g>Z@9_ zHN-=+ZGw&0%(0;N7I&EtX_<31G_VR)Un>;S(EY0NA(HWjUyIbxCNlM`li&*oP~d-= zs)d7l2*lc+8b)F2`4p5X`6vFiAcO1)&o)c2fZwMcoMld8` z^lV-Q4CztEaGaQ09huwnF4%{$k7mxJ0D)H3)El{@(-gBoNj{%A#WF>rpNW5CWIKfm z1?_CpW6lN=C8#q%eu(c(tam<`!;|p2S3@)a(n_~RRwJz(pG>wq@n+dLXccENH-)ui z>E#>IWX?6zubQ}K|EQfre7Vr(V$>KwoO8E6I9>e$8LO%b{;~P%u?SZ4?O;?FI&>BN z-~xI2Kw_8M+Fe4l$nWlko8;eS0e2i+&P*1pbCn+JT{2}C6GUq(8*8EWbrVwagB$il zi(lB{YK3g?k@2Ts%Y6w9tG;Qj8l5~S!)c&k(OM8s9tSnpm6C-Dp!E!fGY`_8BxyjTdQ)RROdLC6Ew)!z*BDQ$OzQ({AdqKrgv zM#4gMV-yNUz1cwZfK*1+Ety$YZqmYPCZE{QAs1w?sSW)LRzctZEyg!8E(710i4Oo> zzAE2ebQh%V_9#nT*vm={HimpMLK-FdHTMSfmu%q_I@5#;Y8Zha7Snlo?!BVS#&1B| zJWA6u8POe0FW?@%BeHYdUjvyb>rttFO;Oas@S5@QBs|Pii+j=LE)A3Ts%Ro=tQ2&8 z?YVsnrod>mu{f)N9e>(Tt8`5*hG&Dr`*nwAjrY?{_a{e1-IDC54k4L({B6`&yEdXk zG|1D>XRiqTsJ6M8x^DjSjcW9n9WDgVF$(Bg9XWW;X!pcuF)T-+Rt?ipaJX`3Nj6ke zGSCG0>y7?l>G4z$vQ*kdH^>~GZ66M_#z2)1yhAfp5QUV zqvj}PTz3&YY5ROXwHc@UjuhXwujehwE=cNrQ`!)7X3d+cW&lUoT|C^XStuM1p1JL4 zGo60#QinhTLaduGz`R^5v+W#1i>Kz)O>ro4T}WT>A375 zD3fRO%~Japl4eJ4T)zOgR54U80Vk;g0*7Vj!L zp3+BVTq}27u-1^MSLej6yhi~*x?3R+y|fMtmlEG(qd)y=vXm!slTNEJ!h^pEdfH#S z3*K~jPBEGXb|OY=h>82cC1bng&~OjIOpCqpuy0i3V%v)GlNB?1gQq)E$mpoc>(t$2A$g45t73RxuTE@)MM^RgV0EK5GwNeAO$SiMWNR1}3l8O3~t z=94Me65Xrpd*st5{Y=dn9i_L!7|Mv%v-fQ%BIkjM zzw}=#7&7fTe0M#AkG7ZpV-Ca%d=lJi$#Uhnxn!nj&AvVll0HVca@TdcOqPmXR8mDQxGr_8 zbLJqE(yJi?-PUH=;u*4JIJz~)JTl$#39>rp#Qgf@A;P{)>n8mMf3wdvf=AcOyxVhm zwR!5=&JqH?of+Bw_>Y{!5BHHQoNZ<@Zh zpsq7m$v3bUrA2k%)@;^3W_ZmgyTf(jtwC_D*Azxlh|GC3>~^aE0AnG#S55LiVO8X| zA9xDd6`Rq8%wZcK;;CG-R>a5`BC_riB-Zeqz@nRrRHaBADbc6RioCY_)~}rbmd(y6 z=WSY+$g2_sN97UPoMf1a`^wXjPH7|ryLXtE#qYbyoDP8nPK?IT)JJw7HOFl1yZl@$Ni|&`5v+sY1YGrCt**+-9?P3z8^R zBNd|#(xS1v+_ze}Zso86sFVkB_lbZ=u6pJ|j(XQsGAl>VTIVmI8@R10y9uK_HuF{^ zh>meZv;?*Y;LCsNS*xhN3bVoy0 zwFYZ6iRvmDCq-V>l-FIt<4*=F%yD_O)?(0kn1#1za7E%Q_6+7`z zcdEG1s=QFigVLskGSxG{M^Q@PK#Q84BBhNxVyD};1XQ*$(JnDpp&9E`H-yDbw*UY^ ztmLi+hzp8$maW>Mw_`I3zOWFy3eL>}Mm^+VK_apolGV~rWb-yEwAwSGZpCW`4H)R3 zFEsF=9MK>#F;m)^zn&_X7bBD+fm25~E!MNcvr>75IjEE_7dO&%3)YeDlpeK)w}hN# zr&nhgto@rob5$o+>S_tOITcMEl=Dw%xWT7phGPhhYRplQij^Z7t4SCbq~)(*YcgwN;;* znnhqLs|N2^5!h1Mq^8lF)mTH;otlgq8L0r~ZfTq8tW7Y{Vc3~p-j}UHDp5s+V8tdW z;8Gf3gaVY(W|K4k8eylJZYUUnlnMZ)#Q+$mqI%P5=}CZW$fqns_NOToGMM37vzt(toM>V;TT>yueHiIRW_rZ520)g8_e z8NPz7uA3u`(z?WeWRupmr$(gSh?!JNa->7#cHn;slj~8*F^N^x_e-3p^!EI!S7epE zw8@EiT<}l5Qjx)Op;YIAp4IKpqN!7}+`-E7xwE8BrUpg(zj;Tur{HSqHcfMO^R>0e z`GLbPj|SVUb>LBA+b$nds4J3^ojBHJrCJTNa{GyN)X4ISulR)i_n0^T4anfDR~$l#V~* z)yLSpA8m37-5vB}>KRxO{(URP^%)GPmv-t(;29UX`~54@em!28{4u9lAv>hGGvs
{VU3>E+n~yCPxb3081W&(;dgPcT=XP8#9Ko)fO%8H>e=e+^}ROq_v7GmU949 zm40W4bR+xA?d{sDUS%?-u$2cHS(r9t&ViWHLkQiRQnAZbg!xxBS8G8QVL`M}A}JUm zt2NHSQMKlK)TG!JR^3VIPx2Sis-@pGD7eiHNTfZZRp=@fjGW@74qB`tZeEp~n?)p1 zT%&VWpp+b7)k~qURd_Bowlhh^$r>bf77vgJHMJbO*9N(bHe;3NgIx+ZNcSGK$2VtU z;)cw@4PfdwByIrJ>${=PHHUKIRwA~g9-@)X-?KY5D>0OV&2%$bf=?BlJ(~hZ73fov zNWw_ZQ%k=BoYw3QN@Jl@$gOl_*g(|u$*7mDPaXlGg@wTam3q{SKotWw&BY+GF9wBh ztx)bX6@p1QOvlZwq`+SS)wz^&1_8xWvs~}WNg(zjInQS z8yr;gTkTwdOJN`%DeGD?D0QL9+zx72WjLlJyz^IXt?)?|L(3}Fs+G_p;z&;-q!Sv3 z5%S{|IFF2)mcW)a-q@`>cGv}EFUZ-eu*;GKM8=IapCgmSQMf?u#Z9+w-~C36?qkDXH^&`qEc)KX0^{Es!0I?v|8aCy*1q#X~u3MXv2~st(rua zXvJE)VYK41o=~iLu82Ni8VN4r)~qWlEn$n2t--4ad$oGjp3Dc`fs=z-(lK83G`Abu zIjWLAb6UYzOlvtc9(&SfnoRLmpjdYEj8GiYI+}8(Y3wokaw(gBVOCN+<24|IBym#a z7A3QY9A>Ud0+Gd6jZAf8&t1Hl$;sShaR$>(b;o*&!M zG&-uDDYi6=`fhSFTj%1moRRb`4kNEK51QHi4}2&kkDBz$JE z?rq#L&T&Lo+bG>Ql2S!LiMfEMINI1XJ*XRjHKoZVj^7KMb5(9*BDES-MeAAfy0Og( zg^G}_4>h440*a`lW}eTqRZCG8*r^;E7VcWft9mOW~aJs zIHntMlsj8oD)Qn(1JYINXK_O>%zx5%MXb!OlSu>SyNwFOaxvU=lz zTT{c%tI=p@DvBduw7H#tjxra!o&c>#Ad1z0dHdHNfT|E&+&hLY+kFA6t#VFDUF^Mh zuST8<5!PC>o>e6DMW(z8h1pg#1Asc3%Y9kqnOKdnsrgg8R2P?Cb_U|Zrqvw}rfQ5i zYn_A;tk^Bb71N}2iWFkrthGFbAP_e(oGH&$JwH$7P^yo-#~ZmE(yN`$xCNtTARq2$ zJw3Yp38w5S$XMhaLG4qycCh`WljKwLbz{M+mRF?!M<9-e9RdFU163FnKnDZcy(5*5 zKv8~BFv`B4;wuXDl%ZogHkC3)-}DuMnKM2s3W~-M=);n(xu`UW(P(VD zmnQ=~tF^av+L-EnO>lZc71~aIg1ajx-c$!U`c`sUnshg<&&n#@xyy>J5|mMpYQ?)M zlI%jNf>` z>qPjM#j?s3g3mEyo~ncV6aiS?E3h+P8BhRJU}C%I-ZnX^tE&yOdv;k70!4Pp8W~t; z4W7rb#%jd6Y`V)lHqRN<5CUUUgqw_=r2haA?!T2}TiH98Vb2GQFzP+UdP zaSw>>4dq6XlqJop|WYq8E!FBrMr4nI{?&N;;bSL)e9+32&Gvz_o#a8LoTX{ zkyE`>S#wjPvv4amm=0&#(vdDX=Ao7g^Q84_8F}>6guLtQbM(-X?7HV zO=mbg(5z}KSZ*sq0ffP<_-+>?CatZ)72wxDE4Wz5)zIaLu4YAJA>z85_YaYp#dvo= z71vGJWDp@ZtE=*@EH?Nc)8tK}t;sQ_2`L@w{k+E_vjG5#w*!n+N-312Ypd>D8n1C` zA3RYD`_;u@!Z7=}Wy-i2y~#@yzreX+6DqLSdX5raW;)w_jpgIY;GSCd$9w>c)Q`Pg2x+yqZ> z>c<(XEP%B!=lQzQB%6;k)LH~ug)%_JT=KHD1-mI>S^xlV-lT4QFKsD6tE6J{Y84h`?$oUmAq>vUaE{kTfq?D3POD0WKbv30pq)5h) z=dC#;H4|`7X#wW8u*-YCUMeF4eBROq0QO;ycIi?r5r zmV&Wv8-2qfr&usY6t<3|gI7pWGAjosaiWt(cGW3JT;jCk%B^Kg*<+ft!J@MUV@ipG zQ=*0$ra9Z3R*{eoSK74SGkap7XQ<<1Bo$zdh+!4tFM^0JBx0Y{#`dEm(G} zE|AFKj~J`buS!Vm+Z`&(#LL>Vl&%*o+u&lfVs!$tP_os9k%lV?D}~J#V8W_OnLJRk zHYpjH)GMKoh>mJiOpF>$%qhXnI#G5Zt!k_}sNT&FYMae!1f-s5Qj!rxwBgLwV8yfy`ogQy)2$oOSUn_2Y;!mN`Rft zLXT5c(3;L0TxyYpWy|3m76So<8~D3Pq4I zNW(r^T;!Y7tQxuN!^I6pqL4pF%zBixoot@;Y$!Z|<_ZZNTG-w;AbM3*b)@t+2RFGD%}2A)_IQ zAMWRO=~3JGdsC8A8MKl&2Mi@$gnkCR*+SZ#@ORjzrz=lfS6O4=YnNg6i4-qzwYzKJ z%LvcTjKmM(HG`B*R9{ohl}R7~PvKVLw|5{ao_(v)lfxFN{;dG~0i-@3i5u?zRSlxz za&}NWc*^^9uBSy(^MFQbVWpytq;dSJ{+n)=(*|!^Rx6uBbXyjS80Qtvc%Jy_dOXND zmf#qWcjvF^{OhKZQGz(KSb6|CB=!T;`&AoF6|XfV)pbS7q0P0qE z2(A)u3EzoX1RK;~Zc+#}+Z2+qk2f>BJPu25?EBdwmvWRpBL4t;)AFvC8{a>}PPZ`0 zb8d~cNY??=`>dz^n$hu=hGNtj-c&Kpsu*#|&U)7+XMcO9-jU}Bke#lja*hXlf0JF< zdE0Y}v^yOShi@$8o*P8eWZJL3FjS~%Tdf*Wh?Iui>Q zig=TinK73NdT--!2L~Yf*J6E+Mw8swlFvl(hLr{KTd71lW>Cdl20JhZBzyG-*w#Jo z!wnYf2GaG9DntJOEar4#Ju(5!VQKf$cq7IS2#`-v8lq!r=B}!+xpZxH0Q0g6sJ0RUqjBdABLVG(?dLQM|BwIF*hWA4>irn z1@+TIf;+SENmGc=)${pmE-y zX$qbyZE!Wd&=q(z$GQP?n#%i0^`v>3=v4I!l3iQ|&P``;+|=m-V?>qiEOh9 zuHnULLu{_2ip)UE&MQjBQdk2~Cc-2amVrk~$z&?nuDV-)F>_fL76dUMQ5l7d=wrzl ztxISZBZ{UI%5G}ZGk`@BcLPIWg~1h@bgPq!yv}7#Gn%N-NX&98IOrBBEJeAesxq3m zw(h-+BgRK+)0qftcLjJRtfkSw!L0U12c;srB~L11Ez2=;OhhGyX(9Q}OWmAfVW4|;+EL2mIR$*R|QwCWWCwn%};peo@*(xWUGV_%i`dbs?y7nX%w7dqjkxxR8k~pbGoEQ#WiEa zKW-MT=mlxWsG8uOl*g#M(4vM*=P{%b9MeJ?HjsIzWGfRZS@8 z^H@qKq}gIc4%w>B9vY?(QOM-46hSmQm8Cd5RcSe?oG~XgUGvUsq98)Ynn2Wyd88kD zsATcCHGUpIsxYBAtr(Dntfm9mMk)yuRFW}KimuLErA$+}6=XPSY7Eqk8#(DuNEl;^ z)ja~j#+j*I3a?6@7zk0tI%F!RB9}0%X72f_NYt}bFObz@2LhYeX%^#$ftr<&0h)f+YaVGyClwk@%4*a!A)}y@<8p9oIhearL%r9%OtF+X zYMEIMBcY6xq?Q&7Q=_02VO3=npEZYLAId$&H*VI=Y`wau=~>e#4aI92+$>wNmu@R& z-b|2lT-;I=6=vS?%YZXeI(*9GS{wHOI@Vl>6q=Q%kgq~(I^yY+^GcjlSX$%Qj`akI zyzx}p?V0gf7C_0?wUoI~nj%|9Bd6(A<+Neix`?1aysb7%G;V-aKHE~cPBKW@4To&t?q)2O6FjfiX)QQUOHi;FfaobiT+#`JO0um3u&W+BQnKTsl_0iU zaw$aWDc@*ZQ`Bi9q}GaiR3gQ5&{fu%O*79?)~QL4Lc3X_E^sS8Xhu&Js`n|1&Yo2{ z#avq@*w1AE;-0aC%_|Yq(^6nKtJE|fWN|7|BJ*vXqMth329o$2>sdJJI3bE-5Pu;6Yqo&`x zRucLl=~Jem7CMTbX&}(en@3z63eS^GWH}kGlkHKzLMcQrNHXpKtAy@LX&j8j;Q#>4 z$AAZVk}VTZyeiIu7|$h`^N*!s<&5+pzQ&Q@N4cJM19360904r=soxDIL~E2|XMnN(qBZ>?I~T0iMkWcg%&txFr_MND0^ z9F@d`;zp_2Lj%t>Sx(nKTAVRq$0n&g1os}t3cr!4umq~Zx$8;0^R> z7PYsQAknaST2@tb4syVNF^$7$`sCJFj6^9$($?dnLUWblrH@Oqx;mDVYprQBGg{ps zeV@d>sBn6MF;ahR-LMHXDJb=D8|o{N&^60%3ExJs+zGVJL-)6EgY#QCZGuG~-6UbZ z0xQto-rjk4s;OhaQZRAXr+oWny!U4m?W5T4PR`v>mY0^2DDy4EOinVn1M)R_pn^fU z9YOy9Yl^5X5tm_7r#bY+2p%9oIT`MLwT!93^fXhF>Q2^DDB*HFLCr$;@+jO`K(>dTc%khj@w-oR7?vL~Vv$c7Rlp-7=xYzg z{{RkB7?R^n5=#?Lv186y2T;gC_QMSOikng|e|FagC7MQZeaZg->(^|zi+k|z?ah{& z$pnqhCE__Bm=&yK;?;XwHqs&`(HCl zxruKeh$0U#GD@SBMhCtL!*%1WXlNF8{vhym`re{NA$eww<8R6s;h7sB!f-hJMh+_i zRle}8^}=e1VoQ;@Oy9glTmYb+g?eGJ-;fU#-%hHMv(cl9r8!02YK)D3#kJ233;1jn z3!5m`S6K0YIr9(zdU56shGyed!MUg`RATY5f?YxWzPiwl=u zwX`u^MqhF=vnsJskCg3VJu&HCJK^nCZ7Wi?yM^%R%HLm6R~d58)KZT;Jr7IqW`k?2 zY0s@`=oa!3y6PlcZ(i+>QQy|NJp)&{(l6tZIU8m`We2r-L6j@o>lP`x+UYYQb_C;c zpKfcw$_8` z7dF=tTU^A^N{m(2#t1Z{OMGMlUPO`JwIhmrRfL-~)ze%ahNSy5A>wYS-A9u5n!nvPKygrv051VAV!Q z6b@cXLJuOW+rfYT1LVeyb4~Xlb-b5*sA3L?9~&w=}VJME0aw`25n|FDqE9` z(x3pku#k2QoW!W>@nk7(sRdcp0B7)g49+cL! zAo6QL=TJBzs=Vv!DW=$25hcI9OZH_8Q2nV#aZPLCjApNuk3o~hpd40A!*3OOd%fAk zXRv2#(kY=_uEge~i3>2R5!x2TU$@iojEW^Bff3uooN-sg4Yz?-p|?a)#XZ?lvF5ui zBQdR=jxj>nFzr{oYav2tL3{=LV`hw$epwwc;uf z#b!-%yN)SXcOh$KD^aDm4brDs)QT1I+zK7U>|eKuRddBdbo&PssN^mxwZ>nmtod7F zxmZqjb*(!oiSJoOFlx=bn>*8#bPJl-6M(gn?pf+tt^+SxsICiVG(r{~$+qUMY4L*N zimZomtJaD`0xGAX9nJV{mEq(H#nmj80U&c*c8&M9(~+AvtxJ0pMI2R5qOm0n?w++YQxn##&uj-uspT@a6^dz=nH}STrn$SO1&wc9 z#_lmxKeO4}BpTkENSQMwSCDa5QL);u{{UvPj+DlGB_P*KsRyCE`91BG!FF>++)33O^W4~aZtN~-m107y+YHI z-mO3`PV$dhf#eknIW)#Ot5FcH`KY_ojTox12nnYLB7nK41kER45IcI))!WvPM@z7d zl(ZQl%13if`$-?gRoP7eX>z6ok#_xwr!CtKOB$?+TAF5%ZyS5%VqQu0s)a6h%8?S1 zin|?WEzQg9g&DEcyAQ^;V>=hi4jKOdiMxIkR{HuoNdC!ep%8uG1_}C_uM~r7A#=UY zBz6_*P{G0;^tER!>N#k(F3)_3r4gTu0?Iz|J%v!Yc6f)GfaK?B=%drz`_e+}&dk}` zoJYH;^)%dhjB;ze8EA$^`&6z^C$Ft1lwGsIs9Z8JS`t?W0Mi*O#8rlAfv`ENa6u)} zJ3@dziH-$rTX<1!ER5}S$polX$j)(sb3#`qnJvyr@c{x<;~Y2m(Qha?8LvgtbbT#X z?AI2HD!Spzb;da$_BFz4nrxa5y(OC+$c`E}?C5z`{J&h*a)XSMHH6fYT~Su)Hp)&h zxMrIV-LFFNrkt9eg|zK**%4Y42`&@@%ET2sdJ;$DUVR?`QsuK8WpoTadeqTaGhIe@ z<*nQd`r|x)RhaqQ4|<-_%E(A0WMGhK#8TB2+vQ?CX~UHwiN@D7)g+3BG$23d$`4gy zDG-v}b=t%86r&@}U!w|SO^H6B_V%oe5c^QWAss{Y^5hv-71`;gLXn}*` zZ5>Lo=NSI$azDLXL&5?ELcxH|Uef$Qf2Cbp+(hM!GApXFJ6MCBN8yTzMn7p>xXN7} zk6u0;mhVYbC>PE}NUkMaf*{0_HxInH$0I!B(z=~H#OwCy5zgqD$U;fzGmbu(u4lqN zHL%y*Lm;?Ei5caBX5PD5$!1sUjnB~Y&jjMOb)5|9%x^8m=ozx5Pu&D(`qw>K^I9!h z#%BZa3dmJS=Lh_M#<(p$+If~aVtGDNLgRz$ z&35Wu=T0%c?b~=G*A>dunYje^7fTBmrAB4R!{mM(X1P5}Prq4ONo~=xNi7~o_dP3S zO;&3gEL?`(vK8IaIX~fC&Bur?4aAHY_BKFM*b&I8iURJDDF{4j%CmZRHLKv_x}Jfr=;+vKp>rQS%Ceu= z6;E!zOu#EkBxBq+%s)`oZ(>=I;mua(NYV9@j-V~LUn#j=<<&+( z{{VQ`cWEA-;~xr7Zf%*?Rt+o)Lo^IVH^dvZMs}V$*8}6dCT$bM_f}9Wi*I)#JYyUX z&$|Hk!3Le-4-!k^oomXw^AQUHBCx>&*B?Vx)z>mIPg^qIhxEI>8Ez~tCw8@Fb%f&t z^2xg+mG6~2gZlWnSAtT9f`95Y}V6e zwRSrhU;h9?HP)JyH7=$as*XJmNceHAE#17DCChxQH^f`Bdw-tw(rOwsdbXQBnQ*7g zM%@wat~(E?{*~jJ4y7iWcMZ&E=0@atiuZdvxb;g5ZBpEWy+Du-#8*uz-ZnU^!kasD8nf~t!4a5(PV2_b!%kID#d01a)q&j z{^>uKed~kLHA(b~^tpw(Qa3MV9+h_zk2EjT=)7%XC62n&4q=@GAHIfX49E$99NgmtAB6(wJA(ZV|)a8+Z(Trf~nwD3yAUBx(9%o zr!}TeBD}9^k3z;IYIk(42vaI4{{Uv&+J?#spJ{P&q(8|FDUWBpdQ%qT3<0eOCPrRp z_LeDF=C5oVX8_hi+RBaIyUF86906I9*&#W=tBqt#k~vM24_ZKGR_|Rm*cAT&4MzHU zp4EQQGE9hMlfG)k_9L3mOAdNd+QZtHJV44fd^-&uGC-WY2Els^a1t#r4%)jyF~7T|wE0Cb{Ts-*+{wX#*)4shUK#*}k`oR1DHQ z&fV$-L$p-Lg}T-^vjo{2sb%JpJ96#;6>G~;QlLd3j8%I^S2HAoPFBW6S$!=PbAd>g zN{iN+HlxNfSW0qicQfxSkyPLc=WieiP6cmWUGE05ZV7U0T5@Z0BxAY}P?T!ZXbX0x zHL>)rl~98?BN|<;S_^D_DSpg-D!rf?xM4~Q)&BsqA4&zcwJ&IZ&pZ9-%hsRSN$pB3 zi9IOxh-P39>S`nm1;$#lE;Cn}Vi&DP6}eiKt;ww9?g^BhcF$Ui z&vV?>m$o~qKOoSUT&~hN?rO8U`kK&a52Zr(s~=@=N(HkH)cLM5#lGGvPB%qS$gGrw*Ve40Zby2FM&OxlOMs)TXIx#kI5lI) zcJ-*<$(yw(q=$1guHQXPC)(VOwQcnF^feP$u>KQTriF5w$jo^(fRJ)3+gUfEr28ZK zRdWvGBe--J6)3%v)YFp9y(&Rwz;va|E0BG%Q{2=|JF(=|rnO<(nk}2sj$kW!j(eI= z3m$6P+A-}?Et&M9;8%_=Dsa0^T8`L`)aJEg&{B6|xmY#@MBuh@SH+W_)bz4F#Y@l= zF`6grDFQg{Tfbw+YKg5!r7m)ek0siimXDtGsrqIH`o=9cblf2;R**fl>JpC#4hIoN-yRT)8J1tAu34%W`>RIK@04>1pGuW<{{U(|m~$9w0raKvTDQiWeJOvlkN0VNAm=&XB+>|&S3~`peJMY) zPo*BjIm{i6iizWD=$lPH-KI90Pij4ga~#vg*s7Am{MT06Vf3h*NGG*5PQtmzJWuaX zG%jnkZ5RETjkH{U4N`@G;{MM5hLh~=>0OKI82%c8w7h=}K2aQzw|`1cA-yZ7Z8smo zQGJ6Qr~{qy8`6`>aC%opY<;PXU_C!dR}p|CZ%TTh?^_LFj)I%^Bk4(jnY7bb8r5qf z=~1w3R8lvFB;>9zaZy7G72H|XhfFc3WSE$pPDm&3bzn2o>0MH8D^oO+dKyv6lg4B` zGj{&I)fxu#aJ;h|D5}$h5Tl{S)dM5F3o|N!{>O0bniWesF*sjisQaoX&m|JNuE21)&lTvNAIs?oF_Y!zrEntFRk&yxG96oK2eHm8(sWpe zwT*C~ga?k4Lq-)Ig)cb4Cf8zcKnMC&Ul?hts^~H55TG|ULlP0x#!vprdHhXJaIr~p z%2kwq2_B=~v~;V4S(*t{JWdR5r=uYlIigDH%!oFJ)6RH5 zms4CWy`xQ`>atr%GM{=j{_-A&>)89&)Iv`P_@(W^Z?nmUjhpz8{nPkz54bhec*fA{ zo*zqyB1f7NykLCW0Qs@_VB^}e<+?WK<(2v~$=fvO&N@;^2sDU!#X+d)iQxNGXnIrS z`=X;xyn572a@N4dZ0b)&7^ZZPeQ{2k~IKJEw@CC#*Q#LPG3e86|X?N=6>)SXk%>;4_AqfOSQKkCsUh!1vs-^mSn z{gXDW;i(jm%(3Hv#^L_})-}rfFVQV-ye+9b8^l)^E3~&&DxE)5`PTmch2(o3N=-iC zNTrETq+kPs&*Q~;_1bfGJ1MVq6s)$#Dh2nzsj^U_kSr=F=D6*1oNL-!djZ6V^Ok)RnugOMF6<#j)ZhIsI#wvo1kiJ9GGo^N$t4kZZGufK}WN9^*9N^{_I85)?az3C~LFJU4RBc!04Rhe6YW z&TEQSJY%hNo)?gfN)o6(Hs&3T#`n87=J?5=r^m25IwP8 zPje$$YUw(X3f=O3iNXGLv{liZotf<47Om1<7S{Mf=C!oQ?Sr(0Y>b2T!2CsXw)%FJ z<82l-FC~@zs)*p8R@}Jjv5$4h;PoG+bp9;W4adU^ZA}zN+o1C>GlCsM=kW%yd@ZSH z<62m)8DoOsGbAm7jM(IlPo)v~eF^GdSXgU1ZN<`DrNmOhG9-h}S5S*@BXsPigY-OC zlWL4+mFMfZ$n6CK;=_Y8cwi81G(YV#OLSy>P93{}l8?X2|}W>Q1PBCtP0MLBZ2 z6H*+}XVT4S70tBPcL=gWDin2L!31L!^S+~I+IFjTV#hv2uO9DRtUy1deGR4FCH|Xl zbcZG51fP6Yl6*nZ{GSp@c%gPq12zUQz+?5sez~rw>vM(@<&~L7!&;Nt84=`R6o4rN zWOdDS`ck3QqniL1A)9H)Y}YNMSS-7qGyFd{KXm^9hg#_THzT$0kpBRF859q6?f6!a zVJ+FNuNBvgZ;=_5w|!QO6zB3Xw@7mD=rG2gnCvOno6xT223XD%}E|S*Fvkwat%Ag77}Rs<;A0NfbWd@ zqjD=Zc{TEtDY!|+?vHX66r!3ewD~n&W+ZV*lStV#k_Ri5STSn32H*!;jaS;NDZ=!p za7-EFn4rJ*!=<{i&a4=cOLZE@vzr)iieb z?N?UY+NVo=cBY^gDJ`!ZDX(je)vU1b(uRkQm8U3-Un3or1%Oltw@TERW2Xz8d0%r>we-KPHlXOHgI-;^`bfe^<^zCm*s>0m#* zPirCl+Sph}r940g=|{5*oa@;S?$bWRKf7HMTLape_EG6ek&Q^iTOsLA`!F4=YwX|- zl@r^KN|y$QdzniB2c=Aqucc1WVDzSK#Vt@+79^pf6r+kpYL>&4h2!+9%^h53%|yeR z&SgZa<_#GILR=#785gSXX0Eqd3LaJ(oRQV9 zE1s0A4>hW$1SuAJREr5UVIuaa)+!Y+C^fF(Q2mE->02Tydcr%3xYHA63u)i%)Mrk| z@YhS^0y3L;oXrAm>3+Mc4G z0Hgy#4@z*1dQ*isVwi?`W73n$9+f2&1&F+{=~4MZ(yU^W6fi6KE9pt(uccYV0ci}c zE+eX?$GhWQ}>n%r*bS+pw{ zzCrY;ni4x!+gp!Hjje~JOH3?cG+xyomOU$3?XlXRYkVG+F5zN_mOUvvuWG)w{?zer z#Vta{TSM(hPlK-q{ry z$m%OOMOx)2sbbbvR8=H`4pE0=UW?&PYwZxU6SvO1pK;jNn8PsT9N-@Hp=)<>Zz{-+ zQbhoqAG|)D{pzVy<#scvPnjL&v7wgKp7PvfOk9D~obrDv($ZWQLhUR2ut@2Oi^ICS zTBV^!AWWkSzvs1UM{X6#Py=@Z(z_B*RB^V}jOT9<`OKk)0o{yq?}|%xD)H{XBoWuR ztJKYQ>pg(A_ZOk#rjfe;GI6sM|_%Fl^ z%GUQXXUamsnEwC>AJA7tVyM?rK{_izG-V{+(4ztxynS7*uO@{gB~{rs1C7g^XYs7% zE>@Y*PCW5zv3FBwX1uwQ-Ek92?HB_XQpX&9D?K>;>fsxqCu!P7GgVbdY*fAOX&tN& z_W`J3=XFmn`lC=o*A<+erjgiu!}nCi`JzYf(A15}k=mn=m>GY%O=m62j=>olSJtej zJ?g5fC|vq>sgcMukouoad?K^*`~eh)8Mv9`$o9gI{RXZ0ir83cR{DY{2h7_iIM1Q| z59w6C4PGtRfFg`GS_$MrJvj~k0JB$Lu38JtHdxB!mB{*zYs;JW+h=TcMGKXNS>wqB zOqo;bQ5z%*67K(t&^XcMd|gflg5pUTS)z6C-MXQ zYY)TAzWUL97!zB5G$U<@Ki^~j0HD+_h`DZZ_fa&q*icT3bsQ7=tX%hxuZ!wr{Z`Z0Gl};QoZ&eT;u3D`U=_-=*;H39oCzug!n~q zFjSDka~@T>2Xu+s{smO;ybA^V@ZI=&<||vX3QG2@#48isSab&+J!?P0*O1BZvsr@W zw?>j%vnrpPnH6*SsI84lN4I@*O_Dpyi#NEojlB5f%Bz;xm{KrCa8DzyeQ7N&iQLI+ z?LzNTxouZTk~tK^Zy{vlH5)Z1LLjBJ0INc26c)9x?sCD*S7?aRk^ z4b&FX5}QPfkw`O-_PS@&n&Wi{7Vk-R+C0d9a6ryfj1l~ecVT`Oa^fANjuv$&`5i%} z-HU{N&HUpoa4(a3WK~)b@*wieWyh>j^MO;3O%X5G_;Q84(+*C z4b5?%4|R3Z^;Ac4BaqbH|wP{L%j5lDO zpZ#jFq(kNSh-}^EwlR~E4tjknO7aD@(tKgM=!vm+SUc~O3 zI>>%m?k792WpWNW{KmDfu0Ye`lpaP8*0PzIEXy$YhH^8-CZ%*2LytU@*V?a^?HL)K zI@3+gpJ%F|%P;Pv`e!Tse>&n;433rS*0zhOcv0=0bLPfE=hSpRo-53JqKwGH45tJh z#=H!D7400CQ`5p!ym?If_dcwLC@bR(!u|aF5!LW*o&&FWR25`&E$_wKzsSDwG9s6^sgyEl8>DP7Cc; zpceq=Kp4LvD@@tet?Z=P{>@h?u2k9WN0(N%Qf#A?E>~Fns#J_r%9P-=a)rpY(lT*V zVvJGB7b-G)Q$p32T4u~raSM@c;+o6NO^RmPT%)-OS_0JjXjS&5$`>HnN)w)yWF;!c zRG=}pT6)J%5!EP)@NbXEkw>qhunYP#Tdz z;`XZYN5=xRT`Idrn#OQ6jEv?&DmJUn4OV11tXxY>gA~kFff+Q$jMO*|; z8cl~Zatvyy6)J&DRXM4VDRPC$V*;kz#WpnNtOcr!1VpLNH7cfiQmP!(s&r9#S8szq^tDK}z@&B3dXxtC@e4xr+z$e9@x8aqVcl;DcR=*zXy(CHep>9<1S zCEby=<8CqDy<R@ zKjB?8YgzKMnzbvdqtfoJmP8GJzyhRwd)5j>$#CjV-6L*&4RuYm(OpPoW#Ep6vG1++ ze)Tw0!S*%Q^*GbEgm4T@3#RNT1a-(i{c7|7037I$=^CZA&7u{xx{q*N@UFNF2jEoK zp<8^)SR8iEVR-%zKf;SJP))q(+0Q^hQa_brRyU2!=uXqOa|6R#*QE*fsnACw{E?$bM^K7Q zE(Td}LoWm#2&HuN3p9I&!0X>4!r~Txk?xsD&j6HCKlB>*iBL37q-P-4&mRk=dwml2 zWF#`)#8=x0+5VOE6_vu>Sw%P???8C3I1tk_?ub~aq|IOy`e?;wX54q7t6YqNMAh)x)rX2M11NtoD=)O$n9KCy><3K ziPx74wMyM1e8bVI;;!sO*^{U5(>yccZ8lUY@w7-m{_!}y$Xn3D-@ny_@RBemvGD`vT0RxiXfXC%td!Hudp>TY;7h{}p zji>zn72axBw%48~)FfaTe%Z1%&NxdZ$LhwoU2P0gha0k_XD6EM!z)1J#J_znBZ<6^ zW3ryANUD2sjy+bjwP^O;NrRo(bv~es)==Xk+ODGN6yAo8lQSd4>f28lImLR7mab-s z*t=wK3C?j|PpAI?%QZa>b~=6Pc@e37uDwYd5t_PEvNNq4v$58tRJM@|fLbzmJ$TJy zcqv$1%P@WvF&Xdj@t?+z6kZ5yBXhxTkb%?;RK5+_7MU#Vo^Xdf3COM1vN^42oejkM zipBlnImhW)*H>R_k#yw4Fm7;q)oo8yOGsyt+ixXT*FCBJ6}NXmeQ+}*gq6)`o~CxP zx!+g;ZEJ6CqX9-S>0CdGG?%v4t|pE)@?^vA1AtFo*EQCq%N9_Jxs>O7$T5wvBM^6#a$`>L6or;hp8!EX)axf{uY1=8mO%@A`+eX@c+*0l0oriKQw3}*N zQL>8)5D0zFk_|Nw87M z7b}FPDpcDAC{af!u0|4`sZszbLe(gR#%-f+YEZQ8wLx+nw3{k@w3|&9703!xcGT>& zn`p3HgKaL+)}+NMtvdzC!qe4#Y5QqH;+jGbFBJWPlnPKPk^wf+ww;PGRbdgbie}$h zl+ze-Q6^F=I@Bzptum8U*-c|5a+52%3{`iGX09;ep=CL&+)GS^M@Z0*O0bK?47D~c z>G`dsNE?F~vx=D&W-F1<2ANQwZtG1w0C*keeeB^HL;LG;!`e z)h5lgX(Db!v2ZFyik>k~L7I0+LM(KjTfOAGD6yZR|;+wXn#W!sLL$-pIHrj5{O2AfSs2(x8uCS=~=8zRccoc2LSSeAm z3PT~qar(8#pQ_FWD;jJVuEs(VCt`3FNv}JGLnN~~IV?+8ZW0%hmt&f{(!>aM%vf>B zH67vsBV(Z%6)6}wK9o$m<5tHw#dn;knC+Es#-@%=IW)=FYh+Xbh&2+>*=mbY4Z|bz zsCo|kREXfNC}qg$Mbiz2D`a!tn(3ZtSQYwE8`M^ELriVFrWsT=c4zXbSsTyXr?z?S zeJU9gFyf|(_h6n~c+Ez|y>&fHz+NK$(6s)`xg*Spa~aPh3hOVT{{Tfe$NNLr*M(_% zgt~U7w=ohnxFGbea?`Hj)--tTV>#TIZ)53Q^eS^k&vVbjQ{|P`%%uc-A}U8x2(EX> zQv}fP2;~n-kGVet#?pOLi*NqKqgofCU5V!X2TzSrAPb* zvaMv2CCWD>cNwQ(u`EwMwa*GtQ|2|4*DopRpAQpfhGcvYX1;&KDj*;F6IZl&KIhKU z8WuTd-2O(qhr*HlpTW98!3`;vQ~1bKAISxJFN1CjdW%J$mQ*A09FOZ*)%cq?roF?n zb@|$(kvBj> zLOi%h&O5boa&RkHEeT@OZA~qv6EvN=`1JnZ}txXf5i1i{V`wWYA+8sU4GX;N<41FYuNt)rb+#3Bk>f<`YYo4)bdD?cpqBe z{BgQ39BM2-=bGfLPcS+;NrJ6B1~z{a7iCSSg-fZIqW)YlEt|~ zI~v-vxm~UpoQ!}CVA?j_!_kdcGB7MhLsL##7bx7_*L4)VOGuHo1sP={p~f+q=%Buf zN$}OAau!yYGmyP_;A7XRt`^-M;^89$b1?u`#=Cg)YJ$=~xoa9i0QCdr{{Y8{t>Z4I zJfX5igcj248j9Rrw%8-a$oSmY{`aP9x3#zl8Z1bm0K)A#$F*^KTE`u_%`3+mFd>zj z1QFi4y*gEUb0j!oINYNk){&8n(bHMG%A=ff$gPV;3fMh*S2LtsI?g=IfLjE58r!;K z3oM8m6r``AlUkgwh%J84u3Z8+cHTeWT>k)#X6zNw_^CvaT3smN<0yWh{{Z#tpRXFE zIcCx7QkCGC&4P`BoM`5v#oTVeM!`;_H0%R53QeM)nnOy!Gi@kAN)0;h~QY!tbr z28#v81QhVJW|wsq0lO)7QtqYA76H3GsM$`<8K-0ec6(8?+N1B(*; ziz$p!JexbxsvWfxrslykPN?it6yZ!1;A>K>J!$JvD^!YT81YL;4J`mUO-KzyDd5r= z;AwMA%{w#*S}6gg27nAwid@rkKq2{}nhhv4hB#A&FdA?)0N`jenWW7CIMO#XnWW7C zF!ZE2r)H9n35?SjY5Abi13yv*JvQm_(l-88=1@3|z&-2J^*~!mx>f38Z{=Q8&51|* zHRxcz7IN3sqRfYK6URzG{{XvC#+V=FE7qDDXR`@j&uc^1B#&{6>nlM)Pu@jE*ru#O#Y(c{0Ma~VdsJexX{KqTEHDk6Vxc^6ds3tAKGgmlXuZW^Ak-^t zlXqjmp^$-5F+B}sE282}GZcJ}y4XLJdIx~D=88dR=l5;%FF%;CJW?c0hp6ak&Xsib z*DAukfn#AC%Lc!5zn2H}1Og zQ!ycU^{Td{42reK8SHaP4)Gk9ynBomZ)f3e4}-uq2;V|kiT-uHpj;TW3rPksyaS&@ zRPTbnh4hdxTG?LNfISLr!2FJCJuT0cjonxp;-0#lbo(B<<06n9sM+WSX(K*l5w~_w ze@d^ZP2_1ea)XVrI|J{7Sd8)gLQ^&T(lI2og|qn8DKKhzj$1wI205;TtcVymrZM84 ze)UGjwIPh}S1iBR3a3`=zt+-YTb)LZ+cm33?j#tg{B_2>J>pO1Yd+2Vy+YaX_heK0 z){l-xb-37n6}q3*sw43f%sVCm;v!BlB9ea^!SQUuFwP`cETuywY5{$Xpz5x;P(_pUSf?6tXB8?lX+yr+}kby~13Q?-(x;TwuKNwnakE zy+_{3>t2=_S_t!T58r1Et6@l707gNqMjh*GT$NV(SQO`Ll26vLn;EI7X-#NFZ^O9s zYO$WRRuhSz>r?txP&JY@G=@uNd+7jVw;Q(S?>F#|&lOez^Uhu04(wR5?oa;!UaCte zAz=pqa>LZst0Xc^hz3r5YiLUP8A>+P?X>+7Ca~s3W+|VUatZHC6}`=r&hXuYkz-sS zI6NMnJg%!5t{^RnPEDj1G`4t*+~pMH;apt~p|lgS6`S{(Md==vqpk^p4d&5usC z)m#(ghX4`>Bi6W$4Y4W&afTWC*K->Nj|V%5$<15tVJ#U(NFltoYe{%k`J-;=)ydpj z$!R;mD8s48*WS9>?VLX7*bZ~eP}VKJ)oRxZgDfZJ$8`Sy>l)?6(o&B+cSiVnyswq) z&TP_W6!ue$)J^xR%2g5GJ2|Ay3Mj==k^s#DflgJ;K4b%NMrq73OvY*RAQq1F;Iv|n zWCMSOmo&Je6kG)#c7QpdMomZ(lafF(kkj_jvX?Rel(g-Xg(>qO8=rby(qj};Oa-Gf zhJ_S4SOFwnMN| zRGVp-=CzGf#bCt%Qqh`Hs)E5xW~XMF%1vhKq1Zs#r!O?Xr!^viD(Td?STRY8kWs}` zsb(t-0+*#JsM)bs?KBmKW{lJ#Oq!E+2Q|-9vO`FbO)0A4P&%4=I6uW)@U3<`3hjle z4RGPHSDzTFEP)w(NtE8M53`Nd~4E zi@it69%xZj-dyyd{_POOxa8K7#B%H_4v3bee6~OpVNq0IQ+Dlan$B3OA*5zXUM3i; zkW5)Jdeqa#k`4gPQe`RfiskypGrJv&7~a{dXf`O~sY2UGEmj&(SFLEPDFua=U@0v? zcc=~=)rdhwIO|(RvkMnxDvQCY9%0=~l6Pjo=|~t4txK$%u$mzTlplIvG@`wrBnFjR z6v0kfKuird8i;+`cr?a5Qi^Ca?9u_i($fK_gFp*Qnr>*#0v95eJkxVU106~!w4l-$ z`cX_2>Hv0Vq!g42o;=s^Wosr)P0*#j;`d9R7=zR#@5w;N>n#y$GiW)60fUCw&Z(&ie!S~q;e`_ya- zvB#|ef$v@NS2@YIWlm}~VM)9N=9tn9nclA+pXm{S{AF{$<<^F z$3Ve`Kk?d+O>8RJlP4qXD<}oJW!QB80D*p$YfEllHOn<-(bY}d^}RLx z-7eZrerS~Q^sLVo%wX{J*d%XdPCJ5nRs9vW=(enKa~SJf?~m?w*xFl<u&#YQOpue~n;qj9^y@?Qioc>FCcGILY2~{{Wzh^ow@1)ND<}Qhd;}K1sn` zWRP+A*OmAddxNiE+{equZiuQ-GPhrp_ZjuBy6aT8wD8Wc9rdJ^R|3jY<|^PbGB(nu z*CYyZ(?VmZ%LH_?QqU@ovsz+RIow$!ax?hn@u+8SA{UkMwNSaopwIYJw+$S2p%PYQ zUm-S=z$tGYe^)h=u3QAsZaS+F0*rd~{f`qSU{j1%}rCb5g&#*GEKH1hQTvE`WXKDE)= zTWMCVlFzEMFe51)yC2k%SZV@rI3CoYvz%7Ye5P_-$Du=|Xxj4?U0UIlS8-I0RQ@^6 zYQ#Pk(5-g9%ejyHQh-14)fK_%H_u~!lOt^-gY-RXy|>j;;UiGFW?%s6pYz3ZLP|*I zlw5Q*t;$-gX4cv`;|v1emi5H&lE7iI z8~Ifka@_0#$9rnh$2!JTftKhA=~S)dFQsElew|r_EEwfYi$nkXT?`RD%PpKVTfxOr)CTmML^&T7m87abRFMK&O;*dm{j zR8(v7Hx<_`R8q1F6TEA;fl);sU)rVwFy^L>R1AvemLZ2JBCpB?LnafYIpzz%sGWRB5k}AQ7lHc4pJMrwpAs#EPbkL#V&ZN@TLt<)*I>; zEUctrtw#AA)l2|0N{`qY&Q)Bt8bz5{ZNRMQvJPt71J^ZD;kYBcC{9CYYBokQ%>hYj zTU5?Tsn`W!S~l!Wi6BxiO-U%orlItww+qjD#nrRWs}$5RZfbBsCTXld>DHomCm_~} zuQuUf1>y5{=B1KgQ#t0d8NiaB^OJx&Qk2^Q>~oSxG>*eH9lGvZ_cS`beXBH^dH^)I zUMeP;&kAYGm>qej(SLc(Tf9(<5QjJ?HF`JLr!^9gsxT@EX4}@BD@krU78?!CR>|CP zN|TMIph?F1Qk!n*M6{xs4LEkMtsr=(4%E>~4FEl9;-eJtO^kS_W|%2OO~7!a%`_TX zU@mEMO`sY;Nt!8woj}Ea5xDo@!8K&lwG@Ak0q|X$Yq|HN>fElTP z=8m+gwJKKulM}a!s*m$v)z$!v8jI}fyLD3tlSKGKn&Es@!S!YbA9XwD-kJ9H{IBgDc+^2baYg2;>S%Gef#&<>!By0y8m zouRpf;*fP&7Y3gb%L}U^WntV`p?Gro*Tj}@r)u`gIYs$pVe>DzZlKkBK4saH?HqU2 z9%AE)g@Dgm?fgsNON}XB?!lVw$w6o1=Zt%S)O(M|6~s6uxhp}%>Td}tE2dr3ZakZ~ z*pdRcZY$J0RXDux9ksx1-@Za|?yX)zjkZOvO%jW*hBB@}Xkn z347I!iUn7fyyGmew?CSjcb6m$v*G=Hf&Eji9xGbq7bL|@+ z=~&Wxqe*mUr1$`np=+5Wmw-QC?z*4xt$j6y);aH39}guXP1aD3O^k;J9h92f($DT# zpIXYQw3)pvVtUty&U7n7{{T$Iaeh3X%+?YtbL$g-uBNgX@cy40EDrABH-G}Wtq1yo`x%m?M^NsSl7 zWov)MgiGO_4&yo688h_@{{Y0-I2+~WxAn&JJOQUTC*`>#pQBWDDV&QpJ$S5LVX&%y z+O1v0j@6N?^Ahvbs*}`-Y+LX+ym>WqX0WsQVE*;?fD~kqdU4jfYwd1LTfusg+*wA} zv)M`HN+w5E0Buq`@Yt>g!iWAOn$a6flBz_x;E?hv5D&OD*zb<(!Z)x<9^`2eqiDt% zOUx9f^Q&&{lO2wCQ)0Iag%wKNN~~Ar4Yz6x`hCoP70vjnbdJUtddTc}^iV&>wys9m zi*IIEmRUh#{pqCsn63|5y!&pYB!HcZ@+N%;`6uzOMh?`{Jo!hOt7dsUx>Eyu+|q95 zo0{j8j)f7iuoB3}pfw~T0JC*G)nI;N0qXT-n`(hs##Xy7O60ru4|)S~DkVAQmz?ug z8MZ@>i%2-ndg**W=TChTuwseNPAi&>;YZTDzXn*!wo=_-?P2ockVks#rnEV#yBo7k zBVuVDX+&helJ-)b_p@ ziryC=XeF6=BcQ1zw`)6iV{%&=RVUDY`s>NgF!6MKs#cQxio?p&GeuQ{pXT8qpJPl`;|RV&HpG>MoBXi#a6_@^t3b69&uF&N^6 z8>%T-4wSIHSG8zF&bw*`IjLk|O+>_EwWnI!iGrGIwkkdNG|8U=wfe=j3l94nt5dQO zU;`lc;$GumCowWCqD6IXXxXUoHCZ&+&MOTJEaf*^x z!qm!l1d7tW(}7jDlGvhW%W+MGa=_K8XeM8Wh31(LIn6aurWOQI-lTn? zaZzu@GD&c?(HiX`a)|PPc&M6VjrG-y= ziMt5Dylu@^dw`_#P|G&eJn>nwPr0#E7`6?YP~2`kYQr+^tZO#;xvds|lvGUuWT5Uf zVOIjFLf=Uq7~s+*iZ~{# zQCxoVJ!;%cS$owsA&A9Wgn+ci5*Y~%NRkcMq`4#lMN&x^NGjBBft&GQrfH7FTZ)1y zj@(j*B;?joi@4JrD`jf3u?kHJ;~uxHY31?uw~N5e{)wq@KfLljR=fqMlN$Dax&po|M~!%JWUjO9-=TF7?Ul zMZ~0cs4ad`NjWC5vP@%q;!Qn)W%sDzRcGd;nni?jR|`1^rqG?)H2(lCcp0eXxCL?z zS6PYgTgsnc*wwdmM!`H(mlCEpHJFPd45o8dV}eN#zj7rWnjxxT5^Sl zCay;R0K6j=jI?${rE)bi;Aw)K4Sj{kADRKA9MikfxW_4{158?QG?)(tlp2g0a-P*L zRv9RzrUs{Gg(L#dDFLH3R{`0j2BO_gR;Y8Z$umkSFlqUy_Ll*3P6ngR8>r{90!-1G zhjvXo9x7c+=mY7k_k{{*YKhdc0T^lM1j-s6n%(jePGluD!iCC%_t(#90+1@Byn4@FBA=D6aTmuXo8UZ7rtz%cYoT(?V>M&aA z*LOQ3u(NIBv`PLIr8R}EvTkcDa=Gmi{{V$~o|CWKX?H5%??6UWn(ws#02o;6afqY< zJ~6ero-1h1GBK1V9md{YX;DUs_Rwx-#u_C!Rn9^=~M+)IXLSO?i{?t5*bc9Wzy7DUjHDgQTu~j|>&fCIjZ1qic-IdUbDalqD>V%KiirUl8Ar+H) z-`V~lyOgdP<{2S>_Opf!_=g{rY1p6LC>>2sCN`T!xM^Mqp3S2GGNMPcHA7w=a2V|b3=1eHNNqtH9s9`jaw2i zzUZj^YDVenQJnUq0}W3J#wrf=EN2+0Wg_P9mbWk1Kf{1ARWgP*5Z2pSt`VQL zYWR-rF7>B)ommnXqEfv+NYPK~4P&!cQ=21#b_Y-w9I0lp+DU5I{DLoBR8yF?G z9+{~me7-wWar9ab zOAZL;ymTBeBalB@_YV&0mb#{k1EF6!IKW}<2Q}MH$0cjnx-H?!E{dmb1aU-QZD2;$ z&reEY%pF;WDpxo^%BuzptVUIbO#0URw>fTUrP@NO#lGmpQh8*#V$n!44@~u_BMme} zI1JhOfaCG0EI~l#2N7YqQWI zSK8FACi9AgkEJ;Qt$Ddn6Q}@Yjli0T-)i7eBXdydH=q|)zFbsJc&L2R4;06gns96c zcKNDkTZ*d0^{Jt3)XCftGqEj78v>IQF~Zhq_XbA9vsAxuR0_vAG_NPiic(==+xIsV ztVtCVe6~+Yu;gvUTxDRfO`mI2Zu_X4lf^=EqOCiC4mqi#o3W_6twbAZ(;1}A^6^w; z3|lo}TXN!uQMQh4K&65@)R4B;sGY!KGfi0z>Z`j5&}S^Q8lf#phjN2YRtnV&Wa_(9 zilK8O2CHo-#wx3*cFjUsfi;`60nJ--O7m6i&>*Ruhe}dfgi6erYLOQLnodm)+ZW!N zOaY&oavmzO$XU6m(B#wQU_A7wC(8^9otz4Zv9z^Pi$gPHCNq;%<-Z8n%{x-M30Q%Q z@5Ob}gKF%C&VtrqD-7}~?2f3vEo4~(8jaO?n|cvfDtFjuqjfnXfNG+#cByAwtaC-W zZah*^QA9H3sp;)k8eW|7RpUU5?@V_+D>oaIi_kG{oYnMF7cE)V2j&^ANf<17spLaM zPd3)YPO=7!)=cuVKg(8a*^2W~$df2#%zzRqlE_)`4LR7-OKP!){po)ooBj1!pIv zhLL3(Y+#y?da>udG{~>=gGk5#$>NkFXLc7Kg(HsDT5-FzKhIR-G{>1(WYd$o&;*Hs zj2c-m7bc^OhJGs4h#7HNNoodqONp>5JLWC{6>%)UZPg9rL@)qmx2F|-1ZC`Uqdh7} zA|L5~ zE*IoAPT}!B2d!F;U9k-Hts>gh3MGgmBoh3SRc>s<%n7S0ISLPIse3z|W36c!B<{x9 zb|_XjMh`T|omNr_sOS#U5ZOP&0hhgRjf00@A+}k0vSr_!P%{iiu(rv;t2*8KyPHcohQzMMkRIsY0#5 zwz3n&L8x7&rK?EC<~%6(r~T2^xy^Fp%(>WGT-+9U zGoIC6;00_Bn5o(&2YGSqG19BdRPuSRt5HdEqlWJHDuPcKr?aX8KZww*pq>tDzS7N> zJ?L?3V%DOwg4rF%G~|7}b~PT{Qugam;L5rrW(TKgZxqb%b4!s>;?ZfLbHJfVRs<3V z=tU-aQg)yXcr|N)BX)9GaJeV2>05UCqluhkFlETcWByHX==*xq>vHPBkl>C5X&R5Y zjH#!xJr2_N%Ah#`v6|k~Tg+}-4UCHOjXzexx0uIrjDhW4*M}xDatJv2zdGorK5Y(Z zLzLb}Q7}+>9-m6^-C2uxuT&=_o0&O3@7J=$Fl)?YXFk65;~LHv#oD6hrObo>03S6N zoh)sH>*!}(pPTcjEyh}(blH`KHXam{UTmG_dJ$HLvK+S+BqOCm)YYg)6jj4lawV|# z>rlAGOve=y^!}Ao*ikCK4P9@;f0xF#C$k4r&-(_sC;QdV_y%Jajr87d8bZICk^O6$ zAH+to_#dI^zAsR>R!$ddE+cMoPhL;ppjFL0Ok#W@E;E(&{ z{&k_FjrUf{dNhhZTGtmFNqP~3mEe1In(eZQeGpfT-LZSAT=#ZAt$Qp(ZK97v{*~i5 z1Q{5QQ(REo>ngFRn}JfX=M@ultwb@6Gb0qNIHX~U0ApsJy?ChGih8#-ENHX*711Ey z@b>f)-z><$5$*>cpXprSW45|WHFnt;iqyrsBQjRZuHLRs>rk=gjoHq7^HH}`S0+M3vr#$uO+P$T zPJUi%DLo59!rT!^KKaM3ByEPl??E_oP?+pmQ_`%$GIQxwQ2e!SCEBa+&2>{Tkn_^C zbd6@`NV*RLkd613v8<<^6k(etqWep+z(bEy#b2~hdJ^gLEl*0Z@uD)PorQ8vaNKfh zV%J=@xR(M%B=A8#)#Ji>SNK0#dR|Wv1Z7XNR;v+h%$^-Rk8WFmxH3Nt@Ay@_XDc9c z&gJBR&lTbk>-Vv3{p^4#$obC|tzqM9%XayvE$r1x5f*1GJeJ4M$turkgdCCp;=JfH zEUttQRfxf)@W;dmE*WjEh)j+jfIgMIt7&aK!ur$)NkC=^&*NSubA^>^N>J9%VyH`! zZA+<;vU=5Nqz0Wc6a*d*rBik#jeLKzY3g^TI5tgMhz4BM0C3*bau>qX%H;~{%`-Us zDU!|e8jT-yD5fGn*~z5O&CNMS%Tcop*sWAug2K7trG(UNjkK|jDjYQn7B}aLR^$qe z2hCDB3NuqE*kmsIY90Ik01Byfa8-x~n+)7?XpK9H=7K&cUTzIkNyh9_yJ33OC;)l8 ziKerSxu{XF^h|v#SixH0O0SVnvwYO(!P`~mlWSm6$}>XTlGORz3e?R!Z>et=8K~0X zV3xgIKkB6jq+&Va93J^9LYS zRpYx!g{xY6zss7|P)auy&G^^Sn;^wH7Q)mrzFQftTk1QA0o_XJx}-(g~c;}dR_kjAtJPbxX7Kb+i4`q#Z~;n=5yApNOwc{RXy|(%W6pPBLUK*u(fc* zBDH3XUH)OsUA2i3K_FLTAG={Vm0mVf7!@Q=3iH;jKG)!4tNA5Z;)t}KprU8qe9grz znjQ^UmI8S-X3pGXW~QT!t_~zq5{p%lx3&#!Tw1HA9cwvlU1S+r$}&%2v3|}16fhMu z$BZ78Bmk^kD!s#!)r}H1C-Rr^K1Y1wG*1 zG03YC#t~??f+R?OUX@Zr+T>Q4by(_)5c7UDHboQK#6oVUZY~N*wy#3Skq~eyvqF-} z4`EtDl8{`i<=rv?q>p~kPH|cesHgzNR(1hOsIAl^5=t_X&4JBZvxxT;K?dgBMP5Lt z*u_mnXoZQRP=h$AZlnPYI?~A~+rh;`5IE%Kxm0fMQCiX4&E(aaiB3LKP<)9Y#}wAf zHCs#@AZKQ7YH%|j9jWbal?{q(VHXtByRjrN%0$>TdTBx+IjW){q`2hM8H}GPJXKDe zwP0PhyH^n9 z6=qA(gN9X5aYX5aT#jm2xJ8?8Dpn~XjN+92);5CN{_H5K_fYeYGgeVT z^rVtNTLffO#&&l@u>zhcS*e48Nt~McM>`plA*XJ@s1>n8NlDd70V_T`(dK*AUFDmK zR&BlO3Dp8-lLM_nWF@mq-@2O3&3W~!HtdQmBji)}8j3#D{QTV1!dd|3Lfq21+A-dq ztTxmVI4xZfl1N0boV8eI!qs?4r#k?-u4&dujAKf3NYb$t12`>HL<3bqt4iPq#g8>1 zeWHdAYXDMkl1Tg}H5Gm^Yku(%JAiwrGty27&FxNhJY=o)`7lU)9+{&f5E)K|HbHmdxN zdYYpti6C-nCSn^EKLNSqRZF5#vbn(=8v1W&(lAiF5x$ik-GnrOT1$_VzP ztC#G_g3=MqG+f4dqDs*uyQdoz@-N{qywL7 zPKP3)v{FKvUrIBPNT(;I2pJ@AwX@TBX_1Z-4!qOsNaxjOJGGgKJ{w&N>dMubf*~q0FRU%eNHPb zQG>^NlTWxd`jxEX{#nY6`4L?EO&YCH?cOFvHVUK`3wW*c9FP5)t$1|=x{adne|Qc* z8jr+nzQ$$^@|mJ>j^ME3toTG{Rkb)L51uQ0W7T>X;Pi`LXR}D*EE&59^ZHkeNy{MKG=aSNy)!azS-$-QtI zVTnHjy^X`^VE2oTOA@ z*_-G^IgdkAwVTG@F$8{96Rykwou}8eLSwOF1GuW5ooVt+@;21@K;u5u4Y}Zx*kYXW zZ}}6ab6Y8Uq&2874TL>9x2;YIVxV=Tiam?-b*YyMtmo(}T5#$_q!KpKv{Yg;-FnfD z&60DPo*2Bw2)tzDccpBh&AFd7i#k4qajohJX#rKwF744r^*+_t>Yode%SE}mx4V*S zm{WO)qsHa$j2@tKR(u-ZHGLa&U48HGGh^#xtuV z^gdpWS#4!17>{h%qj)FB(^yWHx6i)WzF(OA+P~uug|fW!Uuc^h7#B9V+RA#6y@>Q3 zezoOGxf?u&Q_`^ap)VtEcC1f(@ibAoTWU6hG&chbSElO13z3?s;4NjfEhgtfnZq$% z@PpJa>_3%WZB>AEU(N_6*sDkcdY9yO+z^hTIBRH%a z8e<%-@_|ld47sZEF;=NkOs`r}O)x6lIZl+zcQ3)|PPtvpiXlM~oYt^lMDgNW)VaXg zY9Bl_*r{f4stq-9#HDc-8zPZ6l{}iT<9hK-M8M{@jG7gQt;6}4IjhYc25LB0Yh={Y zIK~A;rrA*;DZh%ADEy#JOK%BfEJa6f+dffK%--XXZr5wJ4>fV@(2U?#Wt%qOYfYS$ zBmd4 zGByw9ck5HDVM89Gr$kv7BOh9;IoXvRD@jYSESYYGHkyuZR4_F`T(e|Ve=T zsXG!*&yI$XTX$Nj(`CBS`M6%S!&0l+4Hknc)K2;7Rea*dtyn?36`!)TvcY5oSJNsWS(j*#hW#v zsdOUzEuOU<#P}Enp-DE1jk6SNWv~nD3k^mHEvv}5uh7&Lcj*3 zS%6-(8%i0usJ+S@Ar<#Y*l%^{a$J<$LM5A!{CPa1T6Yv?RkZ$*Q+XpervtV!h0%e(@aj zb~0W0H4~MQb~jGOmT#4a9<^DUZau5%Wep5s$YzAA8iNIRHFf0Pqx;nWg_*hOSUP%} zDQH5=kPRo6PhKk9BCY`KP1+7KRqW7nm9}BH$oHi4rBjW>AWf^2Qy!HII6;7UrmTjwa#7IE&FW5SHo;s{7p86`)H&R0BvS+Qs8sEd zPod3Om}P3AtYx{RPjkFwxbW07u|GU8I6v)Wf2lRA;R3@_wIFBa=DF)v`$vGZ$vMb{ zRQi0b2lcL>!D!8@TVu9!TVh?*Uy&GPZe`|ruD08JJ$QQl<-e7A6OJp^d_-~K%e?3P zSRbgbCvnAbKCUekx@p*p9;pg>c_2V@KXnxp=b#Mu&otb;5NsZLbgdW{NNSz zr(Rei!MAGd1CMI72pm(KhE24Tif~pq$BnI|bbd!;PPf1$`quTJzk%*6$bKYvb#yNk$nYx*OWfQ>NZ>I)I)m(gLMzmDZ-v&nb;qcu_C;d&4OG;`5*=apH6Gmr9#LY@wfwCE^`iO zMfSP1KZ%rDU8IVM8*}qXAjE`HD8q{R#Tz4gmz4$sQ^WSC)xKO(#JM$urKrgq{IyR7 zp0B!mxTeK!80MEatTq%QlTT$8B!gm%Rc4TrgHvv8N{ICtJX6^)xipsJEzMYw2HKUQ z11dz^*cBvE1t8+2+4EG4n^TIuaoA1UMNpg)-qmOw#ME*C8>Lhjnj?lIoZ^;5DA^Te z+=`Cy>`aQME`o^E8DDyZ;XAk$92X;S8Lb%9F$S$iON@a~pr*#9nAOP?D8(`a1?ver zFe8ydN0U_5{{VSc@0SUIS+SwtP7=7AG@)U(nLNN`Q3xbdaznYONnYbCg=Qq;n(Ec5 z9k>cA3#h^^Xr<6BR<}&Bt#tucpGwNKIg_Uqpznpn5|RSE>$#3PQYw(OIwtkzpXILJ zD>+Fm0II4Pxv1_2#p0xsC`lCyzVHP)YT!_bNtZP>#_|9aVPFc|g+B<)0qa{QU?Z`N zuqEoukf<0HW*AgOl&EG#VMUqo+`bS$IHz{b8t)Gb*$VqDKkbA81qoxw$MPR?d8gho@p+=Zj^G^aWmdCw6}9q z)!)tA&NEt1!eXf8ESWX5XQhcWBe-Z&lf^b$fhuv=)~Zb=BV&lIrPnI!3z6-@)8f=R6{I`uQAbV7rg9bZ~N`~H4+lf!uNM%LS+;0=?4Me{aOOrRI#og%CgQ3M^4ONO zG~EW!YQzey87HW$kF_~nr=?E?%c_tKN{i}RV{Z%ZWgRMwycnM+f@?viU5wHWY70_l zpDH*Ns?lgmF1?d9WbW-$V}awB+MTIh$p#S(Thr~Np4-iHT0)wXE{A@FOReHFjoLmhXV$pLMbGDv?5z1c@=7Fa2u0Y?>T41X<9kjD%@HN zmS*8_Dw`G+G?IXN(*p+_Vxh6vXP(L_7IMa%&~NEUH zLyT6DRuj~MHY&q4BisY>)ORRB7^cAkJ7kI^lO&ohSQ?sU!kRq2h$)gVE6=4QwHh-d zocV-Pq#x+&#;ZzkG5XcBhq7VZax2rpPuWz9GMsLjGA2M|B#if}%?M`3a4OTV>E5bH zAGLi)wN^Rf0SH7q44--!WMp-y@ImIKL6tQzlan;EL=4+lXRR3o3XVn$_#H(#26|O3 zSe}FNk%LSsG4!c3g&7@cHay~~p%GwHIL%9*O-0tC*DVNBCm6~0uA9UD5jTVFSNoFO zX9>`^*U(ju2>5(nTz#T--5PSE-`=}DL`jb-B_R}i%(bjA>FUvqTtkn$6Ax6?ZFGAU ziq6^?+wP{+9QvBzCA(=QW@Gn>I2CtQxNED2Y@MLt26_s`VnbF{+l#U^qYJCO%M!!9 zZ$pOb#aYv}i=95@9bJ^E&PVmCaWsgapSn*O?^2XW#^u0j#W%Xqn>4LyYL4SnTYnnp zX?XwxRHwR>qT*sH9HeZS9Im&P_LVXw;2s9SmQ zJYaOgbsvGqttT&Yp4yqgT3naYp@`3u?LwN1btoq_&CG3LT+@|@dWxK;nqgt`5L5wG zSaz!o_eDU%n$BfJ^{)!g_Me8zq>RHeCNb0IQ~hhZ@InEp!}!;l_yR#EgEd$)%y$tm z9?XCG)#`o+L;a%}#&8W)S#w2t1t{6SQ@!yhC&TwEkUn4QURJ`rSHxp>i!$dKTJpyn zkzCO_B35zlQ837xTK8*164LvSV*Y6#a&<>`o+QraftD+W=dJ59FK&l6G zSjt9_j-~5#!i-hL;0#m|3;|Q9&MPCKA$s(rX2}DgrD70!(^r#|NEq$EFFe*pqieq; z514eV*ljPa+ij(s^Edr7jhp!ju-+Ee88^O_b+@TLQ9q#OsxnFLM3ZRZt#_F`yngVI zqcyVthfY%N%JPx-vD4U9=(PJtE>D~pZU+Tq1xWl2T^3g74Y3cS5t{UArsB0YDmzHX zU0UzVUnV&K&)(@>&xigZYMMAm=82irA-uMPGzjh@B3TZfrrxQyjU=hm)V z!(*&i&0&2K%M7uyFg-vc2OgD?q_mOTPib&Ay0=1k&%In`G2C;<93Mkjx2}a+`<@@- z&xTs3h9?&m%-8x^ekP4F@#OF%Uf)r{_UT<5@@O}}x)T7^kW;;O=#VVcm41&^g?Ee2DV<*;hM1o2bP z^EVX^+$lAzeh?;rbDEZC0Zmm|cJWM-Lfi_?!&{ExthsSlSp!3w&q0C-tF15*04Ygo zG*kPs5lZQint`Mue0$ZlZ{2397eQh;aIcDW^S>I@7;AH%N~ZM-9KwQ= z;ODJw*|=m-YbtaCV~<+9Xhmuw;U~3x0Hq;)u|LRd(~erVck(E^B`mHTouWx zi0hmRF5e>n)krd4lwe7%4+532TAdR7qLomVsFJY9At7;4Tn*rgwSWgTT64}vO1Nr) zk=w(tWD1qJH0W3rr!fms+r5M}c&T@BRfFZKZP^u+_Z&#%P|H*t6n|>c>r|&voYu76 zfr81DIO|MAc90QHgacX-LJ8?w%61Ttv5hc$)Nen{f-2m~hz4<*rpO<0Tvl+9>^5K? zJb}$qh_b$F>|Zk#Y9zM`G6g<;L_xnT%{EDP^r++nFr?bfaaDZ)RdRDoX-@9ERO*2g z`_(CaR^pOLfv0XmuQchS0DDzy0>!b~v?M~yicZmDMqJYb1XVVWzcpg=Be;Q3EG@U1 z-kgv$5Id`IOY#LE*J2VJ=q$h4ONj0k%$g1#Nm6K@eT9L}Hf@=zjN!+B0 zs;vs-^{1H_Otz#Imq-5N%j%-x$KJo`@uc*dM#DT>=%$>s( zokY3^QcK4Ofk#?ppUEI|PPt9;s3VF=8DR@rQ;Kl|T4;^LIq6i=-^)0vmDZ zQC$~T?qSllr!H7nP3xht=XsHQ?Sg9~QMY9qkmu=4zMe#o1SA1Z zwVb+vA5SJ+*%O2f-uYf3v|w|(N*o!nE^i6fdh5Uyx6o9bAxkyX)hwPG=a%}a?$u&x7RwLQoy#Z!=# zU}|-gGGJB`gHGcjR>Mr)L14O3$86t+al1v2f0|p#dRS<-O|~bS3z& zr@_U}nr!Ektt$~{Ba=@pwjB5AOxkmRI#af;&>NubUA&qTatP3t-HMwS28M8}h2T^> z#xdTe>N+9W$X0%|-PxuVKJ?yLfS}~mIW|&=_T{iSs}V)BYd3!0l(57Q2X0UDr*c~d zj%!#$t0Ge9k5TYU8?@{$K5YGQTkmcan}7yM>0CF1^>(*!A<6l>lU=-*Swidcde>bx znm8&Zq_aAH1w3*mp{I^4&K){dv3Z?NEhhIq6g|sTq1mHcnJxa0Z z^#>xXYBrInx3em(_E`2YBlyoP`tkTzHA}`0GCE<)DJewbhBHpwE293*fc1?>;Zs}a zA8BvhTPYvjBLG(;nnyy5XD_%@lY6jKMrJ$!qb9u$&%%~5eD^XVFy~}I0Dh*n?cNPG zBlb8WjPxZ(%zqxWl&ht(HH`-MJh^mDW?&3jUE_n@VQhaY(6jI_i7%N#SouJlZkj|- z(4792+|R9FyqiNd52ahPySYfiJ1{xVTF!N4*w!>*)r|0WfOX9x3;6Du*KN#cuq@g6 zmBHj=(>3Yd6|$2`y5DoKE;_4j=D7PEVTk41)9GDCpMD)wvmR?HVkc`eRfmS?>-9^> zZmk|D$t=o8BDhKPOU#mrtUulr&v z2e9)zwN_kl8y{_^m&mzbacwF3MooIB+9L`G82ZpJRB^>Gtv&yD z_TS-L&aG*9S%1-H18^tzZR_-}qQ2fc8a~^-cx+Sp+w31z^FC3yNx@R^$O|($1y30~ zRaUpSc>!1?IrKwcS+wK67*ke7Cm~c1VME3?wjp6{)cJnPMb%{h$ERI3?wes_pVGJN zd?Df+h6Oa6g$KNf6aN50BEEoWl=c+^&5m=5&Eh2b8peW;Q^{@q9_!7IGB{!f`|<<) zvs%{w01a-A4aTDq4&pe=AJmHP+HN}3O>i@Se+q|IY`u4@c9~3wsDbAH^c?Z_To5?9=xZPHDI#8kae}*!g0Me`r|OYJjRc4k_{KO}m4E zSkFFllY>xwp_e_y3L$iDYMOSJ;tOLH>=BnE<&-E6r|Vu>t7*4h8on?}T3cSBx{$uL z-otuB3=_p+_^R--nvIkcTg5@M|kj5iPf z`qvhxkf)JS#~BV821u!wyi^^Jq;GBFzluFZ%qvO&Za;~A>Xp<>JWAzGaf9q@jPNgt z+TPVICwzoB!#72*LzyF*6C_LuIPKWh7HHFRlenHl!av?qg_9k9jcz0ft!Oh@JA%%I zL2k|1{&=iiP6rC=M+dk({eHDeN!4z2`?=A{bqTpc`U-M_oLpG0aQ91bWqU2H!WEV_ zD$0Fn%ExFXwtPjXSZlXye{7Ex#yq)@jtO4i{*{yEji$a+6$MVChhdeTZ<}svSlF7Y zBy1+*IIEWFz|UIedjc&(>T1}LLXn!M%8n{Fb_DZSNorFibCbmy`^}otvyXDsxY$XQq=yfh zo1ZHb`>ZQ-O;QSq3b|4^kDZ#*CuALJupvn%mPvy}fk`&ljJX(@{{R}hY6&$~H4iRN zt!vxB0_L=plteRe2L_g3^?CKC&Nj6(%?!Iu6xx=9v7aX5*gYxmrq>lDr9$VuM+||S z0a{K9D(FcXu^cGHOoJwp-8Uv`U;;Ni>xs#^SfaG5MKzE*in$`IAvvmQ-!WS0rwbts zP!Qsyk&RB#wlh_vU^z7tR(A^yg)(w#U;*h>QeYQ~k{JnXn$MB2xg#Bb)^)_$I2C?o z47^rctA^&fsnfa>C4r9~m9b>mth;aufm&Ao03}6O@{T1<5}8{VV1xBz0bUfBJZzAK!%d`LkwlrF%t8wqK%A1S`IN*kXpPPJxs z^VDLmmd{ZGPq{D+L!IPimKd9%sahhZJ*wJEVHWJuYUZshnc&q+c~pF+n{jdFx64?` zHo+6UznK2jTIm)X3{|^H{Kcxb=*;|dtEVKLnM6rAMD(a6a_#F=c?7RYs?1ffis@7A zE0e&S`_vbaXOq^YjFezcN`m%Gp~Xs*<^e6)QyhVc(l;@@TUd(c;&R+(mf*Spf@`67 z73^pPMwcs&wQW?W;MNtR%FU2T6}c0iFOh>vr!0`-?j^z*6E&F-*)c)ZugP|x6g_IR z7VRa@@D3}TMa5l&i>qo`Ly=Xb+q-3K$O2m9xE0M$D;e-TYGFQROI9wzffx~vD@r@S zssXIqRAyZFrDSqQ8REBuk{V^pr$>yDjGA34HD)=+D>rM9K_;zP$ng)BvztS{rOU(% zFxo|DY6|2j0;Ow)X|mN~Nm0tF6)~4C!+M#>jpTscY03Mv_p9<-ff!-Zs7k;dMI6pd zn+pTwh&5^(FlF9Py;rl^&&^$uV1R@?)XlY`97MXDqpBq@+1_oXs)Q`hd6US^Xw7<& zuM9I#?zR~QqKc4!I)PlQ_e{4NbKbWuCTW8)JXb#GuXUXCHP=EnT9VDgh`qYGJ*sO+ za>ct++o)@GKy!go$c+W7xa*3EHlHZ0R+r!42faKD< zPQYJdv1=}Go%t1`b)C2so}ljLq8DY6h(huz8Ad@Bdv1DEM&EHKy=xf>qdUsSG?Ayx z(yz%D#l=Sqe>Y0GPeE8zTrE!rD~glJ%8UwfCev9envTUg!bjmuwUDz6nv(HL15nwc zZsxR=oJ3xkH%FSuk|y43YEB~+p5zzil{soAQwTv7ejVzd)M~q!Vy^7OJu68_5-PNX zy464lmo+?%voy$lcFicQ3N|g@Y(RTbGj3{$2?{Di2X;+o%Wx&xkxAv_ns9JP6);Sx z$4bUd%vLh42`!4TYB0Gp=`Hs*YDnYT#Wy8ki;mPy@~Qe&rGy@FRPP)v<*9_V10|WB zZhdOgMj1dfu*9VAH7uAI#daxK641o7M?$QisjLlJz}d*GnP}U;r?qskl2)qf(6pL# zq=WK})!Bf?PMt*?==8CbNT!ZK+W`G)7H^uRaCV&4cF8sME=`#zqz=S`QPhDCy**() zPXdJ&$8<)hU4R3vS&B7WllO;O0aX}L^`IPc>s5HfPV8J3IPF(b(F7|XY=Uq-GgOdd zoHjk{YeSJGXS9_^%(+HAjZ|tUv7D1i<*OelV@WVo!NymL>Fo6)sHCvYFi%ixoLF|N zDPS2+2?M1*Im(8PPK(ZJ<0lq#$tfMHm|X*=-g)5ETMGq5AUAB+Dw@ZY9>D$h2AcjU zSOPn;6+x@@#!oSM6A4Lis~%9 zOK)`wlwG`M2ApcbTLh`jJEGr+ZP)uEJNVIBYXV&qjPOP|_6G;>HRkFIF?J=Lj#!h_ z*Q!BvYj*^Z%*s{Jqpp7Pk;tzz)U6Jis7-6Xa;eHc_muJvsJ>=t z!+Z>jk&rn0*7P&SBwPX0rE*Ka$m>=ixpWv-#YCalxXRm|Yy}m80CQahmBK23NUuMO zP<2oV?^o^hb_^7r^@O0!;WN@AxDA869E!HGjO24%u9bP_g&^k@(1`#{|8^I87@Xu!ZD=}5N&Je-OwE1ExP zVUB3~TY<}QS?xa=&P6q+2N*Q@LzvSSjCz`Mccf$!Szda80pk=bxjT+=M<{a|-)kjJ zK=+)5&l#$oZdZfbtyFhl+0I9$3IWV$H2LLQ^{86my=st{W`>jzj)eY|N+h`!e$*X# zJt;iG7u3}~+gRe2rpE;FPn1^&a8ET0k}^8e-az0VPfCVKP%iRufs;&3r+0DW0^Eb! z-mvD8q;l>_Ca1i(Gt9>)Xz5iL)vXNME6#z`f-0T6nBU2B@}IbWrD!2#dw5eloT3cI% z-wdcYBhdTTYLb#T+-%2M!Xmm^Cv^BWj^jNQkjar#7QDDpDP zlk$`NHLa*=@{K+@V`dV#bp5(3qugW{*@G4xCV&wKf&os+>O+dUYb-BC>qavSO4q7RHuxr!|pvC=wCr zS}{K5=hCuoBR*zDYfd&EU(14NBXC=Oc&y8YWMhh!-d5R@(z>CrlQ&eO zt_CYU_7aLuYK9xKvjLte{ooSXI)i6m@~N;SdRG^G%-0Qp-nx{P ze#wG+S2uVEoKL+jSo03$WQ3eCt8lOb8K@pyC<2la+08jcG%K13B8I70sa`6E*Df#) zDpqqE^I7tYWU~1zNHtZbGf9lpcQS`K2B5cXkMEkkODmCcdf2pRrmrwrS2*UWK`1c* zcsQxjUA_3OSw*=TM3GP`kZP2Xp_3x5$v9|<9cqr^TWxI!vE5h7D=L9V>ahcpP}|-pn_=YUx?v?GI~uxuk}C2!sqUj#<0NrF znNl6&ih@b}<-q2!cXArg#@g?5fs!*_EtCNv1def3ZS6w1Y<1?f;bFIKD?0T)$Rt*{ zl~^(pjMgh8et#r&tJ;FPmSyi;-0tfp^2dWu4-4!m9ZXP#i+YiaRA_ex_NsbS<4X}% zJ*w<5u`bJ3DDub>Dg5fpPfA#40k-!vJDu)^tE?~P78%7UB*gSBTrwaIdepY;lO{(| zS<^q7b}_3~>-KnA$>S6_s|=cZ!y4^9Dk$DLzV%|uPd)oZ6+xnoh;Dm38dinT>Gc?Irn!5P@jM{3M*EYt8#GhG{OHaJ1fD=krD zB$3IkeG|}a6)t0Bv>cL8LDoRNr%BIYLs=m z18P*yQB|HTs!ds)_O}%u-&)ENu|))88wReTg1sq%47PDr6*h{#a4621I29Zzx06<8 z#_EfA%f$`c3DK6C`0Y>!#}z8&suXns2VLE1&_=4+6+1+B(kc;7QqsX;CmCKVCBY19 zZPReYR+`s>K&zzCtW>wi!h_4A@-_a-xz0XhE6=?u0^9d~u zF_R-6l>;UYahkU&*z7&(27i~eeWYqx9Q>qWk(e)2nj0)Q;-V?)X}XeQQAm48qL|J` z+!|?K*!<}aTndY}Jqe?7K4a@w?BpwT8>dw{=Cjd0P!CgD7K)LFmQocL<;gXy7b?3m zm%X8_J>h0&8$lzUI@W!~@Q8=s^B%&pt~C=OVGdOXR>vplQt5gH{pplde`V4!M zN>w`qC|hy~ZsnJSV1xCl!WDD5oR&TDn)DkVhw?B(b1ZQw?4xn5+b;@fc2bPR=N0}b z4@2~<+i!DJly*GtN$|#{sxbQ{tgM;Ak(X)@#Mi0lUk>9~)o<_dzy>RE+x_GI6|-;h zCzl!pp>E-gQdG`x*(V>7ADw&Vkt?(%-#7xiqvFl9DXUoODYQJu@kxP#O5myY z;F0(W&Q&MM(|1L}5avxSPAya#m;umss*y@NRh4csE19#YAz4KMK*y~n{{UJyFJno& z6ff4EtGAkJkZM8G6`Z8XQ4Hszfk zme*jOxIbEj?!X;#X{eCqX#J>X1d&PhfwcVHD;4iHlTdxMhGH@WS17s7)wl;BH#DN- zjAy-b#__jil;1cfo;y?JC!Fa%(}RF`sQ%P5f@=U@xgR%LPqr~^f@$)HIlk9}fLg4r zzzU!@Z(8ME<(Y6!YDjNcW7kfXH2(11C#mGFK`z*J^uh2#QS4$^Jm(IyWDU| zqQmAkKF|hv2AH=Xsn0cu_Lkk(r%G_SIL>jJ3AwB;GH^`|J8cIU9<`D7gPu=5w5fP@ zfKNG~cQsmGI&)PnWG@>nMAHTxap}!O(`PgZ>Q!v#nu)nlPmzIYk343YkgPR{?TW7= zZ&SxLJ9Nz>^2YjalHB5a`87J;3W--jQ(~-LpjaVBWQX;us^< z?CmwXY#%W~NQy93zYeuFgLC9bvGK=3csQ=5sm#YdmNdOt91<rAqXc+DoH*lY@yPdg*Y zqQYdeE(R*Ap$9cQl5S&)j6PdwsY$IyF-cV<(-rb_RwYcPMN?iFgI60dGRK+-#ZtIA zV~Vzs<&8l+MO!%HsaXL{QMYEbY=%ZEqGP>Yv;kK&QlCI9vT>S^Zd4rVhZ8D3dP0G?}R%EjG* zBCT3z=@RbaBD7)K5GNJAURbLFi9+dog$h3PHr{RNw9$Cw=H{Z35Bpb*Enc_;(eKS(RYqT!*3D>y zWK9kko}+?dtQ*H6J)hX8sTZJhH9A?<*qc! z5CKCR3U>mal0XMqXl$)H%NmC}S2Zhq#+FEnN5yEj6^g4MX2oBDax+{W+wR~3^PQGWGE>Ne4ib4-!Az^jX}6`27i6o{B{^{G@6Nu>k^ z1Bz~X2uqCZ`c!c_9OkB&Zdz)?geImhxSJl6kbZ8JWoJhiIIK&Hy^?Jm1uPS@p0%ed zwZPYC5u0}vQsG-aFKUq;usy0bxLw#anoY4W_U*{cUknv9RAM2RVysTZBjnPW*1>WK zn7bTRIU~Tqt1!O&=ApfPohw>vlp8Z8eUHUmusg^mvft)xpIX(i7+ThQ5RE6D5kk}r zZY5S>oPcqPsW#&v0<^4wD}z|Y^83ZLbZ}F!X&cy@gB7E%S{pq{!h#XLVOh-C=e>QE z2B%IkTQp$ZorKB7GbbXQ{8ZK)R@{W#V=);9l@mB)`BRlLcQ;PLn>67#$SvtZYC5s2 z%S1h;Sb%2d*i~DLr??885FCXbzNVsgXJT0MTY3hO_N#@GR6BaA{{T~2IZ8~?B^^yq z3TP=SrOo0iAU`Z`)9P!}H1v%v-4F%O$bo$;oIF1Bn-Fz09ut{7zo_4=-%|`r&onvtC5@o)O*t;k#=Mp9=!FS3Hf_G=ELvCZYNDvX9 zyhU<;F!+3)DZaOnbvCwGW7*~Td-6%iJ$|2+c2VA2ybAHUmS8*cNR1kvzcX{6TIX`U zhN)TH@Xru@HP-YX)7s-vwE&iAl!rh)Q~Wbrf?kfD#|FNsU7TaDt#dvl@D_>USe@m! zSZ>HAZejsjKkas5^{m`iLX_WA=l=k-7wCAYQcxF~v#WSN#5x?;V&=kDhTXZDMpcxY z1|FdC^sKaw=p4PgpnJw^IV&4Q+|XHp;-**5I#zaFddDVz-8CCr$eb*45&rFEBx@6G zTi=e=GAQ+~X|)@L`>;v)@liIdcsj&K{0g#aMx4<{R;;Lg_CFeW-a38R58!K$U1~+f z`*ZJxt8i;p?0$X7PpG8hB9x+a2L5O2-KiGpPwyUUCJWf*Uy;>^v8!n&d*-I?4@O$^ z-}~95X`G(58n7aRPnb;#&REk=)`BxY5I+gV2IG^OZfG>LCKe3SbDos!e7sNwI@9J05w-}&tx&j(f*pSH zoy%GbxEU1$%ei@`rD0mZ)DY;?PehhWN)mKpW!`qu=G?yT-| z%yLa{_^RQp^tkNN{{YuM^N;QhpRe++ZU^}Q^sf^&tfe&t(3qjD1O2ONc>VmZn%XCTbBbTWPC}o`_;u zrp6@I*11*Upx`eR5#{-;Wq7?p(vDc4t|HqdH4-eg%lYe>S%I+re*sD(nQW}?0#Ls0Q)%aU%IX;ye4b8L)eB))gKGd4j2&0g^&CO?ChiO0_ zwKbf-ykS=w1$h;XYM&|-)Pep1jywTb%)L(Zu?w{wD+MGVXlWIC8<{++{l|x zTFSj+xri0Gs3uMLtUW{+%TY}x$!LbkMl-H!pqaphb6oD6+oaA7Y0ool3)-TzQ+f=a zdWGcGSYZ-QNT^ z>sgk2m5vQNUb!8ZUCMtY9}XlQf7RSJGMnl z7~Gp%wOf$K5dh0`r{K+gp91KJPU|X^j-bfGVLC zZG_8K@a|3CwMy*ya%UB>*5?2o zX>J#EA;_&FtSg%dC)zA_uW?nh+ZTrCb95%B(@Hh6fNN3|8^$s9tYs@*A?`zal~In> ziuVJ|U`=f52a+p_)FqNTmLoXL6d}wfp<-!Cx#FisV!djmlutUBAd^-Xa<&*_71ZLE zg1yQYGCXq(R=t(s5M#b8GT{~26WX+Fgi8r6jEbpi5^h?zGQ7LF#Y3py&lHM-HFr*x zS=f>CijPr9XKbc73d7o3RxK?Et@UXl*}P;Lxp8?Ehzp>>tdVT;x`EJD%cN9=Rfix} zs#=A|MlD%R02!*XX{jSKp$FQi&Rj3<^G~pQl~ygE#teN0rZ|S52jWtBf|o_*3dQn3n`B#}#4{M0E_QnKDOuu(;cbscZ}*bGob-KDAkJ zr!}pskQKavyA`Kz7*wi>87wkt@C73j zeb0)y0xHLviEXJxOgC{F>mjXRj4<{{T=68F1e)TmhQ%=x$yT3LZhvTGC7TUo6d( zJ!xEaHKB-HHcM@0Y@Rcd>sPGfRgL1fLat8aZlA4Hv6?BPS3`wSw6CRFSr$@Ca;wwp z?M3buvA3jNKbnftHqd_QHP^H5+C!3keQVEQE}LCWI2~(mP1Ggc8bWp`#yaAnQ7$q& z7%ulPN5ILz=Cl>oD9gJ5fMtp8SP(Yp6|yi-6_es^a!DE;63xq8T^+5r_*Xod&zDk@ zHQ~HnO{Ti)l1Z{9Kip3L0E=d{B8nDV7~?-x6@_mkP?dr%5)}xf9=Pg%6O&p|U0?tR zIsI$OuTz?C+a8@Nc7Z(lCY5@)xYO<2dYHz4I>gjI9cXuPx7pH5X%9lJxql;Dsd5U` zpJ@XeNd?J9Dlf;|m+KaMop zdo5hGx`mEa-?VfGJl3$O&7(7vY0)zI81^sM;!z_*U_r~0NEGPgJ{3qrqX+fU2I8juO>pv8?U(JR-77zwEqBdR43Cs z)*D)b+mEG2)?l8Ptlc%xwKjEXLv%E|c&=V1xr6;&(kS%Kf1O;1RJ%?bB!GKh)Hv9* z?rv?x7^)HK=zrEk%kHN&ay!duFav;n8;U?X9+Zp?O|TJ=K@{DM+)x8Kq|HAZ^rXcw z6EvCaPTTE63P3k^G@0g%Pz4|Z_jsb06amFMfXWxGJ7L|LOmcHY!ol91js__@Qf8IH z!qI_97ruj`uf2MKp}mcZ^GdC2Gh?Oor6w`mqPjS(a5DX<~zJGF1^V@8{tnaN$I>}u-w zM*jLqGD>~O^VvsA%|t1aR*`;Dnq&m2~t5(0(gzyIn=zs4wak|K#i*` zn{eLMpK&+unQL0eDp_;sSki2Jrorz-Eh!gm3eJV(2em!q2$&USNWw-j)}Z?{y6zz2 zu1#!1MAmJU$f=~bJda9(+P$rt<5U|W?jz~YP2Xh2CN%}Xh0s7L`cE6 z4wb8iC>GUHIaJoVBFPSYtDAY*n0nT&t;2{wHP1L}a71z;ib6@^pmV*lDtnx`%|jGt zZ#`>R$taAyXDASr^s0AeIaq>5Y9)7x*d7IEO(V3#f@wlBY*#ewphRLuDYu_198?g> z$hjt~HQAP8r14ek-!;V8tlN$WtsN{CeAZhd7UH#Zx7)jQImg``Ni`YSiBM}2D{nIA zarLda;4dLPsu*AiHsjK>jZRqDZ5INp7QsQm#Z*SzSmvK}T0w<14ZLi*-BTF#VDuun z&ek2PHaRx2+gdl0s>b8JX6djz^R{|dRW+sAEVplRcUF`aC5q(LR37+B0HowQH)Cx!5{YjZ0N#0aRkJtkkX1W*la;uC~4y4wU6l>^PIbGrDA+ z)tf(bkl25ny@R{uEAP%cZZ?tRU7BqPl*CC!Q|9h?WP5rm)xvR zTIa4{S!6jCw>r3unATs)6`8ux4|Gpb#3+`wMS#mSs6>I2MwN{8_)aI7*ShnS=^f$J1^xNZUArWk!Q!-)HyDb>n6gKlx4mkt zF~@6yM@q($<(6(KmpAgV>=_lyD9%q%6`&Ga;TUzR(rG221hLI!>1Cell51k_@u9-* zr7N#>3dpHuM%uiGoQlo0%C9x269Sp8S*=GAvdf0SrBE3Osy7l7E(Kk+R%FFE#CHf# z?#ZdAmkWVRllM!G^<9{<)iK12cxJ^;iZpp zs*(w)fo;TkRa=L2U`I-Djo1ymf13fSlSR7*tVnmS&DNmYRN}fJ?x9^8wn?%YR8Z3s zMW4+GsZ<4GYo2dWk7)|v3YF&z4o{_1o@7(W!KTRmY&ZwC5T|!=A{PPKuxh(V&oRKw z5ZgMEPfD?G8kr7y*G7>L=z-k16>etP9#5q?VFA{Q#0D&TRuYnO3mD#dnRD+}P0z`U z)_bNVH0}F(n&?nX3g)Gz3kGw=E~7oO5RzQVkl^`|M4*@Y^(XjqqKswHnBG$F=J~Lv15y^YSwJ+ zr`101n?E5rpL5QA?%(%&UHoTvHf8Zucr|iSJDAr-OVR+N_2aQ0c4-TjHp>*Or(pLF z-rIc#b*W+e2%%yyTsp@s&QWH#N$X=NiO84!qnCs?>Hb*g-pHLaaoJ?E(y~(3{4!(U z8*3QJo%Jn?Xd9pOu+k06`LZ}GW+q>PjPb7z)$YBykDNg<7OCv@@WG`YA1tT zSor}DzQ3HSRhsT21BnM9SsdhEac_9id+h=KtI%1<@~Z z8DIi6B5lvGYa@Yelg8!=f0T~&W{6`7a(`!N^$+CxP^o|Iy(2Z)Ssh9scf#M#=7dm+ zW3w7$Sp59>w`&?J@3_ z^aa8Hk#I%VK~D3o8${g22O5W#>qI#ijL&pKKS1|ig;(R%+7vA6oD1bu9zxgPt`xIh z0Iqrl-@JFf=sG-tl}XwJ8!G6f;GdwM?~0t-BNxl}L$?wU878dk5!R_$LG!Uf;7J%yV+T}AudRIa5i$XjZ2+m0B< z43pGsXNd-6Kee2JpM4I_f0Km9MFw@=Px=i{b{-L`0h5)M=`dsXlD*=)EiO(oB;LigBSk&P^*_^q`+2cq=DKqu?dM)5V~ zC7J3dUWd4n8pFkRL&yec(m6e8%KL_~|5Z?+zwON!b{~aR=~u485Gk1U#yTA@iMHU@ z>u_O`zYqT~mc@CuaAz2P#Q=6h$`x#uFJYGJ&`` zn6`hbxt@&m7%6N!-{-E9U0}z>zuvml?nk0M$42RL29? zZ@`Nqj|Rq3VtuILeat<{)Bu{6IA@w4(K9$sJR?mLRTRXv<8N`iM8<_}9KeP>U$Sst7 zNx15~d#avY;m{%+TI{pp!G{(9ICjao_yicX9z!@y<#jzkI~qXw^wHrLA|ucwHmW1o z%PWB`aJW`V=YkbcOT{6}c>t=fDO`idD!S_U9`^qdumQ_8x(p=}S-v(st~UO5VeUmA zU^PKo&48?LKI_J1WaNcj1Z++4E^Q3Nbnt*w8H^t)wVEr3?egA~<#EoeL5P9O(?Y|U z-54-U8()B$ugJ?OT%}*&i>78vWg8$TCeW5XADu7YEp8f`0hGrxjk@#q`J0LNjZr64m{9r|pOP^0a7J6cL#*|Lvd=7xrpd+b++Nj&r|=rx z_AbU50rRNnCL)<;q)3p(`W9BT)vEqaOc#s7!zL~=ybUcQxp9fwKC*{4Wgft`@P-t- zjt*gDFT(sxP1G6@FZbuedJfJ!Zmh(o{^k}a(Zi!k2x-g?&xiuOwYSe@w8w%4;s`Ap zi>$@6(A!a3v7JKrAW}XQ7iN{=oulNjiH4WgxDOFNzMH^$ss-C|jD^~NaWG-e!Ekb3 z0U`+6jHi@+7Oknj1dt_W9ic&!zRHQ(>#S}#>n;^C2CL?atY%fh%ZdFA6&p?~zv`j* z5PLc(4SNgob;Gi`TqmGH^umR;KD$jnyY9n30c!|ltFXBlr5(2V5Yxt3JY38ENz$xxqq~X=q`vLQ%D*60iOo+!&x*7ZSy^CO;?| zP+f!?>;oryqS=@VnmMG3rEL0$f6b6yxPn;%gZovzUq5M|Se2l#cS?Mn2L^{r(P9*-T=oipbL1;5X>9Crp zCYM0GLp$8r6+e~C;R2oUZB~fGgj+IJl7)JdBr(9{@);R@C|bPIzFqxVCF-B7YY+#( zW(EH8%qUWZaP&gO1rJSLFzhb+Z@IqzI}HHXK-(TgPS9{qj*5UE<*# ztvyX&-AGp5fjg>e2|KS7BquDYedXfHm;VM^JAI95I)OQym9W(_N{(LIezi}K5^Av? z`vD%(E_`frM$^MR0k#tQW*s8yn4W3T#VmJ~N7{biL~an)7#Z3eWnse|<=?QV6}xL` zC*|xOa6Ka00nEuxt)GbKAginL8ExBg-o|VwW;g&w8}7ztA5T1qTEt!25`oYgE1q5g z`z1H|sejzz*g(%RT1*ff$g_RjLb`LwM9B$CQ7PM^uF!~wGz|C;a4(XdzC9lnBn!dX z&Z9qvX1sA*#iE7%H9!6mFg8#-QpslqDdAuvuK2Dzf@BqAk_VlwRjz`CT~1j3j;ANt zer=yVI7BnWIFg4ej~h zbE1_8*a3-I;$VuixxYNY(qTLoJeQ%co~={4xjz5xW4w-)hV7`sekEP@)*_pLT$6Dm zi3#V2V294>y*i<~)_m5jh1`c-^hBWaUOPMLQRloII+EfTYCI&;a2#!23&S2z_5%|2 zVHP6)AkhtR6*w;n>P6*t=>+qSS!s(SJ=WFKcWdXSxL*zVm96` zT}!H;t-VNuM2!U~LvFhYbk;oAxW)7Yc-0Qun;%t#+xl0!Hg)uZ+m!C=91A!X>nUAH zRN+q<9?1qHBMPl|0E=zf9rE9jq5L=tcTs76LYr&Qqd0Jpf^n$B`qb~7nc7nv3*Fr( zm=c#c-0joVSi|}Y(3mVz?ZOM7^$RJqjm#svHKTy3_fr@ znS41*3qSha>xR^IH~?HlL4#8zJ3IlBD|TZ}*hiC?bc7v(+}7pGw1w$h+1Idnh4uGd z|J{$VF=8^&1t&8KsPdgw$Nid%%S4)sDW&L}7Kz~5aBN&UEHqTZK6+hvA#(1&b=5q# zOckHYDk;}UWA&hskG9lcr`=rr8M9MdcL=ye zA#*C18uxHR?z zk@~Oc@b)Gf_x{uTP3i0x1s?~$>+Qn0oW7e?uR2MdG{kS}yh>|GP~u;gBDN5HKT+ur zL*e^pVLl;D;^fbjMj>kmwWBbwdC_tz=QZ9O>-e+2&e?Fc`9SgNFYM+VYyXCoo@$Hz z5HTXqAqj2D5Wd%Zk?l;0^>lc;ax$w2X2tugoGSot5uwM($wdU8=!Wk>>%WJlPBl&p zXDP~#{W;8*Av%xs_B%|o3(8FyT@mZ--=QFqrtiM{M|!62kvi+RPIawxZ5d!KMa6=> zjI*_QIOoD3I6_`MabxNSUdI?V?*W?SS%+#;ST1S0;?w;(fMr#v*AKRrDdIe&s7lB#}ljW9K?}@a5`~6 z!QaED1(hB*SGf?V^#?1P63Xc28q`YroA9?@G=;Cr)*w4Or`t$q&G$0K8j`{Wn5_Ry zQE#MtGD2E=r0~+6hdb1I)hnt+*50yu6);hd`wyX8g6GVV5`+`La7BYwqM{f7#ly;X zcySr)l57a220h0)sawoD^Dww;+80p9IVtYlb3>n+U|E%CeQP$Krt`j_8fnDWMz`1r z9c$t|^w?=7Zz}S<<;oc9>E3jm8SZNoiYfgg@UdmbKiE3TR6^L|#xQJMqh+P+6h0i1 zE;*xte)-P(YKBsxy~~HTvGda2BE^5*2ie|()Zy8M;D+jNg3yPyPzPKPEBN@vGfltY zXyj{?yorZca`3R2zt+!&mo}*cldf=A9jLpH+t@DQg9#Nh-%8X=unTYC6$mtlrC-g^ zcHH7#I0U`-%k>^6p1@V_wlS_3osLThI4>^qiWStC{I_nOue<3B<(PB5!dusgpbfj3 zJvrdFpv*TY7FBoa)=k&fmD}aLFXZ_&Pwl>}YIYR_hA_YK>I)+WpFSrW1B{&jgGi2% zhovh1Ho{m(kMJ-!QD>@KnY9932u3)2Ua9m~Ni7tB81GZc7 zu!SWVBX1h%DWLMEjjpFax^?BJQR!RvRm>w#^r38PnSe9F{zdeX=7Ujmy-_4hmV+n& z#Asvzz)EQFolFbmyBiJJ-lAd>TgP72uYsDGfaKkcY&fq802kH9N9czu3~?AfW?+^! zUtLo%>7)nh?r*&MXiG3GEW|)(4u;9-7KO)8hg zN~D#&Yy5nR{_=k91VEV>Q2xKX2KPo_JE*QG2m-Jq9?qN?J-YA3ou_1g^QkW+s{{PMs}Czx7i0@AoRL$YEHhdQAUXUZ;qLUX1ujr`8lQ$Pf0>4K|IK=#N6 z-b8S2FyIk=u%p7QUu?5@@McSS2Vc%MxHXNB5;;AW?6We)*XU%A9pC2q4TvDTa6gTYS%PFpV0)b7A7EaXr*5pfu+(8H=f*eZR1b51DXmyQK8~^uTwpA$8xvxpX3@SoZx@ddD{tT}kiRr~!X{J}{hxE2>K7(t74tHmo=b7tvi*L; zkG586K$Uk{RwmStv)1_KR7HZdkn_|7klI}A2t{qP|CJ^=UeRNPm93unqG(yDmDf`Z zwkl7Arf}g+9pXizX`_fwnItmR1?4#FDPZyHvd3sZ=o4sCU|}J=!Y70^5$|)t5qfMg zJn12|X2XTD9gwBZwmj0PimmlO(+?6WQgoG3QCvx&2sWyhvM1_D2kC9J7P0Xlsj0bktKM?Gm~c zndK_Qf$F})#r;NiZ$yMEPxa7QFs&ig6>HJs*Sb~?6He)?V)g2>dr#leW5dr zl$q;5!+GDZctJStTPK5S^=g!l47rR>s_c`gwjzDbTg;&~(bmn_Qtdqza}977AuGOq zoJw0PW+f8$4lQT(H%%e#s{VZ*ZQ`#w+4Z>tgdS7TOE4qJ0b=3GafsTPbEnUYnV)w$ zAgjNn(mv7c(A-GYaHRO5=AlJz!)^vKTh&#)tTq(eyvCk3bvi?BQdQ5rhkk0N2kGio zaZU|zTfci~>64r5A1bM_#{Q>yWJT}a`5%qNIL#|=szOXKRLBX?tp|vVpp{eEOCLQnls2B58h+ zJZYt|)Qe|7iq;`H?_LY9mNgmh(}c6pd+bDVQI;LR(Juql6VPjHRgkZ@9SqCg;(jOm zUJApe&5m%?*%d%VjQZ3!5_WvV#{2GZLQ=HH2V_bkDObBT032pLJ?#cYS}i%LM3yAI z)IX0j(RV2ygxn(^wxzn$!Z!;WISLo~edM6+sRJ5X^z*3@2xiO4`0Y;m$Tw(ncl7vo zTy|oplaN=6jVl$60PJh^v#Mw%yn2kZZv|-3aL&85^_K!q0>Za_e*f|$w6GnB-?Ta) zL!SIm3hk4Z-T_<|CIe+>62zRC@1A=RQp}+iR=!5N`jeDU&&<0yXctN^Yi<Le@ysvx~woMqWw{D&iZz7kjK3?c5Q;#J7Zj zz;0NbKNF3o1yl#4?kSfCO)(IY_2j8kdB7T~p1N7(9oPczDL2VSH?x=`O4|^M_fY)g zo3R2TA1HyQy8}Dj(B{RrqgiP6%@aj0HF7h7;s%54fc!s~Ur31~pk1}0u z$7LGsvHZA3lc%TN=f!zQ9z>{#t;?QT7Ps|PAl?T*2;h{ZbT#pWi41Fui>(Kc6Xw_F zV5aH*J95I2!D{-8d8?_{q#26}71XaA#zG48pdEB&$p!$KTp($7b>U}kp9hDIRaaWRk7@h!emnf+dtyDWJA_Ejd132AQVAi zRhV*j!s>@y_S8_*jFZu-6nARWXhDcFHJV1HRfN;Vnrq{W%uqZ;gZCa;|_WlkHZ-=X+&A|sBfsPoo zJAjE&6_PlkOIM6do#6Ga;PGs!QaRJkuTsa?x0cn@Ge}r>?xRqEMA-%FhV5^bytWIA z2*G-=&fBpWh}z%jypwc{S;XhF z^j60WX4Siz;=fDg@aF2k(|hCNU5@NiGDY;0hXeO}3f(B`>|4s)&wnkR3a;!Aq)Ni- z1xn{+?bnyiX-->NuNq85zd*j)$Fwx$px*8h!04v5D2%?H7Ov%Yr;b377#6?%KIoxb zMo-hSB8ufXHKmo!gZd*Qw*6jsR5idV_OFRLAj~2CVorNZVpt6r4)o*O4X)~S8MsDs z*uN*JcAtaGa+CxaID;*|>Nl6^Y`201CoOd+<=a`%gQ#XyOwGFhhRC({y_*J(=yika zkOxi9{~1~l#)10Iy$ z75o@uJuDM)@i-1Y_K%qSb58J`-EP$43PLP3Cqx$IugboZG+Ti+H$MQhby@ofK{Fs1 znqSiqu%fJO`#lYrdo?Fs9YOa-Pc082>d@ZF2e2^I8yDJfru4*NeXa^|b{v=` zeGG3z{XlM=sd{32Wl5t4y(!u(tq<2F4SYp(6l)SMJ@#8qmYepmyu&9;0=Ym&_sEj& z6!@f_ku(~(MBfQ2MAZ(rCDpQ~a36+RY?4yUz{V9fko7TNr9hRD>@$s=TvTXs@pMM4 zp^`Fn-(%niye>LUb2rkhaKT7~af|RaU93*+7{vE9_}@ic0t1?ww4l$&&h$r>eyI*M zTs|Wo=OQuUx?du>dCgsW*RvSK_0h9_bDbDKtT4UoexgaB$&b0k#O+zXb-%$t#`31Y!T=4PYj(K( zV?z6LcM)gNjavJh%}i3=(BP?h?vR;Okt{fNKpZqfWVRb+8P_ktlJEIp*X78C5bZ}| zva#eUmg8Ea)UONadV&G2+o0S%P|MtNJ+Ye$siz4L*Bt8vZ;Fo9DbPEt#R{iOEBq)F zGLy`&e7>Ee5*<$-R7SK)78aY>8mN9x|5v@U7E@u==H5RHl%G0m&`ambh%Mx_sd-mh zMH8-Tv#>g>4|+_uLQ$FIUPM+AV0Eb9pS0cWO77S@C&gN48@_`~Z0*bhKXMIMy{ep2 zZ|gks#({Cpnp3YuZO_yfVuP*L?E5Ci7$x`JVnvlmwcD8)H%%EH^VdsnkpQ*!_n4)9 z1N0N$oS)&3uj(W{>_toxduZd5E1eGRN`FH_mbhR`w-!sf*?s%MAwHV@+p!`epwX%H ziTPIb?lS(i@<%5KzEoPjWePi>i^dt2W-jGsACFJSZBDOT^cjqADrL zv;IuXFVDZSlP~$FdL*WG;s!$k*I7fvo?m^Leg#e$c^dAcO1w3Oj6a`+RDGsU{B7wQ zp=IwH_gr?!GhQRaIK5E$F3F_kqS2rS7^%q5(R0Jw+}YmS)|Pi>L+rMM@4T#*&-@?B zJ)Sp!S@F9q{dG!{Qu@EjHjlqW6QVE;f|fz$+fp@@VsHHZ>9_kVb|k^KiTG$N0N$n8 zB4kyCc{nkrd&p$!snXIqCx)p7TdTTod$#70lIhw!drr*NSCzbym1$|IC$WyFc<}qR z*hq4)WSo!U7oZT;)qVCssSom8zZmokDn5D}tol~XYIbPsZa04;HSYv8_PHc7721rB zLzl0%8@!KD9T5fZHc3(6&)Y28VZKVUpY)WhOf#akUe_UDK)WGqo#o#R;`W^;i;un! zc71{xe{gIql=aK@)WXEh+d7>*yG|BJpO5+A{h;%R+;VQ`A@d0&_HHPmuJG){Fxd_h zqz}pr2CDvvAym##gu>A`QUVl(?&Wdc`T4OJwR%}+%jefZ?JLwHh(!zZ5Jm;^F#|iW z+b%!Kq=@!4LuyfKTIi5I4=jP@47nFg;EJyfjMA_%2;jg^=ucW=xo5J|9qsfp;z#ET_*YPDLp1nO%M zxxXB%`B(Fh%`v;n=3$pVQ+ItCxxRB%H|I*H&J zQ0qh#YUS9Gw*4O3;@)?W3=6n1U+P`7IW(I;)7GYdsQX3x>VJCv;P3HM%l2^REl&2; zR4j$^SW^W2Q10i5Y6K?GNNb9Ullu7TS9;W%-L|017tX2HK>iI*QJkimThOIgwt#0l z5z0q6ehc_VuSkIZf$UZ7&0Lxq+`GN~tJnO%mMG4R4lk`0g@+w4rO_HD#QX9M>Hp~a zvfo^T2adgOY1-nX)`+7wgZ9R&eU-fjZgdk<5az>(j->(F@FnfM+*tbVf3>F_z@6s3 zNBTbuwrR9}mRU@xSfyqljdj$h6y(na+T9D^t=51tt3I#z=RE@iOcPlra$uY60iis9 zLc>G03NtG9c6+p5kT&Ft0Zzv|UPs{BvBR{rmB)xyXh)yd#(>t(=z1!Zh5~71cDcl* zf+5Pk+63b%@Aj5#VQxUHiIWs&$Hq3QRxjgQl(YqAf!G)$Df%ciSP6f9B?LhXB85RJaleZ@nj0e zg+kv30wzfNe2X6QNfrlzti0NLI0h(0!kaC%6+Y|@RU#JM1_@@brCz`DR)hU> zvhwt-BAF>$%@>HOV;Ew& z`3cBrG3?*71@~0AJ)IJ70%es^p$DDbIJo%Rf$RE~Rl^=+Dq3!0|H2|$8r(p`*NRN! z7}01h|5w}qU=ZKe&w2=DK4~pvz&{t@5FQ0&I<6X6?wT)$T!w@IZwpvPOFFh6R-(7>meW0v*AyF07iB}e9 zj#R`s&J(BtX#(%Vr@ABJ+{qG&E@z`++p|xQXVT~jO2MGz<1@amA=Hf0(DT0D2%P{{ z=8>3#{mz$BkvYHKW8U1_6uVlm&c_G3W-5F9H}$e2zH8dBdx;tLs+INd3x;ui>Q1ZK zbIRA!cZ|{FzPl^Rq;v)w^t}V;Har&t9(&==tF@z^tu+qlEWnSAo?30JE6Z>6K7<_< z>_;%6s`VYnBzP!^*o{-e_O<1#j;2 z^G*i_jdi7Htqbw9?0H@YAMT9M?FV(ld^5njIs6m~on0{Q3Ctm`0{g6p?_6x}@;9@X z&ys@XdP42Ndy!AHGKRIIYXnYe0E*A|wx}^~VngXBAYR5_xZ#H}9d17RihiMXFkGPs zdcr;tn;HwdrEb$A(ZU6nredPA&&BHnn>r0$-}p|xvvvFA-)d4zXUjBD$rXS@}>Qza#@ zIXc44v8$o3XoJSHbipfvDB{kTOx|8K19g88>rzQ^Ut0tCw0+0yxI4=(|F+`mxZp;w zJ>IvxK}epv*XF5P|5h9L@vGczni#-LvU?;W#dF11_iy%%5&OLb&$2m5i%&KHKs2x$eHl;6@4(C)v$FZg^hy=0CgRnDoRcGiirrq5>;A`UOxM)> z8wo4?s^zGUslGKNk}EQYSj2>!W)y7B!--H7i++L432l>j4~vc<7R+ZHVu-o2eIz}(s=N>M zODAox?mAXDCJOzyGs%Cy@X^_RF@?`JO&l`=_q>&E;Z-HIX1&zV6c}va8brb*J=9gR zG8P%iDb4E@LPFY?YdDuwQ2IKVl|{OJpKBS8`}yu&u3`I~&Nx{(&wa8#Wb? znG>0j2oaf+C!FY+>wSawpI0qp9?5?ddG!90;rjl?Gg4(6m(pp#fA4&VUCIL08cK{6 z*|VJ0ZUfOaort~rWncuyh8-Q?Y_dw{NTuuV-eGf#8eG(XaFP^cgT z5#_z?_7#AQ3bo3(P!jDikp0-QoLXO;)p1!OZOtv3UTe__=17Jb#ZvfgSJ8}Kr}an; z)e-&fpE^W{6#0mT32N?ZG|wFvb!WYLhoGMvEjD>CJBM_1f2UZpDOUN?%mU0G_z|(N z@EFQrWF6qsz`VTOP>E^?@s%7KeH&-?E5DmS&*Eu-q0BlcEe3{`ul4@I1gOIj}& z0^L>CyOiT={H@+AGwLhViF2@gXly}Eav9ud6;dHxavXdHHHvS;* z73zIL343`VIM3y)(zM}pYbS&JAoN@&{648Kbu#Yg{$qQQE?Q+cQXyDf#k!29o=D0P z-;eLU$v}Y9x%3xqdP_>~I|iYIiJ`rG+BS@V%k-za`c_J--0} zDkSZB+^(1OvNee@fsW6P|3MMiYO5Ue9cqc-4lGra0VvFJx0&V1tBW(sR2~1rHA%l4 zCG!4;yS(Ra0Lbv(DTt@wlNEFhdouD^7i=Hhj7UN^8GQQ{+YfkdSrU3?LCDLcm*_zN zk!@;!DO`@0jF={qaW8)EQFF%Cs-68P`Sa)o$0MT;IcgPEAn)d( zbbsegiRLB~%RuU};1EvYLA+1XB>&h(yx88S9>K1^+h>M9suaUDz>B@2(Q?3DMb}T+ z(5dnN#Y-6L_~?Z2-po8E<39YZqBn~D^o)3a|e`F6vj5lYL#Q5)cq34?l{bK`nG zl2Aw^L1|Zr*8fCDBlU<>-EgTSz)ns+_0E?3^MjcAN|V!g6Wa_vK{_safK4zfY#3(4 z1Ww7}VB}LAt=$guZ5Mn8^?NWu)_K+NGQ8jvm-46wrB)ErE+0ct5KfNF^9JySOvWz+jXuibPzoQpKdTrd3d ziL<@0-FQW-HLjysUdH`Bc966tLH};;!975TU4`THFf6u*BY7m|Xj3^k7ab}26}B4x zWAYw_tgVLn;>UKTh4fKp&!As`)CznPf53&>D7CzOC#nSI?)Vm2=2gd%e_JdT)(N-! zxdBrvI0BF7{^wQ~J_cYeK09uMuN9n}m(o+vJumPuABzRrR!z7tLP;8})|Ex?U!%_b zLbx1)P5S6h3hv=T#tZfrf(6sSE!QRk6Tz9YF!yX-e#-sYGkJUMse}9TZ~cMyN|X%t zU1lU~_}xg&*lHIEx~?C_KwNX9sJB zJGgB{WW)-)0C^oEFC3c9?MqSS4|d&nIO(yiYL$V^D-UR459DU=`#s!Hqw_Vj*y}Q& z?a;S9yQ=5AU+mZ)B&Eb4m1oh2;f8KC>>wLo(8FqPqi9#hV-AOeibe;Em z?{WK(#!TqVaW)CTSAWxo4B@M_IKl=(>qVt@@^ZvLUQaCwKrlZat1l+J6)Dg7ErkwBpBasI5EneSS4RiCBAXN5^9$Hk!Q}C-=I;>MTDS_T* zhR|fL)J37N->JIMK6~w8m2Ieh?}d-vwn+SXQRNjNWXf{hUl{J3X34FLbQg2|Rc}za z`1VTfj2pzsfULWDE2g1J@W3Cpre~UTxL(AYL3z!x9pQWb?s;tVotldjHlzE=5|T-F$S2vTG^E(Zt4(Yz?tPGs#}MYJa%4kRfzFHPrN4A3VfemGAH_q6 zlZVDV)$LZyE-h6<84Er*^pOq^tvx__a++t_u#tXg3%rN*F!^`8BRhi$1Jk<4jW_We?=%mdI$ zug0p^A+pswZk<>xacQfK~KBMV!<3Q}{S# z3TJ`2>3PKlW3_)Y^Wb@F-}B4U=G$X_6)OHd8gH4G+K@BQ$A^RYd-HMZ9!wKV9t}<--}#E5c}|z#}w&32(2ZRE+Ti-NLoqYw#xUr zWyAuZzy|4vQ+K$qy)g0mm0_Tq6CqrDCGyLsIn`L&x(??@#BoIke2&^(i~y*9j#{9@ z8}HQWq|xAQ*G2)HZjxfb!zK*xcZca63WF4D{5fa(ltT%XYdB~!T`IMTja3zHZ*^FD ziuipVFDpKp@NXXV@wZg5#1jfJp$12p^(dg_J&TckfZ~WT0V28G=mhh#23pqbzeYu>Da~frXA%{Xwh9jqo!%Z{9x-cWx2xS|HJ`I)4kNR}kJH&SS<{hlXR zYyYz%pUq|Hra_>@Pzz{qqywMUob&vT#{WoK|I{P<+~g|+20uReFwhOs>1y)SaMO10 z@>ET9@PGEA1{?0;(QAjdgW?&!es9|JMl-Q^dttr8?H-C(l3KqGl0JKgw*HwmXq?N8 zmYm5e3O&8(_#XN%1YcZIJs8Tlzqjv6ZXe9Lsw8??4YNcg^TTK23?=6+>_&A^A62YVc-2!`^S*D$TU7u*@;Ld8SD&!674P+eJ+%>f;&0rbP@sqXKYXn}(92_=RlyseS$>y7 z_7H=9znq(IZUwP)y26qlir-pEvf%R=@HU;HM6ryUDLdm(ORPbd0oT##!hK_u`u7Tb za5N31jWE7NT&o%%OaP^EYIwej;bFNz>n=-_5+HqBbs7W(``E#*}n2D z=}3A2WioV*U%rse{<5DF4P|RTU^KaY5-D~aq#LajKhVxgz=dlO z9ba`_b*7o93PsdXj*bLV*(lD_DJj~#g4-mZp24;DPli~A1w;avM`-nTMgS{Xwe{_? zoEdDNy8h=JJlDZ&COKw}9BvC}do=8> zmLU$>iqhor<@U)BWSB-9_MQK7=R;kcsLhRl=z$&G+<~K&J0}z_XJ1|NoEjGNiJ8Szp-{| zK%@Q^b(8xrpUS8EZqdG$q{wlKq`rV|7n~ zRf}8|IcLJ!`v5Pre!0YSoRZ=jy+SHVvssJ%b8F?N%d4YgP*uS`A8N;c!Ea6XQDy$q zEaTs8I*;kdo2Z+fT_l`}?4!XigNASCj_;)3Z13`WP*UX08YrJ}QWMzy%v@XIsYvUn zGE}QIPPI3R6B*hz!F9%e7VSNkXU~&_sYYK>YJ8V$d&Jlq42CD>ex8e>SFiK6E28wF89 z=ZfL|EB9|seg^2Gnnv0ZT{f$IiuifF0Fcedj6Iun-)gEhAji_9e}=FTUZC7v{4Tdi z*ei*T;$7Qa1!=Y;LFU2}g^-{gf8I8mX1G-tu7I@N1G%~Zi2F4Ht*r0;VMG zR$1pfUR@}Ac5~^ko)k^$&a-dsMW%Xo`}zhoiJrm{H!s~}fa%?BLG>`{QC#R!frm&w z%g=$oFKCs)CQ~yfBshuN)s3m4 z(#Dv7W;w+|W-_vv%o(*^qa!je!D>Ou<*_hy8zz7(bP4USP{}yln@UJeNX-=0u|>`r zZf&<$th@AIHFR3}#`>D}<;{!q=+Ioj}feb!zptjjJKaiE9fL1%L2xpL$ z>!p@HlbfoQd&oo_I4j!?Nl;FEv|;>el1!^hajbUlUL{kXG<_l^RS-MM1ny5e7{J4p2l|y~>16XM3$ckO#tvd^UeUSw>6ivkNZ8Q{kj-but zCw#MVgE$xU%R`R-q9mNv7kI8}?sttP6ON>W$|@@-;?W4vVC#v#L`GG2-hBhw3~J~X~pXwP{t(AnO^oR zEZ3Eg6NTvG{5n)LPWj1ojd~LLy?aU2cG(C>_F}jk=OtKY@r3lx&~NJOPiHEb2CM^r zz27{$XPuocu>oIyk`;Pt>aa!nK=FqWqm)jFa`CkQzUWhV3-~FJd8caPw>X6ne)m-~ zhG;6CiA2Rnl)W=yl=-%&@|k`yT<7s3f}PKO8X$IEn^OrOXQW@`V}EZ&cpt~li6+Ae zTWD1CS>G)v9$uA+;-{f)_ua}$*&~$aT#I5&x~j}|lpY#JnO>oT$nVOl5oN17utVjr z?zB1WLdiFtBbt_14>AvxU;WNrweL^Ne}DhR;>dT!-+yj%jw9@@xm4qI5RgS@{8# zz=L#rs-C}zl^80hP<--|#CfT7M@9kTi~l5JT5~5fB)x&%3%?P#_b1JA-S|BC-l{3k z-Z0O=ZP&q}%{)nDCtw@gL(Ts6Rxe?$bdIY6siVP~BX;i^1DBlF1%S8c++Nl=>4p0N z23>mFRX$Wu{0SZDvpJW*%mR*=4ZOtDE)(}SK5e~Z^ewkPJY{)}uU!k~FieiMRpfc5 zz6F0%AC$|@(rxtK$R$!+`9%G5Vq_<-I(Q(&(uU0y@_TCTn5SX(ZOBMP>FPfk4|gD^ zi>1l4QRJ}#g$IDCsDQ}V3_Dgi@qr3~K{X^LdyY@m+b!vh6sO)~qZOhm*qhr{<<2O+ zf8{bHbCCO4a!P7X=-$w}g4&lktGmDtsP1$K=QD*%V>_ka-e)@6eYeP!W9aa#7$dpD znb8&IGM=V-RS}urZ~bA^i+`YHlb9uF~qu$4S>JzQVT*%_m1t7(G0^>^cp6n<3j_sNV==jf@j zW0|npU#*J#f5_^F;`sUdcZk~zhe0LhVGGAc8SFYemfHUhBLv+0LCr^h zKI9qcOK#Y-$)ueGw%HYvvzVD{Pq>W25D}bJTjoA*PAZL=Xs5<_6?x@H-MD8JT%4?^ zzJ*!SbYP0jWc~8uwIgpmnG|%WVY5GKVBM?XA(w^e!34{BXUQCoY3j2&Jgp#tR$SIODZggHz51fCA5Uf5UDi{yaDImn!O#= zFkEt@BD!J9m4uN!{4X7$bVJk9vUJ#f)40fl5Pd7BpHqeO?35VARI#1|87iZia+Fkb zEg_M}meCLwkx;`wojGp8t=&Z%#7fmGNIquUTwJN@ODSqMO(noZJOf*HXconHa>lV{ zuyJ%;jx$>D$W}0?pruhRRFELNnPIm%u68FfT;?&<)$La3GVG}I*wJD#cdh8fMmJ%; zgvtnioq(%Q-UU}we%`gr>N}kmFEY31=Pg=EVhB6eN zn9*w&pDHR3nAO{@K1*^P&M{faEylpLGxbY$DjOu4n%)Lm6>jx9l%6a%IHoniL4zcN$?_o|VYnUrM*7Msb?yt!GEIeVs8})a4rOnTH_LgVxNp>}c5BJhv*O zWL4cxb%~cJ7^)g0tKBmmf~srRMXol3#%nhYY1oUq8)(TotBy`9D^XSxD~#Y(y&yB% z=dToBp(t`HBDrT^-5IwI&k!R#Rc78|+)ZdgL5l@y2_WBqqXRX%b^)>|T|apo;;^l6 zHr^;6wbNci2A&Y{#b8_6#59d@Xrln_=Ax6;gDhIe6aq)eDfd@O$^aiNR1*IHqV5aYshP~9Xs7J%?k3KL#&z;R zMI2I3I-kFasSCZWiDA^%Joi#N1gj~sC7cJvS)xzR9Tt}Bwylc zlIa?2c;7tKIJGOW+_4(1nycUtYVD1}Ow3DQ9@WoW-ZJcrlj%>mk?kQzLPqLxr_2eO z7uLACG9crx6%t&inNXZmwl`*IaVI$yM&(oOC4uN_BNqMH4WZhEa=r9yGq$(B(dF7I zlg=upp38E|9A^~mLu_QCR7zaUN3h6N^rK|*DxJ=#%_hJ~sj3%}x&T(HBhbpZg-^T1=hz$^oRRe+8L7@1q(aUiiO%FEpqsE}-ugN0`3?)|#~pfU}j4%7nc z&q;)XxXH;$g+lT6?c3?;>Dk%Yxw$#DT0K8Mzp${dxVShoGcz?crBo_aDiyfmyVX)2 zm|)RfL~pSB!2xu1=UoO{Ya{SSq5uG4u!L1&q+%BUtQqmZ?migfH{R72+2sJ$dRnJk zWZm(J9_zFv8?49f`}o4+@Mf$hs$IxKC z6Fb!Y)#@<`m;2070TX`)-PJbJGz=++K|iuZ7=2$<`%8z(xK@HC6r7DFg*c2 zz{yNY=VZdxr)Dgj>)^2UD_E)0(tGZ+_1i$Pezz!<5_C-V3?Jt7{Zaf_@N>(7IoWhv z!?qkNbe4F8Jrt-qzEh%JK#hFuW}0QP_Unx?qzbe^G{sahf-s2%$tfk3)e?ev@(Dt5 zm8yVgb+=EBx^b_V*P_gz*>&x!k%e2!DK~2Wkzi~*+QX#OF!Uavp${U^tZnMc(faNe z4r5vMtx7J(^8Ov361zquN|jYB^K->kSlLV2*xKyn+Gdzi?B;xgjCHI zFfGgaQzz?qa z11!k2zZwx#mx~iwJ#6Rwc>IiZ;*S@&xwL?Wov{OSWq!(|@eo;3%;D9L1C2#hohn9e zW>delA}=I|m7ciie%#47=l3|g`M5Vi-@Wd>#=1e$$qF+uzpmRQFW7e{1O4c`$k_k9gd0DB2oqEc7555=IwjJCW> zKUI4jeIOj%dEnK{{L#n1$M2Npb|prZ+CPU4l31_IMBI}T?0ARCPfWiBwCf%@Rmm27 zdo#o%*A@A;(hF=<2C9hAq?oP>~x z7nC5xi-z)ItA Date: Thu, 24 Sep 2020 23:06:14 +0800 Subject: [PATCH 023/326] Fix about me information --- docs/AboutUs.md | 3 +- docs/images/{kevin.png => lysire.png} | Bin docs/team/lysire.md | 46 ++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) rename docs/images/{kevin.png => lysire.png} (100%) create mode 100644 docs/team/lysire.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 12a13c11dc1..acf23935102 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -31,9 +31,10 @@ You can reach us at the email `seer[at]comp.nus.edu.sg` ### Bec Kyung Huhn (Kevin) - + [[github](http://github.com/lysire)] +[[portfolio](team/lysire.md)] * Role: Developer, IntelliJ Expert * Responsibilities: Deliverables and Deadlines diff --git a/docs/images/kevin.png b/docs/images/lysire.png similarity index 100% rename from docs/images/kevin.png rename to docs/images/lysire.png diff --git a/docs/team/lysire.md b/docs/team/lysire.md new file mode 100644 index 00000000000..a1ba519c8db --- /dev/null +++ b/docs/team/lysire.md @@ -0,0 +1,46 @@ +--- +layout: page +title: Lysire's Project Portfolio Page +--- + +## Project: AddressBook Level 3 + +AddressBook - Level 3 is a desktop address book application used for teaching Software Engineering principles. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 10 kLoC. + +Given below are my contributions to the project. + +* **New Feature**: Added the ability to undo/redo previous commands. + * What it does: allows the user to undo all previous commands one at a time. Preceding undo commands can be reversed by using the redo command. + * Justification: This feature improves the product significantly because a user can make mistakes in commands and the app should provide a convenient way to rectify them. + * Highlights: This enhancement affects existing commands and commands to be added in future. It required an in-depth analysis of design alternatives. The implementation too was challenging as it required changes to existing commands. + * Credits: *{mention here if you reused any code/ideas from elsewhere or if a third-party library is heavily used in the feature so that a reader can make a more accurate judgement of how much effort went into the feature}* + +* **New Feature**: Added a history command that allows the user to navigate to previous commands using up/down keys. + +* **Code contributed**: [RepoSense link]() + +* **Project management**: + * Managed releases `v1.3` - `v1.5rc` (3 releases) on GitHub + +* **Enhancements to existing features**: + * Updated the GUI color scheme (Pull requests [\#33](), [\#34]()) + * Wrote additional tests for existing features to increase coverage from 88% to 92% (Pull requests [\#36](), [\#38]()) + +* **Documentation**: + * User Guide: + * Added documentation for the features `delete` and `find` [\#72]() + * Did cosmetic tweaks to existing documentation of features `clear`, `exit`: [\#74]() + * Developer Guide: + * Added implementation details of the `delete` feature. + +* **Community**: + * PRs reviewed (with non-trivial review comments): [\#12](), [\#32](), [\#19](), [\#42]() + * Contributed to forum discussions (examples: [1](), [2](), [3](), [4]()) + * Reported bugs and suggestions for other teams in the class (examples: [1](), [2](), [3]()) + * Some parts of the history feature I added was adopted by several other class mates ([1](), [2]()) + +* **Tools**: + * Integrated a third party library (Natty) to the project ([\#42]()) + * Integrated a new Github plugin (CircleCI) to the team repo + +* _{you can add/remove categories in the list above}_ From f465a18dac8dd010fce6adadb2e4c34aed526550 Mon Sep 17 00:00:00 2001 From: Jing Yen Loh Date: Fri, 25 Sep 2020 02:42:24 +0800 Subject: [PATCH 024/326] Layout MainWindow according to our mockup --- src/main/resources/view/MainWindow.fxml | 122 +++++++++++++++--------- 1 file changed, 75 insertions(+), 47 deletions(-) diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml index a431648f6c0..fe01d96aa47 100644 --- a/src/main/resources/view/MainWindow.fxml +++ b/src/main/resources/view/MainWindow.fxml @@ -2,59 +2,87 @@ - - + + + - + + - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 8b9cedefdd398e1b46a5d19e2376c3ddc34d2e38 Mon Sep 17 00:00:00 2001 From: mkeoliya Date: Fri, 25 Sep 2020 02:49:28 +0800 Subject: [PATCH 025/326] Modify Person to Student class --- .../address/logic/commands/EditCommand.java | 226 ---------------- .../address/logic/commands/ListCommand.java | 24 -- .../java/seedu/address/model/AddressBook.java | 120 --------- .../address/model/ReadOnlyAddressBook.java | 17 -- .../seedu/address/model/person/Address.java | 57 ----- .../seedu/address/model/person/Person.java | 120 --------- .../model/person/UniquePersonList.java | 137 ---------- .../exceptions/DuplicatePersonException.java | 11 - .../exceptions/PersonNotFoundException.java | 6 - .../address/model/util/SampleDataUtil.java | 60 ----- .../address/storage/JsonAdaptedPerson.java | 109 -------- .../seedu/address/ui/PersonListPanel.java | 49 ---- .../{address => resireg}/AppParameters.java | 6 +- .../java/seedu/{address => resireg}/Main.java | 2 +- .../seedu/{address => resireg}/MainApp.java | 48 ++-- .../commons/core/Config.java | 2 +- .../commons/core/GuiSettings.java | 2 +- .../commons/core/LogsCenter.java | 2 +- .../commons/core/Messages.java | 6 +- .../commons/core/Version.java | 2 +- .../commons/core/index/Index.java | 2 +- .../exceptions/DataConversionException.java | 2 +- .../exceptions/IllegalValueException.java | 2 +- .../commons/util/AppUtil.java | 4 +- .../commons/util/CollectionUtil.java | 2 +- .../commons/util/ConfigUtil.java | 6 +- .../commons/util/FileUtil.java | 2 +- .../commons/util/JsonUtil.java | 6 +- .../commons/util/StringUtil.java | 4 +- .../{address => resireg}/logic/Logic.java | 20 +- .../logic/LogicManager.java | 28 +- .../logic/commands/AddCommand.java | 47 ++-- .../logic/commands/ClearCommand.java | 6 +- .../logic/commands/Command.java | 6 +- .../logic/commands/CommandResult.java | 2 +- .../logic/commands/DeleteCommand.java | 26 +- .../resireg/logic/commands/EditCommand.java | 241 ++++++++++++++++++ .../logic/commands/ExitCommand.java | 4 +- .../logic/commands/FindCommand.java | 16 +- .../logic/commands/HelpCommand.java | 4 +- .../resireg/logic/commands/ListCommand.java | 24 ++ .../commands/exceptions/CommandException.java | 2 +- .../logic/parser/AddCommandParser.java | 44 ++-- .../logic/parser/AddressBookParser.java | 26 +- .../logic/parser/ArgumentMultimap.java | 2 +- .../logic/parser/ArgumentTokenizer.java | 2 +- .../logic/parser/CliSyntax.java | 5 +- .../logic/parser/DeleteCommandParser.java | 10 +- .../logic/parser/EditCommandParser.java | 50 ++-- .../logic/parser/FindCommandParser.java | 10 +- .../logic/parser/Parser.java | 6 +- .../logic/parser/ParserUtil.java | 50 ++-- .../logic/parser/Prefix.java | 2 +- .../parser/exceptions/ParseException.java | 4 +- .../java/seedu/resireg/model/AddressBook.java | 121 +++++++++ .../{address => resireg}/model/Model.java | 39 +-- .../model/ModelManager.java | 50 ++-- .../resireg/model/ReadOnlyAddressBook.java | 17 ++ .../model/ReadOnlyUserPrefs.java | 4 +- .../{address => resireg}/model/UserPrefs.java | 4 +- .../model/student}/Email.java | 6 +- .../model/student}/Name.java | 6 +- .../NameContainsKeywordsPredicate.java | 12 +- .../model/student}/Phone.java | 6 +- .../seedu/resireg/model/student/Student.java | 129 ++++++++++ .../resireg/model/student/StudentId.java | 53 ++++ .../model/student/UniqueStudentList.java | 138 ++++++++++ .../exceptions/DuplicateStudentException.java | 11 + .../exceptions/StudentNotFoundException.java | 6 + .../model/student/faculty/Faculty.java | 57 +++++ .../model/student/faculty/FacultyEnum.java | 36 +++ .../{address => resireg}/model/tag/Tag.java | 4 +- .../resireg/model/util/SampleDataUtil.java | 61 +++++ .../storage/AddressBookStorage.java | 8 +- .../resireg/storage/JsonAdaptedStudent.java | 122 +++++++++ .../storage/JsonAdaptedTag.java | 6 +- .../storage/JsonAddressBookStorage.java | 14 +- .../storage/JsonSerializableAddressBook.java | 30 +-- .../storage/JsonUserPrefsStorage.java | 10 +- .../{address => resireg}/storage/Storage.java | 10 +- .../storage/StorageManager.java | 12 +- .../storage/UserPrefsStorage.java | 12 +- .../{address => resireg}/ui/CommandBox.java | 10 +- .../{address => resireg}/ui/HelpWindow.java | 4 +- .../{address => resireg}/ui/MainWindow.java | 29 ++- .../ui/ResultDisplay.java | 2 +- .../ui/StatusBarFooter.java | 2 +- .../ui/StudentCard.java} | 39 +-- .../seedu/resireg/ui/StudentListPanel.java | 49 ++++ .../seedu/{address => resireg}/ui/Ui.java | 2 +- .../{address => resireg}/ui/UiManager.java | 10 +- .../seedu/{address => resireg}/ui/UiPart.java | 4 +- src/main/resources/view/MainWindow.fxml | 6 +- ...rsonListCard.fxml => StudentListCard.fxml} | 3 +- ...onListPanel.fxml => StudentListPanel.fxml} | 2 +- ...=> invalidAndValidStudentAddressBook.json} | 9 +- ...ok.json => invalidStudentAddressBook.json} | 5 +- ....json => duplicateStudentAddressBook.json} | 8 +- ...ok.json => invalidStudentAddressBook.json} | 5 +- .../typicalPersonsAddressBook.json | 46 ---- .../typicalStudentsAddressBook.json | 53 ++++ .../commands/AddCommandIntegrationTest.java | 45 ---- .../commands/EditPersonDescriptorTest.java | 58 ----- .../logic/parser/AddCommandParserTest.java | 141 ---------- .../seedu/address/model/AddressBookTest.java | 102 -------- .../address/model/person/AddressTest.java | 36 --- .../address/model/person/PersonTest.java | 95 ------- .../model/person/UniquePersonListTest.java | 170 ------------ .../storage/JsonAdaptedPersonTest.java | 110 -------- .../testutil/EditPersonDescriptorBuilder.java | 87 ------- .../seedu/address/testutil/PersonBuilder.java | 96 ------- .../seedu/address/testutil/PersonUtil.java | 62 ----- .../address/testutil/TypicalPersons.java | 76 ------ .../AppParametersTest.java | 2 +- .../commons/core/ConfigTest.java | 2 +- .../commons/core/VersionTest.java | 4 +- .../commons/core/index/IndexTest.java | 18 +- .../commons/util/AppUtilTest.java | 4 +- .../commons/util/CollectionUtilTest.java | 6 +- .../commons/util/ConfigUtilTest.java | 8 +- .../commons/util/FileUtilTest.java | 4 +- .../commons/util/JsonUtilTest.java | 6 +- .../commons/util/StringUtilTest.java | 4 +- .../logic/LogicManagerTest.java | 57 +++-- .../commands/AddCommandIntegrationTest.java | 45 ++++ .../logic/commands/AddCommandTest.java | 96 +++---- .../logic/commands/ClearCommandTest.java | 14 +- .../logic/commands/CommandResultTest.java | 2 +- .../logic/commands/CommandTestUtil.java | 78 +++--- .../logic/commands/DeleteCommandTest.java | 56 ++-- .../logic/commands/EditCommandTest.java | 118 ++++----- .../commands/EditStudentDescriptorTest.java | 63 +++++ .../logic/commands/ExitCommandTest.java | 10 +- .../logic/commands/FindCommandTest.java | 36 +-- .../logic/commands/HelpCommandTest.java | 10 +- .../logic/commands/ListCommandTest.java | 18 +- .../logic/parser/AddCommandParserTest.java | 164 ++++++++++++ .../logic/parser/AddressBookParserTest.java | 52 ++-- .../logic/parser/ArgumentTokenizerTest.java | 2 +- .../logic/parser/CommandParserTestUtil.java | 6 +- .../logic/parser/DeleteCommandParserTest.java | 12 +- .../logic/parser/EditCommandParserTest.java | 145 ++++++----- .../logic/parser/FindCommandParserTest.java | 12 +- .../logic/parser/ParserUtilTest.java | 72 ++++-- .../seedu/resireg/model/AddressBookTest.java | 102 ++++++++ .../model/ModelManagerTest.java | 40 +-- .../model/UserPrefsTest.java | 4 +- .../model/student}/EmailTest.java | 4 +- .../resireg/model/student/FacultyTest.java | 40 +++ .../NameContainsKeywordsPredicateTest.java | 22 +- .../model/student}/NameTest.java | 4 +- .../model/student}/PhoneTest.java | 4 +- .../resireg/model/student/StudentIdTest.java | 42 +++ .../resireg/model/student/StudentTest.java | 104 ++++++++ .../model/student/UniqueStudentListTest.java | 170 ++++++++++++ .../model/tag/TagTest.java | 4 +- .../storage/JsonAdaptedStudentTest.java | 139 ++++++++++ .../storage/JsonAddressBookStorageTest.java | 32 +-- .../JsonSerializableAddressBookTest.java | 28 +- .../storage/JsonUserPrefsStorageTest.java | 10 +- .../storage/StorageManagerTest.java | 12 +- .../testutil/AddressBookBuilder.java | 14 +- .../{address => resireg}/testutil/Assert.java | 2 +- .../EditStudentDescriptorBuilder.java | 97 +++++++ .../testutil/SerializableTestClass.java | 2 +- .../resireg/testutil/StudentBuilder.java | 110 ++++++++ .../seedu/resireg/testutil/StudentUtil.java | 66 +++++ .../testutil/TestUtil.java | 22 +- .../testutil/TypicalIndexes.java | 4 +- .../resireg/testutil/TypicalStudents.java | 84 ++++++ .../ui/TestFxmlObject.java | 2 +- .../{address => resireg}/ui/UiPartTest.java | 6 +- .../resources/view/UiPartTest/validFile.fxml | 2 +- .../view/UiPartTest/validFileWithFxRoot.fxml | 2 +- 174 files changed, 3347 insertions(+), 2976 deletions(-) delete mode 100644 src/main/java/seedu/address/logic/commands/EditCommand.java delete mode 100644 src/main/java/seedu/address/logic/commands/ListCommand.java delete mode 100644 src/main/java/seedu/address/model/AddressBook.java delete mode 100644 src/main/java/seedu/address/model/ReadOnlyAddressBook.java delete mode 100644 src/main/java/seedu/address/model/person/Address.java delete mode 100644 src/main/java/seedu/address/model/person/Person.java delete mode 100644 src/main/java/seedu/address/model/person/UniquePersonList.java delete mode 100644 src/main/java/seedu/address/model/person/exceptions/DuplicatePersonException.java delete mode 100644 src/main/java/seedu/address/model/person/exceptions/PersonNotFoundException.java delete mode 100644 src/main/java/seedu/address/model/util/SampleDataUtil.java delete mode 100644 src/main/java/seedu/address/storage/JsonAdaptedPerson.java delete mode 100644 src/main/java/seedu/address/ui/PersonListPanel.java rename src/main/java/seedu/{address => resireg}/AppParameters.java (93%) rename src/main/java/seedu/{address => resireg}/Main.java (97%) rename src/main/java/seedu/{address => resireg}/MainApp.java (85%) rename src/main/java/seedu/{address => resireg}/commons/core/Config.java (97%) rename src/main/java/seedu/{address => resireg}/commons/core/GuiSettings.java (98%) rename src/main/java/seedu/{address => resireg}/commons/core/LogsCenter.java (99%) rename src/main/java/seedu/{address => resireg}/commons/core/Messages.java (77%) rename src/main/java/seedu/{address => resireg}/commons/core/Version.java (98%) rename src/main/java/seedu/{address => resireg}/commons/core/index/Index.java (97%) rename src/main/java/seedu/{address => resireg}/commons/exceptions/DataConversionException.java (84%) rename src/main/java/seedu/{address => resireg}/commons/exceptions/IllegalValueException.java (93%) rename src/main/java/seedu/{address => resireg}/commons/util/AppUtil.java (94%) rename src/main/java/seedu/{address => resireg}/commons/util/CollectionUtil.java (96%) rename src/main/java/seedu/{address => resireg}/commons/util/ConfigUtil.java (77%) rename src/main/java/seedu/{address => resireg}/commons/util/FileUtil.java (98%) rename src/main/java/seedu/{address => resireg}/commons/util/JsonUtil.java (97%) rename src/main/java/seedu/{address => resireg}/commons/util/StringUtil.java (95%) rename src/main/java/seedu/{address => resireg}/logic/Logic.java (64%) rename src/main/java/seedu/{address => resireg}/logic/LogicManager.java (73%) rename src/main/java/seedu/{address => resireg}/logic/commands/AddCommand.java (51%) rename src/main/java/seedu/{address => resireg}/logic/commands/ClearCommand.java (80%) rename src/main/java/seedu/{address => resireg}/logic/commands/Command.java (78%) rename src/main/java/seedu/{address => resireg}/logic/commands/CommandResult.java (97%) rename src/main/java/seedu/{address => resireg}/logic/commands/DeleteCommand.java (62%) create mode 100644 src/main/java/seedu/resireg/logic/commands/EditCommand.java rename src/main/java/seedu/{address => resireg}/logic/commands/ExitCommand.java (84%) rename src/main/java/seedu/{address => resireg}/logic/commands/FindCommand.java (72%) rename src/main/java/seedu/{address => resireg}/logic/commands/HelpCommand.java (88%) create mode 100644 src/main/java/seedu/resireg/logic/commands/ListCommand.java rename src/main/java/seedu/{address => resireg}/logic/commands/exceptions/CommandException.java (89%) rename src/main/java/seedu/{address => resireg}/logic/parser/AddCommandParser.java (53%) rename src/main/java/seedu/{address => resireg}/logic/parser/AddressBookParser.java (74%) rename src/main/java/seedu/{address => resireg}/logic/parser/ArgumentMultimap.java (98%) rename src/main/java/seedu/{address => resireg}/logic/parser/ArgumentTokenizer.java (99%) rename src/main/java/seedu/{address => resireg}/logic/parser/CliSyntax.java (70%) rename src/main/java/seedu/{address => resireg}/logic/parser/DeleteCommandParser.java (75%) rename src/main/java/seedu/{address => resireg}/logic/parser/EditCommandParser.java (53%) rename src/main/java/seedu/{address => resireg}/logic/parser/FindCommandParser.java (76%) rename src/main/java/seedu/{address => resireg}/logic/parser/Parser.java (72%) rename src/main/java/seedu/{address => resireg}/logic/parser/ParserUtil.java (70%) rename src/main/java/seedu/{address => resireg}/logic/parser/Prefix.java (95%) rename src/main/java/seedu/{address => resireg}/logic/parser/exceptions/ParseException.java (73%) create mode 100644 src/main/java/seedu/resireg/model/AddressBook.java rename src/main/java/seedu/{address => resireg}/model/Model.java (53%) rename src/main/java/seedu/{address => resireg}/model/ModelManager.java (68%) create mode 100644 src/main/java/seedu/resireg/model/ReadOnlyAddressBook.java rename src/main/java/seedu/{address => resireg}/model/ReadOnlyUserPrefs.java (70%) rename src/main/java/seedu/{address => resireg}/model/UserPrefs.java (96%) rename src/main/java/seedu/{address/model/person => resireg/model/student}/Email.java (94%) rename src/main/java/seedu/{address/model/person => resireg/model/student}/Name.java (90%) rename src/main/java/seedu/{address/model/person => resireg/model/student}/NameContainsKeywordsPredicate.java (73%) rename src/main/java/seedu/{address/model/person => resireg/model/student}/Phone.java (88%) create mode 100644 src/main/java/seedu/resireg/model/student/Student.java create mode 100644 src/main/java/seedu/resireg/model/student/StudentId.java create mode 100644 src/main/java/seedu/resireg/model/student/UniqueStudentList.java create mode 100644 src/main/java/seedu/resireg/model/student/exceptions/DuplicateStudentException.java create mode 100644 src/main/java/seedu/resireg/model/student/exceptions/StudentNotFoundException.java create mode 100644 src/main/java/seedu/resireg/model/student/faculty/Faculty.java create mode 100644 src/main/java/seedu/resireg/model/student/faculty/FacultyEnum.java rename src/main/java/seedu/{address => resireg}/model/tag/Tag.java (93%) create mode 100644 src/main/java/seedu/resireg/model/util/SampleDataUtil.java rename src/main/java/seedu/{address => resireg}/storage/AddressBookStorage.java (85%) create mode 100644 src/main/java/seedu/resireg/storage/JsonAdaptedStudent.java rename src/main/java/seedu/{address => resireg}/storage/JsonAdaptedTag.java (89%) rename src/main/java/seedu/{address => resireg}/storage/JsonAddressBookStorage.java (86%) rename src/main/java/seedu/{address => resireg}/storage/JsonSerializableAddressBook.java (57%) rename src/main/java/seedu/{address => resireg}/storage/JsonUserPrefsStorage.java (83%) rename src/main/java/seedu/{address => resireg}/storage/Storage.java (73%) rename src/main/java/seedu/{address => resireg}/storage/StorageManager.java (89%) rename src/main/java/seedu/{address => resireg}/storage/UserPrefsStorage.java (73%) rename src/main/java/seedu/{address => resireg}/ui/CommandBox.java (89%) rename src/main/java/seedu/{address => resireg}/ui/HelpWindow.java (97%) rename src/main/java/seedu/{address => resireg}/ui/MainWindow.java (88%) rename src/main/java/seedu/{address => resireg}/ui/ResultDisplay.java (95%) rename src/main/java/seedu/{address => resireg}/ui/StatusBarFooter.java (96%) rename src/main/java/seedu/{address/ui/PersonCard.java => resireg/ui/StudentCard.java} (58%) create mode 100644 src/main/java/seedu/resireg/ui/StudentListPanel.java rename src/main/java/seedu/{address => resireg}/ui/Ui.java (86%) rename src/main/java/seedu/{address => resireg}/ui/UiManager.java (94%) rename src/main/java/seedu/{address => resireg}/ui/UiPart.java (97%) rename src/main/resources/view/{PersonListCard.fxml => StudentListCard.fxml} (89%) rename src/main/resources/view/{PersonListPanel.fxml => StudentListPanel.fxml} (77%) rename src/test/data/JsonAddressBookStorageTest/{invalidAndValidPersonAddressBook.json => invalidAndValidStudentAddressBook.json} (59%) rename src/test/data/JsonAddressBookStorageTest/{invalidPersonAddressBook.json => invalidStudentAddressBook.json} (64%) rename src/test/data/JsonSerializableAddressBookTest/{duplicatePersonAddressBook.json => duplicateStudentAddressBook.json} (64%) rename src/test/data/JsonSerializableAddressBookTest/{invalidPersonAddressBook.json => invalidStudentAddressBook.json} (57%) delete mode 100644 src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json create mode 100644 src/test/data/JsonSerializableAddressBookTest/typicalStudentsAddressBook.json delete mode 100644 src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java delete mode 100644 src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java delete mode 100644 src/test/java/seedu/address/logic/parser/AddCommandParserTest.java delete mode 100644 src/test/java/seedu/address/model/AddressBookTest.java delete mode 100644 src/test/java/seedu/address/model/person/AddressTest.java delete mode 100644 src/test/java/seedu/address/model/person/PersonTest.java delete mode 100644 src/test/java/seedu/address/model/person/UniquePersonListTest.java delete mode 100644 src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java delete mode 100644 src/test/java/seedu/address/testutil/EditPersonDescriptorBuilder.java delete mode 100644 src/test/java/seedu/address/testutil/PersonBuilder.java delete mode 100644 src/test/java/seedu/address/testutil/PersonUtil.java delete mode 100644 src/test/java/seedu/address/testutil/TypicalPersons.java rename src/test/java/seedu/{address => resireg}/AppParametersTest.java (98%) rename src/test/java/seedu/{address => resireg}/commons/core/ConfigTest.java (95%) rename src/test/java/seedu/{address => resireg}/commons/core/VersionTest.java (98%) rename src/test/java/seedu/{address => resireg}/commons/core/index/IndexTest.java (74%) rename src/test/java/seedu/{address => resireg}/commons/util/AppUtilTest.java (91%) rename src/test/java/seedu/{address => resireg}/commons/util/CollectionUtilTest.java (96%) rename src/test/java/seedu/{address => resireg}/commons/util/ConfigUtilTest.java (94%) rename src/test/java/seedu/{address => resireg}/commons/util/FileUtilTest.java (84%) rename src/test/java/seedu/{address => resireg}/commons/util/JsonUtilTest.java (92%) rename src/test/java/seedu/{address => resireg}/commons/util/StringUtilTest.java (98%) rename src/test/java/seedu/{address => resireg}/logic/LogicManagerTest.java (78%) create mode 100644 src/test/java/seedu/resireg/logic/commands/AddCommandIntegrationTest.java rename src/test/java/seedu/{address => resireg}/logic/commands/AddCommandTest.java (58%) rename src/test/java/seedu/{address => resireg}/logic/commands/ClearCommandTest.java (69%) rename src/test/java/seedu/{address => resireg}/logic/commands/CommandResultTest.java (98%) rename src/test/java/seedu/{address => resireg}/logic/commands/CommandTestUtil.java (59%) rename src/test/java/seedu/{address => resireg}/logic/commands/DeleteCommandTest.java (65%) rename src/test/java/seedu/{address => resireg}/logic/commands/EditCommandTest.java (51%) create mode 100644 src/test/java/seedu/resireg/logic/commands/EditStudentDescriptorTest.java rename src/test/java/seedu/{address => resireg}/logic/commands/ExitCommandTest.java (66%) rename src/test/java/seedu/{address => resireg}/logic/commands/FindCommandTest.java (72%) rename src/test/java/seedu/{address => resireg}/logic/commands/HelpCommandTest.java (65%) rename src/test/java/seedu/{address => resireg}/logic/commands/ListCommandTest.java (63%) create mode 100644 src/test/java/seedu/resireg/logic/parser/AddCommandParserTest.java rename src/test/java/seedu/{address => resireg}/logic/parser/AddressBookParserTest.java (65%) rename src/test/java/seedu/{address => resireg}/logic/parser/ArgumentTokenizerTest.java (99%) rename src/test/java/seedu/{address => resireg}/logic/parser/CommandParserTestUtil.java (89%) rename src/test/java/seedu/{address => resireg}/logic/parser/DeleteCommandParserTest.java (73%) rename src/test/java/seedu/{address => resireg}/logic/parser/EditCommandParserTest.java (54%) rename src/test/java/seedu/{address => resireg}/logic/parser/FindCommandParserTest.java (72%) rename src/test/java/seedu/{address => resireg}/logic/parser/ParserUtilTest.java (71%) create mode 100644 src/test/java/seedu/resireg/model/AddressBookTest.java rename src/test/java/seedu/{address => resireg}/model/ModelManagerTest.java (76%) rename src/test/java/seedu/{address => resireg}/model/UserPrefsTest.java (86%) rename src/test/java/seedu/{address/model/person => resireg/model/student}/EmailTest.java (97%) create mode 100644 src/test/java/seedu/resireg/model/student/FacultyTest.java rename src/test/java/seedu/{address/model/person => resireg/model/student}/NameContainsKeywordsPredicateTest.java (74%) rename src/test/java/seedu/{address/model/person => resireg/model/student}/NameTest.java (93%) rename src/test/java/seedu/{address/model/person => resireg/model/student}/PhoneTest.java (93%) create mode 100644 src/test/java/seedu/resireg/model/student/StudentIdTest.java create mode 100644 src/test/java/seedu/resireg/model/student/StudentTest.java create mode 100644 src/test/java/seedu/resireg/model/student/UniqueStudentListTest.java rename src/test/java/seedu/{address => resireg}/model/tag/TagTest.java (86%) create mode 100644 src/test/java/seedu/resireg/storage/JsonAdaptedStudentTest.java rename src/test/java/seedu/{address => resireg}/storage/JsonAddressBookStorageTest.java (80%) rename src/test/java/seedu/{address => resireg}/storage/JsonSerializableAddressBookTest.java (61%) rename src/test/java/seedu/{address => resireg}/storage/JsonUserPrefsStorageTest.java (94%) rename src/test/java/seedu/{address => resireg}/storage/StorageManagerTest.java (88%) rename src/test/java/seedu/{address => resireg}/testutil/AddressBookBuilder.java (54%) rename src/test/java/seedu/{address => resireg}/testutil/Assert.java (97%) create mode 100644 src/test/java/seedu/resireg/testutil/EditStudentDescriptorBuilder.java rename src/test/java/seedu/{address => resireg}/testutil/SerializableTestClass.java (98%) create mode 100644 src/test/java/seedu/resireg/testutil/StudentBuilder.java create mode 100644 src/test/java/seedu/resireg/testutil/StudentUtil.java rename src/test/java/seedu/{address => resireg}/testutil/TestUtil.java (58%) rename src/test/java/seedu/{address => resireg}/testutil/TypicalIndexes.java (81%) create mode 100644 src/test/java/seedu/resireg/testutil/TypicalStudents.java rename src/test/java/seedu/{address => resireg}/ui/TestFxmlObject.java (96%) rename src/test/java/seedu/{address => resireg}/ui/UiPartTest.java (97%) diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java deleted file mode 100644 index 7e36114902f..00000000000 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ /dev/null @@ -1,226 +0,0 @@ -package seedu.address.logic.commands; - -import static java.util.Objects.requireNonNull; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; -import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; -import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; -import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; -import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; -import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; - -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -import seedu.address.commons.core.Messages; -import seedu.address.commons.core.index.Index; -import seedu.address.commons.util.CollectionUtil; -import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.model.Model; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Person; -import seedu.address.model.person.Phone; -import seedu.address.model.tag.Tag; - -/** - * Edits the details of an existing person in the address book. - */ -public class EditCommand extends Command { - - public static final String COMMAND_WORD = "edit"; - - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the details of the person identified " - + "by the index number used in the displayed person list. " - + "Existing values will be overwritten by the input values.\n" - + "Parameters: INDEX (must be a positive integer) " - + "[" + PREFIX_NAME + "NAME] " - + "[" + PREFIX_PHONE + "PHONE] " - + "[" + PREFIX_EMAIL + "EMAIL] " - + "[" + PREFIX_ADDRESS + "ADDRESS] " - + "[" + PREFIX_TAG + "TAG]...\n" - + "Example: " + COMMAND_WORD + " 1 " - + PREFIX_PHONE + "91234567 " - + PREFIX_EMAIL + "johndoe@example.com"; - - public static final String MESSAGE_EDIT_PERSON_SUCCESS = "Edited Person: %1$s"; - public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided."; - public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book."; - - private final Index index; - private final EditPersonDescriptor editPersonDescriptor; - - /** - * @param index of the person in the filtered person list to edit - * @param editPersonDescriptor details to edit the person with - */ - public EditCommand(Index index, EditPersonDescriptor editPersonDescriptor) { - requireNonNull(index); - requireNonNull(editPersonDescriptor); - - this.index = index; - this.editPersonDescriptor = new EditPersonDescriptor(editPersonDescriptor); - } - - @Override - public CommandResult execute(Model model) throws CommandException { - requireNonNull(model); - List lastShownList = model.getFilteredPersonList(); - - if (index.getZeroBased() >= lastShownList.size()) { - throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); - } - - Person personToEdit = lastShownList.get(index.getZeroBased()); - Person editedPerson = createEditedPerson(personToEdit, editPersonDescriptor); - - if (!personToEdit.isSamePerson(editedPerson) && model.hasPerson(editedPerson)) { - throw new CommandException(MESSAGE_DUPLICATE_PERSON); - } - - model.setPerson(personToEdit, editedPerson); - model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); - return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, editedPerson)); - } - - /** - * Creates and returns a {@code Person} with the details of {@code personToEdit} - * edited with {@code editPersonDescriptor}. - */ - private static Person createEditedPerson(Person personToEdit, EditPersonDescriptor editPersonDescriptor) { - assert personToEdit != null; - - Name updatedName = editPersonDescriptor.getName().orElse(personToEdit.getName()); - Phone updatedPhone = editPersonDescriptor.getPhone().orElse(personToEdit.getPhone()); - Email updatedEmail = editPersonDescriptor.getEmail().orElse(personToEdit.getEmail()); - Address updatedAddress = editPersonDescriptor.getAddress().orElse(personToEdit.getAddress()); - Set updatedTags = editPersonDescriptor.getTags().orElse(personToEdit.getTags()); - - return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags); - } - - @Override - public boolean equals(Object other) { - // short circuit if same object - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof EditCommand)) { - return false; - } - - // state check - EditCommand e = (EditCommand) other; - return index.equals(e.index) - && editPersonDescriptor.equals(e.editPersonDescriptor); - } - - /** - * Stores the details to edit the person with. Each non-empty field value will replace the - * corresponding field value of the person. - */ - public static class EditPersonDescriptor { - private Name name; - private Phone phone; - private Email email; - private Address address; - private Set tags; - - public EditPersonDescriptor() {} - - /** - * Copy constructor. - * A defensive copy of {@code tags} is used internally. - */ - public EditPersonDescriptor(EditPersonDescriptor toCopy) { - setName(toCopy.name); - setPhone(toCopy.phone); - setEmail(toCopy.email); - setAddress(toCopy.address); - setTags(toCopy.tags); - } - - /** - * Returns true if at least one field is edited. - */ - public boolean isAnyFieldEdited() { - return CollectionUtil.isAnyNonNull(name, phone, email, address, tags); - } - - public void setName(Name name) { - this.name = name; - } - - public Optional getName() { - return Optional.ofNullable(name); - } - - public void setPhone(Phone phone) { - this.phone = phone; - } - - public Optional getPhone() { - return Optional.ofNullable(phone); - } - - public void setEmail(Email email) { - this.email = email; - } - - public Optional getEmail() { - return Optional.ofNullable(email); - } - - public void setAddress(Address address) { - this.address = address; - } - - public Optional
getAddress() { - return Optional.ofNullable(address); - } - - /** - * Sets {@code tags} to this object's {@code tags}. - * A defensive copy of {@code tags} is used internally. - */ - public void setTags(Set tags) { - this.tags = (tags != null) ? new HashSet<>(tags) : null; - } - - /** - * Returns an unmodifiable tag set, which throws {@code UnsupportedOperationException} - * if modification is attempted. - * Returns {@code Optional#empty()} if {@code tags} is null. - */ - public Optional> getTags() { - return (tags != null) ? Optional.of(Collections.unmodifiableSet(tags)) : Optional.empty(); - } - - @Override - public boolean equals(Object other) { - // short circuit if same object - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof EditPersonDescriptor)) { - return false; - } - - // state check - EditPersonDescriptor e = (EditPersonDescriptor) other; - - return getName().equals(e.getName()) - && getPhone().equals(e.getPhone()) - && getEmail().equals(e.getEmail()) - && getAddress().equals(e.getAddress()) - && getTags().equals(e.getTags()); - } - } -} diff --git a/src/main/java/seedu/address/logic/commands/ListCommand.java b/src/main/java/seedu/address/logic/commands/ListCommand.java deleted file mode 100644 index 84be6ad2596..00000000000 --- a/src/main/java/seedu/address/logic/commands/ListCommand.java +++ /dev/null @@ -1,24 +0,0 @@ -package seedu.address.logic.commands; - -import static java.util.Objects.requireNonNull; -import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; - -import seedu.address.model.Model; - -/** - * Lists all persons in the address book to the user. - */ -public class ListCommand extends Command { - - public static final String COMMAND_WORD = "list"; - - public static final String MESSAGE_SUCCESS = "Listed all persons"; - - - @Override - public CommandResult execute(Model model) { - requireNonNull(model); - model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); - return new CommandResult(MESSAGE_SUCCESS); - } -} diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java deleted file mode 100644 index 1a943a0781a..00000000000 --- a/src/main/java/seedu/address/model/AddressBook.java +++ /dev/null @@ -1,120 +0,0 @@ -package seedu.address.model; - -import static java.util.Objects.requireNonNull; - -import java.util.List; - -import javafx.collections.ObservableList; -import seedu.address.model.person.Person; -import seedu.address.model.person.UniquePersonList; - -/** - * Wraps all data at the address-book level - * Duplicates are not allowed (by .isSamePerson comparison) - */ -public class AddressBook implements ReadOnlyAddressBook { - - private final UniquePersonList persons; - - /* - * The 'unusual' code block below is a non-static initialization block, sometimes used to avoid duplication - * between constructors. See https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html - * - * Note that non-static init blocks are not recommended to use. There are other ways to avoid duplication - * among constructors. - */ - { - persons = new UniquePersonList(); - } - - public AddressBook() {} - - /** - * Creates an AddressBook using the Persons in the {@code toBeCopied} - */ - public AddressBook(ReadOnlyAddressBook toBeCopied) { - this(); - resetData(toBeCopied); - } - - //// list overwrite operations - - /** - * Replaces the contents of the person list with {@code persons}. - * {@code persons} must not contain duplicate persons. - */ - public void setPersons(List persons) { - this.persons.setPersons(persons); - } - - /** - * Resets the existing data of this {@code AddressBook} with {@code newData}. - */ - public void resetData(ReadOnlyAddressBook newData) { - requireNonNull(newData); - - setPersons(newData.getPersonList()); - } - - //// person-level operations - - /** - * Returns true if a person with the same identity as {@code person} exists in the address book. - */ - public boolean hasPerson(Person person) { - requireNonNull(person); - return persons.contains(person); - } - - /** - * Adds a person to the address book. - * The person must not already exist in the address book. - */ - public void addPerson(Person p) { - persons.add(p); - } - - /** - * Replaces the given person {@code target} in the list with {@code editedPerson}. - * {@code target} must exist in the address book. - * The person identity of {@code editedPerson} must not be the same as another existing person in the address book. - */ - public void setPerson(Person target, Person editedPerson) { - requireNonNull(editedPerson); - - persons.setPerson(target, editedPerson); - } - - /** - * Removes {@code key} from this {@code AddressBook}. - * {@code key} must exist in the address book. - */ - public void removePerson(Person key) { - persons.remove(key); - } - - //// util methods - - @Override - public String toString() { - return persons.asUnmodifiableObservableList().size() + " persons"; - // TODO: refine later - } - - @Override - public ObservableList getPersonList() { - return persons.asUnmodifiableObservableList(); - } - - @Override - public boolean equals(Object other) { - return other == this // short circuit if same object - || (other instanceof AddressBook // instanceof handles nulls - && persons.equals(((AddressBook) other).persons)); - } - - @Override - public int hashCode() { - return persons.hashCode(); - } -} diff --git a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java deleted file mode 100644 index 6ddc2cd9a29..00000000000 --- a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java +++ /dev/null @@ -1,17 +0,0 @@ -package seedu.address.model; - -import javafx.collections.ObservableList; -import seedu.address.model.person.Person; - -/** - * Unmodifiable view of an address book - */ -public interface ReadOnlyAddressBook { - - /** - * Returns an unmodifiable view of the persons list. - * This list will not contain any duplicate persons. - */ - ObservableList getPersonList(); - -} diff --git a/src/main/java/seedu/address/model/person/Address.java b/src/main/java/seedu/address/model/person/Address.java deleted file mode 100644 index 60472ca22a0..00000000000 --- a/src/main/java/seedu/address/model/person/Address.java +++ /dev/null @@ -1,57 +0,0 @@ -package seedu.address.model.person; - -import static java.util.Objects.requireNonNull; -import static seedu.address.commons.util.AppUtil.checkArgument; - -/** - * Represents a Person's address in the address book. - * Guarantees: immutable; is valid as declared in {@link #isValidAddress(String)} - */ -public class Address { - - public static final String MESSAGE_CONSTRAINTS = "Addresses can take any values, and it should not be blank"; - - /* - * The first character of the address must not be a whitespace, - * otherwise " " (a blank string) becomes a valid input. - */ - public static final String VALIDATION_REGEX = "[^\\s].*"; - - public final String value; - - /** - * Constructs an {@code Address}. - * - * @param address A valid address. - */ - public Address(String address) { - requireNonNull(address); - checkArgument(isValidAddress(address), MESSAGE_CONSTRAINTS); - value = address; - } - - /** - * Returns true if a given string is a valid email. - */ - public static boolean isValidAddress(String test) { - return test.matches(VALIDATION_REGEX); - } - - @Override - public String toString() { - return value; - } - - @Override - public boolean equals(Object other) { - return other == this // short circuit if same object - || (other instanceof Address // instanceof handles nulls - && value.equals(((Address) other).value)); // state check - } - - @Override - public int hashCode() { - return value.hashCode(); - } - -} diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java deleted file mode 100644 index 557a7a60cd5..00000000000 --- a/src/main/java/seedu/address/model/person/Person.java +++ /dev/null @@ -1,120 +0,0 @@ -package seedu.address.model.person; - -import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -import seedu.address.model.tag.Tag; - -/** - * Represents a Person in the address book. - * Guarantees: details are present and not null, field values are validated, immutable. - */ -public class Person { - - // Identity fields - private final Name name; - private final Phone phone; - private final Email email; - - // Data fields - private final Address address; - private final Set tags = new HashSet<>(); - - /** - * Every field must be present and not null. - */ - public Person(Name name, Phone phone, Email email, Address address, Set tags) { - requireAllNonNull(name, phone, email, address, tags); - this.name = name; - this.phone = phone; - this.email = email; - this.address = address; - this.tags.addAll(tags); - } - - public Name getName() { - return name; - } - - public Phone getPhone() { - return phone; - } - - public Email getEmail() { - return email; - } - - public Address getAddress() { - return address; - } - - /** - * Returns an immutable tag set, which throws {@code UnsupportedOperationException} - * if modification is attempted. - */ - public Set getTags() { - return Collections.unmodifiableSet(tags); - } - - /** - * Returns true if both persons of the same name have at least one other identity field that is the same. - * This defines a weaker notion of equality between two persons. - */ - public boolean isSamePerson(Person otherPerson) { - if (otherPerson == this) { - return true; - } - - return otherPerson != null - && otherPerson.getName().equals(getName()) - && (otherPerson.getPhone().equals(getPhone()) || otherPerson.getEmail().equals(getEmail())); - } - - /** - * Returns true if both persons have the same identity and data fields. - * This defines a stronger notion of equality between two persons. - */ - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - if (!(other instanceof Person)) { - return false; - } - - Person otherPerson = (Person) other; - return otherPerson.getName().equals(getName()) - && otherPerson.getPhone().equals(getPhone()) - && otherPerson.getEmail().equals(getEmail()) - && otherPerson.getAddress().equals(getAddress()) - && otherPerson.getTags().equals(getTags()); - } - - @Override - public int hashCode() { - // use this method for custom fields hashing instead of implementing your own - return Objects.hash(name, phone, email, address, tags); - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append(getName()) - .append(" Phone: ") - .append(getPhone()) - .append(" Email: ") - .append(getEmail()) - .append(" Address: ") - .append(getAddress()) - .append(" Tags: "); - getTags().forEach(builder::append); - return builder.toString(); - } - -} diff --git a/src/main/java/seedu/address/model/person/UniquePersonList.java b/src/main/java/seedu/address/model/person/UniquePersonList.java deleted file mode 100644 index 0fee4fe57e6..00000000000 --- a/src/main/java/seedu/address/model/person/UniquePersonList.java +++ /dev/null @@ -1,137 +0,0 @@ -package seedu.address.model.person; - -import static java.util.Objects.requireNonNull; -import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; - -import java.util.Iterator; -import java.util.List; - -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import seedu.address.model.person.exceptions.DuplicatePersonException; -import seedu.address.model.person.exceptions.PersonNotFoundException; - -/** - * A list of persons that enforces uniqueness between its elements and does not allow nulls. - * A person is considered unique by comparing using {@code Person#isSamePerson(Person)}. As such, adding and updating of - * persons uses Person#isSamePerson(Person) for equality so as to ensure that the person being added or updated is - * unique in terms of identity in the UniquePersonList. However, the removal of a person uses Person#equals(Object) so - * as to ensure that the person with exactly the same fields will be removed. - * - * Supports a minimal set of list operations. - * - * @see Person#isSamePerson(Person) - */ -public class UniquePersonList implements Iterable { - - private final ObservableList internalList = FXCollections.observableArrayList(); - private final ObservableList internalUnmodifiableList = - FXCollections.unmodifiableObservableList(internalList); - - /** - * Returns true if the list contains an equivalent person as the given argument. - */ - public boolean contains(Person toCheck) { - requireNonNull(toCheck); - return internalList.stream().anyMatch(toCheck::isSamePerson); - } - - /** - * Adds a person to the list. - * The person must not already exist in the list. - */ - public void add(Person toAdd) { - requireNonNull(toAdd); - if (contains(toAdd)) { - throw new DuplicatePersonException(); - } - internalList.add(toAdd); - } - - /** - * Replaces the person {@code target} in the list with {@code editedPerson}. - * {@code target} must exist in the list. - * The person identity of {@code editedPerson} must not be the same as another existing person in the list. - */ - public void setPerson(Person target, Person editedPerson) { - requireAllNonNull(target, editedPerson); - - int index = internalList.indexOf(target); - if (index == -1) { - throw new PersonNotFoundException(); - } - - if (!target.isSamePerson(editedPerson) && contains(editedPerson)) { - throw new DuplicatePersonException(); - } - - internalList.set(index, editedPerson); - } - - /** - * Removes the equivalent person from the list. - * The person must exist in the list. - */ - public void remove(Person toRemove) { - requireNonNull(toRemove); - if (!internalList.remove(toRemove)) { - throw new PersonNotFoundException(); - } - } - - public void setPersons(UniquePersonList replacement) { - requireNonNull(replacement); - internalList.setAll(replacement.internalList); - } - - /** - * Replaces the contents of this list with {@code persons}. - * {@code persons} must not contain duplicate persons. - */ - public void setPersons(List persons) { - requireAllNonNull(persons); - if (!personsAreUnique(persons)) { - throw new DuplicatePersonException(); - } - - internalList.setAll(persons); - } - - /** - * Returns the backing list as an unmodifiable {@code ObservableList}. - */ - public ObservableList asUnmodifiableObservableList() { - return internalUnmodifiableList; - } - - @Override - public Iterator iterator() { - return internalList.iterator(); - } - - @Override - public boolean equals(Object other) { - return other == this // short circuit if same object - || (other instanceof UniquePersonList // instanceof handles nulls - && internalList.equals(((UniquePersonList) other).internalList)); - } - - @Override - public int hashCode() { - return internalList.hashCode(); - } - - /** - * Returns true if {@code persons} contains only unique persons. - */ - private boolean personsAreUnique(List persons) { - for (int i = 0; i < persons.size() - 1; i++) { - for (int j = i + 1; j < persons.size(); j++) { - if (persons.get(i).isSamePerson(persons.get(j))) { - return false; - } - } - } - return true; - } -} diff --git a/src/main/java/seedu/address/model/person/exceptions/DuplicatePersonException.java b/src/main/java/seedu/address/model/person/exceptions/DuplicatePersonException.java deleted file mode 100644 index d7290f59442..00000000000 --- a/src/main/java/seedu/address/model/person/exceptions/DuplicatePersonException.java +++ /dev/null @@ -1,11 +0,0 @@ -package seedu.address.model.person.exceptions; - -/** - * Signals that the operation will result in duplicate Persons (Persons are considered duplicates if they have the same - * identity). - */ -public class DuplicatePersonException extends RuntimeException { - public DuplicatePersonException() { - super("Operation would result in duplicate persons"); - } -} diff --git a/src/main/java/seedu/address/model/person/exceptions/PersonNotFoundException.java b/src/main/java/seedu/address/model/person/exceptions/PersonNotFoundException.java deleted file mode 100644 index fa764426ca7..00000000000 --- a/src/main/java/seedu/address/model/person/exceptions/PersonNotFoundException.java +++ /dev/null @@ -1,6 +0,0 @@ -package seedu.address.model.person.exceptions; - -/** - * Signals that the operation is unable to find the specified person. - */ -public class PersonNotFoundException extends RuntimeException {} diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java deleted file mode 100644 index 1806da4facf..00000000000 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ /dev/null @@ -1,60 +0,0 @@ -package seedu.address.model.util; - -import java.util.Arrays; -import java.util.Set; -import java.util.stream.Collectors; - -import seedu.address.model.AddressBook; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Person; -import seedu.address.model.person.Phone; -import seedu.address.model.tag.Tag; - -/** - * Contains utility methods for populating {@code AddressBook} with sample data. - */ -public class SampleDataUtil { - public static Person[] getSamplePersons() { - return new Person[] { - new Person(new Name("Alex Yeoh"), new Phone("87438807"), new Email("alexyeoh@example.com"), - new Address("Blk 30 Geylang Street 29, #06-40"), - getTagSet("friends")), - new Person(new Name("Bernice Yu"), new Phone("99272758"), new Email("berniceyu@example.com"), - new Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"), - getTagSet("colleagues", "friends")), - new Person(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Email("charlotte@example.com"), - new Address("Blk 11 Ang Mo Kio Street 74, #11-04"), - getTagSet("neighbours")), - new Person(new Name("David Li"), new Phone("91031282"), new Email("lidavid@example.com"), - new Address("Blk 436 Serangoon Gardens Street 26, #16-43"), - getTagSet("family")), - new Person(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"), - new Address("Blk 47 Tampines Street 20, #17-35"), - getTagSet("classmates")), - new Person(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"), - new Address("Blk 45 Aljunied Street 85, #11-31"), - getTagSet("colleagues")) - }; - } - - public static ReadOnlyAddressBook getSampleAddressBook() { - AddressBook sampleAb = new AddressBook(); - for (Person samplePerson : getSamplePersons()) { - sampleAb.addPerson(samplePerson); - } - return sampleAb; - } - - /** - * Returns a tag set containing the list of strings given. - */ - public static Set getTagSet(String... strings) { - return Arrays.stream(strings) - .map(Tag::new) - .collect(Collectors.toSet()); - } - -} diff --git a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java deleted file mode 100644 index a6321cec2ea..00000000000 --- a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java +++ /dev/null @@ -1,109 +0,0 @@ -package seedu.address.storage; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Person; -import seedu.address.model.person.Phone; -import seedu.address.model.tag.Tag; - -/** - * Jackson-friendly version of {@link Person}. - */ -class JsonAdaptedPerson { - - public static final String MISSING_FIELD_MESSAGE_FORMAT = "Person's %s field is missing!"; - - private final String name; - private final String phone; - private final String email; - private final String address; - private final List tagged = new ArrayList<>(); - - /** - * Constructs a {@code JsonAdaptedPerson} with the given person details. - */ - @JsonCreator - public JsonAdaptedPerson(@JsonProperty("name") String name, @JsonProperty("phone") String phone, - @JsonProperty("email") String email, @JsonProperty("address") String address, - @JsonProperty("tagged") List tagged) { - this.name = name; - this.phone = phone; - this.email = email; - this.address = address; - if (tagged != null) { - this.tagged.addAll(tagged); - } - } - - /** - * Converts a given {@code Person} into this class for Jackson use. - */ - public JsonAdaptedPerson(Person source) { - name = source.getName().fullName; - phone = source.getPhone().value; - email = source.getEmail().value; - address = source.getAddress().value; - tagged.addAll(source.getTags().stream() - .map(JsonAdaptedTag::new) - .collect(Collectors.toList())); - } - - /** - * Converts this Jackson-friendly adapted person object into the model's {@code Person} object. - * - * @throws IllegalValueException if there were any data constraints violated in the adapted person. - */ - public Person toModelType() throws IllegalValueException { - final List personTags = new ArrayList<>(); - for (JsonAdaptedTag tag : tagged) { - personTags.add(tag.toModelType()); - } - - if (name == null) { - throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName())); - } - if (!Name.isValidName(name)) { - throw new IllegalValueException(Name.MESSAGE_CONSTRAINTS); - } - final Name modelName = new Name(name); - - if (phone == null) { - throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName())); - } - if (!Phone.isValidPhone(phone)) { - throw new IllegalValueException(Phone.MESSAGE_CONSTRAINTS); - } - final Phone modelPhone = new Phone(phone); - - if (email == null) { - throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Email.class.getSimpleName())); - } - if (!Email.isValidEmail(email)) { - throw new IllegalValueException(Email.MESSAGE_CONSTRAINTS); - } - final Email modelEmail = new Email(email); - - if (address == null) { - throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Address.class.getSimpleName())); - } - if (!Address.isValidAddress(address)) { - throw new IllegalValueException(Address.MESSAGE_CONSTRAINTS); - } - final Address modelAddress = new Address(address); - - final Set modelTags = new HashSet<>(personTags); - return new Person(modelName, modelPhone, modelEmail, modelAddress, modelTags); - } - -} diff --git a/src/main/java/seedu/address/ui/PersonListPanel.java b/src/main/java/seedu/address/ui/PersonListPanel.java deleted file mode 100644 index f4c501a897b..00000000000 --- a/src/main/java/seedu/address/ui/PersonListPanel.java +++ /dev/null @@ -1,49 +0,0 @@ -package seedu.address.ui; - -import java.util.logging.Logger; - -import javafx.collections.ObservableList; -import javafx.fxml.FXML; -import javafx.scene.control.ListCell; -import javafx.scene.control.ListView; -import javafx.scene.layout.Region; -import seedu.address.commons.core.LogsCenter; -import seedu.address.model.person.Person; - -/** - * Panel containing the list of persons. - */ -public class PersonListPanel extends UiPart { - private static final String FXML = "PersonListPanel.fxml"; - private final Logger logger = LogsCenter.getLogger(PersonListPanel.class); - - @FXML - private ListView personListView; - - /** - * Creates a {@code PersonListPanel} with the given {@code ObservableList}. - */ - public PersonListPanel(ObservableList personList) { - super(FXML); - personListView.setItems(personList); - personListView.setCellFactory(listView -> new PersonListViewCell()); - } - - /** - * Custom {@code ListCell} that displays the graphics of a {@code Person} using a {@code PersonCard}. - */ - class PersonListViewCell extends ListCell { - @Override - protected void updateItem(Person person, boolean empty) { - super.updateItem(person, empty); - - if (empty || person == null) { - setGraphic(null); - setText(null); - } else { - setGraphic(new PersonCard(person, getIndex() + 1).getRoot()); - } - } - } - -} diff --git a/src/main/java/seedu/address/AppParameters.java b/src/main/java/seedu/resireg/AppParameters.java similarity index 93% rename from src/main/java/seedu/address/AppParameters.java rename to src/main/java/seedu/resireg/AppParameters.java index ab552c398f3..d0c11811962 100644 --- a/src/main/java/seedu/address/AppParameters.java +++ b/src/main/java/seedu/resireg/AppParameters.java @@ -1,4 +1,4 @@ -package seedu.address; +package seedu.resireg; import java.nio.file.Path; import java.nio.file.Paths; @@ -7,8 +7,8 @@ import java.util.logging.Logger; import javafx.application.Application; -import seedu.address.commons.core.LogsCenter; -import seedu.address.commons.util.FileUtil; +import seedu.resireg.commons.core.LogsCenter; +import seedu.resireg.commons.util.FileUtil; /** * Represents the parsed command-line parameters given to the application. diff --git a/src/main/java/seedu/address/Main.java b/src/main/java/seedu/resireg/Main.java similarity index 97% rename from src/main/java/seedu/address/Main.java rename to src/main/java/seedu/resireg/Main.java index 052a5068631..96814521e54 100644 --- a/src/main/java/seedu/address/Main.java +++ b/src/main/java/seedu/resireg/Main.java @@ -1,4 +1,4 @@ -package seedu.address; +package seedu.resireg; import javafx.application.Application; diff --git a/src/main/java/seedu/address/MainApp.java b/src/main/java/seedu/resireg/MainApp.java similarity index 85% rename from src/main/java/seedu/address/MainApp.java rename to src/main/java/seedu/resireg/MainApp.java index e5cfb161b73..c73f9971d4c 100644 --- a/src/main/java/seedu/address/MainApp.java +++ b/src/main/java/seedu/resireg/MainApp.java @@ -1,4 +1,4 @@ -package seedu.address; +package seedu.resireg; import java.io.IOException; import java.nio.file.Path; @@ -7,29 +7,29 @@ import javafx.application.Application; import javafx.stage.Stage; -import seedu.address.commons.core.Config; -import seedu.address.commons.core.LogsCenter; -import seedu.address.commons.core.Version; -import seedu.address.commons.exceptions.DataConversionException; -import seedu.address.commons.util.ConfigUtil; -import seedu.address.commons.util.StringUtil; -import seedu.address.logic.Logic; -import seedu.address.logic.LogicManager; -import seedu.address.model.AddressBook; -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.ReadOnlyUserPrefs; -import seedu.address.model.UserPrefs; -import seedu.address.model.util.SampleDataUtil; -import seedu.address.storage.AddressBookStorage; -import seedu.address.storage.JsonAddressBookStorage; -import seedu.address.storage.JsonUserPrefsStorage; -import seedu.address.storage.Storage; -import seedu.address.storage.StorageManager; -import seedu.address.storage.UserPrefsStorage; -import seedu.address.ui.Ui; -import seedu.address.ui.UiManager; +import seedu.resireg.commons.core.Config; +import seedu.resireg.commons.core.LogsCenter; +import seedu.resireg.commons.core.Version; +import seedu.resireg.commons.exceptions.DataConversionException; +import seedu.resireg.commons.util.ConfigUtil; +import seedu.resireg.commons.util.StringUtil; +import seedu.resireg.logic.Logic; +import seedu.resireg.logic.LogicManager; +import seedu.resireg.model.AddressBook; +import seedu.resireg.model.Model; +import seedu.resireg.model.ModelManager; +import seedu.resireg.model.ReadOnlyAddressBook; +import seedu.resireg.model.ReadOnlyUserPrefs; +import seedu.resireg.model.UserPrefs; +import seedu.resireg.model.util.SampleDataUtil; +import seedu.resireg.storage.AddressBookStorage; +import seedu.resireg.storage.JsonAddressBookStorage; +import seedu.resireg.storage.JsonUserPrefsStorage; +import seedu.resireg.storage.Storage; +import seedu.resireg.storage.StorageManager; +import seedu.resireg.storage.UserPrefsStorage; +import seedu.resireg.ui.Ui; +import seedu.resireg.ui.UiManager; /** * Runs the application. diff --git a/src/main/java/seedu/address/commons/core/Config.java b/src/main/java/seedu/resireg/commons/core/Config.java similarity index 97% rename from src/main/java/seedu/address/commons/core/Config.java rename to src/main/java/seedu/resireg/commons/core/Config.java index 91145745521..c65f4b4fbb7 100644 --- a/src/main/java/seedu/address/commons/core/Config.java +++ b/src/main/java/seedu/resireg/commons/core/Config.java @@ -1,4 +1,4 @@ -package seedu.address.commons.core; +package seedu.resireg.commons.core; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/src/main/java/seedu/address/commons/core/GuiSettings.java b/src/main/java/seedu/resireg/commons/core/GuiSettings.java similarity index 98% rename from src/main/java/seedu/address/commons/core/GuiSettings.java rename to src/main/java/seedu/resireg/commons/core/GuiSettings.java index ba33653be67..51308a003e5 100644 --- a/src/main/java/seedu/address/commons/core/GuiSettings.java +++ b/src/main/java/seedu/resireg/commons/core/GuiSettings.java @@ -1,4 +1,4 @@ -package seedu.address.commons.core; +package seedu.resireg.commons.core; import java.awt.Point; import java.io.Serializable; diff --git a/src/main/java/seedu/address/commons/core/LogsCenter.java b/src/main/java/seedu/resireg/commons/core/LogsCenter.java similarity index 99% rename from src/main/java/seedu/address/commons/core/LogsCenter.java rename to src/main/java/seedu/resireg/commons/core/LogsCenter.java index 431e7185e76..001f357b60a 100644 --- a/src/main/java/seedu/address/commons/core/LogsCenter.java +++ b/src/main/java/seedu/resireg/commons/core/LogsCenter.java @@ -1,4 +1,4 @@ -package seedu.address.commons.core; +package seedu.resireg.commons.core; import java.io.IOException; import java.util.Arrays; diff --git a/src/main/java/seedu/address/commons/core/Messages.java b/src/main/java/seedu/resireg/commons/core/Messages.java similarity index 77% rename from src/main/java/seedu/address/commons/core/Messages.java rename to src/main/java/seedu/resireg/commons/core/Messages.java index 1deb3a1e469..7199642dbed 100644 --- a/src/main/java/seedu/address/commons/core/Messages.java +++ b/src/main/java/seedu/resireg/commons/core/Messages.java @@ -1,4 +1,4 @@ -package seedu.address.commons.core; +package seedu.resireg.commons.core; /** * Container for user visible messages. @@ -7,7 +7,7 @@ public class Messages { public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command"; public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; - public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; - public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; + public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The student index provided is invalid"; + public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d students listed!"; } diff --git a/src/main/java/seedu/address/commons/core/Version.java b/src/main/java/seedu/resireg/commons/core/Version.java similarity index 98% rename from src/main/java/seedu/address/commons/core/Version.java rename to src/main/java/seedu/resireg/commons/core/Version.java index 12142ec1e32..cab2a696617 100644 --- a/src/main/java/seedu/address/commons/core/Version.java +++ b/src/main/java/seedu/resireg/commons/core/Version.java @@ -1,4 +1,4 @@ -package seedu.address.commons.core; +package seedu.resireg.commons.core; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/src/main/java/seedu/address/commons/core/index/Index.java b/src/main/java/seedu/resireg/commons/core/index/Index.java similarity index 97% rename from src/main/java/seedu/address/commons/core/index/Index.java rename to src/main/java/seedu/resireg/commons/core/index/Index.java index 19536439c09..8ba85a6be25 100644 --- a/src/main/java/seedu/address/commons/core/index/Index.java +++ b/src/main/java/seedu/resireg/commons/core/index/Index.java @@ -1,4 +1,4 @@ -package seedu.address.commons.core.index; +package seedu.resireg.commons.core.index; /** * Represents a zero-based or one-based index. diff --git a/src/main/java/seedu/address/commons/exceptions/DataConversionException.java b/src/main/java/seedu/resireg/commons/exceptions/DataConversionException.java similarity index 84% rename from src/main/java/seedu/address/commons/exceptions/DataConversionException.java rename to src/main/java/seedu/resireg/commons/exceptions/DataConversionException.java index 1f689bd8e3f..94a8bfdb895 100644 --- a/src/main/java/seedu/address/commons/exceptions/DataConversionException.java +++ b/src/main/java/seedu/resireg/commons/exceptions/DataConversionException.java @@ -1,4 +1,4 @@ -package seedu.address.commons.exceptions; +package seedu.resireg.commons.exceptions; /** * Represents an error during conversion of data from one format to another diff --git a/src/main/java/seedu/address/commons/exceptions/IllegalValueException.java b/src/main/java/seedu/resireg/commons/exceptions/IllegalValueException.java similarity index 93% rename from src/main/java/seedu/address/commons/exceptions/IllegalValueException.java rename to src/main/java/seedu/resireg/commons/exceptions/IllegalValueException.java index 19124db485c..7781069f9d5 100644 --- a/src/main/java/seedu/address/commons/exceptions/IllegalValueException.java +++ b/src/main/java/seedu/resireg/commons/exceptions/IllegalValueException.java @@ -1,4 +1,4 @@ -package seedu.address.commons.exceptions; +package seedu.resireg.commons.exceptions; /** * Signals that some given data does not fulfill some constraints. diff --git a/src/main/java/seedu/address/commons/util/AppUtil.java b/src/main/java/seedu/resireg/commons/util/AppUtil.java similarity index 94% rename from src/main/java/seedu/address/commons/util/AppUtil.java rename to src/main/java/seedu/resireg/commons/util/AppUtil.java index 87aa89c0326..6cb49d30fcf 100644 --- a/src/main/java/seedu/address/commons/util/AppUtil.java +++ b/src/main/java/seedu/resireg/commons/util/AppUtil.java @@ -1,9 +1,9 @@ -package seedu.address.commons.util; +package seedu.resireg.commons.util; import static java.util.Objects.requireNonNull; import javafx.scene.image.Image; -import seedu.address.MainApp; +import seedu.resireg.MainApp; /** * A container for App specific utility functions diff --git a/src/main/java/seedu/address/commons/util/CollectionUtil.java b/src/main/java/seedu/resireg/commons/util/CollectionUtil.java similarity index 96% rename from src/main/java/seedu/address/commons/util/CollectionUtil.java rename to src/main/java/seedu/resireg/commons/util/CollectionUtil.java index eafe4dfd681..e3b29a4c544 100644 --- a/src/main/java/seedu/address/commons/util/CollectionUtil.java +++ b/src/main/java/seedu/resireg/commons/util/CollectionUtil.java @@ -1,4 +1,4 @@ -package seedu.address.commons.util; +package seedu.resireg.commons.util; import static java.util.Objects.requireNonNull; diff --git a/src/main/java/seedu/address/commons/util/ConfigUtil.java b/src/main/java/seedu/resireg/commons/util/ConfigUtil.java similarity index 77% rename from src/main/java/seedu/address/commons/util/ConfigUtil.java rename to src/main/java/seedu/resireg/commons/util/ConfigUtil.java index f7f8a2bd44c..c7125d73462 100644 --- a/src/main/java/seedu/address/commons/util/ConfigUtil.java +++ b/src/main/java/seedu/resireg/commons/util/ConfigUtil.java @@ -1,11 +1,11 @@ -package seedu.address.commons.util; +package seedu.resireg.commons.util; import java.io.IOException; import java.nio.file.Path; import java.util.Optional; -import seedu.address.commons.core.Config; -import seedu.address.commons.exceptions.DataConversionException; +import seedu.resireg.commons.core.Config; +import seedu.resireg.commons.exceptions.DataConversionException; /** * A class for accessing the Config File. diff --git a/src/main/java/seedu/address/commons/util/FileUtil.java b/src/main/java/seedu/resireg/commons/util/FileUtil.java similarity index 98% rename from src/main/java/seedu/address/commons/util/FileUtil.java rename to src/main/java/seedu/resireg/commons/util/FileUtil.java index b1e2767cdd9..56da0981b03 100644 --- a/src/main/java/seedu/address/commons/util/FileUtil.java +++ b/src/main/java/seedu/resireg/commons/util/FileUtil.java @@ -1,4 +1,4 @@ -package seedu.address.commons.util; +package seedu.resireg.commons.util; import java.io.IOException; import java.nio.file.Files; diff --git a/src/main/java/seedu/address/commons/util/JsonUtil.java b/src/main/java/seedu/resireg/commons/util/JsonUtil.java similarity index 97% rename from src/main/java/seedu/address/commons/util/JsonUtil.java rename to src/main/java/seedu/resireg/commons/util/JsonUtil.java index 8ef609f055d..2783a856920 100644 --- a/src/main/java/seedu/address/commons/util/JsonUtil.java +++ b/src/main/java/seedu/resireg/commons/util/JsonUtil.java @@ -1,4 +1,4 @@ -package seedu.address.commons.util; +package seedu.resireg.commons.util; import static java.util.Objects.requireNonNull; @@ -20,8 +20,8 @@ import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; -import seedu.address.commons.core.LogsCenter; -import seedu.address.commons.exceptions.DataConversionException; +import seedu.resireg.commons.core.LogsCenter; +import seedu.resireg.commons.exceptions.DataConversionException; /** * Converts a Java object instance to JSON and vice versa diff --git a/src/main/java/seedu/address/commons/util/StringUtil.java b/src/main/java/seedu/resireg/commons/util/StringUtil.java similarity index 95% rename from src/main/java/seedu/address/commons/util/StringUtil.java rename to src/main/java/seedu/resireg/commons/util/StringUtil.java index 61cc8c9a1cb..a6e633f7547 100644 --- a/src/main/java/seedu/address/commons/util/StringUtil.java +++ b/src/main/java/seedu/resireg/commons/util/StringUtil.java @@ -1,7 +1,7 @@ -package seedu.address.commons.util; +package seedu.resireg.commons.util; import static java.util.Objects.requireNonNull; -import static seedu.address.commons.util.AppUtil.checkArgument; +import static seedu.resireg.commons.util.AppUtil.checkArgument; import java.io.PrintWriter; import java.io.StringWriter; diff --git a/src/main/java/seedu/address/logic/Logic.java b/src/main/java/seedu/resireg/logic/Logic.java similarity index 64% rename from src/main/java/seedu/address/logic/Logic.java rename to src/main/java/seedu/resireg/logic/Logic.java index 92cd8fa605a..0cc80e5489e 100644 --- a/src/main/java/seedu/address/logic/Logic.java +++ b/src/main/java/seedu/resireg/logic/Logic.java @@ -1,14 +1,14 @@ -package seedu.address.logic; +package seedu.resireg.logic; import java.nio.file.Path; import javafx.collections.ObservableList; -import seedu.address.commons.core.GuiSettings; -import seedu.address.logic.commands.CommandResult; -import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.person.Person; +import seedu.resireg.commons.core.GuiSettings; +import seedu.resireg.logic.commands.CommandResult; +import seedu.resireg.logic.commands.exceptions.CommandException; +import seedu.resireg.logic.parser.exceptions.ParseException; +import seedu.resireg.model.ReadOnlyAddressBook; +import seedu.resireg.model.student.Student; /** * API of the Logic component @@ -26,12 +26,12 @@ public interface Logic { /** * Returns the AddressBook. * - * @see seedu.address.model.Model#getAddressBook() + * @see seedu.resireg.model.Model#getAddressBook() */ ReadOnlyAddressBook getAddressBook(); - /** Returns an unmodifiable view of the filtered list of persons */ - ObservableList getFilteredPersonList(); + /** Returns an unmodifiable view of the filtered list of students */ + ObservableList getFilteredStudentList(); /** * Returns the user prefs' address book file path. diff --git a/src/main/java/seedu/address/logic/LogicManager.java b/src/main/java/seedu/resireg/logic/LogicManager.java similarity index 73% rename from src/main/java/seedu/address/logic/LogicManager.java rename to src/main/java/seedu/resireg/logic/LogicManager.java index 9d9c6d15bdc..fddf134c05a 100644 --- a/src/main/java/seedu/address/logic/LogicManager.java +++ b/src/main/java/seedu/resireg/logic/LogicManager.java @@ -1,21 +1,21 @@ -package seedu.address.logic; +package seedu.resireg.logic; import java.io.IOException; import java.nio.file.Path; import java.util.logging.Logger; import javafx.collections.ObservableList; -import seedu.address.commons.core.GuiSettings; -import seedu.address.commons.core.LogsCenter; -import seedu.address.logic.commands.Command; -import seedu.address.logic.commands.CommandResult; -import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.logic.parser.AddressBookParser; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.Model; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.person.Person; -import seedu.address.storage.Storage; +import seedu.resireg.commons.core.GuiSettings; +import seedu.resireg.commons.core.LogsCenter; +import seedu.resireg.logic.commands.Command; +import seedu.resireg.logic.commands.CommandResult; +import seedu.resireg.logic.commands.exceptions.CommandException; +import seedu.resireg.logic.parser.AddressBookParser; +import seedu.resireg.logic.parser.exceptions.ParseException; +import seedu.resireg.model.Model; +import seedu.resireg.model.ReadOnlyAddressBook; +import seedu.resireg.model.student.Student; +import seedu.resireg.storage.Storage; /** * The main LogicManager of the app. @@ -60,8 +60,8 @@ public ReadOnlyAddressBook getAddressBook() { } @Override - public ObservableList getFilteredPersonList() { - return model.getFilteredPersonList(); + public ObservableList getFilteredStudentList() { + return model.getFilteredStudentList(); } @Override diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/resireg/logic/commands/AddCommand.java similarity index 51% rename from src/main/java/seedu/address/logic/commands/AddCommand.java rename to src/main/java/seedu/resireg/logic/commands/AddCommand.java index 71656d7c5c8..42822acfb05 100644 --- a/src/main/java/seedu/address/logic/commands/AddCommand.java +++ b/src/main/java/seedu/resireg/logic/commands/AddCommand.java @@ -1,60 +1,63 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; import static java.util.Objects.requireNonNull; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; -import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; -import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; -import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; -import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_EMAIL; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_FACULTY; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_STUDENT_ID; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_TAG; -import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.model.Model; -import seedu.address.model.person.Person; +import seedu.resireg.logic.commands.exceptions.CommandException; +import seedu.resireg.model.Model; +import seedu.resireg.model.student.Student; /** - * Adds a person to the address book. + * Adds a student to the address book. */ public class AddCommand extends Command { public static final String COMMAND_WORD = "add"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a person to the address book. " + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a student to ResiReg. " + "Parameters: " + PREFIX_NAME + "NAME " + + PREFIX_STUDENT_ID + "STUDENT ID " + PREFIX_PHONE + "PHONE " + PREFIX_EMAIL + "EMAIL " - + PREFIX_ADDRESS + "ADDRESS " + + PREFIX_FACULTY + "FACULTY " + "[" + PREFIX_TAG + "TAG]...\n" + "Example: " + COMMAND_WORD + " " + PREFIX_NAME + "John Doe " + + PREFIX_STUDENT_ID + "E01234567 " + PREFIX_PHONE + "98765432 " + PREFIX_EMAIL + "johnd@example.com " - + PREFIX_ADDRESS + "311, Clementi Ave 2, #02-25 " + + PREFIX_FACULTY + "FASS " + PREFIX_TAG + "friends " + PREFIX_TAG + "owesMoney"; - public static final String MESSAGE_SUCCESS = "New person added: %1$s"; - public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book"; + public static final String MESSAGE_SUCCESS = "New student added: %1$s"; + public static final String MESSAGE_DUPLICATE_PERSON = "This student already exists in the address book"; - private final Person toAdd; + private final Student toAdd; /** - * Creates an AddCommand to add the specified {@code Person} + * Creates an AddCommand to add the specified {@code Student} */ - public AddCommand(Person person) { - requireNonNull(person); - toAdd = person; + public AddCommand(Student student) { + requireNonNull(student); + toAdd = student; } @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); - if (model.hasPerson(toAdd)) { + if (model.hasStudent(toAdd)) { throw new CommandException(MESSAGE_DUPLICATE_PERSON); } - model.addPerson(toAdd); + model.addStudent(toAdd); return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd)); } diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/resireg/logic/commands/ClearCommand.java similarity index 80% rename from src/main/java/seedu/address/logic/commands/ClearCommand.java rename to src/main/java/seedu/resireg/logic/commands/ClearCommand.java index 9c86b1fa6e4..c64d677a9a9 100644 --- a/src/main/java/seedu/address/logic/commands/ClearCommand.java +++ b/src/main/java/seedu/resireg/logic/commands/ClearCommand.java @@ -1,9 +1,9 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; import static java.util.Objects.requireNonNull; -import seedu.address.model.AddressBook; -import seedu.address.model.Model; +import seedu.resireg.model.AddressBook; +import seedu.resireg.model.Model; /** * Clears the address book. diff --git a/src/main/java/seedu/address/logic/commands/Command.java b/src/main/java/seedu/resireg/logic/commands/Command.java similarity index 78% rename from src/main/java/seedu/address/logic/commands/Command.java rename to src/main/java/seedu/resireg/logic/commands/Command.java index 64f18992160..5de4d02896b 100644 --- a/src/main/java/seedu/address/logic/commands/Command.java +++ b/src/main/java/seedu/resireg/logic/commands/Command.java @@ -1,7 +1,7 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; -import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.model.Model; +import seedu.resireg.logic.commands.exceptions.CommandException; +import seedu.resireg.model.Model; /** * Represents a command with hidden internal logic and the ability to be executed. diff --git a/src/main/java/seedu/address/logic/commands/CommandResult.java b/src/main/java/seedu/resireg/logic/commands/CommandResult.java similarity index 97% rename from src/main/java/seedu/address/logic/commands/CommandResult.java rename to src/main/java/seedu/resireg/logic/commands/CommandResult.java index 92f900b7916..5262704f493 100644 --- a/src/main/java/seedu/address/logic/commands/CommandResult.java +++ b/src/main/java/seedu/resireg/logic/commands/CommandResult.java @@ -1,4 +1,4 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; import static java.util.Objects.requireNonNull; diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/resireg/logic/commands/DeleteCommand.java similarity index 62% rename from src/main/java/seedu/address/logic/commands/DeleteCommand.java rename to src/main/java/seedu/resireg/logic/commands/DeleteCommand.java index 02fd256acba..8ad6d2a5576 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ b/src/main/java/seedu/resireg/logic/commands/DeleteCommand.java @@ -1,28 +1,28 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; import static java.util.Objects.requireNonNull; import java.util.List; -import seedu.address.commons.core.Messages; -import seedu.address.commons.core.index.Index; -import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.model.Model; -import seedu.address.model.person.Person; +import seedu.resireg.commons.core.Messages; +import seedu.resireg.commons.core.index.Index; +import seedu.resireg.logic.commands.exceptions.CommandException; +import seedu.resireg.model.Model; +import seedu.resireg.model.student.Student; /** - * Deletes a person identified using it's displayed index from the address book. + * Deletes a student identified using it's displayed index from the address book. */ public class DeleteCommand extends Command { public static final String COMMAND_WORD = "delete"; public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Deletes the person identified by the index number used in the displayed person list.\n" + + ": Deletes the student identified by the index number used in the displayed student list.\n" + "Parameters: INDEX (must be a positive integer)\n" + "Example: " + COMMAND_WORD + " 1"; - public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s"; + public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Student: %1$s"; private final Index targetIndex; @@ -33,15 +33,15 @@ public DeleteCommand(Index targetIndex) { @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); - List lastShownList = model.getFilteredPersonList(); + List lastShownList = model.getFilteredStudentList(); if (targetIndex.getZeroBased() >= lastShownList.size()) { throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); } - Person personToDelete = lastShownList.get(targetIndex.getZeroBased()); - model.deletePerson(personToDelete); - return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, personToDelete)); + Student studentToDelete = lastShownList.get(targetIndex.getZeroBased()); + model.deleteStudent(studentToDelete); + return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, studentToDelete)); } @Override diff --git a/src/main/java/seedu/resireg/logic/commands/EditCommand.java b/src/main/java/seedu/resireg/logic/commands/EditCommand.java new file mode 100644 index 00000000000..5781236095e --- /dev/null +++ b/src/main/java/seedu/resireg/logic/commands/EditCommand.java @@ -0,0 +1,241 @@ +package seedu.resireg.logic.commands; + +import static java.util.Objects.requireNonNull; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_EMAIL; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_FACULTY; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_STUDENT_ID; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.resireg.model.Model.PREDICATE_SHOW_ALL_PERSONS; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import seedu.resireg.commons.core.Messages; +import seedu.resireg.commons.core.index.Index; +import seedu.resireg.commons.util.CollectionUtil; +import seedu.resireg.logic.commands.exceptions.CommandException; +import seedu.resireg.model.Model; +import seedu.resireg.model.student.Email; +import seedu.resireg.model.student.Name; +import seedu.resireg.model.student.Phone; +import seedu.resireg.model.student.Student; +import seedu.resireg.model.student.StudentId; +import seedu.resireg.model.student.faculty.Faculty; +import seedu.resireg.model.tag.Tag; + +/** + * Edits the details of an existing student in the address book. + */ +public class EditCommand extends Command { + + public static final String COMMAND_WORD = "edit"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the details of the student identified " + + "by the index number used in the displayed student list. " + + "Existing values will be overwritten by the input values.\n" + + "Parameters: INDEX (must be a positive integer) " + + "[" + PREFIX_NAME + "NAME] " + + "[" + PREFIX_STUDENT_ID + "STUDENT ID] " + + "[" + PREFIX_PHONE + "PHONE] " + + "[" + PREFIX_EMAIL + "EMAIL] " + + "[" + PREFIX_FACULTY + "FACULTY] " + + "[" + PREFIX_TAG + "TAG]...\n" + + "Example: " + COMMAND_WORD + " 1 " + + PREFIX_PHONE + "91234567 " + + PREFIX_EMAIL + "johndoe@example.com"; + + public static final String MESSAGE_EDIT_PERSON_SUCCESS = "Edited Student: %1$s"; + public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided."; + public static final String MESSAGE_DUPLICATE_PERSON = "This student already exists in the address book."; + + private final Index index; + private final EditStudentDescriptor editStudentDescriptor; + + /** + * @param index of the student in the filtered student list to edit + * @param editStudentDescriptor details to edit the student with + */ + public EditCommand(Index index, EditStudentDescriptor editStudentDescriptor) { + requireNonNull(index); + requireNonNull(editStudentDescriptor); + + this.index = index; + this.editStudentDescriptor = new EditStudentDescriptor(editStudentDescriptor); + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + List lastShownList = model.getFilteredStudentList(); + + if (index.getZeroBased() >= lastShownList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + } + + Student studentToEdit = lastShownList.get(index.getZeroBased()); + Student editedStudent = createEditedStudent(studentToEdit, editStudentDescriptor); + + if (!studentToEdit.isSameStudent(editedStudent) && model.hasStudent(editedStudent)) { + throw new CommandException(MESSAGE_DUPLICATE_PERSON); + } + + model.setStudent(studentToEdit, editedStudent); + model.updateFilteredStudentList(PREDICATE_SHOW_ALL_PERSONS); + return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, editedStudent)); + } + + /** + * Creates and returns a {@code Student} with the details of {@code studentToEdit} + * edited with {@code editStudentDescriptor}. + */ + private static Student createEditedStudent(Student studentToEdit, EditStudentDescriptor editStudentDescriptor) { + assert studentToEdit != null; + + Name updatedName = editStudentDescriptor.getName().orElse(studentToEdit.getName()); + Phone updatedPhone = editStudentDescriptor.getPhone().orElse(studentToEdit.getPhone()); + Email updatedEmail = editStudentDescriptor.getEmail().orElse(studentToEdit.getEmail()); + Faculty updatedFaculty = editStudentDescriptor.getFaculty().orElse(studentToEdit.getFaculty()); + StudentId updatedStudentId = editStudentDescriptor.getStudentId().orElse(studentToEdit.getStudentId()); + Set updatedTags = editStudentDescriptor.getTags().orElse(studentToEdit.getTags()); + + return new Student(updatedName, updatedPhone, updatedEmail, updatedFaculty, updatedStudentId, updatedTags); + } + + @Override + public boolean equals(Object other) { + // short circuit if same object + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof EditCommand)) { + return false; + } + + // state check + EditCommand e = (EditCommand) other; + return index.equals(e.index) + && editStudentDescriptor.equals(e.editStudentDescriptor); + } + + /** + * Stores the details to edit the student with. Each non-empty field value will replace the + * corresponding field value of the student. + */ + public static class EditStudentDescriptor { + private Name name; + private Phone phone; + private Email email; + private Faculty faculty; + private StudentId studentId; + private Set tags; + + public EditStudentDescriptor() {} + + /** + * Copy constructor. + * A defensive copy of {@code tags} is used internally. + */ + public EditStudentDescriptor(EditStudentDescriptor toCopy) { + setName(toCopy.name); + setPhone(toCopy.phone); + setEmail(toCopy.email); + setFaculty(toCopy.faculty); + setStudentId(toCopy.studentId); + setTags(toCopy.tags); + } + + /** + * Returns true if at least one field is edited. + */ + public boolean isAnyFieldEdited() { + return CollectionUtil.isAnyNonNull(name, phone, email, faculty, studentId, tags); + } + + public void setName(Name name) { + this.name = name; + } + + public Optional getName() { + return Optional.ofNullable(name); + } + + public void setPhone(Phone phone) { + this.phone = phone; + } + + public Optional getPhone() { + return Optional.ofNullable(phone); + } + + public void setEmail(Email email) { + this.email = email; + } + + public Optional getEmail() { + return Optional.ofNullable(email); + } + + public void setFaculty(Faculty faculty) { + this.faculty = faculty; + } + + public Optional getFaculty() { + return Optional.ofNullable(faculty); + } + + public void setStudentId(StudentId studentId) { + this.studentId = studentId; + } + + public Optional getStudentId() { + return Optional.ofNullable(studentId); + } + + /** + * Sets {@code tags} to this object's {@code tags}. + * A defensive copy of {@code tags} is used internally. + */ + public void setTags(Set tags) { + this.tags = (tags != null) ? new HashSet<>(tags) : null; + } + + /** + * Returns an unmodifiable tag set, which throws {@code UnsupportedOperationException} + * if modification is attempted. + * Returns {@code Optional#empty()} if {@code tags} is null. + */ + public Optional> getTags() { + return (tags != null) ? Optional.of(Collections.unmodifiableSet(tags)) : Optional.empty(); + } + + @Override + public boolean equals(Object other) { + // short circuit if same object + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof EditStudentDescriptor)) { + return false; + } + + // state check + EditStudentDescriptor e = (EditStudentDescriptor) other; + + return getStudentId().equals(e.getStudentId()) + && getName().equals(e.getName()) + && getPhone().equals(e.getPhone()) + && getEmail().equals(e.getEmail()) + && getFaculty().equals(e.getFaculty()) + && getTags().equals(e.getTags()); + } + } +} diff --git a/src/main/java/seedu/address/logic/commands/ExitCommand.java b/src/main/java/seedu/resireg/logic/commands/ExitCommand.java similarity index 84% rename from src/main/java/seedu/address/logic/commands/ExitCommand.java rename to src/main/java/seedu/resireg/logic/commands/ExitCommand.java index 3dd85a8ba90..07cbf463985 100644 --- a/src/main/java/seedu/address/logic/commands/ExitCommand.java +++ b/src/main/java/seedu/resireg/logic/commands/ExitCommand.java @@ -1,6 +1,6 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; -import seedu.address.model.Model; +import seedu.resireg.model.Model; /** * Terminates the program. diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/seedu/resireg/logic/commands/FindCommand.java similarity index 72% rename from src/main/java/seedu/address/logic/commands/FindCommand.java rename to src/main/java/seedu/resireg/logic/commands/FindCommand.java index d6b19b0a0de..3aea9519228 100644 --- a/src/main/java/seedu/address/logic/commands/FindCommand.java +++ b/src/main/java/seedu/resireg/logic/commands/FindCommand.java @@ -1,20 +1,20 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; import static java.util.Objects.requireNonNull; -import seedu.address.commons.core.Messages; -import seedu.address.model.Model; -import seedu.address.model.person.NameContainsKeywordsPredicate; +import seedu.resireg.commons.core.Messages; +import seedu.resireg.model.Model; +import seedu.resireg.model.student.NameContainsKeywordsPredicate; /** - * Finds and lists all persons in address book whose name contains any of the argument keywords. + * Finds and lists all students in address book whose name contains any of the argument keywords. * Keyword matching is case insensitive. */ public class FindCommand extends Command { public static final String COMMAND_WORD = "find"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose names contain any of " + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all students whose names contain any of " + "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n" + "Parameters: KEYWORD [MORE_KEYWORDS]...\n" + "Example: " + COMMAND_WORD + " alice bob charlie"; @@ -28,9 +28,9 @@ public FindCommand(NameContainsKeywordsPredicate predicate) { @Override public CommandResult execute(Model model) { requireNonNull(model); - model.updateFilteredPersonList(predicate); + model.updateFilteredStudentList(predicate); return new CommandResult( - String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size())); + String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredStudentList().size())); } @Override diff --git a/src/main/java/seedu/address/logic/commands/HelpCommand.java b/src/main/java/seedu/resireg/logic/commands/HelpCommand.java similarity index 88% rename from src/main/java/seedu/address/logic/commands/HelpCommand.java rename to src/main/java/seedu/resireg/logic/commands/HelpCommand.java index bf824f91bd0..f80f0dce41b 100644 --- a/src/main/java/seedu/address/logic/commands/HelpCommand.java +++ b/src/main/java/seedu/resireg/logic/commands/HelpCommand.java @@ -1,6 +1,6 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; -import seedu.address.model.Model; +import seedu.resireg.model.Model; /** * Format full help instructions for every command for display. diff --git a/src/main/java/seedu/resireg/logic/commands/ListCommand.java b/src/main/java/seedu/resireg/logic/commands/ListCommand.java new file mode 100644 index 00000000000..ed82efda809 --- /dev/null +++ b/src/main/java/seedu/resireg/logic/commands/ListCommand.java @@ -0,0 +1,24 @@ +package seedu.resireg.logic.commands; + +import static java.util.Objects.requireNonNull; +import static seedu.resireg.model.Model.PREDICATE_SHOW_ALL_PERSONS; + +import seedu.resireg.model.Model; + +/** + * Lists all students in the address book to the user. + */ +public class ListCommand extends Command { + + public static final String COMMAND_WORD = "list"; + + public static final String MESSAGE_SUCCESS = "Listed all students"; + + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + model.updateFilteredStudentList(PREDICATE_SHOW_ALL_PERSONS); + return new CommandResult(MESSAGE_SUCCESS); + } +} diff --git a/src/main/java/seedu/address/logic/commands/exceptions/CommandException.java b/src/main/java/seedu/resireg/logic/commands/exceptions/CommandException.java similarity index 89% rename from src/main/java/seedu/address/logic/commands/exceptions/CommandException.java rename to src/main/java/seedu/resireg/logic/commands/exceptions/CommandException.java index a16bd14f2cd..faf12007b80 100644 --- a/src/main/java/seedu/address/logic/commands/exceptions/CommandException.java +++ b/src/main/java/seedu/resireg/logic/commands/exceptions/CommandException.java @@ -1,4 +1,4 @@ -package seedu.address.logic.commands.exceptions; +package seedu.resireg.logic.commands.exceptions; /** * Represents an error which occurs during execution of a {@link Command}. diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/resireg/logic/parser/AddCommandParser.java similarity index 53% rename from src/main/java/seedu/address/logic/parser/AddCommandParser.java rename to src/main/java/seedu/resireg/logic/parser/AddCommandParser.java index 3b8bfa035e8..254a8e8523f 100644 --- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java +++ b/src/main/java/seedu/resireg/logic/parser/AddCommandParser.java @@ -1,23 +1,25 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; -import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; -import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; -import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; -import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.resireg.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_EMAIL; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_FACULTY; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_STUDENT_ID; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_TAG; import java.util.Set; import java.util.stream.Stream; -import seedu.address.logic.commands.AddCommand; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Person; -import seedu.address.model.person.Phone; -import seedu.address.model.tag.Tag; +import seedu.resireg.logic.commands.AddCommand; +import seedu.resireg.logic.parser.exceptions.ParseException; +import seedu.resireg.model.student.Email; +import seedu.resireg.model.student.Name; +import seedu.resireg.model.student.Phone; +import seedu.resireg.model.student.Student; +import seedu.resireg.model.student.StudentId; +import seedu.resireg.model.student.faculty.Faculty; +import seedu.resireg.model.tag.Tag; /** * Parses input arguments and creates a new AddCommand object @@ -31,9 +33,10 @@ public class AddCommandParser implements Parser { */ public AddCommand parse(String args) throws ParseException { ArgumentMultimap argMultimap = - ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG); + ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_FACULTY, + PREFIX_STUDENT_ID, PREFIX_TAG); - if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ADDRESS, PREFIX_PHONE, PREFIX_EMAIL) + if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_FACULTY, PREFIX_STUDENT_ID, PREFIX_PHONE, PREFIX_EMAIL) || !argMultimap.getPreamble().isEmpty()) { throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE)); } @@ -41,12 +44,13 @@ public AddCommand parse(String args) throws ParseException { Name name = ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get()); Phone phone = ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get()); Email email = ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get()); - Address address = ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get()); + Faculty faculty = ParserUtil.parseFaculty(argMultimap.getValue(PREFIX_FACULTY).get()); + StudentId studentId = ParserUtil.parseStudentId(argMultimap.getValue(PREFIX_STUDENT_ID).get()); Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); - Person person = new Person(name, phone, email, address, tagList); + Student student = new Student(name, phone, email, faculty, studentId, tagList); - return new AddCommand(person); + return new AddCommand(student); } /** diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/resireg/logic/parser/AddressBookParser.java similarity index 74% rename from src/main/java/seedu/address/logic/parser/AddressBookParser.java rename to src/main/java/seedu/resireg/logic/parser/AddressBookParser.java index 1e466792b46..d76ec8443de 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/resireg/logic/parser/AddressBookParser.java @@ -1,21 +1,21 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND; +import static seedu.resireg.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.resireg.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND; import java.util.regex.Matcher; import java.util.regex.Pattern; -import seedu.address.logic.commands.AddCommand; -import seedu.address.logic.commands.ClearCommand; -import seedu.address.logic.commands.Command; -import seedu.address.logic.commands.DeleteCommand; -import seedu.address.logic.commands.EditCommand; -import seedu.address.logic.commands.ExitCommand; -import seedu.address.logic.commands.FindCommand; -import seedu.address.logic.commands.HelpCommand; -import seedu.address.logic.commands.ListCommand; -import seedu.address.logic.parser.exceptions.ParseException; +import seedu.resireg.logic.commands.AddCommand; +import seedu.resireg.logic.commands.ClearCommand; +import seedu.resireg.logic.commands.Command; +import seedu.resireg.logic.commands.DeleteCommand; +import seedu.resireg.logic.commands.EditCommand; +import seedu.resireg.logic.commands.ExitCommand; +import seedu.resireg.logic.commands.FindCommand; +import seedu.resireg.logic.commands.HelpCommand; +import seedu.resireg.logic.commands.ListCommand; +import seedu.resireg.logic.parser.exceptions.ParseException; /** * Parses user input. diff --git a/src/main/java/seedu/address/logic/parser/ArgumentMultimap.java b/src/main/java/seedu/resireg/logic/parser/ArgumentMultimap.java similarity index 98% rename from src/main/java/seedu/address/logic/parser/ArgumentMultimap.java rename to src/main/java/seedu/resireg/logic/parser/ArgumentMultimap.java index 954c8e18f8e..9d7e8bc7b7e 100644 --- a/src/main/java/seedu/address/logic/parser/ArgumentMultimap.java +++ b/src/main/java/seedu/resireg/logic/parser/ArgumentMultimap.java @@ -1,4 +1,4 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/main/java/seedu/address/logic/parser/ArgumentTokenizer.java b/src/main/java/seedu/resireg/logic/parser/ArgumentTokenizer.java similarity index 99% rename from src/main/java/seedu/address/logic/parser/ArgumentTokenizer.java rename to src/main/java/seedu/resireg/logic/parser/ArgumentTokenizer.java index 5c9aebfa488..26d6e465e28 100644 --- a/src/main/java/seedu/address/logic/parser/ArgumentTokenizer.java +++ b/src/main/java/seedu/resireg/logic/parser/ArgumentTokenizer.java @@ -1,4 +1,4 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/main/java/seedu/address/logic/parser/CliSyntax.java b/src/main/java/seedu/resireg/logic/parser/CliSyntax.java similarity index 70% rename from src/main/java/seedu/address/logic/parser/CliSyntax.java rename to src/main/java/seedu/resireg/logic/parser/CliSyntax.java index 75b1a9bf119..60b31209eb6 100644 --- a/src/main/java/seedu/address/logic/parser/CliSyntax.java +++ b/src/main/java/seedu/resireg/logic/parser/CliSyntax.java @@ -1,4 +1,4 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; /** * Contains Command Line Interface (CLI) syntax definitions common to multiple commands @@ -9,7 +9,8 @@ public class CliSyntax { public static final Prefix PREFIX_NAME = new Prefix("n/"); public static final Prefix PREFIX_PHONE = new Prefix("p/"); public static final Prefix PREFIX_EMAIL = new Prefix("e/"); - public static final Prefix PREFIX_ADDRESS = new Prefix("a/"); + public static final Prefix PREFIX_FACULTY = new Prefix("f/"); + public static final Prefix PREFIX_STUDENT_ID = new Prefix("i/"); public static final Prefix PREFIX_TAG = new Prefix("t/"); } diff --git a/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java b/src/main/java/seedu/resireg/logic/parser/DeleteCommandParser.java similarity index 75% rename from src/main/java/seedu/address/logic/parser/DeleteCommandParser.java rename to src/main/java/seedu/resireg/logic/parser/DeleteCommandParser.java index 522b93081cc..95b26a4c8ff 100644 --- a/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java +++ b/src/main/java/seedu/resireg/logic/parser/DeleteCommandParser.java @@ -1,10 +1,10 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.resireg.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import seedu.address.commons.core.index.Index; -import seedu.address.logic.commands.DeleteCommand; -import seedu.address.logic.parser.exceptions.ParseException; +import seedu.resireg.commons.core.index.Index; +import seedu.resireg.logic.commands.DeleteCommand; +import seedu.resireg.logic.parser.exceptions.ParseException; /** * Parses input arguments and creates a new DeleteCommand object diff --git a/src/main/java/seedu/address/logic/parser/EditCommandParser.java b/src/main/java/seedu/resireg/logic/parser/EditCommandParser.java similarity index 53% rename from src/main/java/seedu/address/logic/parser/EditCommandParser.java rename to src/main/java/seedu/resireg/logic/parser/EditCommandParser.java index 845644b7dea..40b157d72ad 100644 --- a/src/main/java/seedu/address/logic/parser/EditCommandParser.java +++ b/src/main/java/seedu/resireg/logic/parser/EditCommandParser.java @@ -1,23 +1,24 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; import static java.util.Objects.requireNonNull; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; -import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; -import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; -import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; -import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.resireg.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_EMAIL; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_FACULTY; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_STUDENT_ID; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_TAG; import java.util.Collection; import java.util.Collections; import java.util.Optional; import java.util.Set; -import seedu.address.commons.core.index.Index; -import seedu.address.logic.commands.EditCommand; -import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.tag.Tag; +import seedu.resireg.commons.core.index.Index; +import seedu.resireg.logic.commands.EditCommand; +import seedu.resireg.logic.commands.EditCommand.EditStudentDescriptor; +import seedu.resireg.logic.parser.exceptions.ParseException; +import seedu.resireg.model.tag.Tag; /** * Parses input arguments and creates a new EditCommand object @@ -32,7 +33,8 @@ public class EditCommandParser implements Parser { public EditCommand parse(String args) throws ParseException { requireNonNull(args); ArgumentMultimap argMultimap = - ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG); + ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_FACULTY, + PREFIX_STUDENT_ID, PREFIX_TAG); Index index; @@ -42,26 +44,30 @@ public EditCommand parse(String args) throws ParseException { throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE), pe); } - EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor(); + EditStudentDescriptor editStudentDescriptor = new EditStudentDescriptor(); if (argMultimap.getValue(PREFIX_NAME).isPresent()) { - editPersonDescriptor.setName(ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get())); + editStudentDescriptor.setName(ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get())); } if (argMultimap.getValue(PREFIX_PHONE).isPresent()) { - editPersonDescriptor.setPhone(ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get())); + editStudentDescriptor.setPhone(ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get())); } if (argMultimap.getValue(PREFIX_EMAIL).isPresent()) { - editPersonDescriptor.setEmail(ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get())); + editStudentDescriptor.setEmail(ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get())); } - if (argMultimap.getValue(PREFIX_ADDRESS).isPresent()) { - editPersonDescriptor.setAddress(ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get())); + if (argMultimap.getValue(PREFIX_FACULTY).isPresent()) { + editStudentDescriptor.setFaculty(ParserUtil.parseFaculty(argMultimap.getValue(PREFIX_FACULTY).get())); } - parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editPersonDescriptor::setTags); + if (argMultimap.getValue(PREFIX_STUDENT_ID).isPresent()) { + editStudentDescriptor.setStudentId(ParserUtil.parseStudentId(argMultimap + .getValue(PREFIX_STUDENT_ID).get())); + } + parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editStudentDescriptor::setTags); - if (!editPersonDescriptor.isAnyFieldEdited()) { + if (!editStudentDescriptor.isAnyFieldEdited()) { throw new ParseException(EditCommand.MESSAGE_NOT_EDITED); } - return new EditCommand(index, editPersonDescriptor); + return new EditCommand(index, editStudentDescriptor); } /** diff --git a/src/main/java/seedu/address/logic/parser/FindCommandParser.java b/src/main/java/seedu/resireg/logic/parser/FindCommandParser.java similarity index 76% rename from src/main/java/seedu/address/logic/parser/FindCommandParser.java rename to src/main/java/seedu/resireg/logic/parser/FindCommandParser.java index 4fb71f23103..9d470d750aa 100644 --- a/src/main/java/seedu/address/logic/parser/FindCommandParser.java +++ b/src/main/java/seedu/resireg/logic/parser/FindCommandParser.java @@ -1,12 +1,12 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.resireg.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; import java.util.Arrays; -import seedu.address.logic.commands.FindCommand; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.NameContainsKeywordsPredicate; +import seedu.resireg.logic.commands.FindCommand; +import seedu.resireg.logic.parser.exceptions.ParseException; +import seedu.resireg.model.student.NameContainsKeywordsPredicate; /** * Parses input arguments and creates a new FindCommand object diff --git a/src/main/java/seedu/address/logic/parser/Parser.java b/src/main/java/seedu/resireg/logic/parser/Parser.java similarity index 72% rename from src/main/java/seedu/address/logic/parser/Parser.java rename to src/main/java/seedu/resireg/logic/parser/Parser.java index d6551ad8e3f..697ce8a0cbd 100644 --- a/src/main/java/seedu/address/logic/parser/Parser.java +++ b/src/main/java/seedu/resireg/logic/parser/Parser.java @@ -1,7 +1,7 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; -import seedu.address.logic.commands.Command; -import seedu.address.logic.parser.exceptions.ParseException; +import seedu.resireg.logic.commands.Command; +import seedu.resireg.logic.parser.exceptions.ParseException; /** * Represents a Parser that is able to parse user input into a {@code Command} of type {@code T}. diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/resireg/logic/parser/ParserUtil.java similarity index 70% rename from src/main/java/seedu/address/logic/parser/ParserUtil.java rename to src/main/java/seedu/resireg/logic/parser/ParserUtil.java index b117acb9c55..4febcca56e4 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/resireg/logic/parser/ParserUtil.java @@ -1,4 +1,4 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; import static java.util.Objects.requireNonNull; @@ -6,14 +6,15 @@ import java.util.HashSet; import java.util.Set; -import seedu.address.commons.core.index.Index; -import seedu.address.commons.util.StringUtil; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Phone; -import seedu.address.model.tag.Tag; +import seedu.resireg.commons.core.index.Index; +import seedu.resireg.commons.util.StringUtil; +import seedu.resireg.logic.parser.exceptions.ParseException; +import seedu.resireg.model.student.Email; +import seedu.resireg.model.student.Name; +import seedu.resireg.model.student.Phone; +import seedu.resireg.model.student.StudentId; +import seedu.resireg.model.student.faculty.Faculty; +import seedu.resireg.model.tag.Tag; /** * Contains utility methods used for parsing strings in the various *Parser classes. @@ -66,18 +67,33 @@ public static Phone parsePhone(String phone) throws ParseException { } /** - * Parses a {@code String address} into an {@code Address}. + * Parses a {@code String faculty} into a {@code Faculty}. * Leading and trailing whitespaces will be trimmed. * - * @throws ParseException if the given {@code address} is invalid. + * @throws ParseException if the given {@code faculty} is invalid. */ - public static Address parseAddress(String address) throws ParseException { - requireNonNull(address); - String trimmedAddress = address.trim(); - if (!Address.isValidAddress(trimmedAddress)) { - throw new ParseException(Address.MESSAGE_CONSTRAINTS); + public static Faculty parseFaculty(String faculty) throws ParseException { + requireNonNull(faculty); + String trimmedFaculty = faculty.trim(); + if (!Faculty.isValidFaculty(trimmedFaculty)) { + throw new ParseException(Faculty.MESSAGE_CONSTRAINTS); } - return new Address(trimmedAddress); + return new Faculty(trimmedFaculty); + } + + /** + * Parses a {@code String studentId} into a {@code StudentId}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws ParseException if the given {@code studentId} is invalid. + */ + public static StudentId parseStudentId(String studentId) throws ParseException { + requireNonNull(studentId); + String trimmedStudentId = studentId.trim(); + if (!StudentId.isValidStudentId(trimmedStudentId)) { + throw new ParseException(StudentId.MESSAGE_CONSTRAINTS); + } + return new StudentId(trimmedStudentId); } /** diff --git a/src/main/java/seedu/address/logic/parser/Prefix.java b/src/main/java/seedu/resireg/logic/parser/Prefix.java similarity index 95% rename from src/main/java/seedu/address/logic/parser/Prefix.java rename to src/main/java/seedu/resireg/logic/parser/Prefix.java index c859d5fa5db..6239f80becf 100644 --- a/src/main/java/seedu/address/logic/parser/Prefix.java +++ b/src/main/java/seedu/resireg/logic/parser/Prefix.java @@ -1,4 +1,4 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; /** * A prefix that marks the beginning of an argument in an arguments string. diff --git a/src/main/java/seedu/address/logic/parser/exceptions/ParseException.java b/src/main/java/seedu/resireg/logic/parser/exceptions/ParseException.java similarity index 73% rename from src/main/java/seedu/address/logic/parser/exceptions/ParseException.java rename to src/main/java/seedu/resireg/logic/parser/exceptions/ParseException.java index 158a1a54c1c..2c449582654 100644 --- a/src/main/java/seedu/address/logic/parser/exceptions/ParseException.java +++ b/src/main/java/seedu/resireg/logic/parser/exceptions/ParseException.java @@ -1,6 +1,6 @@ -package seedu.address.logic.parser.exceptions; +package seedu.resireg.logic.parser.exceptions; -import seedu.address.commons.exceptions.IllegalValueException; +import seedu.resireg.commons.exceptions.IllegalValueException; /** * Represents a parse error encountered by a parser. diff --git a/src/main/java/seedu/resireg/model/AddressBook.java b/src/main/java/seedu/resireg/model/AddressBook.java new file mode 100644 index 00000000000..e84dce062e4 --- /dev/null +++ b/src/main/java/seedu/resireg/model/AddressBook.java @@ -0,0 +1,121 @@ +package seedu.resireg.model; + +import static java.util.Objects.requireNonNull; + +import java.util.List; + +import javafx.collections.ObservableList; +import seedu.resireg.model.student.Student; +import seedu.resireg.model.student.UniqueStudentList; + +/** + * Wraps all data at the address-book level + * Duplicates are not allowed (by .isSameStudent comparison) + */ +public class AddressBook implements ReadOnlyAddressBook { + + private final UniqueStudentList students; + + /* + * The 'unusual' code block below is a non-static initialization block, sometimes used to avoid duplication + * between constructors. See https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html + * + * Note that non-static init blocks are not recommended to use. There are other ways to avoid duplication + * among constructors. + */ + { + students = new UniqueStudentList(); + } + + public AddressBook() {} + + /** + * Creates an AddressBook using the Students in the {@code toBeCopied} + */ + public AddressBook(ReadOnlyAddressBook toBeCopied) { + this(); + resetData(toBeCopied); + } + + //// list overwrite operations + + /** + * Replaces the contents of the student list with {@code students}. + * {@code students} must not contain duplicate students. + */ + public void setStudents(List students) { + this.students.setStudents(students); + } + + /** + * Resets the existing data of this {@code AddressBook} with {@code newData}. + */ + public void resetData(ReadOnlyAddressBook newData) { + requireNonNull(newData); + + setStudents(newData.getStudentList()); + } + + //// student-level operations + + /** + * Returns true if a student with the same identity as {@code student} exists in the address book. + */ + public boolean hasStudent(Student student) { + requireNonNull(student); + return students.contains(student); + } + + /** + * Adds a student to the address book. + * The student must not already exist in the address book. + */ + public void addStudent(Student p) { + students.add(p); + } + + /** + * Replaces the given student {@code target} in the list with {@code editedStudent}. + * {@code target} must exist in the address book. + * The student identity of {@code editedStudent} must not be the same as another existing student + * in the address book. + */ + public void setStudent(Student target, Student editedStudent) { + requireNonNull(editedStudent); + + students.setStudent(target, editedStudent); + } + + /** + * Removes {@code key} from this {@code AddressBook}. + * {@code key} must exist in the address book. + */ + public void removeStudent(Student key) { + students.remove(key); + } + + //// util methods + + @Override + public String toString() { + return students.asUnmodifiableObservableList().size() + " students"; + // TODO: refine later + } + + @Override + public ObservableList getStudentList() { + return students.asUnmodifiableObservableList(); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof AddressBook // instanceof handles nulls + && students.equals(((AddressBook) other).students)); + } + + @Override + public int hashCode() { + return students.hashCode(); + } +} diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/resireg/model/Model.java similarity index 53% rename from src/main/java/seedu/address/model/Model.java rename to src/main/java/seedu/resireg/model/Model.java index d54df471c1f..81ab690e36f 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/resireg/model/Model.java @@ -1,18 +1,18 @@ -package seedu.address.model; +package seedu.resireg.model; import java.nio.file.Path; import java.util.function.Predicate; import javafx.collections.ObservableList; -import seedu.address.commons.core.GuiSettings; -import seedu.address.model.person.Person; +import seedu.resireg.commons.core.GuiSettings; +import seedu.resireg.model.student.Student; /** * The API of the Model component. */ public interface Model { /** {@code Predicate} that always evaluate to true */ - Predicate PREDICATE_SHOW_ALL_PERSONS = unused -> true; + Predicate PREDICATE_SHOW_ALL_PERSONS = unused -> true; /** * Replaces user prefs data with the data in {@code userPrefs}. @@ -53,35 +53,36 @@ public interface Model { ReadOnlyAddressBook getAddressBook(); /** - * Returns true if a person with the same identity as {@code person} exists in the address book. + * Returns true if a student with the same identity as {@code student} exists in the address book. */ - boolean hasPerson(Person person); + boolean hasStudent(Student student); /** - * Deletes the given person. - * The person must exist in the address book. + * Deletes the given student. + * The student must exist in the address book. */ - void deletePerson(Person target); + void deleteStudent(Student target); /** - * Adds the given person. - * {@code person} must not already exist in the address book. + * Adds the given student. + * {@code student} must not already exist in the address book. */ - void addPerson(Person person); + void addStudent(Student student); /** - * Replaces the given person {@code target} with {@code editedPerson}. + * Replaces the given student {@code target} with {@code editedStudent}. * {@code target} must exist in the address book. - * The person identity of {@code editedPerson} must not be the same as another existing person in the address book. + * The student identity of {@code editedStudent} must not be the same as another existing student + * in the address book. */ - void setPerson(Person target, Person editedPerson); + void setStudent(Student target, Student editedStudent); - /** Returns an unmodifiable view of the filtered person list */ - ObservableList getFilteredPersonList(); + /** Returns an unmodifiable view of the filtered student list */ + ObservableList getFilteredStudentList(); /** - * Updates the filter of the filtered person list to filter by the given {@code predicate}. + * Updates the filter of the filtered student list to filter by the given {@code predicate}. * @throws NullPointerException if {@code predicate} is null. */ - void updateFilteredPersonList(Predicate predicate); + void updateFilteredStudentList(Predicate predicate); } diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/resireg/model/ModelManager.java similarity index 68% rename from src/main/java/seedu/address/model/ModelManager.java rename to src/main/java/seedu/resireg/model/ModelManager.java index 0650c954f5c..9d68c4c6f03 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/resireg/model/ModelManager.java @@ -1,7 +1,7 @@ -package seedu.address.model; +package seedu.resireg.model; import static java.util.Objects.requireNonNull; -import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; +import static seedu.resireg.commons.util.CollectionUtil.requireAllNonNull; import java.nio.file.Path; import java.util.function.Predicate; @@ -9,9 +9,9 @@ import javafx.collections.ObservableList; import javafx.collections.transformation.FilteredList; -import seedu.address.commons.core.GuiSettings; -import seedu.address.commons.core.LogsCenter; -import seedu.address.model.person.Person; +import seedu.resireg.commons.core.GuiSettings; +import seedu.resireg.commons.core.LogsCenter; +import seedu.resireg.model.student.Student; /** * Represents the in-memory model of the address book data. @@ -21,7 +21,7 @@ public class ModelManager implements Model { private final AddressBook addressBook; private final UserPrefs userPrefs; - private final FilteredList filteredPersons; + private final FilteredList filteredStudents; /** * Initializes a ModelManager with the given addressBook and userPrefs. @@ -34,7 +34,7 @@ public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyUserPrefs userPrefs this.addressBook = new AddressBook(addressBook); this.userPrefs = new UserPrefs(userPrefs); - filteredPersons = new FilteredList<>(this.addressBook.getPersonList()); + filteredStudents = new FilteredList<>(this.addressBook.getStudentList()); } public ModelManager() { @@ -89,44 +89,44 @@ public ReadOnlyAddressBook getAddressBook() { } @Override - public boolean hasPerson(Person person) { - requireNonNull(person); - return addressBook.hasPerson(person); + public boolean hasStudent(Student student) { + requireNonNull(student); + return addressBook.hasStudent(student); } @Override - public void deletePerson(Person target) { - addressBook.removePerson(target); + public void deleteStudent(Student target) { + addressBook.removeStudent(target); } @Override - public void addPerson(Person person) { - addressBook.addPerson(person); - updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); + public void addStudent(Student student) { + addressBook.addStudent(student); + updateFilteredStudentList(PREDICATE_SHOW_ALL_PERSONS); } @Override - public void setPerson(Person target, Person editedPerson) { - requireAllNonNull(target, editedPerson); + public void setStudent(Student target, Student editedStudent) { + requireAllNonNull(target, editedStudent); - addressBook.setPerson(target, editedPerson); + addressBook.setStudent(target, editedStudent); } - //=========== Filtered Person List Accessors ============================================================= + //=========== Filtered Student List Accessors ============================================================= /** - * Returns an unmodifiable view of the list of {@code Person} backed by the internal list of + * Returns an unmodifiable view of the list of {@code Student} backed by the internal list of * {@code versionedAddressBook} */ @Override - public ObservableList getFilteredPersonList() { - return filteredPersons; + public ObservableList getFilteredStudentList() { + return filteredStudents; } @Override - public void updateFilteredPersonList(Predicate predicate) { + public void updateFilteredStudentList(Predicate predicate) { requireNonNull(predicate); - filteredPersons.setPredicate(predicate); + filteredStudents.setPredicate(predicate); } @Override @@ -145,7 +145,7 @@ public boolean equals(Object obj) { ModelManager other = (ModelManager) obj; return addressBook.equals(other.addressBook) && userPrefs.equals(other.userPrefs) - && filteredPersons.equals(other.filteredPersons); + && filteredStudents.equals(other.filteredStudents); } } diff --git a/src/main/java/seedu/resireg/model/ReadOnlyAddressBook.java b/src/main/java/seedu/resireg/model/ReadOnlyAddressBook.java new file mode 100644 index 00000000000..9e7dda44935 --- /dev/null +++ b/src/main/java/seedu/resireg/model/ReadOnlyAddressBook.java @@ -0,0 +1,17 @@ +package seedu.resireg.model; + +import javafx.collections.ObservableList; +import seedu.resireg.model.student.Student; + +/** + * Unmodifiable view of an address book + */ +public interface ReadOnlyAddressBook { + + /** + * Returns an unmodifiable view of the students list. + * This list will not contain any duplicate students. + */ + ObservableList getStudentList(); + +} diff --git a/src/main/java/seedu/address/model/ReadOnlyUserPrefs.java b/src/main/java/seedu/resireg/model/ReadOnlyUserPrefs.java similarity index 70% rename from src/main/java/seedu/address/model/ReadOnlyUserPrefs.java rename to src/main/java/seedu/resireg/model/ReadOnlyUserPrefs.java index befd58a4c73..06fc3393988 100644 --- a/src/main/java/seedu/address/model/ReadOnlyUserPrefs.java +++ b/src/main/java/seedu/resireg/model/ReadOnlyUserPrefs.java @@ -1,8 +1,8 @@ -package seedu.address.model; +package seedu.resireg.model; import java.nio.file.Path; -import seedu.address.commons.core.GuiSettings; +import seedu.resireg.commons.core.GuiSettings; /** * Unmodifiable view of user prefs. diff --git a/src/main/java/seedu/address/model/UserPrefs.java b/src/main/java/seedu/resireg/model/UserPrefs.java similarity index 96% rename from src/main/java/seedu/address/model/UserPrefs.java rename to src/main/java/seedu/resireg/model/UserPrefs.java index 25a5fd6eab9..2fa550c66db 100644 --- a/src/main/java/seedu/address/model/UserPrefs.java +++ b/src/main/java/seedu/resireg/model/UserPrefs.java @@ -1,4 +1,4 @@ -package seedu.address.model; +package seedu.resireg.model; import static java.util.Objects.requireNonNull; @@ -6,7 +6,7 @@ import java.nio.file.Paths; import java.util.Objects; -import seedu.address.commons.core.GuiSettings; +import seedu.resireg.commons.core.GuiSettings; /** * Represents User's preferences. diff --git a/src/main/java/seedu/address/model/person/Email.java b/src/main/java/seedu/resireg/model/student/Email.java similarity index 94% rename from src/main/java/seedu/address/model/person/Email.java rename to src/main/java/seedu/resireg/model/student/Email.java index a5bbe0b6a5f..55af7714a4c 100644 --- a/src/main/java/seedu/address/model/person/Email.java +++ b/src/main/java/seedu/resireg/model/student/Email.java @@ -1,10 +1,10 @@ -package seedu.address.model.person; +package seedu.resireg.model.student; import static java.util.Objects.requireNonNull; -import static seedu.address.commons.util.AppUtil.checkArgument; +import static seedu.resireg.commons.util.AppUtil.checkArgument; /** - * Represents a Person's email in the address book. + * Represents a Student's email in the address book. * Guarantees: immutable; is valid as declared in {@link #isValidEmail(String)} */ public class Email { diff --git a/src/main/java/seedu/address/model/person/Name.java b/src/main/java/seedu/resireg/model/student/Name.java similarity index 90% rename from src/main/java/seedu/address/model/person/Name.java rename to src/main/java/seedu/resireg/model/student/Name.java index 79244d71cf7..8d791bfce80 100644 --- a/src/main/java/seedu/address/model/person/Name.java +++ b/src/main/java/seedu/resireg/model/student/Name.java @@ -1,10 +1,10 @@ -package seedu.address.model.person; +package seedu.resireg.model.student; import static java.util.Objects.requireNonNull; -import static seedu.address.commons.util.AppUtil.checkArgument; +import static seedu.resireg.commons.util.AppUtil.checkArgument; /** - * Represents a Person's name in the address book. + * Represents a Student's name in the address book. * Guarantees: immutable; is valid as declared in {@link #isValidName(String)} */ public class Name { diff --git a/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java b/src/main/java/seedu/resireg/model/student/NameContainsKeywordsPredicate.java similarity index 73% rename from src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java rename to src/main/java/seedu/resireg/model/student/NameContainsKeywordsPredicate.java index c9b5868427c..8045be9d079 100644 --- a/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java +++ b/src/main/java/seedu/resireg/model/student/NameContainsKeywordsPredicate.java @@ -1,14 +1,14 @@ -package seedu.address.model.person; +package seedu.resireg.model.student; import java.util.List; import java.util.function.Predicate; -import seedu.address.commons.util.StringUtil; +import seedu.resireg.commons.util.StringUtil; /** - * Tests that a {@code Person}'s {@code Name} matches any of the keywords given. + * Tests that a {@code Student}'s {@code Name} matches any of the keywords given. */ -public class NameContainsKeywordsPredicate implements Predicate { +public class NameContainsKeywordsPredicate implements Predicate { private final List keywords; public NameContainsKeywordsPredicate(List keywords) { @@ -16,9 +16,9 @@ public NameContainsKeywordsPredicate(List keywords) { } @Override - public boolean test(Person person) { + public boolean test(Student student) { return keywords.stream() - .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getName().fullName, keyword)); + .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(student.getName().fullName, keyword)); } @Override diff --git a/src/main/java/seedu/address/model/person/Phone.java b/src/main/java/seedu/resireg/model/student/Phone.java similarity index 88% rename from src/main/java/seedu/address/model/person/Phone.java rename to src/main/java/seedu/resireg/model/student/Phone.java index 872c76b382f..4c559069f19 100644 --- a/src/main/java/seedu/address/model/person/Phone.java +++ b/src/main/java/seedu/resireg/model/student/Phone.java @@ -1,10 +1,10 @@ -package seedu.address.model.person; +package seedu.resireg.model.student; import static java.util.Objects.requireNonNull; -import static seedu.address.commons.util.AppUtil.checkArgument; +import static seedu.resireg.commons.util.AppUtil.checkArgument; /** - * Represents a Person's phone number in the address book. + * Represents a Student's phone number in the address book. * Guarantees: immutable; is valid as declared in {@link #isValidPhone(String)} */ public class Phone { diff --git a/src/main/java/seedu/resireg/model/student/Student.java b/src/main/java/seedu/resireg/model/student/Student.java new file mode 100644 index 00000000000..16a2b5e3a3f --- /dev/null +++ b/src/main/java/seedu/resireg/model/student/Student.java @@ -0,0 +1,129 @@ +package seedu.resireg.model.student; + +import static seedu.resireg.commons.util.CollectionUtil.requireAllNonNull; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import seedu.resireg.model.student.faculty.Faculty; +import seedu.resireg.model.tag.Tag; + +/** + * Represents a Student in ResiReg. + * Guarantees: details are present and not null, field values are validated, immutable. + */ +public class Student { + + // Identity fields + private final Name name; + private final Phone phone; + private final Email email; + private final Faculty faculty; + private final StudentId studentId; + + // Data fields + private final Set tags = new HashSet<>(); + + /** + * Every field must be present and not null. + */ + public Student(Name name, Phone phone, Email email, Faculty faculty, StudentId studentId, Set tags) { + requireAllNonNull(name, phone, email, faculty, studentId, tags); + this.name = name; + this.phone = phone; + this.email = email; + this.faculty = faculty; + this.studentId = studentId; + this.tags.addAll(tags); + } + + public Name getName() { + return name; + } + + public Phone getPhone() { + return phone; + } + + public Email getEmail() { + return email; + } + + public Faculty getFaculty() { + return faculty; + } + + public StudentId getStudentId() { + return studentId; + } + + /** + * Returns an immutable tag set, which throws {@code UnsupportedOperationException} + * if modification is attempted. + */ + public Set getTags() { + return Collections.unmodifiableSet(tags); + } + + /** + * Returns true if both students have the same student identification number (StudentId). + * This defines a weaker notion of equality between two students, and includes students that have the same ID, + * but different fields (name, email, phone or faculty). + */ + public boolean isSameStudent(Student otherStudent) { + if (otherStudent == this) { + return true; + } + + return otherStudent != null && otherStudent.getStudentId().equals(getStudentId()); + } + + /** + * Returns true if both students have the same identity and data fields. + * This defines a stronger notion of equality between two students. + */ + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof Student)) { + return false; + } + + Student otherStudent = (Student) other; + return otherStudent.getStudentId().equals(getStudentId()) + && otherStudent.getName().equals(getName()) + && otherStudent.getPhone().equals(getPhone()) + && otherStudent.getEmail().equals(getEmail()) + && otherStudent.getFaculty().equals(getFaculty()) + && otherStudent.getTags().equals(getTags()); + } + + @Override + public int hashCode() { + // use this method for custom fields hashing instead of implementing your own + return Objects.hash(name, phone, email, faculty, studentId, tags); + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append(getName()) + .append(" Student ID: ") + .append(getStudentId()) + .append(" Phone: ") + .append(getPhone()) + .append(" Email: ") + .append(getEmail()) + .append(" Faculty: ") + .append(getFaculty()) + .append(" Tags: "); + getTags().forEach(builder::append); + return builder.toString(); + } + +} diff --git a/src/main/java/seedu/resireg/model/student/StudentId.java b/src/main/java/seedu/resireg/model/student/StudentId.java new file mode 100644 index 00000000000..861cf6bfa8c --- /dev/null +++ b/src/main/java/seedu/resireg/model/student/StudentId.java @@ -0,0 +1,53 @@ +package seedu.resireg.model.student; + +import static java.util.Objects.requireNonNull; +import static seedu.resireg.commons.util.AppUtil.checkArgument; + +/** + * Represents a Student's identification number in ResiReg. + * Guarantees: immutable; is valid as declared in {@link #isValidStudentId(String)} + */ +public class StudentId { + + + public static final String MESSAGE_CONSTRAINTS = + "A student's identification number should begin with an \'E0\' followed by 6 digits."; + public static final String VALIDATION_REGEX = "E0[0-9]{6}"; + public final String value; + + /** + * Constructs a {@code StudentId}. + * + * @param studentId A valid student identification number. + */ + public StudentId(String studentId) { + requireNonNull(studentId); + checkArgument(isValidStudentId(studentId), MESSAGE_CONSTRAINTS); + value = studentId; + } + + /** + * Returns true if a given string is a valid phone number. + */ + public static boolean isValidStudentId(String test) { + return test.matches(VALIDATION_REGEX); + } + + @Override + public String toString() { + return value; + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof StudentId // instanceof handles nulls + && value.equals(((StudentId) other).value)); // state check + } + + @Override + public int hashCode() { + return value.hashCode(); + } + +} diff --git a/src/main/java/seedu/resireg/model/student/UniqueStudentList.java b/src/main/java/seedu/resireg/model/student/UniqueStudentList.java new file mode 100644 index 00000000000..a24075c2079 --- /dev/null +++ b/src/main/java/seedu/resireg/model/student/UniqueStudentList.java @@ -0,0 +1,138 @@ +package seedu.resireg.model.student; + +import static java.util.Objects.requireNonNull; +import static seedu.resireg.commons.util.CollectionUtil.requireAllNonNull; + +import java.util.Iterator; +import java.util.List; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import seedu.resireg.model.student.exceptions.DuplicateStudentException; +import seedu.resireg.model.student.exceptions.StudentNotFoundException; + +/** + * A list of students that enforces uniqueness between its elements and does not allow nulls. + * A student is considered unique by comparing using {@code Student#isSameStudent(Student)}. + * As such, adding and updating of students uses Student#isSameStudent(Student) for equality so as to ensure + * that the student being added or updated is unique in terms of identity in the UniqueStudentList. + * However, the removal of a student uses Student#equals(Object) so as to ensure that the student with + * exactly the same fields will be removed. + * + * Supports a minimal set of list operations. + * + * @see Student#isSameStudent(Student) + */ +public class UniqueStudentList implements Iterable { + + private final ObservableList internalList = FXCollections.observableArrayList(); + private final ObservableList internalUnmodifiableList = + FXCollections.unmodifiableObservableList(internalList); + + /** + * Returns true if the list contains an equivalent student as the given argument. + */ + public boolean contains(Student toCheck) { + requireNonNull(toCheck); + return internalList.stream().anyMatch(toCheck::isSameStudent); + } + + /** + * Adds a student to the list. + * The student must not already exist in the list. + */ + public void add(Student toAdd) { + requireNonNull(toAdd); + if (contains(toAdd)) { + throw new DuplicateStudentException(); + } + internalList.add(toAdd); + } + + /** + * Replaces the student {@code target} in the list with {@code editedStudent}. + * {@code target} must exist in the list. + * The student identity of {@code editedStudent} must not be the same as another existing student in the list. + */ + public void setStudent(Student target, Student editedStudent) { + requireAllNonNull(target, editedStudent); + + int index = internalList.indexOf(target); + if (index == -1) { + throw new StudentNotFoundException(); + } + + if (!target.isSameStudent(editedStudent) && contains(editedStudent)) { + throw new DuplicateStudentException(); + } + + internalList.set(index, editedStudent); + } + + /** + * Removes the equivalent student from the list. + * The student must exist in the list. + */ + public void remove(Student toRemove) { + requireNonNull(toRemove); + if (!internalList.remove(toRemove)) { + throw new StudentNotFoundException(); + } + } + + public void setStudents(UniqueStudentList replacement) { + requireNonNull(replacement); + internalList.setAll(replacement.internalList); + } + + /** + * Replaces the contents of this list with {@code students}. + * {@code students} must not contain duplicate students. + */ + public void setStudents(List students) { + requireAllNonNull(students); + if (!studentsAreUnique(students)) { + throw new DuplicateStudentException(); + } + + internalList.setAll(students); + } + + /** + * Returns the backing list as an unmodifiable {@code ObservableList}. + */ + public ObservableList asUnmodifiableObservableList() { + return internalUnmodifiableList; + } + + @Override + public Iterator iterator() { + return internalList.iterator(); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof UniqueStudentList // instanceof handles nulls + && internalList.equals(((UniqueStudentList) other).internalList)); + } + + @Override + public int hashCode() { + return internalList.hashCode(); + } + + /** + * Returns true if {@code students} contains only unique students. + */ + private boolean studentsAreUnique(List students) { + for (int i = 0; i < students.size() - 1; i++) { + for (int j = i + 1; j < students.size(); j++) { + if (students.get(i).isSameStudent(students.get(j))) { + return false; + } + } + } + return true; + } +} diff --git a/src/main/java/seedu/resireg/model/student/exceptions/DuplicateStudentException.java b/src/main/java/seedu/resireg/model/student/exceptions/DuplicateStudentException.java new file mode 100644 index 00000000000..6a424ad0f0c --- /dev/null +++ b/src/main/java/seedu/resireg/model/student/exceptions/DuplicateStudentException.java @@ -0,0 +1,11 @@ +package seedu.resireg.model.student.exceptions; + +/** + * Signals that the operation will result in duplicate Students (Students are considered duplicates if they have the + * same identity). + */ +public class DuplicateStudentException extends RuntimeException { + public DuplicateStudentException() { + super("Operation would result in duplicate students"); + } +} diff --git a/src/main/java/seedu/resireg/model/student/exceptions/StudentNotFoundException.java b/src/main/java/seedu/resireg/model/student/exceptions/StudentNotFoundException.java new file mode 100644 index 00000000000..ef4222b54b2 --- /dev/null +++ b/src/main/java/seedu/resireg/model/student/exceptions/StudentNotFoundException.java @@ -0,0 +1,6 @@ +package seedu.resireg.model.student.exceptions; + +/** + * Signals that the operation is unable to find the specified student. + */ +public class StudentNotFoundException extends RuntimeException {} diff --git a/src/main/java/seedu/resireg/model/student/faculty/Faculty.java b/src/main/java/seedu/resireg/model/student/faculty/Faculty.java new file mode 100644 index 00000000000..c02ab7fc917 --- /dev/null +++ b/src/main/java/seedu/resireg/model/student/faculty/Faculty.java @@ -0,0 +1,57 @@ +package seedu.resireg.model.student.faculty; + +import static java.util.Objects.requireNonNull; +import static seedu.resireg.commons.util.AppUtil.checkArgument; + +import java.util.Arrays; +import java.util.List; + +/** + * Represents a Student's faculty in ResiReg. + * Guarantees: immutable; is valid as declared in {@link #isValidFaculty(String)} + */ +public class Faculty { + + + public static final String MESSAGE_CONSTRAINTS = + "A faculty must be listed here: http://www.nus.edu.sg/education"; + public static final String VALIDATION_REGEX = "\\d{3,}"; + public final String value; + + /** + * Constructs a {@code Faculty}. + * + * @param facultyAbbr A valid faculty abbreviation. + */ + public Faculty(String facultyAbbr) { + requireNonNull(facultyAbbr); + checkArgument(isValidFaculty(facultyAbbr), MESSAGE_CONSTRAINTS); + value = facultyAbbr; + } + + /** + * Returns true if a given string is a valid faculty abbreviation. + */ + public static boolean isValidFaculty(String test) { + List faculties = Arrays.asList(FacultyEnum.values()); + return faculties.stream().anyMatch(faculty -> faculty.matchesFacultyAbbreviation(test)); + } + + @Override + public String toString() { + return value; + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof Faculty // instanceof handles nulls + && value.equals(((Faculty) other).value)); // state check + } + + @Override + public int hashCode() { + return value.hashCode(); + } + +} diff --git a/src/main/java/seedu/resireg/model/student/faculty/FacultyEnum.java b/src/main/java/seedu/resireg/model/student/faculty/FacultyEnum.java new file mode 100644 index 00000000000..d5ddf96b9ce --- /dev/null +++ b/src/main/java/seedu/resireg/model/student/faculty/FacultyEnum.java @@ -0,0 +1,36 @@ +package seedu.resireg.model.student.faculty; + +public enum FacultyEnum { + ARTS_SOCIAL_SCIENCES("FASS"), + BUSINESS("BIZ"), + COMPUTING("SOC"), + CONTINUING_LIFELONG_EDUCATION("CLE"), + DENTISTRY("DEN"), + DESIGN_AND_ENVIRONMENT("SDE"), + DUKE_NUS("DNUS"), + ENGINEERING("ENG"), + INTEGRATIVE_SCIENCES_AND_ENGINEERING("ISE"), + LAW("LAW"), + MEDICINE("MED"), + MUSIC("MUS"), + PUBLIC_HEALTH("PH"), + PUBLIC_POLICY("PP"), + SCIENCE("FOS"), + UNIVERSITY_SCHOLARS_PROGRAMME("USP"), + YALE_NUS("YNUS"); + + private String abbreviation; + + FacultyEnum (String abbreviation) { + this.abbreviation = abbreviation; + } + + public boolean matchesFacultyAbbreviation(String test) { + return test.equals(abbreviation); + } + + @Override + public String toString() { + return abbreviation; + } +} diff --git a/src/main/java/seedu/address/model/tag/Tag.java b/src/main/java/seedu/resireg/model/tag/Tag.java similarity index 93% rename from src/main/java/seedu/address/model/tag/Tag.java rename to src/main/java/seedu/resireg/model/tag/Tag.java index b0ea7e7dad7..4d6f093c951 100644 --- a/src/main/java/seedu/address/model/tag/Tag.java +++ b/src/main/java/seedu/resireg/model/tag/Tag.java @@ -1,7 +1,7 @@ -package seedu.address.model.tag; +package seedu.resireg.model.tag; import static java.util.Objects.requireNonNull; -import static seedu.address.commons.util.AppUtil.checkArgument; +import static seedu.resireg.commons.util.AppUtil.checkArgument; /** * Represents a Tag in the address book. diff --git a/src/main/java/seedu/resireg/model/util/SampleDataUtil.java b/src/main/java/seedu/resireg/model/util/SampleDataUtil.java new file mode 100644 index 00000000000..8da485c8eb3 --- /dev/null +++ b/src/main/java/seedu/resireg/model/util/SampleDataUtil.java @@ -0,0 +1,61 @@ +package seedu.resireg.model.util; + +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +import seedu.resireg.model.AddressBook; +import seedu.resireg.model.ReadOnlyAddressBook; +import seedu.resireg.model.student.Email; +import seedu.resireg.model.student.Name; +import seedu.resireg.model.student.Phone; +import seedu.resireg.model.student.Student; +import seedu.resireg.model.student.StudentId; +import seedu.resireg.model.student.faculty.Faculty; +import seedu.resireg.model.tag.Tag; + +/** + * Contains utility methods for populating {@code AddressBook} with sample data. + */ +public class SampleDataUtil { + public static Student[] getSampleStudents() { + return new Student[] { + new Student(new Name("Alex Yeoh"), new Phone("87438807"), new Email("alexyeoh@example.com"), + new Faculty("FASS"), new StudentId("E0111111"), + getTagSet("friends")), + new Student(new Name("Bernice Yu"), new Phone("99272758"), new Email("berniceyu@example.com"), + new Faculty("SOC"), new StudentId("E0222222"), + getTagSet("colleagues", "friends")), + new Student(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Email("charlotte@example.com"), + new Faculty("DEN"), new StudentId("E0333333"), + getTagSet("neighbours")), + new Student(new Name("David Li"), new Phone("91031282"), new Email("lidavid@example.com"), + new Faculty("FOS"), new StudentId("E0444444"), + getTagSet("family")), + new Student(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"), + new Faculty("BIZ"), new StudentId("E0555555"), + getTagSet("classmates")), + new Student(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"), + new Faculty("FASS"), new StudentId("E0666666"), + getTagSet("colleagues")) + }; + } + + public static ReadOnlyAddressBook getSampleAddressBook() { + AddressBook sampleAb = new AddressBook(); + for (Student sampleStudent : getSampleStudents()) { + sampleAb.addStudent(sampleStudent); + } + return sampleAb; + } + + /** + * Returns a tag set containing the list of strings given. + */ + public static Set getTagSet(String... strings) { + return Arrays.stream(strings) + .map(Tag::new) + .collect(Collectors.toSet()); + } + +} diff --git a/src/main/java/seedu/address/storage/AddressBookStorage.java b/src/main/java/seedu/resireg/storage/AddressBookStorage.java similarity index 85% rename from src/main/java/seedu/address/storage/AddressBookStorage.java rename to src/main/java/seedu/resireg/storage/AddressBookStorage.java index 4599182b3f9..71967e555c8 100644 --- a/src/main/java/seedu/address/storage/AddressBookStorage.java +++ b/src/main/java/seedu/resireg/storage/AddressBookStorage.java @@ -1,14 +1,14 @@ -package seedu.address.storage; +package seedu.resireg.storage; import java.io.IOException; import java.nio.file.Path; import java.util.Optional; -import seedu.address.commons.exceptions.DataConversionException; -import seedu.address.model.ReadOnlyAddressBook; +import seedu.resireg.commons.exceptions.DataConversionException; +import seedu.resireg.model.ReadOnlyAddressBook; /** - * Represents a storage for {@link seedu.address.model.AddressBook}. + * Represents a storage for {@link seedu.resireg.model.AddressBook}. */ public interface AddressBookStorage { diff --git a/src/main/java/seedu/resireg/storage/JsonAdaptedStudent.java b/src/main/java/seedu/resireg/storage/JsonAdaptedStudent.java new file mode 100644 index 00000000000..fc009ab8e54 --- /dev/null +++ b/src/main/java/seedu/resireg/storage/JsonAdaptedStudent.java @@ -0,0 +1,122 @@ +package seedu.resireg.storage; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import seedu.resireg.commons.exceptions.IllegalValueException; +import seedu.resireg.model.student.Email; +import seedu.resireg.model.student.Name; +import seedu.resireg.model.student.Phone; +import seedu.resireg.model.student.Student; +import seedu.resireg.model.student.StudentId; +import seedu.resireg.model.student.faculty.Faculty; +import seedu.resireg.model.tag.Tag; + +/** + * Jackson-friendly version of {@link Student}. + */ +class JsonAdaptedStudent { + + public static final String MISSING_FIELD_MESSAGE_FORMAT = "Student's %s field is missing!"; + + private final String name; + private final String phone; + private final String email; + private final String faculty; + private final String studentId; + private final List tagged = new ArrayList<>(); + + /** + * Constructs a {@code JsonAdaptedStudent} with the given student details. + */ + @JsonCreator + public JsonAdaptedStudent(@JsonProperty("name") String name, @JsonProperty("phone") String phone, + @JsonProperty("email") String email, @JsonProperty("faculty") String faculty, + @JsonProperty("studentId") String studentId, @JsonProperty("tagged") List tagged) { + this.name = name; + this.phone = phone; + this.email = email; + this.faculty = faculty; + this.studentId = studentId; + if (tagged != null) { + this.tagged.addAll(tagged); + } + } + + /** + * Converts a given {@code Student} into this class for Jackson use. + */ + public JsonAdaptedStudent(Student source) { + name = source.getName().fullName; + phone = source.getPhone().value; + email = source.getEmail().value; + faculty = source.getFaculty().value; + studentId = source.getStudentId().value; + tagged.addAll(source.getTags().stream() + .map(JsonAdaptedTag::new) + .collect(Collectors.toList())); + } + + /** + * Converts this Jackson-friendly adapted student object into the model's {@code Student} object. + * + * @throws IllegalValueException if there were any data constraints violated in the adapted student. + */ + public Student toModelType() throws IllegalValueException { + final List studentTags = new ArrayList<>(); + for (JsonAdaptedTag tag : tagged) { + studentTags.add(tag.toModelType()); + } + + if (name == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName())); + } + if (!Name.isValidName(name)) { + throw new IllegalValueException(Name.MESSAGE_CONSTRAINTS); + } + final Name modelName = new Name(name); + + if (phone == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName())); + } + if (!Phone.isValidPhone(phone)) { + throw new IllegalValueException(Phone.MESSAGE_CONSTRAINTS); + } + final Phone modelPhone = new Phone(phone); + + if (email == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Email.class.getSimpleName())); + } + if (!Email.isValidEmail(email)) { + throw new IllegalValueException(Email.MESSAGE_CONSTRAINTS); + } + final Email modelEmail = new Email(email); + + if (faculty == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Faculty.class.getSimpleName())); + } + if (!Faculty.isValidFaculty(faculty)) { + throw new IllegalValueException(Faculty.MESSAGE_CONSTRAINTS); + } + final Faculty modelFaculty = new Faculty(faculty); + + if (studentId == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, + StudentId.class.getSimpleName())); + } + if (!StudentId.isValidStudentId(studentId)) { + throw new IllegalValueException(StudentId.MESSAGE_CONSTRAINTS); + } + final StudentId modelStudentId = new StudentId(studentId); + + final Set modelTags = new HashSet<>(studentTags); + return new Student(modelName, modelPhone, modelEmail, modelFaculty, modelStudentId, modelTags); + } + +} diff --git a/src/main/java/seedu/address/storage/JsonAdaptedTag.java b/src/main/java/seedu/resireg/storage/JsonAdaptedTag.java similarity index 89% rename from src/main/java/seedu/address/storage/JsonAdaptedTag.java rename to src/main/java/seedu/resireg/storage/JsonAdaptedTag.java index 0df22bdb754..d70c4abe798 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedTag.java +++ b/src/main/java/seedu/resireg/storage/JsonAdaptedTag.java @@ -1,10 +1,10 @@ -package seedu.address.storage; +package seedu.resireg.storage; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.model.tag.Tag; +import seedu.resireg.commons.exceptions.IllegalValueException; +import seedu.resireg.model.tag.Tag; /** * Jackson-friendly version of {@link Tag}. diff --git a/src/main/java/seedu/address/storage/JsonAddressBookStorage.java b/src/main/java/seedu/resireg/storage/JsonAddressBookStorage.java similarity index 86% rename from src/main/java/seedu/address/storage/JsonAddressBookStorage.java rename to src/main/java/seedu/resireg/storage/JsonAddressBookStorage.java index dfab9daaa0d..0faf95ac8de 100644 --- a/src/main/java/seedu/address/storage/JsonAddressBookStorage.java +++ b/src/main/java/seedu/resireg/storage/JsonAddressBookStorage.java @@ -1,4 +1,4 @@ -package seedu.address.storage; +package seedu.resireg.storage; import static java.util.Objects.requireNonNull; @@ -7,12 +7,12 @@ import java.util.Optional; import java.util.logging.Logger; -import seedu.address.commons.core.LogsCenter; -import seedu.address.commons.exceptions.DataConversionException; -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.commons.util.FileUtil; -import seedu.address.commons.util.JsonUtil; -import seedu.address.model.ReadOnlyAddressBook; +import seedu.resireg.commons.core.LogsCenter; +import seedu.resireg.commons.exceptions.DataConversionException; +import seedu.resireg.commons.exceptions.IllegalValueException; +import seedu.resireg.commons.util.FileUtil; +import seedu.resireg.commons.util.JsonUtil; +import seedu.resireg.model.ReadOnlyAddressBook; /** * A class to access AddressBook data stored as a json file on the hard disk. diff --git a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java b/src/main/java/seedu/resireg/storage/JsonSerializableAddressBook.java similarity index 57% rename from src/main/java/seedu/address/storage/JsonSerializableAddressBook.java rename to src/main/java/seedu/resireg/storage/JsonSerializableAddressBook.java index 5efd834091d..ab4f7b27c0b 100644 --- a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java +++ b/src/main/java/seedu/resireg/storage/JsonSerializableAddressBook.java @@ -1,4 +1,4 @@ -package seedu.address.storage; +package seedu.resireg.storage; import java.util.ArrayList; import java.util.List; @@ -8,10 +8,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonRootName; -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.model.AddressBook; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.person.Person; +import seedu.resireg.commons.exceptions.IllegalValueException; +import seedu.resireg.model.AddressBook; +import seedu.resireg.model.ReadOnlyAddressBook; +import seedu.resireg.model.student.Student; /** * An Immutable AddressBook that is serializable to JSON format. @@ -19,16 +19,16 @@ @JsonRootName(value = "addressbook") class JsonSerializableAddressBook { - public static final String MESSAGE_DUPLICATE_PERSON = "Persons list contains duplicate person(s)."; + public static final String MESSAGE_DUPLICATE_PERSON = "Students list contains duplicate student(s)."; - private final List persons = new ArrayList<>(); + private final List students = new ArrayList<>(); /** - * Constructs a {@code JsonSerializableAddressBook} with the given persons. + * Constructs a {@code JsonSerializableAddressBook} with the given students. */ @JsonCreator - public JsonSerializableAddressBook(@JsonProperty("persons") List persons) { - this.persons.addAll(persons); + public JsonSerializableAddressBook(@JsonProperty("students") List students) { + this.students.addAll(students); } /** @@ -37,7 +37,7 @@ public JsonSerializableAddressBook(@JsonProperty("persons") List readUserPrefs() throws DataConversionException, IOException; /** - * Saves the given {@link seedu.address.model.ReadOnlyUserPrefs} to the storage. + * Saves the given {@link seedu.resireg.model.ReadOnlyUserPrefs} to the storage. * @param userPrefs cannot be null. * @throws IOException if there was any problem writing to the file. */ diff --git a/src/main/java/seedu/address/ui/CommandBox.java b/src/main/java/seedu/resireg/ui/CommandBox.java similarity index 89% rename from src/main/java/seedu/address/ui/CommandBox.java rename to src/main/java/seedu/resireg/ui/CommandBox.java index 5cc21e47889..1152e6670ff 100644 --- a/src/main/java/seedu/address/ui/CommandBox.java +++ b/src/main/java/seedu/resireg/ui/CommandBox.java @@ -1,12 +1,12 @@ -package seedu.address.ui; +package seedu.resireg.ui; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.scene.control.TextField; import javafx.scene.layout.Region; -import seedu.address.logic.commands.CommandResult; -import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.logic.parser.exceptions.ParseException; +import seedu.resireg.logic.commands.CommandResult; +import seedu.resireg.logic.commands.exceptions.CommandException; +import seedu.resireg.logic.parser.exceptions.ParseException; /** * The UI component that is responsible for receiving user command inputs. @@ -72,7 +72,7 @@ public interface CommandExecutor { /** * Executes the command and returns the result. * - * @see seedu.address.logic.Logic#execute(String) + * @see seedu.resireg.logic.Logic#execute(String) */ CommandResult execute(String commandText) throws CommandException, ParseException; } diff --git a/src/main/java/seedu/address/ui/HelpWindow.java b/src/main/java/seedu/resireg/ui/HelpWindow.java similarity index 97% rename from src/main/java/seedu/address/ui/HelpWindow.java rename to src/main/java/seedu/resireg/ui/HelpWindow.java index 9a665915949..d1a43808f69 100644 --- a/src/main/java/seedu/address/ui/HelpWindow.java +++ b/src/main/java/seedu/resireg/ui/HelpWindow.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.resireg.ui; import java.util.logging.Logger; @@ -8,7 +8,7 @@ import javafx.scene.input.Clipboard; import javafx.scene.input.ClipboardContent; import javafx.stage.Stage; -import seedu.address.commons.core.LogsCenter; +import seedu.resireg.commons.core.LogsCenter; /** * Controller for a help page diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/resireg/ui/MainWindow.java similarity index 88% rename from src/main/java/seedu/address/ui/MainWindow.java rename to src/main/java/seedu/resireg/ui/MainWindow.java index 9106c3aa6e5..deaa51d4d6b 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/resireg/ui/MainWindow.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.resireg.ui; import java.util.logging.Logger; @@ -10,12 +10,12 @@ import javafx.scene.input.KeyEvent; import javafx.scene.layout.StackPane; import javafx.stage.Stage; -import seedu.address.commons.core.GuiSettings; -import seedu.address.commons.core.LogsCenter; -import seedu.address.logic.Logic; -import seedu.address.logic.commands.CommandResult; -import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.logic.parser.exceptions.ParseException; +import seedu.resireg.commons.core.GuiSettings; +import seedu.resireg.commons.core.LogsCenter; +import seedu.resireg.logic.Logic; +import seedu.resireg.logic.commands.CommandResult; +import seedu.resireg.logic.commands.exceptions.CommandException; +import seedu.resireg.logic.parser.exceptions.ParseException; /** * The Main Window. Provides the basic application layout containing @@ -31,7 +31,7 @@ public class MainWindow extends UiPart { private Logic logic; // Independent Ui parts residing in this Ui container - private PersonListPanel personListPanel; + private StudentListPanel studentListPanel; private ResultDisplay resultDisplay; private HelpWindow helpWindow; @@ -42,7 +42,7 @@ public class MainWindow extends UiPart { private MenuItem helpMenuItem; @FXML - private StackPane personListPanelPlaceholder; + private StackPane studentListPanelPlaceholder; @FXML private StackPane resultDisplayPlaceholder; @@ -110,8 +110,9 @@ private void setAccelerator(MenuItem menuItem, KeyCombination keyCombination) { * Fills up all the placeholders of this window. */ void fillInnerParts() { - personListPanel = new PersonListPanel(logic.getFilteredPersonList()); - personListPanelPlaceholder.getChildren().add(personListPanel.getRoot()); + studentListPanel = new StudentListPanel(logic.getFilteredStudentList()); + studentListPanelPlaceholder.getChildren() + .add(studentListPanel.getRoot()); resultDisplay = new ResultDisplay(); resultDisplayPlaceholder.getChildren().add(resultDisplay.getRoot()); @@ -163,14 +164,14 @@ private void handleExit() { primaryStage.hide(); } - public PersonListPanel getPersonListPanel() { - return personListPanel; + public StudentListPanel getStudentListPanel() { + return studentListPanel; } /** * Executes the command and returns the result. * - * @see seedu.address.logic.Logic#execute(String) + * @see seedu.resireg.logic.Logic#execute(String) */ private CommandResult executeCommand(String commandText) throws CommandException, ParseException { try { diff --git a/src/main/java/seedu/address/ui/ResultDisplay.java b/src/main/java/seedu/resireg/ui/ResultDisplay.java similarity index 95% rename from src/main/java/seedu/address/ui/ResultDisplay.java rename to src/main/java/seedu/resireg/ui/ResultDisplay.java index 7d98e84eedf..2fde25c2294 100644 --- a/src/main/java/seedu/address/ui/ResultDisplay.java +++ b/src/main/java/seedu/resireg/ui/ResultDisplay.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.resireg.ui; import static java.util.Objects.requireNonNull; diff --git a/src/main/java/seedu/address/ui/StatusBarFooter.java b/src/main/java/seedu/resireg/ui/StatusBarFooter.java similarity index 96% rename from src/main/java/seedu/address/ui/StatusBarFooter.java rename to src/main/java/seedu/resireg/ui/StatusBarFooter.java index b577f829423..65c292fbf2d 100644 --- a/src/main/java/seedu/address/ui/StatusBarFooter.java +++ b/src/main/java/seedu/resireg/ui/StatusBarFooter.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.resireg.ui; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/resireg/ui/StudentCard.java similarity index 58% rename from src/main/java/seedu/address/ui/PersonCard.java rename to src/main/java/seedu/resireg/ui/StudentCard.java index 7fc927bc5d9..17b7f002963 100644 --- a/src/main/java/seedu/address/ui/PersonCard.java +++ b/src/main/java/seedu/resireg/ui/StudentCard.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.resireg.ui; import java.util.Comparator; @@ -7,14 +7,14 @@ import javafx.scene.layout.FlowPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Region; -import seedu.address.model.person.Person; +import seedu.resireg.model.student.Student; /** - * An UI component that displays information of a {@code Person}. + * An UI component that displays information of a {@code Student}. */ -public class PersonCard extends UiPart { +public class StudentCard extends UiPart { - private static final String FXML = "PersonListCard.fxml"; + private static final String FXML = "StudentListCard.fxml"; /** * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX. @@ -24,7 +24,7 @@ public class PersonCard extends UiPart { * @see The issue on AddressBook level 4 */ - public final Person person; + public final Student student; @FXML private HBox cardPane; @@ -35,24 +35,27 @@ public class PersonCard extends UiPart { @FXML private Label phone; @FXML - private Label address; + private Label faculty; + @FXML + private Label studentId; @FXML private Label email; @FXML private FlowPane tags; /** - * Creates a {@code PersonCode} with the given {@code Person} and index to display. + * Creates a {@code StudentCard} with the given {@code Student} and index to display. */ - public PersonCard(Person person, int displayedIndex) { + public StudentCard(Student student, int displayedIndex) { super(FXML); - this.person = person; + this.student = student; id.setText(displayedIndex + ". "); - name.setText(person.getName().fullName); - phone.setText(person.getPhone().value); - address.setText(person.getAddress().value); - email.setText(person.getEmail().value); - person.getTags().stream() + name.setText(student.getName().fullName); + phone.setText(student.getPhone().value); + faculty.setText(student.getFaculty().value); + studentId.setText(student.getStudentId().value); + email.setText(student.getEmail().value); + student.getTags().stream() .sorted(Comparator.comparing(tag -> tag.tagName)) .forEach(tag -> tags.getChildren().add(new Label(tag.tagName))); } @@ -65,13 +68,13 @@ public boolean equals(Object other) { } // instanceof handles nulls - if (!(other instanceof PersonCard)) { + if (!(other instanceof StudentCard)) { return false; } // state check - PersonCard card = (PersonCard) other; + StudentCard card = (StudentCard) other; return id.getText().equals(card.id.getText()) - && person.equals(card.person); + && student.equals(card.student); } } diff --git a/src/main/java/seedu/resireg/ui/StudentListPanel.java b/src/main/java/seedu/resireg/ui/StudentListPanel.java new file mode 100644 index 00000000000..dda7570512e --- /dev/null +++ b/src/main/java/seedu/resireg/ui/StudentListPanel.java @@ -0,0 +1,49 @@ +package seedu.resireg.ui; + +import java.util.logging.Logger; + +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.layout.Region; +import seedu.resireg.commons.core.LogsCenter; +import seedu.resireg.model.student.Student; + +/** + * Panel containing the list of students. + */ +public class StudentListPanel extends UiPart { + private static final String FXML = "StudentListPanel.fxml"; + private final Logger logger = LogsCenter.getLogger(StudentListPanel.class); + + @FXML + private ListView studentListView; + + /** + * Creates a {@code StudentListPanel} with the given {@code ObservableList}. + */ + public StudentListPanel(ObservableList studentList) { + super(FXML); + studentListView.setItems(studentList); + studentListView.setCellFactory(listView -> new StudentListViewCell()); + } + + /** + * Custom {@code ListCell} that displays the graphics of a {@code Student} using a {@code StudentCard}. + */ + class StudentListViewCell extends ListCell { + @Override + protected void updateItem(Student student, boolean empty) { + super.updateItem(student, empty); + + if (empty || student == null) { + setGraphic(null); + setText(null); + } else { + setGraphic(new StudentCard(student, getIndex() + 1).getRoot()); + } + } + } + +} diff --git a/src/main/java/seedu/address/ui/Ui.java b/src/main/java/seedu/resireg/ui/Ui.java similarity index 86% rename from src/main/java/seedu/address/ui/Ui.java rename to src/main/java/seedu/resireg/ui/Ui.java index 17aa0b494fe..c49226af369 100644 --- a/src/main/java/seedu/address/ui/Ui.java +++ b/src/main/java/seedu/resireg/ui/Ui.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.resireg.ui; import javafx.stage.Stage; diff --git a/src/main/java/seedu/address/ui/UiManager.java b/src/main/java/seedu/resireg/ui/UiManager.java similarity index 94% rename from src/main/java/seedu/address/ui/UiManager.java rename to src/main/java/seedu/resireg/ui/UiManager.java index 882027e4537..c42b13dd877 100644 --- a/src/main/java/seedu/address/ui/UiManager.java +++ b/src/main/java/seedu/resireg/ui/UiManager.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.resireg.ui; import java.util.logging.Logger; @@ -7,10 +7,10 @@ import javafx.scene.control.Alert.AlertType; import javafx.scene.image.Image; import javafx.stage.Stage; -import seedu.address.MainApp; -import seedu.address.commons.core.LogsCenter; -import seedu.address.commons.util.StringUtil; -import seedu.address.logic.Logic; +import seedu.resireg.MainApp; +import seedu.resireg.commons.core.LogsCenter; +import seedu.resireg.commons.util.StringUtil; +import seedu.resireg.logic.Logic; /** * The manager of the UI component. diff --git a/src/main/java/seedu/address/ui/UiPart.java b/src/main/java/seedu/resireg/ui/UiPart.java similarity index 97% rename from src/main/java/seedu/address/ui/UiPart.java rename to src/main/java/seedu/resireg/ui/UiPart.java index fc820e01a9c..2540ac4fa38 100644 --- a/src/main/java/seedu/address/ui/UiPart.java +++ b/src/main/java/seedu/resireg/ui/UiPart.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.resireg.ui; import static java.util.Objects.requireNonNull; @@ -6,7 +6,7 @@ import java.net.URL; import javafx.fxml.FXMLLoader; -import seedu.address.MainApp; +import seedu.resireg.MainApp; /** * Represents a distinct part of the UI. e.g. Windows, dialogs, panels, status bars, etc. diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml index a431648f6c0..5d17a839c92 100644 --- a/src/main/resources/view/MainWindow.fxml +++ b/src/main/resources/view/MainWindow.fxml @@ -12,7 +12,7 @@ + title="ResiReg" minWidth="450" minHeight="600" onCloseRequest="#handleExit"> @@ -46,11 +46,11 @@ - + - + diff --git a/src/main/resources/view/PersonListCard.fxml b/src/main/resources/view/StudentListCard.fxml similarity index 89% rename from src/main/resources/view/PersonListCard.fxml rename to src/main/resources/view/StudentListCard.fxml index f08ea32ad55..c94d7819e48 100644 --- a/src/main/resources/view/PersonListCard.fxml +++ b/src/main/resources/view/StudentListCard.fxml @@ -28,8 +28,9 @@ diff --git a/src/main/resources/view/PersonListPanel.fxml b/src/main/resources/view/StudentListPanel.fxml similarity index 77% rename from src/main/resources/view/PersonListPanel.fxml rename to src/main/resources/view/StudentListPanel.fxml index 8836d323cc5..e6b906fed69 100644 --- a/src/main/resources/view/PersonListPanel.fxml +++ b/src/main/resources/view/StudentListPanel.fxml @@ -4,5 +4,5 @@ - + diff --git a/src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json b/src/test/data/JsonAddressBookStorageTest/invalidAndValidStudentAddressBook.json similarity index 59% rename from src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json rename to src/test/data/JsonAddressBookStorageTest/invalidAndValidStudentAddressBook.json index 6a4d2b7181c..152db5fd782 100644 --- a/src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json +++ b/src/test/data/JsonAddressBookStorageTest/invalidAndValidStudentAddressBook.json @@ -1,13 +1,14 @@ { - "persons": [ { + "students": [ { "name": "Valid Person", "phone": "9482424", "email": "hans@example.com", - "address": "4th street" + "faculty": "FASS", + "studentId": "E0407881" }, { "name": "Person With Invalid Phone Field", "phone": "948asdf2424", - "email": "hans@example.com", - "address": "4th street" + "faculty": "FASS", + "studentId": "E0407881" } ] } diff --git a/src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json b/src/test/data/JsonAddressBookStorageTest/invalidStudentAddressBook.json similarity index 64% rename from src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json rename to src/test/data/JsonAddressBookStorageTest/invalidStudentAddressBook.json index ccd21f7d1a9..0ab29178eb4 100644 --- a/src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json +++ b/src/test/data/JsonAddressBookStorageTest/invalidStudentAddressBook.json @@ -1,8 +1,9 @@ { - "persons": [ { + "students": [ { "name": "Person with invalid name field: Ha!ns Mu@ster", "phone": "9482424", "email": "hans@example.com", - "address": "4th street" + "faculty": "FASS", + "studentId": "E0407881" } ] } diff --git a/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/duplicateStudentAddressBook.json similarity index 64% rename from src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json rename to src/test/data/JsonSerializableAddressBookTest/duplicateStudentAddressBook.json index 48831cc7674..1143e84e3c0 100644 --- a/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json +++ b/src/test/data/JsonSerializableAddressBookTest/duplicateStudentAddressBook.json @@ -1,14 +1,16 @@ { - "persons": [ { + "students": [ { "name": "Alice Pauline", "phone": "94351253", "email": "alice@example.com", - "address": "123, Jurong West Ave 6, #08-111", + "faculty": "FASS", + "studentId": "E0407881", "tagged": [ "friends" ] }, { "name": "Alice Pauline", "phone": "94351253", "email": "pauline@example.com", - "address": "4th street" + "faculty": "FASS", + "studentId": "E0407881" } ] } diff --git a/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/invalidStudentAddressBook.json similarity index 57% rename from src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json rename to src/test/data/JsonSerializableAddressBookTest/invalidStudentAddressBook.json index ad3f135ae42..430f00ae4f2 100644 --- a/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json +++ b/src/test/data/JsonSerializableAddressBookTest/invalidStudentAddressBook.json @@ -1,8 +1,9 @@ { - "persons": [ { + "students": [ { "name": "Hans Muster", "phone": "9482424", "email": "invalid@email!3e", - "address": "4th street" + "faculty": "FASS", + "studentId": "E0407881" } ] } diff --git a/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json deleted file mode 100644 index f10eddee12e..00000000000 --- a/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "_comment": "AddressBook save file which contains the same Person values as in TypicalPersons#getTypicalAddressBook()", - "persons" : [ { - "name" : "Alice Pauline", - "phone" : "94351253", - "email" : "alice@example.com", - "address" : "123, Jurong West Ave 6, #08-111", - "tagged" : [ "friends" ] - }, { - "name" : "Benson Meier", - "phone" : "98765432", - "email" : "johnd@example.com", - "address" : "311, Clementi Ave 2, #02-25", - "tagged" : [ "owesMoney", "friends" ] - }, { - "name" : "Carl Kurz", - "phone" : "95352563", - "email" : "heinz@example.com", - "address" : "wall street", - "tagged" : [ ] - }, { - "name" : "Daniel Meier", - "phone" : "87652533", - "email" : "cornelia@example.com", - "address" : "10th street", - "tagged" : [ "friends" ] - }, { - "name" : "Elle Meyer", - "phone" : "9482224", - "email" : "werner@example.com", - "address" : "michegan ave", - "tagged" : [ ] - }, { - "name" : "Fiona Kunz", - "phone" : "9482427", - "email" : "lydia@example.com", - "address" : "little tokyo", - "tagged" : [ ] - }, { - "name" : "George Best", - "phone" : "9482442", - "email" : "anna@example.com", - "address" : "4th street", - "tagged" : [ ] - } ] -} diff --git a/src/test/data/JsonSerializableAddressBookTest/typicalStudentsAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/typicalStudentsAddressBook.json new file mode 100644 index 00000000000..b795a6a5370 --- /dev/null +++ b/src/test/data/JsonSerializableAddressBookTest/typicalStudentsAddressBook.json @@ -0,0 +1,53 @@ +{ + "_comment": "AddressBook save file which contains the same Student values as in TypicalStudents#getTypicalAddressBook()", + "students" : [ { + "name" : "Alice Pauline", + "phone" : "94351253", + "email" : "alice@example.com", + "faculty": "FASS", + "studentId": "E0111110", + "tagged" : [ "friends" ] + }, { + "name" : "Benson Meier", + "phone" : "98765432", + "email" : "benson@example.com", + "faculty": "FASS", + "studentId": "E0222228", + "tagged" : [ "owesMoney", "friends" ] + }, { + "name" : "Carl Kurz", + "phone" : "95352563", + "email" : "carl@example.com", + "faculty": "FASS", + "studentId": "E0111112", + "tagged" : [ ] + }, { + "name" : "Daniel Meier", + "phone" : "87652533", + "email" : "daniel@example.com", + "faculty": "FASS", + "studentId": "E0111113", + "tagged" : [ "friends" ] + }, { + "name" : "Elle Meyer", + "phone" : "9482224", + "email" : "elle@example.com", + "faculty": "FASS", + "studentId": "E0111114", + "tagged" : [ ] + }, { + "name" : "Fiona Kunz", + "phone" : "9482427", + "email" : "fiona@example.com", + "faculty": "FASS", + "studentId": "E0111115", + "tagged" : [ ] + }, { + "name" : "George Best", + "phone" : "9482442", + "email" : "george@example.com", + "faculty": "FASS", + "studentId": "E0111101", + "tagged" : [ ] + } ] +} diff --git a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java deleted file mode 100644 index cb8714bb055..00000000000 --- a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package seedu.address.logic.commands; - -import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.UserPrefs; -import seedu.address.model.person.Person; -import seedu.address.testutil.PersonBuilder; - -/** - * Contains integration tests (interaction with the Model) for {@code AddCommand}. - */ -public class AddCommandIntegrationTest { - - private Model model; - - @BeforeEach - public void setUp() { - model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); - } - - @Test - public void execute_newPerson_success() { - Person validPerson = new PersonBuilder().build(); - - Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); - expectedModel.addPerson(validPerson); - - assertCommandSuccess(new AddCommand(validPerson), model, - String.format(AddCommand.MESSAGE_SUCCESS, validPerson), expectedModel); - } - - @Test - public void execute_duplicatePerson_throwsCommandException() { - Person personInList = model.getAddressBook().getPersonList().get(0); - assertCommandFailure(new AddCommand(personInList), model, AddCommand.MESSAGE_DUPLICATE_PERSON); - } - -} diff --git a/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java b/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java deleted file mode 100644 index e0288792e72..00000000000 --- a/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package seedu.address.logic.commands; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.logic.commands.CommandTestUtil.DESC_AMY; -import static seedu.address.logic.commands.CommandTestUtil.DESC_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; - -import org.junit.jupiter.api.Test; - -import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; -import seedu.address.testutil.EditPersonDescriptorBuilder; - -public class EditPersonDescriptorTest { - - @Test - public void equals() { - // same values -> returns true - EditPersonDescriptor descriptorWithSameValues = new EditPersonDescriptor(DESC_AMY); - assertTrue(DESC_AMY.equals(descriptorWithSameValues)); - - // same object -> returns true - assertTrue(DESC_AMY.equals(DESC_AMY)); - - // null -> returns false - assertFalse(DESC_AMY.equals(null)); - - // different types -> returns false - assertFalse(DESC_AMY.equals(5)); - - // different values -> returns false - assertFalse(DESC_AMY.equals(DESC_BOB)); - - // different name -> returns false - EditPersonDescriptor editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withName(VALID_NAME_BOB).build(); - assertFalse(DESC_AMY.equals(editedAmy)); - - // different phone -> returns false - editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withPhone(VALID_PHONE_BOB).build(); - assertFalse(DESC_AMY.equals(editedAmy)); - - // different email -> returns false - editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withEmail(VALID_EMAIL_BOB).build(); - assertFalse(DESC_AMY.equals(editedAmy)); - - // different address -> returns false - editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withAddress(VALID_ADDRESS_BOB).build(); - assertFalse(DESC_AMY.equals(editedAmy)); - - // different tags -> returns false - editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withTags(VALID_TAG_HUSBAND).build(); - assertFalse(DESC_AMY.equals(editedAmy)); - } -} diff --git a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java deleted file mode 100644 index 5cf487d7ebb..00000000000 --- a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java +++ /dev/null @@ -1,141 +0,0 @@ -package seedu.address.logic.parser; - -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY; -import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_BOB; -import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY; -import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_BOB; -import static seedu.address.logic.commands.CommandTestUtil.INVALID_ADDRESS_DESC; -import static seedu.address.logic.commands.CommandTestUtil.INVALID_EMAIL_DESC; -import static seedu.address.logic.commands.CommandTestUtil.INVALID_NAME_DESC; -import static seedu.address.logic.commands.CommandTestUtil.INVALID_PHONE_DESC; -import static seedu.address.logic.commands.CommandTestUtil.INVALID_TAG_DESC; -import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY; -import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_BOB; -import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_AMY; -import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_BOB; -import static seedu.address.logic.commands.CommandTestUtil.PREAMBLE_NON_EMPTY; -import static seedu.address.logic.commands.CommandTestUtil.PREAMBLE_WHITESPACE; -import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_FRIEND; -import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_HUSBAND; -import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND; -import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; -import static seedu.address.testutil.TypicalPersons.AMY; -import static seedu.address.testutil.TypicalPersons.BOB; - -import org.junit.jupiter.api.Test; - -import seedu.address.logic.commands.AddCommand; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Person; -import seedu.address.model.person.Phone; -import seedu.address.model.tag.Tag; -import seedu.address.testutil.PersonBuilder; - -public class AddCommandParserTest { - private AddCommandParser parser = new AddCommandParser(); - - @Test - public void parse_allFieldsPresent_success() { - Person expectedPerson = new PersonBuilder(BOB).withTags(VALID_TAG_FRIEND).build(); - - // whitespace only preamble - assertParseSuccess(parser, PREAMBLE_WHITESPACE + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB - + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedPerson)); - - // multiple names - last name accepted - assertParseSuccess(parser, NAME_DESC_AMY + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB - + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedPerson)); - - // multiple phones - last phone accepted - assertParseSuccess(parser, NAME_DESC_BOB + PHONE_DESC_AMY + PHONE_DESC_BOB + EMAIL_DESC_BOB - + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedPerson)); - - // multiple emails - last email accepted - assertParseSuccess(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_AMY + EMAIL_DESC_BOB - + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedPerson)); - - // multiple addresses - last address accepted - assertParseSuccess(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_AMY - + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedPerson)); - - // multiple tags - all accepted - Person expectedPersonMultipleTags = new PersonBuilder(BOB).withTags(VALID_TAG_FRIEND, VALID_TAG_HUSBAND) - .build(); - assertParseSuccess(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB - + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, new AddCommand(expectedPersonMultipleTags)); - } - - @Test - public void parse_optionalFieldsMissing_success() { - // zero tags - Person expectedPerson = new PersonBuilder(AMY).withTags().build(); - assertParseSuccess(parser, NAME_DESC_AMY + PHONE_DESC_AMY + EMAIL_DESC_AMY + ADDRESS_DESC_AMY, - new AddCommand(expectedPerson)); - } - - @Test - public void parse_compulsoryFieldMissing_failure() { - String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE); - - // missing name prefix - assertParseFailure(parser, VALID_NAME_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB, - expectedMessage); - - // missing phone prefix - assertParseFailure(parser, NAME_DESC_BOB + VALID_PHONE_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB, - expectedMessage); - - // missing email prefix - assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + VALID_EMAIL_BOB + ADDRESS_DESC_BOB, - expectedMessage); - - // missing address prefix - assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + VALID_ADDRESS_BOB, - expectedMessage); - - // all prefixes missing - assertParseFailure(parser, VALID_NAME_BOB + VALID_PHONE_BOB + VALID_EMAIL_BOB + VALID_ADDRESS_BOB, - expectedMessage); - } - - @Test - public void parse_invalidValue_failure() { - // invalid name - assertParseFailure(parser, INVALID_NAME_DESC + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB - + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Name.MESSAGE_CONSTRAINTS); - - // invalid phone - assertParseFailure(parser, NAME_DESC_BOB + INVALID_PHONE_DESC + EMAIL_DESC_BOB + ADDRESS_DESC_BOB - + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Phone.MESSAGE_CONSTRAINTS); - - // invalid email - assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + INVALID_EMAIL_DESC + ADDRESS_DESC_BOB - + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Email.MESSAGE_CONSTRAINTS); - - // invalid address - assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + INVALID_ADDRESS_DESC - + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Address.MESSAGE_CONSTRAINTS); - - // invalid tag - assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB - + INVALID_TAG_DESC + VALID_TAG_FRIEND, Tag.MESSAGE_CONSTRAINTS); - - // two invalid values, only first invalid value reported - assertParseFailure(parser, INVALID_NAME_DESC + PHONE_DESC_BOB + EMAIL_DESC_BOB + INVALID_ADDRESS_DESC, - Name.MESSAGE_CONSTRAINTS); - - // non-empty preamble - assertParseFailure(parser, PREAMBLE_NON_EMPTY + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB - + ADDRESS_DESC_BOB + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, - String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE)); - } -} diff --git a/src/test/java/seedu/address/model/AddressBookTest.java b/src/test/java/seedu/address/model/AddressBookTest.java deleted file mode 100644 index 87782528ecd..00000000000 --- a/src/test/java/seedu/address/model/AddressBookTest.java +++ /dev/null @@ -1,102 +0,0 @@ -package seedu.address.model; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; -import static seedu.address.testutil.Assert.assertThrows; -import static seedu.address.testutil.TypicalPersons.ALICE; -import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.junit.jupiter.api.Test; - -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import seedu.address.model.person.Person; -import seedu.address.model.person.exceptions.DuplicatePersonException; -import seedu.address.testutil.PersonBuilder; - -public class AddressBookTest { - - private final AddressBook addressBook = new AddressBook(); - - @Test - public void constructor() { - assertEquals(Collections.emptyList(), addressBook.getPersonList()); - } - - @Test - public void resetData_null_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> addressBook.resetData(null)); - } - - @Test - public void resetData_withValidReadOnlyAddressBook_replacesData() { - AddressBook newData = getTypicalAddressBook(); - addressBook.resetData(newData); - assertEquals(newData, addressBook); - } - - @Test - public void resetData_withDuplicatePersons_throwsDuplicatePersonException() { - // Two persons with the same identity fields - Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND) - .build(); - List newPersons = Arrays.asList(ALICE, editedAlice); - AddressBookStub newData = new AddressBookStub(newPersons); - - assertThrows(DuplicatePersonException.class, () -> addressBook.resetData(newData)); - } - - @Test - public void hasPerson_nullPerson_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> addressBook.hasPerson(null)); - } - - @Test - public void hasPerson_personNotInAddressBook_returnsFalse() { - assertFalse(addressBook.hasPerson(ALICE)); - } - - @Test - public void hasPerson_personInAddressBook_returnsTrue() { - addressBook.addPerson(ALICE); - assertTrue(addressBook.hasPerson(ALICE)); - } - - @Test - public void hasPerson_personWithSameIdentityFieldsInAddressBook_returnsTrue() { - addressBook.addPerson(ALICE); - Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND) - .build(); - assertTrue(addressBook.hasPerson(editedAlice)); - } - - @Test - public void getPersonList_modifyList_throwsUnsupportedOperationException() { - assertThrows(UnsupportedOperationException.class, () -> addressBook.getPersonList().remove(0)); - } - - /** - * A stub ReadOnlyAddressBook whose persons list can violate interface constraints. - */ - private static class AddressBookStub implements ReadOnlyAddressBook { - private final ObservableList persons = FXCollections.observableArrayList(); - - AddressBookStub(Collection persons) { - this.persons.setAll(persons); - } - - @Override - public ObservableList getPersonList() { - return persons; - } - } - -} diff --git a/src/test/java/seedu/address/model/person/AddressTest.java b/src/test/java/seedu/address/model/person/AddressTest.java deleted file mode 100644 index dcd3be87b3a..00000000000 --- a/src/test/java/seedu/address/model/person/AddressTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package seedu.address.model.person; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.testutil.Assert.assertThrows; - -import org.junit.jupiter.api.Test; - -public class AddressTest { - - @Test - public void constructor_null_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> new Address(null)); - } - - @Test - public void constructor_invalidAddress_throwsIllegalArgumentException() { - String invalidAddress = ""; - assertThrows(IllegalArgumentException.class, () -> new Address(invalidAddress)); - } - - @Test - public void isValidAddress() { - // null address - assertThrows(NullPointerException.class, () -> Address.isValidAddress(null)); - - // invalid addresses - assertFalse(Address.isValidAddress("")); // empty string - assertFalse(Address.isValidAddress(" ")); // spaces only - - // valid addresses - assertTrue(Address.isValidAddress("Blk 456, Den Road, #01-355")); - assertTrue(Address.isValidAddress("-")); // one character - assertTrue(Address.isValidAddress("Leng Inc; 1234 Market St; San Francisco CA 2349879; USA")); // long address - } -} diff --git a/src/test/java/seedu/address/model/person/PersonTest.java b/src/test/java/seedu/address/model/person/PersonTest.java deleted file mode 100644 index 7c1058d8635..00000000000 --- a/src/test/java/seedu/address/model/person/PersonTest.java +++ /dev/null @@ -1,95 +0,0 @@ -package seedu.address.model.person; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; -import static seedu.address.testutil.Assert.assertThrows; -import static seedu.address.testutil.TypicalPersons.ALICE; -import static seedu.address.testutil.TypicalPersons.BOB; - -import org.junit.jupiter.api.Test; - -import seedu.address.testutil.PersonBuilder; - -public class PersonTest { - - @Test - public void asObservableList_modifyList_throwsUnsupportedOperationException() { - Person person = new PersonBuilder().build(); - assertThrows(UnsupportedOperationException.class, () -> person.getTags().remove(0)); - } - - @Test - public void isSamePerson() { - // same object -> returns true - assertTrue(ALICE.isSamePerson(ALICE)); - - // null -> returns false - assertFalse(ALICE.isSamePerson(null)); - - // different phone and email -> returns false - Person editedAlice = new PersonBuilder(ALICE).withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB).build(); - assertFalse(ALICE.isSamePerson(editedAlice)); - - // different name -> returns false - editedAlice = new PersonBuilder(ALICE).withName(VALID_NAME_BOB).build(); - assertFalse(ALICE.isSamePerson(editedAlice)); - - // same name, same phone, different attributes -> returns true - editedAlice = new PersonBuilder(ALICE).withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB) - .withTags(VALID_TAG_HUSBAND).build(); - assertTrue(ALICE.isSamePerson(editedAlice)); - - // same name, same email, different attributes -> returns true - editedAlice = new PersonBuilder(ALICE).withPhone(VALID_PHONE_BOB).withAddress(VALID_ADDRESS_BOB) - .withTags(VALID_TAG_HUSBAND).build(); - assertTrue(ALICE.isSamePerson(editedAlice)); - - // same name, same phone, same email, different attributes -> returns true - editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND).build(); - assertTrue(ALICE.isSamePerson(editedAlice)); - } - - @Test - public void equals() { - // same values -> returns true - Person aliceCopy = new PersonBuilder(ALICE).build(); - assertTrue(ALICE.equals(aliceCopy)); - - // same object -> returns true - assertTrue(ALICE.equals(ALICE)); - - // null -> returns false - assertFalse(ALICE.equals(null)); - - // different type -> returns false - assertFalse(ALICE.equals(5)); - - // different person -> returns false - assertFalse(ALICE.equals(BOB)); - - // different name -> returns false - Person editedAlice = new PersonBuilder(ALICE).withName(VALID_NAME_BOB).build(); - assertFalse(ALICE.equals(editedAlice)); - - // different phone -> returns false - editedAlice = new PersonBuilder(ALICE).withPhone(VALID_PHONE_BOB).build(); - assertFalse(ALICE.equals(editedAlice)); - - // different email -> returns false - editedAlice = new PersonBuilder(ALICE).withEmail(VALID_EMAIL_BOB).build(); - assertFalse(ALICE.equals(editedAlice)); - - // different address -> returns false - editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).build(); - assertFalse(ALICE.equals(editedAlice)); - - // different tags -> returns false - editedAlice = new PersonBuilder(ALICE).withTags(VALID_TAG_HUSBAND).build(); - assertFalse(ALICE.equals(editedAlice)); - } -} diff --git a/src/test/java/seedu/address/model/person/UniquePersonListTest.java b/src/test/java/seedu/address/model/person/UniquePersonListTest.java deleted file mode 100644 index 1cc5fe9e0fe..00000000000 --- a/src/test/java/seedu/address/model/person/UniquePersonListTest.java +++ /dev/null @@ -1,170 +0,0 @@ -package seedu.address.model.person; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; -import static seedu.address.testutil.Assert.assertThrows; -import static seedu.address.testutil.TypicalPersons.ALICE; -import static seedu.address.testutil.TypicalPersons.BOB; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.junit.jupiter.api.Test; - -import seedu.address.model.person.exceptions.DuplicatePersonException; -import seedu.address.model.person.exceptions.PersonNotFoundException; -import seedu.address.testutil.PersonBuilder; - -public class UniquePersonListTest { - - private final UniquePersonList uniquePersonList = new UniquePersonList(); - - @Test - public void contains_nullPerson_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> uniquePersonList.contains(null)); - } - - @Test - public void contains_personNotInList_returnsFalse() { - assertFalse(uniquePersonList.contains(ALICE)); - } - - @Test - public void contains_personInList_returnsTrue() { - uniquePersonList.add(ALICE); - assertTrue(uniquePersonList.contains(ALICE)); - } - - @Test - public void contains_personWithSameIdentityFieldsInList_returnsTrue() { - uniquePersonList.add(ALICE); - Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND) - .build(); - assertTrue(uniquePersonList.contains(editedAlice)); - } - - @Test - public void add_nullPerson_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> uniquePersonList.add(null)); - } - - @Test - public void add_duplicatePerson_throwsDuplicatePersonException() { - uniquePersonList.add(ALICE); - assertThrows(DuplicatePersonException.class, () -> uniquePersonList.add(ALICE)); - } - - @Test - public void setPerson_nullTargetPerson_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> uniquePersonList.setPerson(null, ALICE)); - } - - @Test - public void setPerson_nullEditedPerson_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> uniquePersonList.setPerson(ALICE, null)); - } - - @Test - public void setPerson_targetPersonNotInList_throwsPersonNotFoundException() { - assertThrows(PersonNotFoundException.class, () -> uniquePersonList.setPerson(ALICE, ALICE)); - } - - @Test - public void setPerson_editedPersonIsSamePerson_success() { - uniquePersonList.add(ALICE); - uniquePersonList.setPerson(ALICE, ALICE); - UniquePersonList expectedUniquePersonList = new UniquePersonList(); - expectedUniquePersonList.add(ALICE); - assertEquals(expectedUniquePersonList, uniquePersonList); - } - - @Test - public void setPerson_editedPersonHasSameIdentity_success() { - uniquePersonList.add(ALICE); - Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND) - .build(); - uniquePersonList.setPerson(ALICE, editedAlice); - UniquePersonList expectedUniquePersonList = new UniquePersonList(); - expectedUniquePersonList.add(editedAlice); - assertEquals(expectedUniquePersonList, uniquePersonList); - } - - @Test - public void setPerson_editedPersonHasDifferentIdentity_success() { - uniquePersonList.add(ALICE); - uniquePersonList.setPerson(ALICE, BOB); - UniquePersonList expectedUniquePersonList = new UniquePersonList(); - expectedUniquePersonList.add(BOB); - assertEquals(expectedUniquePersonList, uniquePersonList); - } - - @Test - public void setPerson_editedPersonHasNonUniqueIdentity_throwsDuplicatePersonException() { - uniquePersonList.add(ALICE); - uniquePersonList.add(BOB); - assertThrows(DuplicatePersonException.class, () -> uniquePersonList.setPerson(ALICE, BOB)); - } - - @Test - public void remove_nullPerson_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> uniquePersonList.remove(null)); - } - - @Test - public void remove_personDoesNotExist_throwsPersonNotFoundException() { - assertThrows(PersonNotFoundException.class, () -> uniquePersonList.remove(ALICE)); - } - - @Test - public void remove_existingPerson_removesPerson() { - uniquePersonList.add(ALICE); - uniquePersonList.remove(ALICE); - UniquePersonList expectedUniquePersonList = new UniquePersonList(); - assertEquals(expectedUniquePersonList, uniquePersonList); - } - - @Test - public void setPersons_nullUniquePersonList_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> uniquePersonList.setPersons((UniquePersonList) null)); - } - - @Test - public void setPersons_uniquePersonList_replacesOwnListWithProvidedUniquePersonList() { - uniquePersonList.add(ALICE); - UniquePersonList expectedUniquePersonList = new UniquePersonList(); - expectedUniquePersonList.add(BOB); - uniquePersonList.setPersons(expectedUniquePersonList); - assertEquals(expectedUniquePersonList, uniquePersonList); - } - - @Test - public void setPersons_nullList_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> uniquePersonList.setPersons((List) null)); - } - - @Test - public void setPersons_list_replacesOwnListWithProvidedList() { - uniquePersonList.add(ALICE); - List personList = Collections.singletonList(BOB); - uniquePersonList.setPersons(personList); - UniquePersonList expectedUniquePersonList = new UniquePersonList(); - expectedUniquePersonList.add(BOB); - assertEquals(expectedUniquePersonList, uniquePersonList); - } - - @Test - public void setPersons_listWithDuplicatePersons_throwsDuplicatePersonException() { - List listWithDuplicatePersons = Arrays.asList(ALICE, ALICE); - assertThrows(DuplicatePersonException.class, () -> uniquePersonList.setPersons(listWithDuplicatePersons)); - } - - @Test - public void asUnmodifiableObservableList_modifyList_throwsUnsupportedOperationException() { - assertThrows(UnsupportedOperationException.class, () - -> uniquePersonList.asUnmodifiableObservableList().remove(0)); - } -} diff --git a/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java b/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java deleted file mode 100644 index 83b11331cdb..00000000000 --- a/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java +++ /dev/null @@ -1,110 +0,0 @@ -package seedu.address.storage; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static seedu.address.storage.JsonAdaptedPerson.MISSING_FIELD_MESSAGE_FORMAT; -import static seedu.address.testutil.Assert.assertThrows; -import static seedu.address.testutil.TypicalPersons.BENSON; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.Test; - -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Phone; - -public class JsonAdaptedPersonTest { - private static final String INVALID_NAME = "R@chel"; - private static final String INVALID_PHONE = "+651234"; - private static final String INVALID_ADDRESS = " "; - private static final String INVALID_EMAIL = "example.com"; - private static final String INVALID_TAG = "#friend"; - - private static final String VALID_NAME = BENSON.getName().toString(); - private static final String VALID_PHONE = BENSON.getPhone().toString(); - private static final String VALID_EMAIL = BENSON.getEmail().toString(); - private static final String VALID_ADDRESS = BENSON.getAddress().toString(); - private static final List VALID_TAGS = BENSON.getTags().stream() - .map(JsonAdaptedTag::new) - .collect(Collectors.toList()); - - @Test - public void toModelType_validPersonDetails_returnsPerson() throws Exception { - JsonAdaptedPerson person = new JsonAdaptedPerson(BENSON); - assertEquals(BENSON, person.toModelType()); - } - - @Test - public void toModelType_invalidName_throwsIllegalValueException() { - JsonAdaptedPerson person = - new JsonAdaptedPerson(INVALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); - String expectedMessage = Name.MESSAGE_CONSTRAINTS; - assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); - } - - @Test - public void toModelType_nullName_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(null, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); - String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName()); - assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); - } - - @Test - public void toModelType_invalidPhone_throwsIllegalValueException() { - JsonAdaptedPerson person = - new JsonAdaptedPerson(VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); - String expectedMessage = Phone.MESSAGE_CONSTRAINTS; - assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); - } - - @Test - public void toModelType_nullPhone_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, null, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); - String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName()); - assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); - } - - @Test - public void toModelType_invalidEmail_throwsIllegalValueException() { - JsonAdaptedPerson person = - new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, INVALID_EMAIL, VALID_ADDRESS, VALID_TAGS); - String expectedMessage = Email.MESSAGE_CONSTRAINTS; - assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); - } - - @Test - public void toModelType_nullEmail_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, null, VALID_ADDRESS, VALID_TAGS); - String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Email.class.getSimpleName()); - assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); - } - - @Test - public void toModelType_invalidAddress_throwsIllegalValueException() { - JsonAdaptedPerson person = - new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, INVALID_ADDRESS, VALID_TAGS); - String expectedMessage = Address.MESSAGE_CONSTRAINTS; - assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); - } - - @Test - public void toModelType_nullAddress_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, null, VALID_TAGS); - String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Address.class.getSimpleName()); - assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); - } - - @Test - public void toModelType_invalidTags_throwsIllegalValueException() { - List invalidTags = new ArrayList<>(VALID_TAGS); - invalidTags.add(new JsonAdaptedTag(INVALID_TAG)); - JsonAdaptedPerson person = - new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, invalidTags); - assertThrows(IllegalValueException.class, person::toModelType); - } - -} diff --git a/src/test/java/seedu/address/testutil/EditPersonDescriptorBuilder.java b/src/test/java/seedu/address/testutil/EditPersonDescriptorBuilder.java deleted file mode 100644 index 4584bd5044e..00000000000 --- a/src/test/java/seedu/address/testutil/EditPersonDescriptorBuilder.java +++ /dev/null @@ -1,87 +0,0 @@ -package seedu.address.testutil; - -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Person; -import seedu.address.model.person.Phone; -import seedu.address.model.tag.Tag; - -/** - * A utility class to help with building EditPersonDescriptor objects. - */ -public class EditPersonDescriptorBuilder { - - private EditPersonDescriptor descriptor; - - public EditPersonDescriptorBuilder() { - descriptor = new EditPersonDescriptor(); - } - - public EditPersonDescriptorBuilder(EditPersonDescriptor descriptor) { - this.descriptor = new EditPersonDescriptor(descriptor); - } - - /** - * Returns an {@code EditPersonDescriptor} with fields containing {@code person}'s details - */ - public EditPersonDescriptorBuilder(Person person) { - descriptor = new EditPersonDescriptor(); - descriptor.setName(person.getName()); - descriptor.setPhone(person.getPhone()); - descriptor.setEmail(person.getEmail()); - descriptor.setAddress(person.getAddress()); - descriptor.setTags(person.getTags()); - } - - /** - * Sets the {@code Name} of the {@code EditPersonDescriptor} that we are building. - */ - public EditPersonDescriptorBuilder withName(String name) { - descriptor.setName(new Name(name)); - return this; - } - - /** - * Sets the {@code Phone} of the {@code EditPersonDescriptor} that we are building. - */ - public EditPersonDescriptorBuilder withPhone(String phone) { - descriptor.setPhone(new Phone(phone)); - return this; - } - - /** - * Sets the {@code Email} of the {@code EditPersonDescriptor} that we are building. - */ - public EditPersonDescriptorBuilder withEmail(String email) { - descriptor.setEmail(new Email(email)); - return this; - } - - /** - * Sets the {@code Address} of the {@code EditPersonDescriptor} that we are building. - */ - public EditPersonDescriptorBuilder withAddress(String address) { - descriptor.setAddress(new Address(address)); - return this; - } - - /** - * Parses the {@code tags} into a {@code Set} and set it to the {@code EditPersonDescriptor} - * that we are building. - */ - public EditPersonDescriptorBuilder withTags(String... tags) { - Set tagSet = Stream.of(tags).map(Tag::new).collect(Collectors.toSet()); - descriptor.setTags(tagSet); - return this; - } - - public EditPersonDescriptor build() { - return descriptor; - } -} diff --git a/src/test/java/seedu/address/testutil/PersonBuilder.java b/src/test/java/seedu/address/testutil/PersonBuilder.java deleted file mode 100644 index efe744cd12c..00000000000 --- a/src/test/java/seedu/address/testutil/PersonBuilder.java +++ /dev/null @@ -1,96 +0,0 @@ -package seedu.address.testutil; - -import java.util.HashSet; -import java.util.Set; - -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Person; -import seedu.address.model.person.Phone; -import seedu.address.model.tag.Tag; -import seedu.address.model.util.SampleDataUtil; - -/** - * A utility class to help with building Person objects. - */ -public class PersonBuilder { - - public static final String DEFAULT_NAME = "Alice Pauline"; - public static final String DEFAULT_PHONE = "85355255"; - public static final String DEFAULT_EMAIL = "alice@gmail.com"; - public static final String DEFAULT_ADDRESS = "123, Jurong West Ave 6, #08-111"; - - private Name name; - private Phone phone; - private Email email; - private Address address; - private Set tags; - - /** - * Creates a {@code PersonBuilder} with the default details. - */ - public PersonBuilder() { - name = new Name(DEFAULT_NAME); - phone = new Phone(DEFAULT_PHONE); - email = new Email(DEFAULT_EMAIL); - address = new Address(DEFAULT_ADDRESS); - tags = new HashSet<>(); - } - - /** - * Initializes the PersonBuilder with the data of {@code personToCopy}. - */ - public PersonBuilder(Person personToCopy) { - name = personToCopy.getName(); - phone = personToCopy.getPhone(); - email = personToCopy.getEmail(); - address = personToCopy.getAddress(); - tags = new HashSet<>(personToCopy.getTags()); - } - - /** - * Sets the {@code Name} of the {@code Person} that we are building. - */ - public PersonBuilder withName(String name) { - this.name = new Name(name); - return this; - } - - /** - * Parses the {@code tags} into a {@code Set} and set it to the {@code Person} that we are building. - */ - public PersonBuilder withTags(String ... tags) { - this.tags = SampleDataUtil.getTagSet(tags); - return this; - } - - /** - * Sets the {@code Address} of the {@code Person} that we are building. - */ - public PersonBuilder withAddress(String address) { - this.address = new Address(address); - return this; - } - - /** - * Sets the {@code Phone} of the {@code Person} that we are building. - */ - public PersonBuilder withPhone(String phone) { - this.phone = new Phone(phone); - return this; - } - - /** - * Sets the {@code Email} of the {@code Person} that we are building. - */ - public PersonBuilder withEmail(String email) { - this.email = new Email(email); - return this; - } - - public Person build() { - return new Person(name, phone, email, address, tags); - } - -} diff --git a/src/test/java/seedu/address/testutil/PersonUtil.java b/src/test/java/seedu/address/testutil/PersonUtil.java deleted file mode 100644 index 90849945183..00000000000 --- a/src/test/java/seedu/address/testutil/PersonUtil.java +++ /dev/null @@ -1,62 +0,0 @@ -package seedu.address.testutil; - -import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; -import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; -import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; -import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; -import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; - -import java.util.Set; - -import seedu.address.logic.commands.AddCommand; -import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; -import seedu.address.model.person.Person; -import seedu.address.model.tag.Tag; - -/** - * A utility class for Person. - */ -public class PersonUtil { - - /** - * Returns an add command string for adding the {@code person}. - */ - public static String getAddCommand(Person person) { - return AddCommand.COMMAND_WORD + " " + getPersonDetails(person); - } - - /** - * Returns the part of command string for the given {@code person}'s details. - */ - public static String getPersonDetails(Person person) { - StringBuilder sb = new StringBuilder(); - sb.append(PREFIX_NAME + person.getName().fullName + " "); - sb.append(PREFIX_PHONE + person.getPhone().value + " "); - sb.append(PREFIX_EMAIL + person.getEmail().value + " "); - sb.append(PREFIX_ADDRESS + person.getAddress().value + " "); - person.getTags().stream().forEach( - s -> sb.append(PREFIX_TAG + s.tagName + " ") - ); - return sb.toString(); - } - - /** - * Returns the part of command string for the given {@code EditPersonDescriptor}'s details. - */ - public static String getEditPersonDescriptorDetails(EditPersonDescriptor descriptor) { - StringBuilder sb = new StringBuilder(); - descriptor.getName().ifPresent(name -> sb.append(PREFIX_NAME).append(name.fullName).append(" ")); - descriptor.getPhone().ifPresent(phone -> sb.append(PREFIX_PHONE).append(phone.value).append(" ")); - descriptor.getEmail().ifPresent(email -> sb.append(PREFIX_EMAIL).append(email.value).append(" ")); - descriptor.getAddress().ifPresent(address -> sb.append(PREFIX_ADDRESS).append(address.value).append(" ")); - if (descriptor.getTags().isPresent()) { - Set tags = descriptor.getTags().get(); - if (tags.isEmpty()) { - sb.append(PREFIX_TAG); - } else { - tags.forEach(s -> sb.append(PREFIX_TAG).append(s.tagName).append(" ")); - } - } - return sb.toString(); - } -} diff --git a/src/test/java/seedu/address/testutil/TypicalPersons.java b/src/test/java/seedu/address/testutil/TypicalPersons.java deleted file mode 100644 index fec76fb7129..00000000000 --- a/src/test/java/seedu/address/testutil/TypicalPersons.java +++ /dev/null @@ -1,76 +0,0 @@ -package seedu.address.testutil; - -import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_AMY; -import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY; -import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_AMY; -import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_AMY; -import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND; -import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import seedu.address.model.AddressBook; -import seedu.address.model.person.Person; - -/** - * A utility class containing a list of {@code Person} objects to be used in tests. - */ -public class TypicalPersons { - - public static final Person ALICE = new PersonBuilder().withName("Alice Pauline") - .withAddress("123, Jurong West Ave 6, #08-111").withEmail("alice@example.com") - .withPhone("94351253") - .withTags("friends").build(); - public static final Person BENSON = new PersonBuilder().withName("Benson Meier") - .withAddress("311, Clementi Ave 2, #02-25") - .withEmail("johnd@example.com").withPhone("98765432") - .withTags("owesMoney", "friends").build(); - public static final Person CARL = new PersonBuilder().withName("Carl Kurz").withPhone("95352563") - .withEmail("heinz@example.com").withAddress("wall street").build(); - public static final Person DANIEL = new PersonBuilder().withName("Daniel Meier").withPhone("87652533") - .withEmail("cornelia@example.com").withAddress("10th street").withTags("friends").build(); - public static final Person ELLE = new PersonBuilder().withName("Elle Meyer").withPhone("9482224") - .withEmail("werner@example.com").withAddress("michegan ave").build(); - public static final Person FIONA = new PersonBuilder().withName("Fiona Kunz").withPhone("9482427") - .withEmail("lydia@example.com").withAddress("little tokyo").build(); - public static final Person GEORGE = new PersonBuilder().withName("George Best").withPhone("9482442") - .withEmail("anna@example.com").withAddress("4th street").build(); - - // Manually added - public static final Person HOON = new PersonBuilder().withName("Hoon Meier").withPhone("8482424") - .withEmail("stefan@example.com").withAddress("little india").build(); - public static final Person IDA = new PersonBuilder().withName("Ida Mueller").withPhone("8482131") - .withEmail("hans@example.com").withAddress("chicago ave").build(); - - // Manually added - Person's details found in {@code CommandTestUtil} - public static final Person AMY = new PersonBuilder().withName(VALID_NAME_AMY).withPhone(VALID_PHONE_AMY) - .withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY).withTags(VALID_TAG_FRIEND).build(); - public static final Person BOB = new PersonBuilder().withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB) - .withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND) - .build(); - - public static final String KEYWORD_MATCHING_MEIER = "Meier"; // A keyword that matches MEIER - - private TypicalPersons() {} // prevents instantiation - - /** - * Returns an {@code AddressBook} with all the typical persons. - */ - public static AddressBook getTypicalAddressBook() { - AddressBook ab = new AddressBook(); - for (Person person : getTypicalPersons()) { - ab.addPerson(person); - } - return ab; - } - - public static List getTypicalPersons() { - return new ArrayList<>(Arrays.asList(ALICE, BENSON, CARL, DANIEL, ELLE, FIONA, GEORGE)); - } -} diff --git a/src/test/java/seedu/address/AppParametersTest.java b/src/test/java/seedu/resireg/AppParametersTest.java similarity index 98% rename from src/test/java/seedu/address/AppParametersTest.java rename to src/test/java/seedu/resireg/AppParametersTest.java index 61326b2d31a..38fb17d7044 100644 --- a/src/test/java/seedu/address/AppParametersTest.java +++ b/src/test/java/seedu/resireg/AppParametersTest.java @@ -1,4 +1,4 @@ -package seedu.address; +package seedu.resireg; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/seedu/address/commons/core/ConfigTest.java b/src/test/java/seedu/resireg/commons/core/ConfigTest.java similarity index 95% rename from src/test/java/seedu/address/commons/core/ConfigTest.java rename to src/test/java/seedu/resireg/commons/core/ConfigTest.java index 07cd7f73d53..41506ad74e7 100644 --- a/src/test/java/seedu/address/commons/core/ConfigTest.java +++ b/src/test/java/seedu/resireg/commons/core/ConfigTest.java @@ -1,4 +1,4 @@ -package seedu.address.commons.core; +package seedu.resireg.commons.core; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/src/test/java/seedu/address/commons/core/VersionTest.java b/src/test/java/seedu/resireg/commons/core/VersionTest.java similarity index 98% rename from src/test/java/seedu/address/commons/core/VersionTest.java rename to src/test/java/seedu/resireg/commons/core/VersionTest.java index 495cd231554..1c6bcc08a69 100644 --- a/src/test/java/seedu/address/commons/core/VersionTest.java +++ b/src/test/java/seedu/resireg/commons/core/VersionTest.java @@ -1,8 +1,8 @@ -package seedu.address.commons.core; +package seedu.resireg.commons.core; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/address/commons/core/index/IndexTest.java b/src/test/java/seedu/resireg/commons/core/index/IndexTest.java similarity index 74% rename from src/test/java/seedu/address/commons/core/index/IndexTest.java rename to src/test/java/seedu/resireg/commons/core/index/IndexTest.java index a3ec6f8e747..de099f386f5 100644 --- a/src/test/java/seedu/address/commons/core/index/IndexTest.java +++ b/src/test/java/seedu/resireg/commons/core/index/IndexTest.java @@ -1,9 +1,9 @@ -package seedu.address.commons.core.index; +package seedu.resireg.commons.core.index; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import org.junit.jupiter.api.Test; @@ -39,22 +39,22 @@ public void createZeroBasedIndex() { @Test public void equals() { - final Index fifthPersonIndex = Index.fromOneBased(5); + final Index fifthStudentIndex = Index.fromOneBased(5); // same values -> returns true - assertTrue(fifthPersonIndex.equals(Index.fromOneBased(5))); - assertTrue(fifthPersonIndex.equals(Index.fromZeroBased(4))); + assertTrue(fifthStudentIndex.equals(Index.fromOneBased(5))); + assertTrue(fifthStudentIndex.equals(Index.fromZeroBased(4))); // same object -> returns true - assertTrue(fifthPersonIndex.equals(fifthPersonIndex)); + assertTrue(fifthStudentIndex.equals(fifthStudentIndex)); // null -> returns false - assertFalse(fifthPersonIndex.equals(null)); + assertFalse(fifthStudentIndex.equals(null)); // different types -> returns false - assertFalse(fifthPersonIndex.equals(5.0f)); + assertFalse(fifthStudentIndex.equals(5.0f)); // different index -> returns false - assertFalse(fifthPersonIndex.equals(Index.fromOneBased(1))); + assertFalse(fifthStudentIndex.equals(Index.fromOneBased(1))); } } diff --git a/src/test/java/seedu/address/commons/util/AppUtilTest.java b/src/test/java/seedu/resireg/commons/util/AppUtilTest.java similarity index 91% rename from src/test/java/seedu/address/commons/util/AppUtilTest.java rename to src/test/java/seedu/resireg/commons/util/AppUtilTest.java index 594de1e6365..64bfbf585a7 100644 --- a/src/test/java/seedu/address/commons/util/AppUtilTest.java +++ b/src/test/java/seedu/resireg/commons/util/AppUtilTest.java @@ -1,7 +1,7 @@ -package seedu.address.commons.util; +package seedu.resireg.commons.util; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/address/commons/util/CollectionUtilTest.java b/src/test/java/seedu/resireg/commons/util/CollectionUtilTest.java similarity index 96% rename from src/test/java/seedu/address/commons/util/CollectionUtilTest.java rename to src/test/java/seedu/resireg/commons/util/CollectionUtilTest.java index b467a3dc025..28bfdfe6de8 100644 --- a/src/test/java/seedu/address/commons/util/CollectionUtilTest.java +++ b/src/test/java/seedu/resireg/commons/util/CollectionUtilTest.java @@ -1,9 +1,9 @@ -package seedu.address.commons.util; +package seedu.resireg.commons.util; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.commons.util.CollectionUtil.requireAllNonNull; +import static seedu.resireg.testutil.Assert.assertThrows; import java.util.Arrays; import java.util.Collection; diff --git a/src/test/java/seedu/address/commons/util/ConfigUtilTest.java b/src/test/java/seedu/resireg/commons/util/ConfigUtilTest.java similarity index 94% rename from src/test/java/seedu/address/commons/util/ConfigUtilTest.java rename to src/test/java/seedu/resireg/commons/util/ConfigUtilTest.java index d2ab2839a52..0699992597b 100644 --- a/src/test/java/seedu/address/commons/util/ConfigUtilTest.java +++ b/src/test/java/seedu/resireg/commons/util/ConfigUtilTest.java @@ -1,8 +1,8 @@ -package seedu.address.commons.util; +package seedu.resireg.commons.util; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import java.io.IOException; import java.nio.file.Path; @@ -13,8 +13,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import seedu.address.commons.core.Config; -import seedu.address.commons.exceptions.DataConversionException; +import seedu.resireg.commons.core.Config; +import seedu.resireg.commons.exceptions.DataConversionException; public class ConfigUtilTest { diff --git a/src/test/java/seedu/address/commons/util/FileUtilTest.java b/src/test/java/seedu/resireg/commons/util/FileUtilTest.java similarity index 84% rename from src/test/java/seedu/address/commons/util/FileUtilTest.java rename to src/test/java/seedu/resireg/commons/util/FileUtilTest.java index 1fe5478c756..90767e9239f 100644 --- a/src/test/java/seedu/address/commons/util/FileUtilTest.java +++ b/src/test/java/seedu/resireg/commons/util/FileUtilTest.java @@ -1,8 +1,8 @@ -package seedu.address.commons.util; +package seedu.resireg.commons.util; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/address/commons/util/JsonUtilTest.java b/src/test/java/seedu/resireg/commons/util/JsonUtilTest.java similarity index 92% rename from src/test/java/seedu/address/commons/util/JsonUtilTest.java rename to src/test/java/seedu/resireg/commons/util/JsonUtilTest.java index d4907539dee..3732f11e8ac 100644 --- a/src/test/java/seedu/address/commons/util/JsonUtilTest.java +++ b/src/test/java/seedu/resireg/commons/util/JsonUtilTest.java @@ -1,4 +1,4 @@ -package seedu.address.commons.util; +package seedu.resireg.commons.util; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -7,8 +7,8 @@ import org.junit.jupiter.api.Test; -import seedu.address.testutil.SerializableTestClass; -import seedu.address.testutil.TestUtil; +import seedu.resireg.testutil.SerializableTestClass; +import seedu.resireg.testutil.TestUtil; /** * Tests JSON Read and Write diff --git a/src/test/java/seedu/address/commons/util/StringUtilTest.java b/src/test/java/seedu/resireg/commons/util/StringUtilTest.java similarity index 98% rename from src/test/java/seedu/address/commons/util/StringUtilTest.java rename to src/test/java/seedu/resireg/commons/util/StringUtilTest.java index c56d407bf3f..675b50ea74d 100644 --- a/src/test/java/seedu/address/commons/util/StringUtilTest.java +++ b/src/test/java/seedu/resireg/commons/util/StringUtilTest.java @@ -1,8 +1,8 @@ -package seedu.address.commons.util; +package seedu.resireg.commons.util; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import java.io.FileNotFoundException; diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/resireg/logic/LogicManagerTest.java similarity index 78% rename from src/test/java/seedu/address/logic/LogicManagerTest.java rename to src/test/java/seedu/resireg/logic/LogicManagerTest.java index ad923ac249a..70e90b14dd0 100644 --- a/src/test/java/seedu/address/logic/LogicManagerTest.java +++ b/src/test/java/seedu/resireg/logic/LogicManagerTest.java @@ -1,14 +1,15 @@ -package seedu.address.logic; +package seedu.resireg.logic; import static org.junit.jupiter.api.Assertions.assertEquals; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX; -import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND; -import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY; -import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY; -import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY; -import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_AMY; -import static seedu.address.testutil.Assert.assertThrows; -import static seedu.address.testutil.TypicalPersons.AMY; +import static seedu.resireg.commons.core.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX; +import static seedu.resireg.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND; +import static seedu.resireg.logic.commands.CommandTestUtil.EMAIL_DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.FACULTY_DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.NAME_DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.PHONE_DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.STUDENT_ID_DESC_AMY; +import static seedu.resireg.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.TypicalStudents.AMY; import java.io.IOException; import java.nio.file.Path; @@ -17,20 +18,20 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import seedu.address.logic.commands.AddCommand; -import seedu.address.logic.commands.CommandResult; -import seedu.address.logic.commands.ListCommand; -import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.UserPrefs; -import seedu.address.model.person.Person; -import seedu.address.storage.JsonAddressBookStorage; -import seedu.address.storage.JsonUserPrefsStorage; -import seedu.address.storage.StorageManager; -import seedu.address.testutil.PersonBuilder; +import seedu.resireg.logic.commands.AddCommand; +import seedu.resireg.logic.commands.CommandResult; +import seedu.resireg.logic.commands.ListCommand; +import seedu.resireg.logic.commands.exceptions.CommandException; +import seedu.resireg.logic.parser.exceptions.ParseException; +import seedu.resireg.model.Model; +import seedu.resireg.model.ModelManager; +import seedu.resireg.model.ReadOnlyAddressBook; +import seedu.resireg.model.UserPrefs; +import seedu.resireg.model.student.Student; +import seedu.resireg.storage.JsonAddressBookStorage; +import seedu.resireg.storage.JsonUserPrefsStorage; +import seedu.resireg.storage.StorageManager; +import seedu.resireg.testutil.StudentBuilder; public class LogicManagerTest { private static final IOException DUMMY_IO_EXCEPTION = new IOException("dummy exception"); @@ -80,17 +81,17 @@ public void execute_storageThrowsIoException_throwsCommandException() { // Execute add command String addCommand = AddCommand.COMMAND_WORD + NAME_DESC_AMY + PHONE_DESC_AMY + EMAIL_DESC_AMY - + ADDRESS_DESC_AMY; - Person expectedPerson = new PersonBuilder(AMY).withTags().build(); + + FACULTY_DESC_AMY + STUDENT_ID_DESC_AMY; + Student expectedStudent = new StudentBuilder(AMY).withTags().build(); ModelManager expectedModel = new ModelManager(); - expectedModel.addPerson(expectedPerson); + expectedModel.addStudent(expectedStudent); String expectedMessage = LogicManager.FILE_OPS_ERROR_MESSAGE + DUMMY_IO_EXCEPTION; assertCommandFailure(addCommand, CommandException.class, expectedMessage, expectedModel); } @Test - public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException() { - assertThrows(UnsupportedOperationException.class, () -> logic.getFilteredPersonList().remove(0)); + public void getFilteredStudentList_modifyList_throwsUnsupportedOperationException() { + assertThrows(UnsupportedOperationException.class, () -> logic.getFilteredStudentList().remove(0)); } /** diff --git a/src/test/java/seedu/resireg/logic/commands/AddCommandIntegrationTest.java b/src/test/java/seedu/resireg/logic/commands/AddCommandIntegrationTest.java new file mode 100644 index 00000000000..75c491e1286 --- /dev/null +++ b/src/test/java/seedu/resireg/logic/commands/AddCommandIntegrationTest.java @@ -0,0 +1,45 @@ +package seedu.resireg.logic.commands; + +import static seedu.resireg.logic.commands.CommandTestUtil.assertCommandFailure; +import static seedu.resireg.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.resireg.testutil.TypicalStudents.getTypicalAddressBook; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import seedu.resireg.model.Model; +import seedu.resireg.model.ModelManager; +import seedu.resireg.model.UserPrefs; +import seedu.resireg.model.student.Student; +import seedu.resireg.testutil.StudentBuilder; + +/** + * Contains integration tests (interaction with the Model) for {@code AddCommand}. + */ +public class AddCommandIntegrationTest { + + private Model model; + + @BeforeEach + public void setUp() { + model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + } + + @Test + public void execute_newStudent_success() { + Student validStudent = new StudentBuilder().build(); + + Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + expectedModel.addStudent(validStudent); + + assertCommandSuccess(new AddCommand(validStudent), model, + String.format(AddCommand.MESSAGE_SUCCESS, validStudent), expectedModel); + } + + @Test + public void execute_duplicateStudent_throwsCommandException() { + Student studentInList = model.getAddressBook().getStudentList().get(0); + assertCommandFailure(new AddCommand(studentInList), model, AddCommand.MESSAGE_DUPLICATE_PERSON); + } + +} diff --git a/src/test/java/seedu/address/logic/commands/AddCommandTest.java b/src/test/java/seedu/resireg/logic/commands/AddCommandTest.java similarity index 58% rename from src/test/java/seedu/address/logic/commands/AddCommandTest.java rename to src/test/java/seedu/resireg/logic/commands/AddCommandTest.java index 5865713d5dd..13e17d1317b 100644 --- a/src/test/java/seedu/address/logic/commands/AddCommandTest.java +++ b/src/test/java/seedu/resireg/logic/commands/AddCommandTest.java @@ -1,10 +1,10 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; import static java.util.Objects.requireNonNull; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import java.nio.file.Path; import java.util.ArrayList; @@ -14,46 +14,46 @@ import org.junit.jupiter.api.Test; import javafx.collections.ObservableList; -import seedu.address.commons.core.GuiSettings; -import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.model.AddressBook; -import seedu.address.model.Model; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.ReadOnlyUserPrefs; -import seedu.address.model.person.Person; -import seedu.address.testutil.PersonBuilder; +import seedu.resireg.commons.core.GuiSettings; +import seedu.resireg.logic.commands.exceptions.CommandException; +import seedu.resireg.model.AddressBook; +import seedu.resireg.model.Model; +import seedu.resireg.model.ReadOnlyAddressBook; +import seedu.resireg.model.ReadOnlyUserPrefs; +import seedu.resireg.model.student.Student; +import seedu.resireg.testutil.StudentBuilder; public class AddCommandTest { @Test - public void constructor_nullPerson_throwsNullPointerException() { + public void constructor_nullStudent_throwsNullPointerException() { assertThrows(NullPointerException.class, () -> new AddCommand(null)); } @Test - public void execute_personAcceptedByModel_addSuccessful() throws Exception { - ModelStubAcceptingPersonAdded modelStub = new ModelStubAcceptingPersonAdded(); - Person validPerson = new PersonBuilder().build(); + public void execute_studentAcceptedByModel_addSuccessful() throws Exception { + ModelStubAcceptingStudentAdded modelStub = new ModelStubAcceptingStudentAdded(); + Student validStudent = new StudentBuilder().build(); - CommandResult commandResult = new AddCommand(validPerson).execute(modelStub); + CommandResult commandResult = new AddCommand(validStudent).execute(modelStub); - assertEquals(String.format(AddCommand.MESSAGE_SUCCESS, validPerson), commandResult.getFeedbackToUser()); - assertEquals(Arrays.asList(validPerson), modelStub.personsAdded); + assertEquals(String.format(AddCommand.MESSAGE_SUCCESS, validStudent), commandResult.getFeedbackToUser()); + assertEquals(Arrays.asList(validStudent), modelStub.studentsAdded); } @Test - public void execute_duplicatePerson_throwsCommandException() { - Person validPerson = new PersonBuilder().build(); - AddCommand addCommand = new AddCommand(validPerson); - ModelStub modelStub = new ModelStubWithPerson(validPerson); + public void execute_duplicateStudent_throwsCommandException() { + Student validStudent = new StudentBuilder().build(); + AddCommand addCommand = new AddCommand(validStudent); + ModelStub modelStub = new ModelStubWithStudent(validStudent); assertThrows(CommandException.class, AddCommand.MESSAGE_DUPLICATE_PERSON, () -> addCommand.execute(modelStub)); } @Test public void equals() { - Person alice = new PersonBuilder().withName("Alice").build(); - Person bob = new PersonBuilder().withName("Bob").build(); + Student alice = new StudentBuilder().withName("Alice").build(); + Student bob = new StudentBuilder().withName("Bob").build(); AddCommand addAliceCommand = new AddCommand(alice); AddCommand addBobCommand = new AddCommand(bob); @@ -70,7 +70,7 @@ public void equals() { // null -> returns false assertFalse(addAliceCommand.equals(null)); - // different person -> returns false + // different student -> returns false assertFalse(addAliceCommand.equals(addBobCommand)); } @@ -109,7 +109,7 @@ public void setAddressBookFilePath(Path addressBookFilePath) { } @Override - public void addPerson(Person person) { + public void addStudent(Student student) { throw new AssertionError("This method should not be called."); } @@ -124,65 +124,65 @@ public ReadOnlyAddressBook getAddressBook() { } @Override - public boolean hasPerson(Person person) { + public boolean hasStudent(Student student) { throw new AssertionError("This method should not be called."); } @Override - public void deletePerson(Person target) { + public void deleteStudent(Student target) { throw new AssertionError("This method should not be called."); } @Override - public void setPerson(Person target, Person editedPerson) { + public void setStudent(Student target, Student editedStudent) { throw new AssertionError("This method should not be called."); } @Override - public ObservableList getFilteredPersonList() { + public ObservableList getFilteredStudentList() { throw new AssertionError("This method should not be called."); } @Override - public void updateFilteredPersonList(Predicate predicate) { + public void updateFilteredStudentList(Predicate predicate) { throw new AssertionError("This method should not be called."); } } /** - * A Model stub that contains a single person. + * A Model stub that contains a single student. */ - private class ModelStubWithPerson extends ModelStub { - private final Person person; + private class ModelStubWithStudent extends ModelStub { + private final Student student; - ModelStubWithPerson(Person person) { - requireNonNull(person); - this.person = person; + ModelStubWithStudent(Student student) { + requireNonNull(student); + this.student = student; } @Override - public boolean hasPerson(Person person) { - requireNonNull(person); - return this.person.isSamePerson(person); + public boolean hasStudent(Student student) { + requireNonNull(student); + return this.student.isSameStudent(student); } } /** - * A Model stub that always accept the person being added. + * A Model stub that always accept the student being added. */ - private class ModelStubAcceptingPersonAdded extends ModelStub { - final ArrayList personsAdded = new ArrayList<>(); + private class ModelStubAcceptingStudentAdded extends ModelStub { + final ArrayList studentsAdded = new ArrayList<>(); @Override - public boolean hasPerson(Person person) { - requireNonNull(person); - return personsAdded.stream().anyMatch(person::isSamePerson); + public boolean hasStudent(Student student) { + requireNonNull(student); + return studentsAdded.stream().anyMatch(student::isSameStudent); } @Override - public void addPerson(Person person) { - requireNonNull(person); - personsAdded.add(person); + public void addStudent(Student student) { + requireNonNull(student); + studentsAdded.add(student); } @Override diff --git a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java b/src/test/java/seedu/resireg/logic/commands/ClearCommandTest.java similarity index 69% rename from src/test/java/seedu/address/logic/commands/ClearCommandTest.java rename to src/test/java/seedu/resireg/logic/commands/ClearCommandTest.java index 80d9110c03a..baf95cd4dba 100644 --- a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java +++ b/src/test/java/seedu/resireg/logic/commands/ClearCommandTest.java @@ -1,14 +1,14 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; +import static seedu.resireg.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.resireg.testutil.TypicalStudents.getTypicalAddressBook; import org.junit.jupiter.api.Test; -import seedu.address.model.AddressBook; -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.UserPrefs; +import seedu.resireg.model.AddressBook; +import seedu.resireg.model.Model; +import seedu.resireg.model.ModelManager; +import seedu.resireg.model.UserPrefs; public class ClearCommandTest { diff --git a/src/test/java/seedu/address/logic/commands/CommandResultTest.java b/src/test/java/seedu/resireg/logic/commands/CommandResultTest.java similarity index 98% rename from src/test/java/seedu/address/logic/commands/CommandResultTest.java rename to src/test/java/seedu/resireg/logic/commands/CommandResultTest.java index 4f3eb46e9ef..43b8646f267 100644 --- a/src/test/java/seedu/address/logic/commands/CommandResultTest.java +++ b/src/test/java/seedu/resireg/logic/commands/CommandResultTest.java @@ -1,4 +1,4 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/resireg/logic/commands/CommandTestUtil.java similarity index 59% rename from src/test/java/seedu/address/logic/commands/CommandTestUtil.java rename to src/test/java/seedu/resireg/logic/commands/CommandTestUtil.java index 643a1d08069..e42fad63355 100644 --- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java +++ b/src/test/java/seedu/resireg/logic/commands/CommandTestUtil.java @@ -1,25 +1,26 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; -import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; -import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; -import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; -import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_EMAIL; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_FACULTY; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_STUDENT_ID; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.resireg.testutil.Assert.assertThrows; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import seedu.address.commons.core.index.Index; -import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.model.AddressBook; -import seedu.address.model.Model; -import seedu.address.model.person.NameContainsKeywordsPredicate; -import seedu.address.model.person.Person; -import seedu.address.testutil.EditPersonDescriptorBuilder; +import seedu.resireg.commons.core.index.Index; +import seedu.resireg.logic.commands.exceptions.CommandException; +import seedu.resireg.model.AddressBook; +import seedu.resireg.model.Model; +import seedu.resireg.model.student.NameContainsKeywordsPredicate; +import seedu.resireg.model.student.Student; +import seedu.resireg.testutil.EditStudentDescriptorBuilder; /** * Contains helper methods for testing commands. @@ -32,8 +33,10 @@ public class CommandTestUtil { public static final String VALID_PHONE_BOB = "22222222"; public static final String VALID_EMAIL_AMY = "amy@example.com"; public static final String VALID_EMAIL_BOB = "bob@example.com"; - public static final String VALID_ADDRESS_AMY = "Block 312, Amy Street 1"; - public static final String VALID_ADDRESS_BOB = "Block 123, Bobby Street 3"; + public static final String VALID_FACULTY_AMY = "FASS"; + public static final String VALID_FACULTY_BOB = "SOC"; + public static final String VALID_STUDENT_ID_AMY = "E0111111"; + public static final String VALID_STUDENT_ID_BOB = "E0222222"; public static final String VALID_TAG_HUSBAND = "husband"; public static final String VALID_TAG_FRIEND = "friend"; @@ -43,29 +46,34 @@ public class CommandTestUtil { public static final String PHONE_DESC_BOB = " " + PREFIX_PHONE + VALID_PHONE_BOB; public static final String EMAIL_DESC_AMY = " " + PREFIX_EMAIL + VALID_EMAIL_AMY; public static final String EMAIL_DESC_BOB = " " + PREFIX_EMAIL + VALID_EMAIL_BOB; - public static final String ADDRESS_DESC_AMY = " " + PREFIX_ADDRESS + VALID_ADDRESS_AMY; - public static final String ADDRESS_DESC_BOB = " " + PREFIX_ADDRESS + VALID_ADDRESS_BOB; + public static final String FACULTY_DESC_AMY = " " + PREFIX_FACULTY + VALID_FACULTY_AMY; + public static final String FACULTY_DESC_BOB = " " + PREFIX_FACULTY + VALID_FACULTY_BOB; + public static final String STUDENT_ID_DESC_AMY = " " + PREFIX_STUDENT_ID + VALID_STUDENT_ID_AMY; + public static final String STUDENT_ID_DESC_BOB = " " + PREFIX_STUDENT_ID + VALID_STUDENT_ID_BOB; public static final String TAG_DESC_FRIEND = " " + PREFIX_TAG + VALID_TAG_FRIEND; public static final String TAG_DESC_HUSBAND = " " + PREFIX_TAG + VALID_TAG_HUSBAND; public static final String INVALID_NAME_DESC = " " + PREFIX_NAME + "James&"; // '&' not allowed in names public static final String INVALID_PHONE_DESC = " " + PREFIX_PHONE + "911a"; // 'a' not allowed in phones public static final String INVALID_EMAIL_DESC = " " + PREFIX_EMAIL + "bob!yahoo"; // missing '@' symbol - public static final String INVALID_ADDRESS_DESC = " " + PREFIX_ADDRESS; // empty string not allowed for addresses + public static final String INVALID_FACULTY_DESC = " " + PREFIX_FACULTY; // empty string not allowed for faculties + public static final String INVALID_STUDENT_ID_DESC = " " + PREFIX_STUDENT_ID; // empty string not allowed for ids public static final String INVALID_TAG_DESC = " " + PREFIX_TAG + "hubby*"; // '*' not allowed in tags public static final String PREAMBLE_WHITESPACE = "\t \r \n"; public static final String PREAMBLE_NON_EMPTY = "NonEmptyPreamble"; - public static final EditCommand.EditPersonDescriptor DESC_AMY; - public static final EditCommand.EditPersonDescriptor DESC_BOB; + public static final EditCommand.EditStudentDescriptor DESC_AMY; + public static final EditCommand.EditStudentDescriptor DESC_BOB; static { - DESC_AMY = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY) - .withPhone(VALID_PHONE_AMY).withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY) + DESC_AMY = new EditStudentDescriptorBuilder().withName(VALID_NAME_AMY) + .withPhone(VALID_PHONE_AMY).withEmail(VALID_EMAIL_AMY).withFaculty(VALID_FACULTY_AMY) + .withStudentId(VALID_STUDENT_ID_AMY) .withTags(VALID_TAG_FRIEND).build(); - DESC_BOB = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB) - .withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB) + DESC_BOB = new EditStudentDescriptorBuilder().withName(VALID_NAME_BOB) + .withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB).withFaculty(VALID_FACULTY_BOB) + .withStudentId(VALID_STUDENT_ID_BOB) .withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND).build(); } @@ -99,30 +107,30 @@ public static void assertCommandSuccess(Command command, Model actualModel, Stri * Executes the given {@code command}, confirms that
* - a {@code CommandException} is thrown
* - the CommandException message matches {@code expectedMessage}
- * - the address book, filtered person list and selected person in {@code actualModel} remain unchanged + * - the address book, filtered student list and selected student in {@code actualModel} remain unchanged */ public static void assertCommandFailure(Command command, Model actualModel, String expectedMessage) { // we are unable to defensively copy the model for comparison later, so we can // only do so by copying its components. AddressBook expectedAddressBook = new AddressBook(actualModel.getAddressBook()); - List expectedFilteredList = new ArrayList<>(actualModel.getFilteredPersonList()); + List expectedFilteredList = new ArrayList<>(actualModel.getFilteredStudentList()); assertThrows(CommandException.class, expectedMessage, () -> command.execute(actualModel)); assertEquals(expectedAddressBook, actualModel.getAddressBook()); - assertEquals(expectedFilteredList, actualModel.getFilteredPersonList()); + assertEquals(expectedFilteredList, actualModel.getFilteredStudentList()); } /** - * Updates {@code model}'s filtered list to show only the person at the given {@code targetIndex} in the + * Updates {@code model}'s filtered list to show only the student at the given {@code targetIndex} in the * {@code model}'s address book. */ - public static void showPersonAtIndex(Model model, Index targetIndex) { - assertTrue(targetIndex.getZeroBased() < model.getFilteredPersonList().size()); + public static void showStudentAtIndex(Model model, Index targetIndex) { + assertTrue(targetIndex.getZeroBased() < model.getFilteredStudentList().size()); - Person person = model.getFilteredPersonList().get(targetIndex.getZeroBased()); - final String[] splitName = person.getName().fullName.split("\\s+"); - model.updateFilteredPersonList(new NameContainsKeywordsPredicate(Arrays.asList(splitName[0]))); + Student student = model.getFilteredStudentList().get(targetIndex.getZeroBased()); + final String[] splitName = student.getName().fullName.split("\\s+"); + model.updateFilteredStudentList(new NameContainsKeywordsPredicate(Arrays.asList(splitName[0]))); - assertEquals(1, model.getFilteredPersonList().size()); + assertEquals(1, model.getFilteredStudentList().size()); } } diff --git a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java b/src/test/java/seedu/resireg/logic/commands/DeleteCommandTest.java similarity index 65% rename from src/test/java/seedu/address/logic/commands/DeleteCommandTest.java rename to src/test/java/seedu/resireg/logic/commands/DeleteCommandTest.java index 0f77d8295f6..7f8d356a43e 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java +++ b/src/test/java/seedu/resireg/logic/commands/DeleteCommandTest.java @@ -1,22 +1,22 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex; -import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; -import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON; -import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; +import static seedu.resireg.logic.commands.CommandTestUtil.assertCommandFailure; +import static seedu.resireg.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.resireg.logic.commands.CommandTestUtil.showStudentAtIndex; +import static seedu.resireg.testutil.TypicalIndexes.INDEX_FIRST_PERSON; +import static seedu.resireg.testutil.TypicalIndexes.INDEX_SECOND_PERSON; +import static seedu.resireg.testutil.TypicalStudents.getTypicalAddressBook; import org.junit.jupiter.api.Test; -import seedu.address.commons.core.Messages; -import seedu.address.commons.core.index.Index; -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.UserPrefs; -import seedu.address.model.person.Person; +import seedu.resireg.commons.core.Messages; +import seedu.resireg.commons.core.index.Index; +import seedu.resireg.model.Model; +import seedu.resireg.model.ModelManager; +import seedu.resireg.model.UserPrefs; +import seedu.resireg.model.student.Student; /** * Contains integration tests (interaction with the Model, UndoCommand and RedoCommand) and unit tests for @@ -28,20 +28,20 @@ public class DeleteCommandTest { @Test public void execute_validIndexUnfilteredList_success() { - Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); + Student studentToDelete = model.getFilteredStudentList().get(INDEX_FIRST_PERSON.getZeroBased()); DeleteCommand deleteCommand = new DeleteCommand(INDEX_FIRST_PERSON); - String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, personToDelete); + String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, studentToDelete); ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); - expectedModel.deletePerson(personToDelete); + expectedModel.deleteStudent(studentToDelete); assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel); } @Test public void execute_invalidIndexUnfilteredList_throwsCommandException() { - Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredStudentList().size() + 1); DeleteCommand deleteCommand = new DeleteCommand(outOfBoundIndex); assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); @@ -49,27 +49,27 @@ public void execute_invalidIndexUnfilteredList_throwsCommandException() { @Test public void execute_validIndexFilteredList_success() { - showPersonAtIndex(model, INDEX_FIRST_PERSON); + showStudentAtIndex(model, INDEX_FIRST_PERSON); - Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); + Student studentToDelete = model.getFilteredStudentList().get(INDEX_FIRST_PERSON.getZeroBased()); DeleteCommand deleteCommand = new DeleteCommand(INDEX_FIRST_PERSON); - String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, personToDelete); + String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, studentToDelete); Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); - expectedModel.deletePerson(personToDelete); - showNoPerson(expectedModel); + expectedModel.deleteStudent(studentToDelete); + showNoStudent(expectedModel); assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel); } @Test public void execute_invalidIndexFilteredList_throwsCommandException() { - showPersonAtIndex(model, INDEX_FIRST_PERSON); + showStudentAtIndex(model, INDEX_FIRST_PERSON); Index outOfBoundIndex = INDEX_SECOND_PERSON; // ensures that outOfBoundIndex is still in bounds of address book list - assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size()); + assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getStudentList().size()); DeleteCommand deleteCommand = new DeleteCommand(outOfBoundIndex); @@ -94,16 +94,16 @@ public void equals() { // null -> returns false assertFalse(deleteFirstCommand.equals(null)); - // different person -> returns false + // different student -> returns false assertFalse(deleteFirstCommand.equals(deleteSecondCommand)); } /** * Updates {@code model}'s filtered list to show no one. */ - private void showNoPerson(Model model) { - model.updateFilteredPersonList(p -> false); + private void showNoStudent(Model model) { + model.updateFilteredStudentList(p -> false); - assertTrue(model.getFilteredPersonList().isEmpty()); + assertTrue(model.getFilteredStudentList().isEmpty()); } } diff --git a/src/test/java/seedu/address/logic/commands/EditCommandTest.java b/src/test/java/seedu/resireg/logic/commands/EditCommandTest.java similarity index 51% rename from src/test/java/seedu/address/logic/commands/EditCommandTest.java rename to src/test/java/seedu/resireg/logic/commands/EditCommandTest.java index 1c27530fa99..59bd77ad384 100644 --- a/src/test/java/seedu/address/logic/commands/EditCommandTest.java +++ b/src/test/java/seedu/resireg/logic/commands/EditCommandTest.java @@ -1,31 +1,31 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.logic.commands.CommandTestUtil.DESC_AMY; -import static seedu.address.logic.commands.CommandTestUtil.DESC_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex; -import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; -import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON; -import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; +import static seedu.resireg.logic.commands.CommandTestUtil.DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.DESC_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_NAME_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_PHONE_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; +import static seedu.resireg.logic.commands.CommandTestUtil.assertCommandFailure; +import static seedu.resireg.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.resireg.logic.commands.CommandTestUtil.showStudentAtIndex; +import static seedu.resireg.testutil.TypicalIndexes.INDEX_FIRST_PERSON; +import static seedu.resireg.testutil.TypicalIndexes.INDEX_SECOND_PERSON; +import static seedu.resireg.testutil.TypicalStudents.getTypicalAddressBook; import org.junit.jupiter.api.Test; -import seedu.address.commons.core.Messages; -import seedu.address.commons.core.index.Index; -import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; -import seedu.address.model.AddressBook; -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.UserPrefs; -import seedu.address.model.person.Person; -import seedu.address.testutil.EditPersonDescriptorBuilder; -import seedu.address.testutil.PersonBuilder; +import seedu.resireg.commons.core.Messages; +import seedu.resireg.commons.core.index.Index; +import seedu.resireg.logic.commands.EditCommand.EditStudentDescriptor; +import seedu.resireg.model.AddressBook; +import seedu.resireg.model.Model; +import seedu.resireg.model.ModelManager; +import seedu.resireg.model.UserPrefs; +import seedu.resireg.model.student.Student; +import seedu.resireg.testutil.EditStudentDescriptorBuilder; +import seedu.resireg.testutil.StudentBuilder; /** * Contains integration tests (interaction with the Model, UndoCommand and RedoCommand) and unit tests for EditCommand. @@ -36,45 +36,45 @@ public class EditCommandTest { @Test public void execute_allFieldsSpecifiedUnfilteredList_success() { - Person editedPerson = new PersonBuilder().build(); - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(editedPerson).build(); + Student editedStudent = new StudentBuilder().build(); + EditStudentDescriptor descriptor = new EditStudentDescriptorBuilder(editedStudent).build(); EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, descriptor); - String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, editedPerson); + String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, editedStudent); Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs()); - expectedModel.setPerson(model.getFilteredPersonList().get(0), editedPerson); + expectedModel.setStudent(model.getFilteredStudentList().get(0), editedStudent); assertCommandSuccess(editCommand, model, expectedMessage, expectedModel); } @Test public void execute_someFieldsSpecifiedUnfilteredList_success() { - Index indexLastPerson = Index.fromOneBased(model.getFilteredPersonList().size()); - Person lastPerson = model.getFilteredPersonList().get(indexLastPerson.getZeroBased()); + Index indexLastStudent = Index.fromOneBased(model.getFilteredStudentList().size()); + Student lastStudent = model.getFilteredStudentList().get(indexLastStudent.getZeroBased()); - PersonBuilder personInList = new PersonBuilder(lastPerson); - Person editedPerson = personInList.withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB) + StudentBuilder studentInList = new StudentBuilder(lastStudent); + Student editedStudent = studentInList.withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB) .withTags(VALID_TAG_HUSBAND).build(); - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB) + EditStudentDescriptor descriptor = new EditStudentDescriptorBuilder().withName(VALID_NAME_BOB) .withPhone(VALID_PHONE_BOB).withTags(VALID_TAG_HUSBAND).build(); - EditCommand editCommand = new EditCommand(indexLastPerson, descriptor); + EditCommand editCommand = new EditCommand(indexLastStudent, descriptor); - String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, editedPerson); + String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, editedStudent); Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs()); - expectedModel.setPerson(lastPerson, editedPerson); + expectedModel.setStudent(lastStudent, editedStudent); assertCommandSuccess(editCommand, model, expectedMessage, expectedModel); } @Test public void execute_noFieldSpecifiedUnfilteredList_success() { - EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, new EditPersonDescriptor()); - Person editedPerson = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); + EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, new EditStudentDescriptor()); + Student editedStudent = model.getFilteredStudentList().get(INDEX_FIRST_PERSON.getZeroBased()); - String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, editedPerson); + String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, editedStudent); Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs()); @@ -83,46 +83,46 @@ public void execute_noFieldSpecifiedUnfilteredList_success() { @Test public void execute_filteredList_success() { - showPersonAtIndex(model, INDEX_FIRST_PERSON); + showStudentAtIndex(model, INDEX_FIRST_PERSON); - Person personInFilteredList = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); - Person editedPerson = new PersonBuilder(personInFilteredList).withName(VALID_NAME_BOB).build(); + Student studentInFilteredList = model.getFilteredStudentList().get(INDEX_FIRST_PERSON.getZeroBased()); + Student editedStudent = new StudentBuilder(studentInFilteredList).withName(VALID_NAME_BOB).build(); EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, - new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build()); + new EditStudentDescriptorBuilder().withName(VALID_NAME_BOB).build()); - String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, editedPerson); + String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, editedStudent); Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs()); - expectedModel.setPerson(model.getFilteredPersonList().get(0), editedPerson); + expectedModel.setStudent(model.getFilteredStudentList().get(0), editedStudent); assertCommandSuccess(editCommand, model, expectedMessage, expectedModel); } @Test - public void execute_duplicatePersonUnfilteredList_failure() { - Person firstPerson = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(firstPerson).build(); + public void execute_duplicateStudentUnfilteredList_failure() { + Student firstStudent = model.getFilteredStudentList().get(INDEX_FIRST_PERSON.getZeroBased()); + EditStudentDescriptor descriptor = new EditStudentDescriptorBuilder(firstStudent).build(); EditCommand editCommand = new EditCommand(INDEX_SECOND_PERSON, descriptor); assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_PERSON); } @Test - public void execute_duplicatePersonFilteredList_failure() { - showPersonAtIndex(model, INDEX_FIRST_PERSON); + public void execute_duplicateStudentFilteredList_failure() { + showStudentAtIndex(model, INDEX_FIRST_PERSON); - // edit person in filtered list into a duplicate in address book - Person personInList = model.getAddressBook().getPersonList().get(INDEX_SECOND_PERSON.getZeroBased()); + // edit student in filtered list into a duplicate in address book + Student studentInList = model.getAddressBook().getStudentList().get(INDEX_SECOND_PERSON.getZeroBased()); EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, - new EditPersonDescriptorBuilder(personInList).build()); + new EditStudentDescriptorBuilder(studentInList).build()); assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_PERSON); } @Test - public void execute_invalidPersonIndexUnfilteredList_failure() { - Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build(); + public void execute_invalidStudentIndexUnfilteredList_failure() { + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredStudentList().size() + 1); + EditStudentDescriptor descriptor = new EditStudentDescriptorBuilder().withName(VALID_NAME_BOB).build(); EditCommand editCommand = new EditCommand(outOfBoundIndex, descriptor); assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); @@ -133,14 +133,14 @@ public void execute_invalidPersonIndexUnfilteredList_failure() { * but smaller than size of address book */ @Test - public void execute_invalidPersonIndexFilteredList_failure() { - showPersonAtIndex(model, INDEX_FIRST_PERSON); + public void execute_invalidStudentIndexFilteredList_failure() { + showStudentAtIndex(model, INDEX_FIRST_PERSON); Index outOfBoundIndex = INDEX_SECOND_PERSON; // ensures that outOfBoundIndex is still in bounds of address book list - assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size()); + assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getStudentList().size()); EditCommand editCommand = new EditCommand(outOfBoundIndex, - new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build()); + new EditStudentDescriptorBuilder().withName(VALID_NAME_BOB).build()); assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); } @@ -150,7 +150,7 @@ public void equals() { final EditCommand standardCommand = new EditCommand(INDEX_FIRST_PERSON, DESC_AMY); // same values -> returns true - EditPersonDescriptor copyDescriptor = new EditPersonDescriptor(DESC_AMY); + EditStudentDescriptor copyDescriptor = new EditStudentDescriptor(DESC_AMY); EditCommand commandWithSameValues = new EditCommand(INDEX_FIRST_PERSON, copyDescriptor); assertTrue(standardCommand.equals(commandWithSameValues)); diff --git a/src/test/java/seedu/resireg/logic/commands/EditStudentDescriptorTest.java b/src/test/java/seedu/resireg/logic/commands/EditStudentDescriptorTest.java new file mode 100644 index 00000000000..1f4c2c29ca0 --- /dev/null +++ b/src/test/java/seedu/resireg/logic/commands/EditStudentDescriptorTest.java @@ -0,0 +1,63 @@ +package seedu.resireg.logic.commands; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.resireg.logic.commands.CommandTestUtil.DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.DESC_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_EMAIL_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_FACULTY_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_NAME_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_PHONE_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_STUDENT_ID_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; + +import org.junit.jupiter.api.Test; + +import seedu.resireg.logic.commands.EditCommand.EditStudentDescriptor; +import seedu.resireg.testutil.EditStudentDescriptorBuilder; + +public class EditStudentDescriptorTest { + + @Test + public void equals() { + // same values -> returns true + EditStudentDescriptor descriptorWithSameValues = new EditStudentDescriptor(DESC_AMY); + assertTrue(DESC_AMY.equals(descriptorWithSameValues)); + + // same object -> returns true + assertTrue(DESC_AMY.equals(DESC_AMY)); + + // null -> returns false + assertFalse(DESC_AMY.equals(null)); + + // different types -> returns false + assertFalse(DESC_AMY.equals(5)); + + // different values -> returns false + assertFalse(DESC_AMY.equals(DESC_BOB)); + + // different name -> returns false + EditStudentDescriptor editedAmy = new EditStudentDescriptorBuilder(DESC_AMY).withName(VALID_NAME_BOB).build(); + assertFalse(DESC_AMY.equals(editedAmy)); + + // different phone -> returns false + editedAmy = new EditStudentDescriptorBuilder(DESC_AMY).withPhone(VALID_PHONE_BOB).build(); + assertFalse(DESC_AMY.equals(editedAmy)); + + // different email -> returns false + editedAmy = new EditStudentDescriptorBuilder(DESC_AMY).withEmail(VALID_EMAIL_BOB).build(); + assertFalse(DESC_AMY.equals(editedAmy)); + + // different faculty -> returns false + editedAmy = new EditStudentDescriptorBuilder(DESC_AMY).withFaculty(VALID_FACULTY_BOB).build(); + assertFalse(DESC_AMY.equals(editedAmy)); + + // different student ID -> returns false + editedAmy = new EditStudentDescriptorBuilder(DESC_AMY).withStudentId(VALID_STUDENT_ID_BOB).build(); + assertFalse(DESC_AMY.equals(editedAmy)); + + // different tags -> returns false + editedAmy = new EditStudentDescriptorBuilder(DESC_AMY).withTags(VALID_TAG_HUSBAND).build(); + assertFalse(DESC_AMY.equals(editedAmy)); + } +} diff --git a/src/test/java/seedu/address/logic/commands/ExitCommandTest.java b/src/test/java/seedu/resireg/logic/commands/ExitCommandTest.java similarity index 66% rename from src/test/java/seedu/address/logic/commands/ExitCommandTest.java rename to src/test/java/seedu/resireg/logic/commands/ExitCommandTest.java index 9533c473875..abf1068bf66 100644 --- a/src/test/java/seedu/address/logic/commands/ExitCommandTest.java +++ b/src/test/java/seedu/resireg/logic/commands/ExitCommandTest.java @@ -1,12 +1,12 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.logic.commands.ExitCommand.MESSAGE_EXIT_ACKNOWLEDGEMENT; +import static seedu.resireg.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.resireg.logic.commands.ExitCommand.MESSAGE_EXIT_ACKNOWLEDGEMENT; import org.junit.jupiter.api.Test; -import seedu.address.model.Model; -import seedu.address.model.ModelManager; +import seedu.resireg.model.Model; +import seedu.resireg.model.ModelManager; public class ExitCommandTest { private Model model = new ModelManager(); diff --git a/src/test/java/seedu/address/logic/commands/FindCommandTest.java b/src/test/java/seedu/resireg/logic/commands/FindCommandTest.java similarity index 72% rename from src/test/java/seedu/address/logic/commands/FindCommandTest.java rename to src/test/java/seedu/resireg/logic/commands/FindCommandTest.java index 9b15db28bbb..e49c576efca 100644 --- a/src/test/java/seedu/address/logic/commands/FindCommandTest.java +++ b/src/test/java/seedu/resireg/logic/commands/FindCommandTest.java @@ -1,24 +1,24 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.commons.core.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.testutil.TypicalPersons.CARL; -import static seedu.address.testutil.TypicalPersons.ELLE; -import static seedu.address.testutil.TypicalPersons.FIONA; -import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; +import static seedu.resireg.commons.core.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW; +import static seedu.resireg.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.resireg.testutil.TypicalStudents.CARL; +import static seedu.resireg.testutil.TypicalStudents.ELLE; +import static seedu.resireg.testutil.TypicalStudents.FIONA; +import static seedu.resireg.testutil.TypicalStudents.getTypicalAddressBook; import java.util.Arrays; import java.util.Collections; import org.junit.jupiter.api.Test; -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.UserPrefs; -import seedu.address.model.person.NameContainsKeywordsPredicate; +import seedu.resireg.model.Model; +import seedu.resireg.model.ModelManager; +import seedu.resireg.model.UserPrefs; +import seedu.resireg.model.student.NameContainsKeywordsPredicate; /** * Contains integration tests (interaction with the Model) for {@code FindCommand}. @@ -50,28 +50,28 @@ public void equals() { // null -> returns false assertFalse(findFirstCommand.equals(null)); - // different person -> returns false + // different student -> returns false assertFalse(findFirstCommand.equals(findSecondCommand)); } @Test - public void execute_zeroKeywords_noPersonFound() { + public void execute_zeroKeywords_noStudentFound() { String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0); NameContainsKeywordsPredicate predicate = preparePredicate(" "); FindCommand command = new FindCommand(predicate); - expectedModel.updateFilteredPersonList(predicate); + expectedModel.updateFilteredStudentList(predicate); assertCommandSuccess(command, model, expectedMessage, expectedModel); - assertEquals(Collections.emptyList(), model.getFilteredPersonList()); + assertEquals(Collections.emptyList(), model.getFilteredStudentList()); } @Test - public void execute_multipleKeywords_multiplePersonsFound() { + public void execute_multipleKeywords_multipleStudentsFound() { String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 3); NameContainsKeywordsPredicate predicate = preparePredicate("Kurz Elle Kunz"); FindCommand command = new FindCommand(predicate); - expectedModel.updateFilteredPersonList(predicate); + expectedModel.updateFilteredStudentList(predicate); assertCommandSuccess(command, model, expectedMessage, expectedModel); - assertEquals(Arrays.asList(CARL, ELLE, FIONA), model.getFilteredPersonList()); + assertEquals(Arrays.asList(CARL, ELLE, FIONA), model.getFilteredStudentList()); } /** diff --git a/src/test/java/seedu/address/logic/commands/HelpCommandTest.java b/src/test/java/seedu/resireg/logic/commands/HelpCommandTest.java similarity index 65% rename from src/test/java/seedu/address/logic/commands/HelpCommandTest.java rename to src/test/java/seedu/resireg/logic/commands/HelpCommandTest.java index 4904fc4352e..219dbfa9fc5 100644 --- a/src/test/java/seedu/address/logic/commands/HelpCommandTest.java +++ b/src/test/java/seedu/resireg/logic/commands/HelpCommandTest.java @@ -1,12 +1,12 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.logic.commands.HelpCommand.SHOWING_HELP_MESSAGE; +import static seedu.resireg.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.resireg.logic.commands.HelpCommand.SHOWING_HELP_MESSAGE; import org.junit.jupiter.api.Test; -import seedu.address.model.Model; -import seedu.address.model.ModelManager; +import seedu.resireg.model.Model; +import seedu.resireg.model.ModelManager; public class HelpCommandTest { private Model model = new ModelManager(); diff --git a/src/test/java/seedu/address/logic/commands/ListCommandTest.java b/src/test/java/seedu/resireg/logic/commands/ListCommandTest.java similarity index 63% rename from src/test/java/seedu/address/logic/commands/ListCommandTest.java rename to src/test/java/seedu/resireg/logic/commands/ListCommandTest.java index 435ff1f7275..25d00d56ea4 100644 --- a/src/test/java/seedu/address/logic/commands/ListCommandTest.java +++ b/src/test/java/seedu/resireg/logic/commands/ListCommandTest.java @@ -1,16 +1,16 @@ -package seedu.address.logic.commands; +package seedu.resireg.logic.commands; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex; -import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; -import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; +import static seedu.resireg.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.resireg.logic.commands.CommandTestUtil.showStudentAtIndex; +import static seedu.resireg.testutil.TypicalIndexes.INDEX_FIRST_PERSON; +import static seedu.resireg.testutil.TypicalStudents.getTypicalAddressBook; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.UserPrefs; +import seedu.resireg.model.Model; +import seedu.resireg.model.ModelManager; +import seedu.resireg.model.UserPrefs; /** * Contains integration tests (interaction with the Model) and unit tests for ListCommand. @@ -33,7 +33,7 @@ public void execute_listIsNotFiltered_showsSameList() { @Test public void execute_listIsFiltered_showsEverything() { - showPersonAtIndex(model, INDEX_FIRST_PERSON); + showStudentAtIndex(model, INDEX_FIRST_PERSON); assertCommandSuccess(new ListCommand(), model, ListCommand.MESSAGE_SUCCESS, expectedModel); } } diff --git a/src/test/java/seedu/resireg/logic/parser/AddCommandParserTest.java b/src/test/java/seedu/resireg/logic/parser/AddCommandParserTest.java new file mode 100644 index 00000000000..ac26a3f7cba --- /dev/null +++ b/src/test/java/seedu/resireg/logic/parser/AddCommandParserTest.java @@ -0,0 +1,164 @@ +package seedu.resireg.logic.parser; + +import static seedu.resireg.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.resireg.logic.commands.CommandTestUtil.EMAIL_DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.EMAIL_DESC_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.FACULTY_DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.FACULTY_DESC_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.INVALID_EMAIL_DESC; +import static seedu.resireg.logic.commands.CommandTestUtil.INVALID_FACULTY_DESC; +import static seedu.resireg.logic.commands.CommandTestUtil.INVALID_NAME_DESC; +import static seedu.resireg.logic.commands.CommandTestUtil.INVALID_PHONE_DESC; +import static seedu.resireg.logic.commands.CommandTestUtil.INVALID_STUDENT_ID_DESC; +import static seedu.resireg.logic.commands.CommandTestUtil.INVALID_TAG_DESC; +import static seedu.resireg.logic.commands.CommandTestUtil.NAME_DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.NAME_DESC_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.PHONE_DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.PHONE_DESC_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.PREAMBLE_NON_EMPTY; +import static seedu.resireg.logic.commands.CommandTestUtil.PREAMBLE_WHITESPACE; +import static seedu.resireg.logic.commands.CommandTestUtil.STUDENT_ID_DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.STUDENT_ID_DESC_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.TAG_DESC_FRIEND; +import static seedu.resireg.logic.commands.CommandTestUtil.TAG_DESC_HUSBAND; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_EMAIL_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_FACULTY_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_NAME_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_PHONE_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_STUDENT_ID_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_TAG_FRIEND; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; +import static seedu.resireg.logic.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.resireg.logic.parser.CommandParserTestUtil.assertParseSuccess; +import static seedu.resireg.testutil.TypicalStudents.AMY; +import static seedu.resireg.testutil.TypicalStudents.BOB; + +import org.junit.jupiter.api.Test; + +import seedu.resireg.logic.commands.AddCommand; +import seedu.resireg.model.student.Email; +import seedu.resireg.model.student.Name; +import seedu.resireg.model.student.Phone; +import seedu.resireg.model.student.Student; +import seedu.resireg.model.student.StudentId; +import seedu.resireg.model.student.faculty.Faculty; +import seedu.resireg.model.tag.Tag; +import seedu.resireg.testutil.StudentBuilder; + +public class AddCommandParserTest { + private AddCommandParser parser = new AddCommandParser(); + + @Test + public void parse_allFieldsPresent_success() { + Student expectedStudent = new StudentBuilder(BOB).withTags(VALID_TAG_FRIEND).build(); + + // whitespace only preamble + assertParseSuccess(parser, PREAMBLE_WHITESPACE + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + + FACULTY_DESC_BOB + STUDENT_ID_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedStudent)); + + // multiple names - last name accepted + assertParseSuccess(parser, NAME_DESC_AMY + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + + FACULTY_DESC_BOB + STUDENT_ID_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedStudent)); + + // multiple phones - last phone accepted + assertParseSuccess(parser, NAME_DESC_BOB + PHONE_DESC_AMY + PHONE_DESC_BOB + EMAIL_DESC_BOB + + FACULTY_DESC_BOB + STUDENT_ID_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedStudent)); + + // multiple emails - last email accepted + assertParseSuccess(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_AMY + EMAIL_DESC_BOB + + FACULTY_DESC_BOB + STUDENT_ID_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedStudent)); + + // multiple faculties - last address accepted + assertParseSuccess(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + FACULTY_DESC_AMY + + FACULTY_DESC_BOB + STUDENT_ID_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedStudent)); + + // multiple tags - all accepted + Student expectedStudentMultipleTags = new StudentBuilder(BOB).withTags(VALID_TAG_FRIEND, VALID_TAG_HUSBAND) + .build(); + assertParseSuccess(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + FACULTY_DESC_BOB + + STUDENT_ID_DESC_BOB + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, + new AddCommand(expectedStudentMultipleTags)); + } + + @Test + public void parse_optionalFieldsMissing_success() { + // zero tags + Student expectedStudent = new StudentBuilder(AMY).withTags().build(); + assertParseSuccess(parser, NAME_DESC_AMY + PHONE_DESC_AMY + EMAIL_DESC_AMY + + FACULTY_DESC_AMY + STUDENT_ID_DESC_AMY, + new AddCommand(expectedStudent)); + } + + @Test + public void parse_compulsoryFieldMissing_failure() { + String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE); + + // missing name prefix + assertParseFailure(parser, VALID_NAME_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + + FACULTY_DESC_BOB + STUDENT_ID_DESC_BOB, + expectedMessage); + + // missing phone prefix + assertParseFailure(parser, NAME_DESC_BOB + VALID_PHONE_BOB + EMAIL_DESC_BOB + + FACULTY_DESC_BOB + STUDENT_ID_DESC_BOB, + expectedMessage); + + // missing email prefix + assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + VALID_EMAIL_BOB + + FACULTY_DESC_BOB + STUDENT_ID_DESC_BOB, + expectedMessage); + + // missing faculty prefix + assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + + VALID_FACULTY_BOB + STUDENT_ID_DESC_BOB, + expectedMessage); + + // all prefixes missing + assertParseFailure(parser, VALID_NAME_BOB + VALID_PHONE_BOB + VALID_EMAIL_BOB + + VALID_FACULTY_BOB + VALID_STUDENT_ID_BOB, + expectedMessage); + } + + @Test + public void parse_invalidValue_failure() { + // invalid name + assertParseFailure(parser, INVALID_NAME_DESC + PHONE_DESC_BOB + EMAIL_DESC_BOB + + FACULTY_DESC_BOB + STUDENT_ID_DESC_BOB + + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Name.MESSAGE_CONSTRAINTS); + + // invalid phone + assertParseFailure(parser, NAME_DESC_BOB + INVALID_PHONE_DESC + EMAIL_DESC_BOB + + FACULTY_DESC_BOB + STUDENT_ID_DESC_BOB + + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Phone.MESSAGE_CONSTRAINTS); + + // invalid email + assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + INVALID_EMAIL_DESC + + FACULTY_DESC_BOB + STUDENT_ID_DESC_BOB + + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Email.MESSAGE_CONSTRAINTS); + + // invalid faculty + assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + + INVALID_FACULTY_DESC + STUDENT_ID_DESC_BOB + + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Faculty.MESSAGE_CONSTRAINTS); + + // invalid student ID + assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + + FACULTY_DESC_BOB + INVALID_STUDENT_ID_DESC + + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, StudentId.MESSAGE_CONSTRAINTS); + + // invalid tag + assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + + FACULTY_DESC_BOB + STUDENT_ID_DESC_BOB + + INVALID_TAG_DESC + VALID_TAG_FRIEND, Tag.MESSAGE_CONSTRAINTS); + + // two invalid values, only first invalid value reported + assertParseFailure(parser, INVALID_NAME_DESC + PHONE_DESC_BOB + EMAIL_DESC_BOB + INVALID_FACULTY_DESC + + STUDENT_ID_DESC_BOB, + Name.MESSAGE_CONSTRAINTS); + + // non-empty preamble + assertParseFailure(parser, PREAMBLE_NON_EMPTY + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + + FACULTY_DESC_BOB + STUDENT_ID_DESC_BOB + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, + String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE)); + } +} diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/resireg/logic/parser/AddressBookParserTest.java similarity index 65% rename from src/test/java/seedu/address/logic/parser/AddressBookParserTest.java rename to src/test/java/seedu/resireg/logic/parser/AddressBookParserTest.java index d9659205b57..b59969ea759 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/resireg/logic/parser/AddressBookParserTest.java @@ -1,11 +1,11 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND; -import static seedu.address.testutil.Assert.assertThrows; -import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; +import static seedu.resireg.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.resireg.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND; +import static seedu.resireg.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import java.util.Arrays; import java.util.List; @@ -13,21 +13,21 @@ import org.junit.jupiter.api.Test; -import seedu.address.logic.commands.AddCommand; -import seedu.address.logic.commands.ClearCommand; -import seedu.address.logic.commands.DeleteCommand; -import seedu.address.logic.commands.EditCommand; -import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; -import seedu.address.logic.commands.ExitCommand; -import seedu.address.logic.commands.FindCommand; -import seedu.address.logic.commands.HelpCommand; -import seedu.address.logic.commands.ListCommand; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.NameContainsKeywordsPredicate; -import seedu.address.model.person.Person; -import seedu.address.testutil.EditPersonDescriptorBuilder; -import seedu.address.testutil.PersonBuilder; -import seedu.address.testutil.PersonUtil; +import seedu.resireg.logic.commands.AddCommand; +import seedu.resireg.logic.commands.ClearCommand; +import seedu.resireg.logic.commands.DeleteCommand; +import seedu.resireg.logic.commands.EditCommand; +import seedu.resireg.logic.commands.EditCommand.EditStudentDescriptor; +import seedu.resireg.logic.commands.ExitCommand; +import seedu.resireg.logic.commands.FindCommand; +import seedu.resireg.logic.commands.HelpCommand; +import seedu.resireg.logic.commands.ListCommand; +import seedu.resireg.logic.parser.exceptions.ParseException; +import seedu.resireg.model.student.NameContainsKeywordsPredicate; +import seedu.resireg.model.student.Student; +import seedu.resireg.testutil.EditStudentDescriptorBuilder; +import seedu.resireg.testutil.StudentBuilder; +import seedu.resireg.testutil.StudentUtil; public class AddressBookParserTest { @@ -35,9 +35,9 @@ public class AddressBookParserTest { @Test public void parseCommand_add() throws Exception { - Person person = new PersonBuilder().build(); - AddCommand command = (AddCommand) parser.parseCommand(PersonUtil.getAddCommand(person)); - assertEquals(new AddCommand(person), command); + Student student = new StudentBuilder().build(); + AddCommand command = (AddCommand) parser.parseCommand(StudentUtil.getAddCommand(student)); + assertEquals(new AddCommand(student), command); } @Test @@ -55,10 +55,10 @@ public void parseCommand_delete() throws Exception { @Test public void parseCommand_edit() throws Exception { - Person person = new PersonBuilder().build(); - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(person).build(); + Student student = new StudentBuilder().build(); + EditStudentDescriptor descriptor = new EditStudentDescriptorBuilder(student).build(); EditCommand command = (EditCommand) parser.parseCommand(EditCommand.COMMAND_WORD + " " - + INDEX_FIRST_PERSON.getOneBased() + " " + PersonUtil.getEditPersonDescriptorDetails(descriptor)); + + INDEX_FIRST_PERSON.getOneBased() + " " + StudentUtil.getEditStudentDescriptorDetails(descriptor)); assertEquals(new EditCommand(INDEX_FIRST_PERSON, descriptor), command); } diff --git a/src/test/java/seedu/address/logic/parser/ArgumentTokenizerTest.java b/src/test/java/seedu/resireg/logic/parser/ArgumentTokenizerTest.java similarity index 99% rename from src/test/java/seedu/address/logic/parser/ArgumentTokenizerTest.java rename to src/test/java/seedu/resireg/logic/parser/ArgumentTokenizerTest.java index c97308935f5..907b81267c6 100644 --- a/src/test/java/seedu/address/logic/parser/ArgumentTokenizerTest.java +++ b/src/test/java/seedu/resireg/logic/parser/ArgumentTokenizerTest.java @@ -1,4 +1,4 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/seedu/address/logic/parser/CommandParserTestUtil.java b/src/test/java/seedu/resireg/logic/parser/CommandParserTestUtil.java similarity index 89% rename from src/test/java/seedu/address/logic/parser/CommandParserTestUtil.java rename to src/test/java/seedu/resireg/logic/parser/CommandParserTestUtil.java index e4c33515768..778d19a219b 100644 --- a/src/test/java/seedu/address/logic/parser/CommandParserTestUtil.java +++ b/src/test/java/seedu/resireg/logic/parser/CommandParserTestUtil.java @@ -1,9 +1,9 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; import static org.junit.jupiter.api.Assertions.assertEquals; -import seedu.address.logic.commands.Command; -import seedu.address.logic.parser.exceptions.ParseException; +import seedu.resireg.logic.commands.Command; +import seedu.resireg.logic.parser.exceptions.ParseException; /** * Contains helper methods for testing command parsers. diff --git a/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java b/src/test/java/seedu/resireg/logic/parser/DeleteCommandParserTest.java similarity index 73% rename from src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java rename to src/test/java/seedu/resireg/logic/parser/DeleteCommandParserTest.java index 27eaec84450..1eaf35adf40 100644 --- a/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java +++ b/src/test/java/seedu/resireg/logic/parser/DeleteCommandParserTest.java @@ -1,13 +1,13 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; -import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; +import static seedu.resireg.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.resireg.logic.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.resireg.logic.parser.CommandParserTestUtil.assertParseSuccess; +import static seedu.resireg.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import org.junit.jupiter.api.Test; -import seedu.address.logic.commands.DeleteCommand; +import seedu.resireg.logic.commands.DeleteCommand; /** * As we are only doing white-box testing, our test cases do not cover path variations diff --git a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java b/src/test/java/seedu/resireg/logic/parser/EditCommandParserTest.java similarity index 54% rename from src/test/java/seedu/address/logic/parser/EditCommandParserTest.java rename to src/test/java/seedu/resireg/logic/parser/EditCommandParserTest.java index 2ff31522486..12a4dcc8fbf 100644 --- a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java +++ b/src/test/java/seedu/resireg/logic/parser/EditCommandParserTest.java @@ -1,47 +1,53 @@ -package seedu.address.logic.parser; - -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY; -import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_BOB; -import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY; -import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_BOB; -import static seedu.address.logic.commands.CommandTestUtil.INVALID_ADDRESS_DESC; -import static seedu.address.logic.commands.CommandTestUtil.INVALID_EMAIL_DESC; -import static seedu.address.logic.commands.CommandTestUtil.INVALID_NAME_DESC; -import static seedu.address.logic.commands.CommandTestUtil.INVALID_PHONE_DESC; -import static seedu.address.logic.commands.CommandTestUtil.INVALID_TAG_DESC; -import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY; -import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_AMY; -import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_BOB; -import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_FRIEND; -import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_HUSBAND; -import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_AMY; -import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY; -import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_AMY; -import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_AMY; -import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB; -import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND; -import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; -import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; -import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; -import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON; -import static seedu.address.testutil.TypicalIndexes.INDEX_THIRD_PERSON; +package seedu.resireg.logic.parser; + +import static seedu.resireg.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.resireg.logic.commands.CommandTestUtil.EMAIL_DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.EMAIL_DESC_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.FACULTY_DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.FACULTY_DESC_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.INVALID_EMAIL_DESC; +import static seedu.resireg.logic.commands.CommandTestUtil.INVALID_FACULTY_DESC; +import static seedu.resireg.logic.commands.CommandTestUtil.INVALID_NAME_DESC; +import static seedu.resireg.logic.commands.CommandTestUtil.INVALID_PHONE_DESC; +import static seedu.resireg.logic.commands.CommandTestUtil.INVALID_STUDENT_ID_DESC; +import static seedu.resireg.logic.commands.CommandTestUtil.INVALID_TAG_DESC; +import static seedu.resireg.logic.commands.CommandTestUtil.NAME_DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.PHONE_DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.PHONE_DESC_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.STUDENT_ID_DESC_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.STUDENT_ID_DESC_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.TAG_DESC_FRIEND; +import static seedu.resireg.logic.commands.CommandTestUtil.TAG_DESC_HUSBAND; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_EMAIL_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_EMAIL_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_FACULTY_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_FACULTY_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_NAME_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_PHONE_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_PHONE_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_STUDENT_ID_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_STUDENT_ID_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_TAG_FRIEND; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.resireg.logic.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.resireg.logic.parser.CommandParserTestUtil.assertParseSuccess; +import static seedu.resireg.testutil.TypicalIndexes.INDEX_FIRST_PERSON; +import static seedu.resireg.testutil.TypicalIndexes.INDEX_SECOND_PERSON; +import static seedu.resireg.testutil.TypicalIndexes.INDEX_THIRD_PERSON; import org.junit.jupiter.api.Test; -import seedu.address.commons.core.index.Index; -import seedu.address.logic.commands.EditCommand; -import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Phone; -import seedu.address.model.tag.Tag; -import seedu.address.testutil.EditPersonDescriptorBuilder; +import seedu.resireg.commons.core.index.Index; +import seedu.resireg.logic.commands.EditCommand; +import seedu.resireg.logic.commands.EditCommand.EditStudentDescriptor; +import seedu.resireg.model.student.Email; +import seedu.resireg.model.student.Name; +import seedu.resireg.model.student.Phone; +import seedu.resireg.model.student.StudentId; +import seedu.resireg.model.student.faculty.Faculty; +import seedu.resireg.model.tag.Tag; +import seedu.resireg.testutil.EditStudentDescriptorBuilder; public class EditCommandParserTest { @@ -76,7 +82,7 @@ public void parse_invalidPreamble_failure() { assertParseFailure(parser, "1 some random string", MESSAGE_INVALID_FORMAT); // invalid prefix being parsed as preamble - assertParseFailure(parser, "1 i/ string", MESSAGE_INVALID_FORMAT); + assertParseFailure(parser, "1 j/ string", MESSAGE_INVALID_FORMAT); } @Test @@ -84,7 +90,8 @@ public void parse_invalidValue_failure() { assertParseFailure(parser, "1" + INVALID_NAME_DESC, Name.MESSAGE_CONSTRAINTS); // invalid name assertParseFailure(parser, "1" + INVALID_PHONE_DESC, Phone.MESSAGE_CONSTRAINTS); // invalid phone assertParseFailure(parser, "1" + INVALID_EMAIL_DESC, Email.MESSAGE_CONSTRAINTS); // invalid email - assertParseFailure(parser, "1" + INVALID_ADDRESS_DESC, Address.MESSAGE_CONSTRAINTS); // invalid address + assertParseFailure(parser, "1" + INVALID_FACULTY_DESC, Faculty.MESSAGE_CONSTRAINTS); // invalid faculty + assertParseFailure(parser, "1" + INVALID_STUDENT_ID_DESC, StudentId.MESSAGE_CONSTRAINTS); // invalid id assertParseFailure(parser, "1" + INVALID_TAG_DESC, Tag.MESSAGE_CONSTRAINTS); // invalid tag // invalid phone followed by valid email @@ -94,14 +101,15 @@ public void parse_invalidValue_failure() { // is tested at {@code parse_invalidValueFollowedByValidValue_success()} assertParseFailure(parser, "1" + PHONE_DESC_BOB + INVALID_PHONE_DESC, Phone.MESSAGE_CONSTRAINTS); - // while parsing {@code PREFIX_TAG} alone will reset the tags of the {@code Person} being edited, + // while parsing {@code PREFIX_TAG} alone will reset the tags of the {@code Student} being edited, // parsing it together with a valid tag results in error assertParseFailure(parser, "1" + TAG_DESC_FRIEND + TAG_DESC_HUSBAND + TAG_EMPTY, Tag.MESSAGE_CONSTRAINTS); assertParseFailure(parser, "1" + TAG_DESC_FRIEND + TAG_EMPTY + TAG_DESC_HUSBAND, Tag.MESSAGE_CONSTRAINTS); assertParseFailure(parser, "1" + TAG_EMPTY + TAG_DESC_FRIEND + TAG_DESC_HUSBAND, Tag.MESSAGE_CONSTRAINTS); // multiple invalid values, but only the first invalid value is captured - assertParseFailure(parser, "1" + INVALID_NAME_DESC + INVALID_EMAIL_DESC + VALID_ADDRESS_AMY + VALID_PHONE_AMY, + assertParseFailure(parser, "1" + INVALID_NAME_DESC + INVALID_EMAIL_DESC + VALID_FACULTY_AMY + + VALID_STUDENT_ID_AMY + VALID_PHONE_AMY, Name.MESSAGE_CONSTRAINTS); } @@ -109,10 +117,11 @@ public void parse_invalidValue_failure() { public void parse_allFieldsSpecified_success() { Index targetIndex = INDEX_SECOND_PERSON; String userInput = targetIndex.getOneBased() + PHONE_DESC_BOB + TAG_DESC_HUSBAND - + EMAIL_DESC_AMY + ADDRESS_DESC_AMY + NAME_DESC_AMY + TAG_DESC_FRIEND; + + EMAIL_DESC_AMY + FACULTY_DESC_AMY + STUDENT_ID_DESC_AMY + NAME_DESC_AMY + TAG_DESC_FRIEND; - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY) - .withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY) + EditStudentDescriptor descriptor = new EditStudentDescriptorBuilder().withName(VALID_NAME_AMY) + .withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_AMY).withFaculty(VALID_FACULTY_AMY) + .withStudentId(VALID_STUDENT_ID_AMY) .withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND).build(); EditCommand expectedCommand = new EditCommand(targetIndex, descriptor); @@ -124,7 +133,7 @@ public void parse_someFieldsSpecified_success() { Index targetIndex = INDEX_FIRST_PERSON; String userInput = targetIndex.getOneBased() + PHONE_DESC_BOB + EMAIL_DESC_AMY; - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_BOB) + EditStudentDescriptor descriptor = new EditStudentDescriptorBuilder().withPhone(VALID_PHONE_BOB) .withEmail(VALID_EMAIL_AMY).build(); EditCommand expectedCommand = new EditCommand(targetIndex, descriptor); @@ -136,31 +145,31 @@ public void parse_oneFieldSpecified_success() { // name Index targetIndex = INDEX_THIRD_PERSON; String userInput = targetIndex.getOneBased() + NAME_DESC_AMY; - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY).build(); + EditStudentDescriptor descriptor = new EditStudentDescriptorBuilder().withName(VALID_NAME_AMY).build(); EditCommand expectedCommand = new EditCommand(targetIndex, descriptor); assertParseSuccess(parser, userInput, expectedCommand); // phone userInput = targetIndex.getOneBased() + PHONE_DESC_AMY; - descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_AMY).build(); + descriptor = new EditStudentDescriptorBuilder().withPhone(VALID_PHONE_AMY).build(); expectedCommand = new EditCommand(targetIndex, descriptor); assertParseSuccess(parser, userInput, expectedCommand); // email userInput = targetIndex.getOneBased() + EMAIL_DESC_AMY; - descriptor = new EditPersonDescriptorBuilder().withEmail(VALID_EMAIL_AMY).build(); + descriptor = new EditStudentDescriptorBuilder().withEmail(VALID_EMAIL_AMY).build(); expectedCommand = new EditCommand(targetIndex, descriptor); assertParseSuccess(parser, userInput, expectedCommand); // address - userInput = targetIndex.getOneBased() + ADDRESS_DESC_AMY; - descriptor = new EditPersonDescriptorBuilder().withAddress(VALID_ADDRESS_AMY).build(); + userInput = targetIndex.getOneBased() + FACULTY_DESC_AMY; + descriptor = new EditStudentDescriptorBuilder().withFaculty(VALID_FACULTY_AMY).build(); expectedCommand = new EditCommand(targetIndex, descriptor); assertParseSuccess(parser, userInput, expectedCommand); // tags userInput = targetIndex.getOneBased() + TAG_DESC_FRIEND; - descriptor = new EditPersonDescriptorBuilder().withTags(VALID_TAG_FRIEND).build(); + descriptor = new EditStudentDescriptorBuilder().withTags(VALID_TAG_FRIEND).build(); expectedCommand = new EditCommand(targetIndex, descriptor); assertParseSuccess(parser, userInput, expectedCommand); } @@ -168,12 +177,14 @@ public void parse_oneFieldSpecified_success() { @Test public void parse_multipleRepeatedFields_acceptsLast() { Index targetIndex = INDEX_FIRST_PERSON; - String userInput = targetIndex.getOneBased() + PHONE_DESC_AMY + ADDRESS_DESC_AMY + EMAIL_DESC_AMY - + TAG_DESC_FRIEND + PHONE_DESC_AMY + ADDRESS_DESC_AMY + EMAIL_DESC_AMY + TAG_DESC_FRIEND - + PHONE_DESC_BOB + ADDRESS_DESC_BOB + EMAIL_DESC_BOB + TAG_DESC_HUSBAND; - - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_BOB) - .withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_FRIEND, VALID_TAG_HUSBAND) + String userInput = targetIndex.getOneBased() + PHONE_DESC_AMY + FACULTY_DESC_AMY + EMAIL_DESC_AMY + + TAG_DESC_FRIEND + PHONE_DESC_AMY + FACULTY_DESC_AMY + STUDENT_ID_DESC_AMY + + EMAIL_DESC_AMY + TAG_DESC_FRIEND + + PHONE_DESC_BOB + FACULTY_DESC_BOB + STUDENT_ID_DESC_BOB + EMAIL_DESC_BOB + TAG_DESC_HUSBAND; + + EditStudentDescriptor descriptor = new EditStudentDescriptorBuilder().withPhone(VALID_PHONE_BOB) + .withEmail(VALID_EMAIL_BOB).withFaculty(VALID_FACULTY_BOB).withStudentId(VALID_STUDENT_ID_BOB) + .withTags(VALID_TAG_FRIEND, VALID_TAG_HUSBAND) .build(); EditCommand expectedCommand = new EditCommand(targetIndex, descriptor); @@ -185,15 +196,15 @@ public void parse_invalidValueFollowedByValidValue_success() { // no other valid values specified Index targetIndex = INDEX_FIRST_PERSON; String userInput = targetIndex.getOneBased() + INVALID_PHONE_DESC + PHONE_DESC_BOB; - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_BOB).build(); + EditStudentDescriptor descriptor = new EditStudentDescriptorBuilder().withPhone(VALID_PHONE_BOB).build(); EditCommand expectedCommand = new EditCommand(targetIndex, descriptor); assertParseSuccess(parser, userInput, expectedCommand); // other valid values specified - userInput = targetIndex.getOneBased() + EMAIL_DESC_BOB + INVALID_PHONE_DESC + ADDRESS_DESC_BOB - + PHONE_DESC_BOB; - descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB) - .withAddress(VALID_ADDRESS_BOB).build(); + userInput = targetIndex.getOneBased() + EMAIL_DESC_BOB + INVALID_PHONE_DESC + FACULTY_DESC_BOB + + STUDENT_ID_DESC_BOB + PHONE_DESC_BOB; + descriptor = new EditStudentDescriptorBuilder().withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB) + .withFaculty(VALID_FACULTY_BOB).withStudentId(VALID_STUDENT_ID_BOB).build(); expectedCommand = new EditCommand(targetIndex, descriptor); assertParseSuccess(parser, userInput, expectedCommand); } @@ -203,7 +214,7 @@ public void parse_resetTags_success() { Index targetIndex = INDEX_THIRD_PERSON; String userInput = targetIndex.getOneBased() + TAG_EMPTY; - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withTags().build(); + EditStudentDescriptor descriptor = new EditStudentDescriptorBuilder().withTags().build(); EditCommand expectedCommand = new EditCommand(targetIndex, descriptor); assertParseSuccess(parser, userInput, expectedCommand); diff --git a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java b/src/test/java/seedu/resireg/logic/parser/FindCommandParserTest.java similarity index 72% rename from src/test/java/seedu/address/logic/parser/FindCommandParserTest.java rename to src/test/java/seedu/resireg/logic/parser/FindCommandParserTest.java index 70f4f0e79c4..ea246bc7991 100644 --- a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java +++ b/src/test/java/seedu/resireg/logic/parser/FindCommandParserTest.java @@ -1,15 +1,15 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; +import static seedu.resireg.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.resireg.logic.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.resireg.logic.parser.CommandParserTestUtil.assertParseSuccess; import java.util.Arrays; import org.junit.jupiter.api.Test; -import seedu.address.logic.commands.FindCommand; -import seedu.address.model.person.NameContainsKeywordsPredicate; +import seedu.resireg.logic.commands.FindCommand; +import seedu.resireg.model.student.NameContainsKeywordsPredicate; public class FindCommandParserTest { diff --git a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java b/src/test/java/seedu/resireg/logic/parser/ParserUtilTest.java similarity index 71% rename from src/test/java/seedu/address/logic/parser/ParserUtilTest.java rename to src/test/java/seedu/resireg/logic/parser/ParserUtilTest.java index 4256788b1a7..2802d9c389f 100644 --- a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java +++ b/src/test/java/seedu/resireg/logic/parser/ParserUtilTest.java @@ -1,10 +1,10 @@ -package seedu.address.logic.parser; +package seedu.resireg.logic.parser; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.logic.parser.ParserUtil.MESSAGE_INVALID_INDEX; -import static seedu.address.testutil.Assert.assertThrows; -import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; +import static seedu.resireg.logic.parser.ParserUtil.MESSAGE_INVALID_INDEX; +import static seedu.resireg.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import java.util.Arrays; import java.util.Collections; @@ -13,23 +13,26 @@ import org.junit.jupiter.api.Test; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Phone; -import seedu.address.model.tag.Tag; +import seedu.resireg.logic.parser.exceptions.ParseException; +import seedu.resireg.model.student.Email; +import seedu.resireg.model.student.Name; +import seedu.resireg.model.student.Phone; +import seedu.resireg.model.student.StudentId; +import seedu.resireg.model.student.faculty.Faculty; +import seedu.resireg.model.tag.Tag; public class ParserUtilTest { private static final String INVALID_NAME = "R@chel"; private static final String INVALID_PHONE = "+651234"; - private static final String INVALID_ADDRESS = " "; + private static final String INVALID_FACULTY = "foo"; + private static final String INVALID_STUDENT_ID = "bar"; private static final String INVALID_EMAIL = "example.com"; private static final String INVALID_TAG = "#friend"; private static final String VALID_NAME = "Rachel Walker"; private static final String VALID_PHONE = "123456"; - private static final String VALID_ADDRESS = "123 Main Street #0505"; + private static final String VALID_FACULTY = "FASS"; + private static final String VALID_STUDENT_ID = "E0111111"; private static final String VALID_EMAIL = "rachel@example.com"; private static final String VALID_TAG_1 = "friend"; private static final String VALID_TAG_2 = "neighbour"; @@ -103,26 +106,49 @@ public void parsePhone_validValueWithWhitespace_returnsTrimmedPhone() throws Exc } @Test - public void parseAddress_null_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> ParserUtil.parseAddress((String) null)); + public void parseFaculty_null_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> ParserUtil.parseFaculty((String) null)); } @Test - public void parseAddress_invalidValue_throwsParseException() { - assertThrows(ParseException.class, () -> ParserUtil.parseAddress(INVALID_ADDRESS)); + public void parseFaculty_invalidValue_throwsParseException() { + assertThrows(ParseException.class, () -> ParserUtil.parseFaculty(INVALID_FACULTY)); } @Test - public void parseAddress_validValueWithoutWhitespace_returnsAddress() throws Exception { - Address expectedAddress = new Address(VALID_ADDRESS); - assertEquals(expectedAddress, ParserUtil.parseAddress(VALID_ADDRESS)); + public void parseFaculty_validValueWithoutWhitespace_returnsFaculty() throws Exception { + Faculty expectedFaculty = new Faculty(VALID_FACULTY); + assertEquals(expectedFaculty, ParserUtil.parseFaculty(VALID_FACULTY)); } @Test - public void parseAddress_validValueWithWhitespace_returnsTrimmedAddress() throws Exception { - String addressWithWhitespace = WHITESPACE + VALID_ADDRESS + WHITESPACE; - Address expectedAddress = new Address(VALID_ADDRESS); - assertEquals(expectedAddress, ParserUtil.parseAddress(addressWithWhitespace)); + public void parseFaculty_validValueWithWhitespace_returnsTrimmedAddress() throws Exception { + String facultyWithWhitespace = WHITESPACE + VALID_FACULTY + WHITESPACE; + Faculty expectedFaculty = new Faculty(VALID_FACULTY); + assertEquals(expectedFaculty, ParserUtil.parseFaculty(facultyWithWhitespace)); + } + + @Test + public void parseStudentId_null_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> ParserUtil.parseStudentId((String) null)); + } + + @Test + public void parseStudentId_invalidValue_throwsParseException() { + assertThrows(ParseException.class, () -> ParserUtil.parseStudentId(INVALID_STUDENT_ID)); + } + + @Test + public void parseStudentId_validValueWithoutWhitespace_returnsStudentId() throws Exception { + StudentId expectedStudentId = new StudentId(VALID_STUDENT_ID); + assertEquals(expectedStudentId, ParserUtil.parseStudentId(VALID_STUDENT_ID)); + } + + @Test + public void parseStudentId_validValueWithWhitespace_returnsTrimmedStudentId() throws Exception { + String studentIdWithWhitespace = WHITESPACE + VALID_STUDENT_ID + WHITESPACE; + StudentId expectedStudentId = new StudentId(VALID_STUDENT_ID); + assertEquals(expectedStudentId, ParserUtil.parseStudentId(studentIdWithWhitespace)); } @Test diff --git a/src/test/java/seedu/resireg/model/AddressBookTest.java b/src/test/java/seedu/resireg/model/AddressBookTest.java new file mode 100644 index 00000000000..4a39f314cee --- /dev/null +++ b/src/test/java/seedu/resireg/model/AddressBookTest.java @@ -0,0 +1,102 @@ +package seedu.resireg.model; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_FACULTY_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; +import static seedu.resireg.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.TypicalStudents.ALICE; +import static seedu.resireg.testutil.TypicalStudents.getTypicalAddressBook; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import seedu.resireg.model.student.Student; +import seedu.resireg.model.student.exceptions.DuplicateStudentException; +import seedu.resireg.testutil.StudentBuilder; + +public class AddressBookTest { + + private final AddressBook addressBook = new AddressBook(); + + @Test + public void constructor() { + assertEquals(Collections.emptyList(), addressBook.getStudentList()); + } + + @Test + public void resetData_null_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> addressBook.resetData(null)); + } + + @Test + public void resetData_withValidReadOnlyAddressBook_replacesData() { + AddressBook newData = getTypicalAddressBook(); + addressBook.resetData(newData); + assertEquals(newData, addressBook); + } + + @Test + public void resetData_withDuplicateStudents_throwsDuplicateStudentException() { + // Two students with the same identity fields + Student editedAlice = new StudentBuilder(ALICE).withFaculty(VALID_FACULTY_BOB).withTags(VALID_TAG_HUSBAND) + .build(); + List newStudents = Arrays.asList(ALICE, editedAlice); + AddressBookStub newData = new AddressBookStub(newStudents); + + assertThrows(DuplicateStudentException.class, () -> addressBook.resetData(newData)); + } + + @Test + public void hasStudent_nullStudent_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> addressBook.hasStudent(null)); + } + + @Test + public void hasStudent_studentNotInAddressBook_returnsFalse() { + assertFalse(addressBook.hasStudent(ALICE)); + } + + @Test + public void hasStudent_studentInAddressBook_returnsTrue() { + addressBook.addStudent(ALICE); + assertTrue(addressBook.hasStudent(ALICE)); + } + + @Test + public void hasStudent_studentWithSameIdentityFieldsInAddressBook_returnsTrue() { + addressBook.addStudent(ALICE); + Student editedAlice = new StudentBuilder(ALICE).withFaculty(VALID_FACULTY_BOB).withTags(VALID_TAG_HUSBAND) + .build(); + assertTrue(addressBook.hasStudent(editedAlice)); + } + + @Test + public void getStudentList_modifyList_throwsUnsupportedOperationException() { + assertThrows(UnsupportedOperationException.class, () -> addressBook.getStudentList().remove(0)); + } + + /** + * A stub ReadOnlyAddressBook whose students list can violate interface constraints. + */ + private static class AddressBookStub implements ReadOnlyAddressBook { + private final ObservableList students = FXCollections.observableArrayList(); + + AddressBookStub(Collection students) { + this.students.setAll(students); + } + + @Override + public ObservableList getStudentList() { + return students; + } + } + +} diff --git a/src/test/java/seedu/address/model/ModelManagerTest.java b/src/test/java/seedu/resireg/model/ModelManagerTest.java similarity index 76% rename from src/test/java/seedu/address/model/ModelManagerTest.java rename to src/test/java/seedu/resireg/model/ModelManagerTest.java index 2cf1418d116..88f4bd627a3 100644 --- a/src/test/java/seedu/address/model/ModelManagerTest.java +++ b/src/test/java/seedu/resireg/model/ModelManagerTest.java @@ -1,12 +1,12 @@ -package seedu.address.model; +package seedu.resireg.model; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; -import static seedu.address.testutil.Assert.assertThrows; -import static seedu.address.testutil.TypicalPersons.ALICE; -import static seedu.address.testutil.TypicalPersons.BENSON; +import static seedu.resireg.model.Model.PREDICATE_SHOW_ALL_PERSONS; +import static seedu.resireg.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.TypicalStudents.ALICE; +import static seedu.resireg.testutil.TypicalStudents.BENSON; import java.nio.file.Path; import java.nio.file.Paths; @@ -14,9 +14,9 @@ import org.junit.jupiter.api.Test; -import seedu.address.commons.core.GuiSettings; -import seedu.address.model.person.NameContainsKeywordsPredicate; -import seedu.address.testutil.AddressBookBuilder; +import seedu.resireg.commons.core.GuiSettings; +import seedu.resireg.model.student.NameContainsKeywordsPredicate; +import seedu.resireg.testutil.AddressBookBuilder; public class ModelManagerTest { @@ -73,29 +73,29 @@ public void setAddressBookFilePath_validPath_setsAddressBookFilePath() { } @Test - public void hasPerson_nullPerson_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> modelManager.hasPerson(null)); + public void hasStudent_nullStudent_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> modelManager.hasStudent(null)); } @Test - public void hasPerson_personNotInAddressBook_returnsFalse() { - assertFalse(modelManager.hasPerson(ALICE)); + public void hasStudent_studentNotInAddressBook_returnsFalse() { + assertFalse(modelManager.hasStudent(ALICE)); } @Test - public void hasPerson_personInAddressBook_returnsTrue() { - modelManager.addPerson(ALICE); - assertTrue(modelManager.hasPerson(ALICE)); + public void hasStudent_studentInAddressBook_returnsTrue() { + modelManager.addStudent(ALICE); + assertTrue(modelManager.hasStudent(ALICE)); } @Test - public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException() { - assertThrows(UnsupportedOperationException.class, () -> modelManager.getFilteredPersonList().remove(0)); + public void getFilteredStudentList_modifyList_throwsUnsupportedOperationException() { + assertThrows(UnsupportedOperationException.class, () -> modelManager.getFilteredStudentList().remove(0)); } @Test public void equals() { - AddressBook addressBook = new AddressBookBuilder().withPerson(ALICE).withPerson(BENSON).build(); + AddressBook addressBook = new AddressBookBuilder().withStudent(ALICE).withStudent(BENSON).build(); AddressBook differentAddressBook = new AddressBook(); UserPrefs userPrefs = new UserPrefs(); @@ -118,11 +118,11 @@ public void equals() { // different filteredList -> returns false String[] keywords = ALICE.getName().fullName.split("\\s+"); - modelManager.updateFilteredPersonList(new NameContainsKeywordsPredicate(Arrays.asList(keywords))); + modelManager.updateFilteredStudentList(new NameContainsKeywordsPredicate(Arrays.asList(keywords))); assertFalse(modelManager.equals(new ModelManager(addressBook, userPrefs))); // resets modelManager to initial state for upcoming tests - modelManager.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); + modelManager.updateFilteredStudentList(PREDICATE_SHOW_ALL_PERSONS); // different userPrefs -> returns false UserPrefs differentUserPrefs = new UserPrefs(); diff --git a/src/test/java/seedu/address/model/UserPrefsTest.java b/src/test/java/seedu/resireg/model/UserPrefsTest.java similarity index 86% rename from src/test/java/seedu/address/model/UserPrefsTest.java rename to src/test/java/seedu/resireg/model/UserPrefsTest.java index b1307a70d52..4e47d40bf58 100644 --- a/src/test/java/seedu/address/model/UserPrefsTest.java +++ b/src/test/java/seedu/resireg/model/UserPrefsTest.java @@ -1,6 +1,6 @@ -package seedu.address.model; +package seedu.resireg.model; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/address/model/person/EmailTest.java b/src/test/java/seedu/resireg/model/student/EmailTest.java similarity index 97% rename from src/test/java/seedu/address/model/person/EmailTest.java rename to src/test/java/seedu/resireg/model/student/EmailTest.java index 7fa726ceb18..9b3690e8dd9 100644 --- a/src/test/java/seedu/address/model/person/EmailTest.java +++ b/src/test/java/seedu/resireg/model/student/EmailTest.java @@ -1,8 +1,8 @@ -package seedu.address.model.person; +package seedu.resireg.model.student; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/resireg/model/student/FacultyTest.java b/src/test/java/seedu/resireg/model/student/FacultyTest.java new file mode 100644 index 00000000000..78d547a50db --- /dev/null +++ b/src/test/java/seedu/resireg/model/student/FacultyTest.java @@ -0,0 +1,40 @@ +package seedu.resireg.model.student; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.resireg.testutil.Assert.assertThrows; + +import org.junit.jupiter.api.Test; + +import seedu.resireg.model.student.faculty.Faculty; + +public class FacultyTest { + + @Test + public void constructor_null_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> new Faculty(null)); + } + + @Test + public void constructor_invalidAddress_throwsIllegalArgumentException() { + String invalidFaculty = ""; + assertThrows(IllegalArgumentException.class, () -> new Faculty(invalidFaculty)); + } + + @Test + public void isValidFaculty() { + // null faculty + assertThrows(NullPointerException.class, () -> Faculty.isValidFaculty(null)); + + // invalid faculties + assertFalse(Faculty.isValidFaculty("")); // empty string + assertFalse(Faculty.isValidFaculty(" ")); // spaces only + assertFalse(Faculty.isValidFaculty("dnfj")); // invalid faculty abbreviation + + + // valid faculties + assertTrue(Faculty.isValidFaculty("FASS")); + assertTrue(Faculty.isValidFaculty("DEN")); + assertTrue(Faculty.isValidFaculty("USP")); + } +} diff --git a/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java b/src/test/java/seedu/resireg/model/student/NameContainsKeywordsPredicateTest.java similarity index 74% rename from src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java rename to src/test/java/seedu/resireg/model/student/NameContainsKeywordsPredicateTest.java index f136664e017..c7b5f3b2d35 100644 --- a/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java +++ b/src/test/java/seedu/resireg/model/student/NameContainsKeywordsPredicateTest.java @@ -1,4 +1,4 @@ -package seedu.address.model.person; +package seedu.resireg.model.student; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test; -import seedu.address.testutil.PersonBuilder; +import seedu.resireg.testutil.StudentBuilder; public class NameContainsKeywordsPredicateTest { @@ -34,7 +34,7 @@ public void equals() { // null -> returns false assertFalse(firstPredicate.equals(null)); - // different person -> returns false + // different student -> returns false assertFalse(firstPredicate.equals(secondPredicate)); } @@ -42,34 +42,34 @@ public void equals() { public void test_nameContainsKeywords_returnsTrue() { // One keyword NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Collections.singletonList("Alice")); - assertTrue(predicate.test(new PersonBuilder().withName("Alice Bob").build())); + assertTrue(predicate.test(new StudentBuilder().withName("Alice Bob").build())); // Multiple keywords predicate = new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob")); - assertTrue(predicate.test(new PersonBuilder().withName("Alice Bob").build())); + assertTrue(predicate.test(new StudentBuilder().withName("Alice Bob").build())); // Only one matching keyword predicate = new NameContainsKeywordsPredicate(Arrays.asList("Bob", "Carol")); - assertTrue(predicate.test(new PersonBuilder().withName("Alice Carol").build())); + assertTrue(predicate.test(new StudentBuilder().withName("Alice Carol").build())); // Mixed-case keywords predicate = new NameContainsKeywordsPredicate(Arrays.asList("aLIce", "bOB")); - assertTrue(predicate.test(new PersonBuilder().withName("Alice Bob").build())); + assertTrue(predicate.test(new StudentBuilder().withName("Alice Bob").build())); } @Test public void test_nameDoesNotContainKeywords_returnsFalse() { // Zero keywords NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Collections.emptyList()); - assertFalse(predicate.test(new PersonBuilder().withName("Alice").build())); + assertFalse(predicate.test(new StudentBuilder().withName("Alice").build())); // Non-matching keyword predicate = new NameContainsKeywordsPredicate(Arrays.asList("Carol")); - assertFalse(predicate.test(new PersonBuilder().withName("Alice Bob").build())); + assertFalse(predicate.test(new StudentBuilder().withName("Alice Bob").build())); // Keywords match phone, email and address, but does not match name predicate = new NameContainsKeywordsPredicate(Arrays.asList("12345", "alice@email.com", "Main", "Street")); - assertFalse(predicate.test(new PersonBuilder().withName("Alice").withPhone("12345") - .withEmail("alice@email.com").withAddress("Main Street").build())); + assertFalse(predicate.test(new StudentBuilder().withName("Alice").withPhone("12345") + .withEmail("alice@email.com").withFaculty("FASS").withStudentId("E0111111").build())); } } diff --git a/src/test/java/seedu/address/model/person/NameTest.java b/src/test/java/seedu/resireg/model/student/NameTest.java similarity index 93% rename from src/test/java/seedu/address/model/person/NameTest.java rename to src/test/java/seedu/resireg/model/student/NameTest.java index c9801392874..6ee5b3d7a0a 100644 --- a/src/test/java/seedu/address/model/person/NameTest.java +++ b/src/test/java/seedu/resireg/model/student/NameTest.java @@ -1,8 +1,8 @@ -package seedu.address.model.person; +package seedu.resireg.model.student; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/address/model/person/PhoneTest.java b/src/test/java/seedu/resireg/model/student/PhoneTest.java similarity index 93% rename from src/test/java/seedu/address/model/person/PhoneTest.java rename to src/test/java/seedu/resireg/model/student/PhoneTest.java index 8dd52766a5f..2bb46855b06 100644 --- a/src/test/java/seedu/address/model/person/PhoneTest.java +++ b/src/test/java/seedu/resireg/model/student/PhoneTest.java @@ -1,8 +1,8 @@ -package seedu.address.model.person; +package seedu.resireg.model.student; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/resireg/model/student/StudentIdTest.java b/src/test/java/seedu/resireg/model/student/StudentIdTest.java new file mode 100644 index 00000000000..43e371a49d2 --- /dev/null +++ b/src/test/java/seedu/resireg/model/student/StudentIdTest.java @@ -0,0 +1,42 @@ +package seedu.resireg.model.student; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.resireg.testutil.Assert.assertThrows; + +import org.junit.jupiter.api.Test; + +import seedu.resireg.model.student.faculty.Faculty; + +public class StudentIdTest { + + @Test + public void constructor_null_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> new StudentId(null)); + } + + @Test + public void constructor_invalidAddress_throwsIllegalArgumentException() { + String invalidStudentId = ""; + assertThrows(IllegalArgumentException.class, () -> new Faculty(invalidStudentId)); + } + + @Test + public void isValidFaculty() { + // null student ID + assertThrows(NullPointerException.class, () -> Faculty.isValidFaculty(null)); + + // invalid student IDs + assertFalse(Faculty.isValidFaculty("")); // empty string + assertFalse(Faculty.isValidFaculty(" ")); // spaces only + assertFalse(Faculty.isValidFaculty("e")); // missing "0" and 6 digits + assertFalse(Faculty.isValidFaculty("E0")); // missing 6 digits + assertFalse(Faculty.isValidFaculty("E012345")); // only 5 digits + + + // valid student IDs + assertTrue(StudentId.isValidStudentId("E0407889")); + assertTrue(StudentId.isValidStudentId("E0123456")); + assertTrue(StudentId.isValidStudentId("E0123457")); + } +} diff --git a/src/test/java/seedu/resireg/model/student/StudentTest.java b/src/test/java/seedu/resireg/model/student/StudentTest.java new file mode 100644 index 00000000000..1869319fa8e --- /dev/null +++ b/src/test/java/seedu/resireg/model/student/StudentTest.java @@ -0,0 +1,104 @@ +package seedu.resireg.model.student; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_EMAIL_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_FACULTY_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_NAME_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_PHONE_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_STUDENT_ID_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; +import static seedu.resireg.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.TypicalStudents.ALICE; +import static seedu.resireg.testutil.TypicalStudents.BOB; + +import org.junit.jupiter.api.Test; + +import seedu.resireg.testutil.StudentBuilder; + +public class StudentTest { + + @Test + public void asObservableList_modifyList_throwsUnsupportedOperationException() { + Student student = new StudentBuilder().build(); + assertThrows(UnsupportedOperationException.class, () -> student.getTags().remove(0)); + } + + @Test + public void isSameStudent() { + // same object -> returns true + assertTrue(ALICE.isSameStudent(ALICE)); + + // null -> returns false + assertFalse(ALICE.isSameStudent(null)); + + // different phone and email, same student ID -> returns true + Student editedAlice = new StudentBuilder(ALICE).withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB).build(); + assertTrue(ALICE.isSameStudent(editedAlice)); + + // different name, same student ID -> returns true + editedAlice = new StudentBuilder(ALICE).withName(VALID_NAME_BOB).build(); + assertTrue(ALICE.isSameStudent(editedAlice)); + + // same name, same phone, different attributes (including student id) -> returns false + editedAlice = new StudentBuilder(ALICE).withEmail(VALID_EMAIL_BOB) + .withFaculty(VALID_FACULTY_BOB).withStudentId(VALID_STUDENT_ID_BOB) + .withTags(VALID_TAG_HUSBAND).build(); + assertFalse(ALICE.isSameStudent(editedAlice)); + + // same name, same email, different attributes (including student id) -> returns false + editedAlice = new StudentBuilder(ALICE).withPhone(VALID_PHONE_BOB) + .withFaculty(VALID_FACULTY_BOB).withStudentId(VALID_STUDENT_ID_BOB) + .withTags(VALID_TAG_HUSBAND).build(); + assertFalse(ALICE.isSameStudent(editedAlice)); + + // same name, same phone, same email, different attributes (including student id) -> returns false + editedAlice = new StudentBuilder(ALICE).withFaculty(VALID_FACULTY_BOB) + .withStudentId(VALID_STUDENT_ID_BOB) + .withTags(VALID_TAG_HUSBAND).build(); + assertFalse(ALICE.isSameStudent(editedAlice)); + } + + @Test + public void equals() { + // same values -> returns true + Student aliceCopy = new StudentBuilder(ALICE).build(); + assertTrue(ALICE.equals(aliceCopy)); + + // same object -> returns true + assertTrue(ALICE.equals(ALICE)); + + // null -> returns false + assertFalse(ALICE.equals(null)); + + // different type -> returns false + assertFalse(ALICE.equals(5)); + + // different student -> returns false + assertFalse(ALICE.equals(BOB)); + + // different name -> returns false + Student editedAlice = new StudentBuilder(ALICE).withName(VALID_NAME_BOB).build(); + assertFalse(ALICE.equals(editedAlice)); + + // different phone -> returns false + editedAlice = new StudentBuilder(ALICE).withPhone(VALID_PHONE_BOB).build(); + assertFalse(ALICE.equals(editedAlice)); + + // different email -> returns false + editedAlice = new StudentBuilder(ALICE).withEmail(VALID_EMAIL_BOB).build(); + assertFalse(ALICE.equals(editedAlice)); + + // different faculty -> returns false + editedAlice = new StudentBuilder(ALICE).withFaculty(VALID_FACULTY_BOB).build(); + assertFalse(ALICE.equals(editedAlice)); + + // different student ID -> returns false + editedAlice = new StudentBuilder(ALICE).withStudentId(VALID_STUDENT_ID_BOB).build(); + assertFalse(ALICE.equals(editedAlice)); + + // different tags -> returns false + editedAlice = new StudentBuilder(ALICE).withTags(VALID_TAG_HUSBAND).build(); + assertFalse(ALICE.equals(editedAlice)); + } +} diff --git a/src/test/java/seedu/resireg/model/student/UniqueStudentListTest.java b/src/test/java/seedu/resireg/model/student/UniqueStudentListTest.java new file mode 100644 index 00000000000..aa38fd1c79d --- /dev/null +++ b/src/test/java/seedu/resireg/model/student/UniqueStudentListTest.java @@ -0,0 +1,170 @@ +package seedu.resireg.model.student; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_FACULTY_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; +import static seedu.resireg.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.TypicalStudents.ALICE; +import static seedu.resireg.testutil.TypicalStudents.BOB; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import seedu.resireg.model.student.exceptions.DuplicateStudentException; +import seedu.resireg.model.student.exceptions.StudentNotFoundException; +import seedu.resireg.testutil.StudentBuilder; + +public class UniqueStudentListTest { + + private final UniqueStudentList uniqueStudentList = new UniqueStudentList(); + + @Test + public void contains_nullStudent_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> uniqueStudentList.contains(null)); + } + + @Test + public void contains_studentNotInList_returnsFalse() { + assertFalse(uniqueStudentList.contains(ALICE)); + } + + @Test + public void contains_studentInList_returnsTrue() { + uniqueStudentList.add(ALICE); + assertTrue(uniqueStudentList.contains(ALICE)); + } + + @Test + public void contains_studentWithSameIdentityFieldsInList_returnsTrue() { + uniqueStudentList.add(ALICE); + Student editedAlice = new StudentBuilder(ALICE).withFaculty(VALID_FACULTY_BOB).withTags(VALID_TAG_HUSBAND) + .build(); + assertTrue(uniqueStudentList.contains(editedAlice)); + } + + @Test + public void add_nullStudent_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> uniqueStudentList.add(null)); + } + + @Test + public void add_duplicateStudent_throwsDuplicateStudentException() { + uniqueStudentList.add(ALICE); + assertThrows(DuplicateStudentException.class, () -> uniqueStudentList.add(ALICE)); + } + + @Test + public void setStudent_nullTargetStudent_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> uniqueStudentList.setStudent(null, ALICE)); + } + + @Test + public void setStudent_nullEditedStudent_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> uniqueStudentList.setStudent(ALICE, null)); + } + + @Test + public void setStudent_targetStudentNotInList_throwsStudentNotFoundException() { + assertThrows(StudentNotFoundException.class, () -> uniqueStudentList.setStudent(ALICE, ALICE)); + } + + @Test + public void setStudent_editedStudentIsSameStudent_success() { + uniqueStudentList.add(ALICE); + uniqueStudentList.setStudent(ALICE, ALICE); + UniqueStudentList expectedUniqueStudentList = new UniqueStudentList(); + expectedUniqueStudentList.add(ALICE); + assertEquals(expectedUniqueStudentList, uniqueStudentList); + } + + @Test + public void setStudent_editedStudentHasSameIdentity_success() { + uniqueStudentList.add(ALICE); + Student editedAlice = new StudentBuilder(ALICE).withFaculty(VALID_FACULTY_BOB).withTags(VALID_TAG_HUSBAND) + .build(); + uniqueStudentList.setStudent(ALICE, editedAlice); + UniqueStudentList expectedUniqueStudentList = new UniqueStudentList(); + expectedUniqueStudentList.add(editedAlice); + assertEquals(expectedUniqueStudentList, uniqueStudentList); + } + + @Test + public void setStudent_editedStudentHasDifferentIdentity_success() { + uniqueStudentList.add(ALICE); + uniqueStudentList.setStudent(ALICE, BOB); + UniqueStudentList expectedUniqueStudentList = new UniqueStudentList(); + expectedUniqueStudentList.add(BOB); + assertEquals(expectedUniqueStudentList, uniqueStudentList); + } + + @Test + public void setStudent_editedStudentHasNonUniqueIdentity_throwsDuplicateStudentException() { + uniqueStudentList.add(ALICE); + uniqueStudentList.add(BOB); + assertThrows(DuplicateStudentException.class, () -> uniqueStudentList.setStudent(ALICE, BOB)); + } + + @Test + public void remove_nullStudent_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> uniqueStudentList.remove(null)); + } + + @Test + public void remove_studentDoesNotExist_throwsStudentNotFoundException() { + assertThrows(StudentNotFoundException.class, () -> uniqueStudentList.remove(ALICE)); + } + + @Test + public void remove_existingStudent_removesStudent() { + uniqueStudentList.add(ALICE); + uniqueStudentList.remove(ALICE); + UniqueStudentList expectedUniqueStudentList = new UniqueStudentList(); + assertEquals(expectedUniqueStudentList, uniqueStudentList); + } + + @Test + public void setStudents_nullUniqueStudentList_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> uniqueStudentList.setStudents((UniqueStudentList) null)); + } + + @Test + public void setStudents_uniqueStudentList_replacesOwnListWithProvidedUniqueStudentList() { + uniqueStudentList.add(ALICE); + UniqueStudentList expectedUniqueStudentList = new UniqueStudentList(); + expectedUniqueStudentList.add(BOB); + uniqueStudentList.setStudents(expectedUniqueStudentList); + assertEquals(expectedUniqueStudentList, uniqueStudentList); + } + + @Test + public void setStudents_nullList_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> uniqueStudentList.setStudents((List) null)); + } + + @Test + public void setStudents_list_replacesOwnListWithProvidedList() { + uniqueStudentList.add(ALICE); + List studentList = Collections.singletonList(BOB); + uniqueStudentList.setStudents(studentList); + UniqueStudentList expectedUniqueStudentList = new UniqueStudentList(); + expectedUniqueStudentList.add(BOB); + assertEquals(expectedUniqueStudentList, uniqueStudentList); + } + + @Test + public void setStudents_listWithDuplicateStudents_throwsDuplicateStudentException() { + List listWithDuplicateStudents = Arrays.asList(ALICE, ALICE); + assertThrows(DuplicateStudentException.class, () -> uniqueStudentList.setStudents(listWithDuplicateStudents)); + } + + @Test + public void asUnmodifiableObservableList_modifyList_throwsUnsupportedOperationException() { + assertThrows(UnsupportedOperationException.class, () + -> uniqueStudentList.asUnmodifiableObservableList().remove(0)); + } +} diff --git a/src/test/java/seedu/address/model/tag/TagTest.java b/src/test/java/seedu/resireg/model/tag/TagTest.java similarity index 86% rename from src/test/java/seedu/address/model/tag/TagTest.java rename to src/test/java/seedu/resireg/model/tag/TagTest.java index 64d07d79ee2..0a7a0d6f6bb 100644 --- a/src/test/java/seedu/address/model/tag/TagTest.java +++ b/src/test/java/seedu/resireg/model/tag/TagTest.java @@ -1,6 +1,6 @@ -package seedu.address.model.tag; +package seedu.resireg.model.tag; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/resireg/storage/JsonAdaptedStudentTest.java b/src/test/java/seedu/resireg/storage/JsonAdaptedStudentTest.java new file mode 100644 index 00000000000..ec449395e31 --- /dev/null +++ b/src/test/java/seedu/resireg/storage/JsonAdaptedStudentTest.java @@ -0,0 +1,139 @@ +package seedu.resireg.storage; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static seedu.resireg.storage.JsonAdaptedStudent.MISSING_FIELD_MESSAGE_FORMAT; +import static seedu.resireg.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.TypicalStudents.BENSON; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; + +import seedu.resireg.commons.exceptions.IllegalValueException; +import seedu.resireg.model.student.Email; +import seedu.resireg.model.student.Name; +import seedu.resireg.model.student.Phone; +import seedu.resireg.model.student.StudentId; +import seedu.resireg.model.student.faculty.Faculty; + +public class JsonAdaptedStudentTest { + private static final String INVALID_NAME = "R@chel"; + private static final String INVALID_PHONE = "+651234"; + private static final String INVALID_FACULTY = " "; + private static final String INVALID_STUDENT_ID = " "; + private static final String INVALID_EMAIL = "example.com"; + private static final String INVALID_TAG = "#friend"; + + private static final String VALID_NAME = BENSON.getName().toString(); + private static final String VALID_PHONE = BENSON.getPhone().toString(); + private static final String VALID_EMAIL = BENSON.getEmail().toString(); + private static final String VALID_FACULTY = BENSON.getFaculty().toString(); + private static final String VALID_STUDENT_ID = BENSON.getStudentId().toString(); + private static final List VALID_TAGS = BENSON.getTags().stream() + .map(JsonAdaptedTag::new) + .collect(Collectors.toList()); + + @Test + public void toModelType_validStudentDetails_returnsStudent() throws Exception { + JsonAdaptedStudent student = new JsonAdaptedStudent(BENSON); + assertEquals(BENSON, student.toModelType()); + } + + @Test + public void toModelType_invalidName_throwsIllegalValueException() { + JsonAdaptedStudent student = + new JsonAdaptedStudent(INVALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_FACULTY, + VALID_STUDENT_ID, VALID_TAGS); + String expectedMessage = Name.MESSAGE_CONSTRAINTS; + assertThrows(IllegalValueException.class, expectedMessage, student::toModelType); + } + + @Test + public void toModelType_nullName_throwsIllegalValueException() { + JsonAdaptedStudent student = new JsonAdaptedStudent(null, VALID_PHONE, VALID_EMAIL, VALID_FACULTY, + VALID_STUDENT_ID, VALID_TAGS); + String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName()); + assertThrows(IllegalValueException.class, expectedMessage, student::toModelType); + } + + @Test + public void toModelType_invalidPhone_throwsIllegalValueException() { + JsonAdaptedStudent student = + new JsonAdaptedStudent(VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_FACULTY, + VALID_STUDENT_ID, VALID_TAGS); + String expectedMessage = Phone.MESSAGE_CONSTRAINTS; + assertThrows(IllegalValueException.class, expectedMessage, student::toModelType); + } + + @Test + public void toModelType_nullPhone_throwsIllegalValueException() { + JsonAdaptedStudent student = new JsonAdaptedStudent(VALID_NAME, null, VALID_EMAIL, VALID_FACULTY, + VALID_STUDENT_ID, VALID_TAGS); + String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName()); + assertThrows(IllegalValueException.class, expectedMessage, student::toModelType); + } + + @Test + public void toModelType_invalidEmail_throwsIllegalValueException() { + JsonAdaptedStudent student = + new JsonAdaptedStudent(VALID_NAME, VALID_PHONE, INVALID_EMAIL, VALID_FACULTY, + VALID_STUDENT_ID, VALID_TAGS); + String expectedMessage = Email.MESSAGE_CONSTRAINTS; + assertThrows(IllegalValueException.class, expectedMessage, student::toModelType); + } + + @Test + public void toModelType_nullEmail_throwsIllegalValueException() { + JsonAdaptedStudent student = new JsonAdaptedStudent(VALID_NAME, VALID_PHONE, null, VALID_FACULTY, + VALID_STUDENT_ID, VALID_TAGS); + String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Email.class.getSimpleName()); + assertThrows(IllegalValueException.class, expectedMessage, student::toModelType); + } + + @Test + public void toModelType_invalidFaculty_throwsIllegalValueException() { + JsonAdaptedStudent student = + new JsonAdaptedStudent(VALID_NAME, VALID_PHONE, VALID_EMAIL, INVALID_FACULTY, + VALID_STUDENT_ID, VALID_TAGS); + String expectedMessage = Faculty.MESSAGE_CONSTRAINTS; + assertThrows(IllegalValueException.class, expectedMessage, student::toModelType); + } + + @Test + public void toModelType_nullFaculty_throwsIllegalValueException() { + JsonAdaptedStudent student = new JsonAdaptedStudent(VALID_NAME, VALID_PHONE, VALID_EMAIL, null, + VALID_STUDENT_ID, VALID_TAGS); + String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Faculty.class.getSimpleName()); + assertThrows(IllegalValueException.class, expectedMessage, student::toModelType); + } + + @Test + public void toModelType_invalidStudentId_throwsIllegalValueException() { + JsonAdaptedStudent student = + new JsonAdaptedStudent(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_FACULTY, + INVALID_STUDENT_ID, VALID_TAGS); + String expectedMessage = StudentId.MESSAGE_CONSTRAINTS; + assertThrows(IllegalValueException.class, expectedMessage, student::toModelType); + } + + @Test + public void toModelType_nullStudentId_throwsIllegalValueException() { + JsonAdaptedStudent student = new JsonAdaptedStudent(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_FACULTY, + null, VALID_TAGS); + String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, StudentId.class.getSimpleName()); + assertThrows(IllegalValueException.class, expectedMessage, student::toModelType); + } + + @Test + public void toModelType_invalidTags_throwsIllegalValueException() { + List invalidTags = new ArrayList<>(VALID_TAGS); + invalidTags.add(new JsonAdaptedTag(INVALID_TAG)); + JsonAdaptedStudent student = + new JsonAdaptedStudent(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_FACULTY, VALID_STUDENT_ID, + invalidTags); + assertThrows(IllegalValueException.class, student::toModelType); + } + +} diff --git a/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java b/src/test/java/seedu/resireg/storage/JsonAddressBookStorageTest.java similarity index 80% rename from src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java rename to src/test/java/seedu/resireg/storage/JsonAddressBookStorageTest.java index ac3c3af9566..644db18dec2 100644 --- a/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java +++ b/src/test/java/seedu/resireg/storage/JsonAddressBookStorageTest.java @@ -1,12 +1,12 @@ -package seedu.address.storage; +package seedu.resireg.storage; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -import static seedu.address.testutil.Assert.assertThrows; -import static seedu.address.testutil.TypicalPersons.ALICE; -import static seedu.address.testutil.TypicalPersons.HOON; -import static seedu.address.testutil.TypicalPersons.IDA; -import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; +import static seedu.resireg.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.TypicalStudents.ALICE; +import static seedu.resireg.testutil.TypicalStudents.HOON; +import static seedu.resireg.testutil.TypicalStudents.IDA; +import static seedu.resireg.testutil.TypicalStudents.getTypicalAddressBook; import java.io.IOException; import java.nio.file.Path; @@ -15,9 +15,9 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import seedu.address.commons.exceptions.DataConversionException; -import seedu.address.model.AddressBook; -import seedu.address.model.ReadOnlyAddressBook; +import seedu.resireg.commons.exceptions.DataConversionException; +import seedu.resireg.model.AddressBook; +import seedu.resireg.model.ReadOnlyAddressBook; public class JsonAddressBookStorageTest { private static final Path TEST_DATA_FOLDER = Paths.get("src", "test", "data", "JsonAddressBookStorageTest"); @@ -51,13 +51,13 @@ public void read_notJsonFormat_exceptionThrown() { } @Test - public void readAddressBook_invalidPersonAddressBook_throwDataConversionException() { - assertThrows(DataConversionException.class, () -> readAddressBook("invalidPersonAddressBook.json")); + public void readAddressBook_invalidStudentAddressBook_throwDataConversionException() { + assertThrows(DataConversionException.class, () -> readAddressBook("invalidStudentAddressBook.json")); } @Test - public void readAddressBook_invalidAndValidPersonAddressBook_throwDataConversionException() { - assertThrows(DataConversionException.class, () -> readAddressBook("invalidAndValidPersonAddressBook.json")); + public void readAddressBook_invalidAndValidStudentAddressBook_throwDataConversionException() { + assertThrows(DataConversionException.class, () -> readAddressBook("invalidAndValidStudentAddressBook.json")); } @Test @@ -72,14 +72,14 @@ public void readAndSaveAddressBook_allInOrder_success() throws Exception { assertEquals(original, new AddressBook(readBack)); // Modify data, overwrite exiting file, and read back - original.addPerson(HOON); - original.removePerson(ALICE); + original.addStudent(HOON); + original.removeStudent(ALICE); jsonAddressBookStorage.saveAddressBook(original, filePath); readBack = jsonAddressBookStorage.readAddressBook(filePath).get(); assertEquals(original, new AddressBook(readBack)); // Save and read without specifying file path - original.addPerson(IDA); + original.addStudent(IDA); jsonAddressBookStorage.saveAddressBook(original); // file path not specified readBack = jsonAddressBookStorage.readAddressBook().get(); // file path not specified assertEquals(original, new AddressBook(readBack)); diff --git a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java b/src/test/java/seedu/resireg/storage/JsonSerializableAddressBookTest.java similarity index 61% rename from src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java rename to src/test/java/seedu/resireg/storage/JsonSerializableAddressBookTest.java index 188c9058d20..ab7b92a01c3 100644 --- a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java +++ b/src/test/java/seedu/resireg/storage/JsonSerializableAddressBookTest.java @@ -1,43 +1,43 @@ -package seedu.address.storage; +package seedu.resireg.storage; import static org.junit.jupiter.api.Assertions.assertEquals; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import java.nio.file.Path; import java.nio.file.Paths; import org.junit.jupiter.api.Test; -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.commons.util.JsonUtil; -import seedu.address.model.AddressBook; -import seedu.address.testutil.TypicalPersons; +import seedu.resireg.commons.exceptions.IllegalValueException; +import seedu.resireg.commons.util.JsonUtil; +import seedu.resireg.model.AddressBook; +import seedu.resireg.testutil.TypicalStudents; public class JsonSerializableAddressBookTest { private static final Path TEST_DATA_FOLDER = Paths.get("src", "test", "data", "JsonSerializableAddressBookTest"); - private static final Path TYPICAL_PERSONS_FILE = TEST_DATA_FOLDER.resolve("typicalPersonsAddressBook.json"); - private static final Path INVALID_PERSON_FILE = TEST_DATA_FOLDER.resolve("invalidPersonAddressBook.json"); - private static final Path DUPLICATE_PERSON_FILE = TEST_DATA_FOLDER.resolve("duplicatePersonAddressBook.json"); + private static final Path TYPICAL_PERSONS_FILE = TEST_DATA_FOLDER.resolve("typicalStudentsAddressBook.json"); + private static final Path INVALID_PERSON_FILE = TEST_DATA_FOLDER.resolve("invalidStudentAddressBook.json"); + private static final Path DUPLICATE_PERSON_FILE = TEST_DATA_FOLDER.resolve("duplicateStudentAddressBook.json"); @Test - public void toModelType_typicalPersonsFile_success() throws Exception { + public void toModelType_typicalStudentsFile_success() throws Exception { JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(TYPICAL_PERSONS_FILE, JsonSerializableAddressBook.class).get(); AddressBook addressBookFromFile = dataFromFile.toModelType(); - AddressBook typicalPersonsAddressBook = TypicalPersons.getTypicalAddressBook(); - assertEquals(addressBookFromFile, typicalPersonsAddressBook); + AddressBook typicalStudentsAddressBook = TypicalStudents.getTypicalAddressBook(); + assertEquals(addressBookFromFile, typicalStudentsAddressBook); } @Test - public void toModelType_invalidPersonFile_throwsIllegalValueException() throws Exception { + public void toModelType_invalidStudentFile_throwsIllegalValueException() throws Exception { JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(INVALID_PERSON_FILE, JsonSerializableAddressBook.class).get(); assertThrows(IllegalValueException.class, dataFromFile::toModelType); } @Test - public void toModelType_duplicatePersons_throwsIllegalValueException() throws Exception { + public void toModelType_duplicateStudents_throwsIllegalValueException() throws Exception { JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(DUPLICATE_PERSON_FILE, JsonSerializableAddressBook.class).get(); assertThrows(IllegalValueException.class, JsonSerializableAddressBook.MESSAGE_DUPLICATE_PERSON, diff --git a/src/test/java/seedu/address/storage/JsonUserPrefsStorageTest.java b/src/test/java/seedu/resireg/storage/JsonUserPrefsStorageTest.java similarity index 94% rename from src/test/java/seedu/address/storage/JsonUserPrefsStorageTest.java rename to src/test/java/seedu/resireg/storage/JsonUserPrefsStorageTest.java index 16f33f4a6bb..1fa6b24d479 100644 --- a/src/test/java/seedu/address/storage/JsonUserPrefsStorageTest.java +++ b/src/test/java/seedu/resireg/storage/JsonUserPrefsStorageTest.java @@ -1,8 +1,8 @@ -package seedu.address.storage; +package seedu.resireg.storage; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import java.io.IOException; import java.nio.file.Path; @@ -12,9 +12,9 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import seedu.address.commons.core.GuiSettings; -import seedu.address.commons.exceptions.DataConversionException; -import seedu.address.model.UserPrefs; +import seedu.resireg.commons.core.GuiSettings; +import seedu.resireg.commons.exceptions.DataConversionException; +import seedu.resireg.model.UserPrefs; public class JsonUserPrefsStorageTest { diff --git a/src/test/java/seedu/address/storage/StorageManagerTest.java b/src/test/java/seedu/resireg/storage/StorageManagerTest.java similarity index 88% rename from src/test/java/seedu/address/storage/StorageManagerTest.java rename to src/test/java/seedu/resireg/storage/StorageManagerTest.java index 99a16548970..5f4086070d7 100644 --- a/src/test/java/seedu/address/storage/StorageManagerTest.java +++ b/src/test/java/seedu/resireg/storage/StorageManagerTest.java @@ -1,8 +1,8 @@ -package seedu.address.storage; +package seedu.resireg.storage; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; +import static seedu.resireg.testutil.TypicalStudents.getTypicalAddressBook; import java.nio.file.Path; @@ -10,10 +10,10 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import seedu.address.commons.core.GuiSettings; -import seedu.address.model.AddressBook; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.UserPrefs; +import seedu.resireg.commons.core.GuiSettings; +import seedu.resireg.model.AddressBook; +import seedu.resireg.model.ReadOnlyAddressBook; +import seedu.resireg.model.UserPrefs; public class StorageManagerTest { diff --git a/src/test/java/seedu/address/testutil/AddressBookBuilder.java b/src/test/java/seedu/resireg/testutil/AddressBookBuilder.java similarity index 54% rename from src/test/java/seedu/address/testutil/AddressBookBuilder.java rename to src/test/java/seedu/resireg/testutil/AddressBookBuilder.java index d53799fd110..35f1a0949aa 100644 --- a/src/test/java/seedu/address/testutil/AddressBookBuilder.java +++ b/src/test/java/seedu/resireg/testutil/AddressBookBuilder.java @@ -1,12 +1,12 @@ -package seedu.address.testutil; +package seedu.resireg.testutil; -import seedu.address.model.AddressBook; -import seedu.address.model.person.Person; +import seedu.resireg.model.AddressBook; +import seedu.resireg.model.student.Student; /** * A utility class to help with building Addressbook objects. * Example usage:
- * {@code AddressBook ab = new AddressBookBuilder().withPerson("John", "Doe").build();} + * {@code AddressBook ab = new AddressBookBuilder().withStudent("John", "Doe").build();} */ public class AddressBookBuilder { @@ -21,10 +21,10 @@ public AddressBookBuilder(AddressBook addressBook) { } /** - * Adds a new {@code Person} to the {@code AddressBook} that we are building. + * Adds a new {@code Student} to the {@code AddressBook} that we are building. */ - public AddressBookBuilder withPerson(Person person) { - addressBook.addPerson(person); + public AddressBookBuilder withStudent(Student student) { + addressBook.addStudent(student); return this; } diff --git a/src/test/java/seedu/address/testutil/Assert.java b/src/test/java/seedu/resireg/testutil/Assert.java similarity index 97% rename from src/test/java/seedu/address/testutil/Assert.java rename to src/test/java/seedu/resireg/testutil/Assert.java index 9863093bd6e..7b3fff6056c 100644 --- a/src/test/java/seedu/address/testutil/Assert.java +++ b/src/test/java/seedu/resireg/testutil/Assert.java @@ -1,4 +1,4 @@ -package seedu.address.testutil; +package seedu.resireg.testutil; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.function.Executable; diff --git a/src/test/java/seedu/resireg/testutil/EditStudentDescriptorBuilder.java b/src/test/java/seedu/resireg/testutil/EditStudentDescriptorBuilder.java new file mode 100644 index 00000000000..7c7e1e32c1b --- /dev/null +++ b/src/test/java/seedu/resireg/testutil/EditStudentDescriptorBuilder.java @@ -0,0 +1,97 @@ +package seedu.resireg.testutil; + +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import seedu.resireg.logic.commands.EditCommand.EditStudentDescriptor; +import seedu.resireg.model.student.Email; +import seedu.resireg.model.student.Name; +import seedu.resireg.model.student.Phone; +import seedu.resireg.model.student.Student; +import seedu.resireg.model.student.StudentId; +import seedu.resireg.model.student.faculty.Faculty; +import seedu.resireg.model.tag.Tag; + +/** + * A utility class to help with building EditStudentDescriptor objects. + */ +public class EditStudentDescriptorBuilder { + + private EditStudentDescriptor descriptor; + + public EditStudentDescriptorBuilder() { + descriptor = new EditStudentDescriptor(); + } + + public EditStudentDescriptorBuilder(EditStudentDescriptor descriptor) { + this.descriptor = new EditStudentDescriptor(descriptor); + } + + /** + * Returns an {@code EditStudentDescriptor} with fields containing {@code student}'s details + */ + public EditStudentDescriptorBuilder(Student student) { + descriptor = new EditStudentDescriptor(); + descriptor.setName(student.getName()); + descriptor.setPhone(student.getPhone()); + descriptor.setEmail(student.getEmail()); + descriptor.setFaculty(student.getFaculty()); + descriptor.setStudentId(student.getStudentId()); + descriptor.setTags(student.getTags()); + } + + /** + * Sets the {@code Name} of the {@code EditStudentDescriptor} that we are building. + */ + public EditStudentDescriptorBuilder withName(String name) { + descriptor.setName(new Name(name)); + return this; + } + + /** + * Sets the {@code Phone} of the {@code EditStudentDescriptor} that we are building. + */ + public EditStudentDescriptorBuilder withPhone(String phone) { + descriptor.setPhone(new Phone(phone)); + return this; + } + + /** + * Sets the {@code Email} of the {@code EditStudentDescriptor} that we are building. + */ + public EditStudentDescriptorBuilder withEmail(String email) { + descriptor.setEmail(new Email(email)); + return this; + } + + /** + * Sets the {@code Faculty} of the {@code EditStudentDescriptor} that we are building. + */ + public EditStudentDescriptorBuilder withFaculty(String faculty) { + descriptor.setFaculty(new Faculty(faculty)); + return this; + } + + /** + * Sets the {@code StudentId} of the {@code EditStudentDescriptor} that we are building. + */ + public EditStudentDescriptorBuilder withStudentId(String studentId) { + descriptor.setStudentId(new StudentId(studentId)); + return this; + } + + /** + * Parses the {@code tags} into a {@code Set} and set it to the {@code EditStudentDescriptor} + * that we are building. + */ + public EditStudentDescriptorBuilder withTags(String... tags) { + Set tagSet = Stream.of(tags).map(Tag::new).collect(Collectors.toSet()); + descriptor.setTags(tagSet); + return this; + } + + public EditStudentDescriptor build() { + return descriptor; + } +} diff --git a/src/test/java/seedu/address/testutil/SerializableTestClass.java b/src/test/java/seedu/resireg/testutil/SerializableTestClass.java similarity index 98% rename from src/test/java/seedu/address/testutil/SerializableTestClass.java rename to src/test/java/seedu/resireg/testutil/SerializableTestClass.java index f5a66340489..6a37b5b3a10 100644 --- a/src/test/java/seedu/address/testutil/SerializableTestClass.java +++ b/src/test/java/seedu/resireg/testutil/SerializableTestClass.java @@ -1,4 +1,4 @@ -package seedu.address.testutil; +package seedu.resireg.testutil; import java.time.LocalDateTime; import java.util.ArrayList; diff --git a/src/test/java/seedu/resireg/testutil/StudentBuilder.java b/src/test/java/seedu/resireg/testutil/StudentBuilder.java new file mode 100644 index 00000000000..5a157cc869f --- /dev/null +++ b/src/test/java/seedu/resireg/testutil/StudentBuilder.java @@ -0,0 +1,110 @@ +package seedu.resireg.testutil; + +import java.util.HashSet; +import java.util.Set; + +import seedu.resireg.model.student.Email; +import seedu.resireg.model.student.Name; +import seedu.resireg.model.student.Phone; +import seedu.resireg.model.student.Student; +import seedu.resireg.model.student.StudentId; +import seedu.resireg.model.student.faculty.Faculty; +import seedu.resireg.model.tag.Tag; +import seedu.resireg.model.util.SampleDataUtil; + +/** + * A utility class to help with building Student objects. + */ +public class StudentBuilder { + + public static final String DEFAULT_NAME = "Alice Pauline"; + public static final String DEFAULT_PHONE = "85355255"; + public static final String DEFAULT_EMAIL = "alice@gmail.com"; + public static final String DEFAULT_FACULTY = "FASS"; + public static final String DEFAULT_STUDENT_ID = "E0407889"; + + + private Name name; + private Phone phone; + private Email email; + private Faculty faculty; + private StudentId studentId; + private Set tags; + + /** + * Creates a {@code StudentBuilder} with the default details. + */ + public StudentBuilder() { + name = new Name(DEFAULT_NAME); + phone = new Phone(DEFAULT_PHONE); + email = new Email(DEFAULT_EMAIL); + faculty = new Faculty(DEFAULT_FACULTY); + studentId = new StudentId(DEFAULT_STUDENT_ID); + tags = new HashSet<>(); + } + + /** + * Initializes the StudentBuilder with the data of {@code studentToCopy}. + */ + public StudentBuilder(Student studentToCopy) { + name = studentToCopy.getName(); + phone = studentToCopy.getPhone(); + email = studentToCopy.getEmail(); + faculty = studentToCopy.getFaculty(); + studentId = studentToCopy.getStudentId(); + tags = new HashSet<>(studentToCopy.getTags()); + } + + /** + * Sets the {@code Name} of the {@code Student} that we are building. + */ + public StudentBuilder withName(String name) { + this.name = new Name(name); + return this; + } + + /** + * Parses the {@code tags} into a {@code Set} and set it to the {@code Student} that we are building. + */ + public StudentBuilder withTags(String ... tags) { + this.tags = SampleDataUtil.getTagSet(tags); + return this; + } + + /** + * Sets the {@code Faculty} of the {@code Student} that we are building. + */ + public StudentBuilder withFaculty(String faculty) { + this.faculty = new Faculty(faculty); + return this; + } + + /** + * Sets the {@code StudentId} of the {@code Student} that we are building. + */ + public StudentBuilder withStudentId(String studentId) { + this.studentId = new StudentId(studentId); + return this; + } + + /** + * Sets the {@code Phone} of the {@code Student} that we are building. + */ + public StudentBuilder withPhone(String phone) { + this.phone = new Phone(phone); + return this; + } + + /** + * Sets the {@code Email} of the {@code Student} that we are building. + */ + public StudentBuilder withEmail(String email) { + this.email = new Email(email); + return this; + } + + public Student build() { + return new Student(name, phone, email, faculty, studentId, tags); + } + +} diff --git a/src/test/java/seedu/resireg/testutil/StudentUtil.java b/src/test/java/seedu/resireg/testutil/StudentUtil.java new file mode 100644 index 00000000000..ae5ba09a3eb --- /dev/null +++ b/src/test/java/seedu/resireg/testutil/StudentUtil.java @@ -0,0 +1,66 @@ +package seedu.resireg.testutil; + +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_EMAIL; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_FACULTY; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_STUDENT_ID; +import static seedu.resireg.logic.parser.CliSyntax.PREFIX_TAG; + +import java.util.Set; + +import seedu.resireg.logic.commands.AddCommand; +import seedu.resireg.logic.commands.EditCommand.EditStudentDescriptor; +import seedu.resireg.model.student.Student; +import seedu.resireg.model.tag.Tag; + +/** + * A utility class for Student. + */ +public class StudentUtil { + + /** + * Returns an add command string for adding the {@code student}. + */ + public static String getAddCommand(Student student) { + return AddCommand.COMMAND_WORD + " " + getStudentDetails(student); + } + + /** + * Returns the part of command string for the given {@code student}'s details. + */ + public static String getStudentDetails(Student student) { + StringBuilder sb = new StringBuilder(); + sb.append(PREFIX_NAME + student.getName().fullName + " "); + sb.append(PREFIX_PHONE + student.getPhone().value + " "); + sb.append(PREFIX_EMAIL + student.getEmail().value + " "); + sb.append(PREFIX_FACULTY + student.getFaculty().value + " "); + sb.append(PREFIX_STUDENT_ID + student.getStudentId().value + " "); + student.getTags().stream().forEach( + s -> sb.append(PREFIX_TAG + s.tagName + " ") + ); + return sb.toString(); + } + + /** + * Returns the part of command string for the given {@code EditStudentDescriptor}'s details. + */ + public static String getEditStudentDescriptorDetails(EditStudentDescriptor descriptor) { + StringBuilder sb = new StringBuilder(); + descriptor.getName().ifPresent(name -> sb.append(PREFIX_NAME).append(name.fullName).append(" ")); + descriptor.getPhone().ifPresent(phone -> sb.append(PREFIX_PHONE).append(phone.value).append(" ")); + descriptor.getEmail().ifPresent(email -> sb.append(PREFIX_EMAIL).append(email.value).append(" ")); + descriptor.getFaculty().ifPresent(faculty -> sb.append(PREFIX_FACULTY).append(faculty.value).append(" ")); + descriptor.getStudentId().ifPresent(studentId -> + sb.append(PREFIX_STUDENT_ID).append(studentId.value).append(" ")); + if (descriptor.getTags().isPresent()) { + Set tags = descriptor.getTags().get(); + if (tags.isEmpty()) { + sb.append(PREFIX_TAG); + } else { + tags.forEach(s -> sb.append(PREFIX_TAG).append(s.tagName).append(" ")); + } + } + return sb.toString(); + } +} diff --git a/src/test/java/seedu/address/testutil/TestUtil.java b/src/test/java/seedu/resireg/testutil/TestUtil.java similarity index 58% rename from src/test/java/seedu/address/testutil/TestUtil.java rename to src/test/java/seedu/resireg/testutil/TestUtil.java index 896d103eb0b..aabbd859aae 100644 --- a/src/test/java/seedu/address/testutil/TestUtil.java +++ b/src/test/java/seedu/resireg/testutil/TestUtil.java @@ -1,13 +1,13 @@ -package seedu.address.testutil; +package seedu.resireg.testutil; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import seedu.address.commons.core.index.Index; -import seedu.address.model.Model; -import seedu.address.model.person.Person; +import seedu.resireg.commons.core.index.Index; +import seedu.resireg.model.Model; +import seedu.resireg.model.student.Student; /** * A utility class for test cases. @@ -33,23 +33,23 @@ public static Path getFilePathInSandboxFolder(String fileName) { } /** - * Returns the middle index of the person in the {@code model}'s person list. + * Returns the middle index of the student in the {@code model}'s student list. */ public static Index getMidIndex(Model model) { - return Index.fromOneBased(model.getFilteredPersonList().size() / 2); + return Index.fromOneBased(model.getFilteredStudentList().size() / 2); } /** - * Returns the last index of the person in the {@code model}'s person list. + * Returns the last index of the student in the {@code model}'s student list. */ public static Index getLastIndex(Model model) { - return Index.fromOneBased(model.getFilteredPersonList().size()); + return Index.fromOneBased(model.getFilteredStudentList().size()); } /** - * Returns the person in the {@code model}'s person list at {@code index}. + * Returns the student in the {@code model}'s student list at {@code index}. */ - public static Person getPerson(Model model, Index index) { - return model.getFilteredPersonList().get(index.getZeroBased()); + public static Student getStudent(Model model, Index index) { + return model.getFilteredStudentList().get(index.getZeroBased()); } } diff --git a/src/test/java/seedu/address/testutil/TypicalIndexes.java b/src/test/java/seedu/resireg/testutil/TypicalIndexes.java similarity index 81% rename from src/test/java/seedu/address/testutil/TypicalIndexes.java rename to src/test/java/seedu/resireg/testutil/TypicalIndexes.java index 1e613937657..0e97e10df5b 100644 --- a/src/test/java/seedu/address/testutil/TypicalIndexes.java +++ b/src/test/java/seedu/resireg/testutil/TypicalIndexes.java @@ -1,6 +1,6 @@ -package seedu.address.testutil; +package seedu.resireg.testutil; -import seedu.address.commons.core.index.Index; +import seedu.resireg.commons.core.index.Index; /** * A utility class containing a list of {@code Index} objects to be used in tests. diff --git a/src/test/java/seedu/resireg/testutil/TypicalStudents.java b/src/test/java/seedu/resireg/testutil/TypicalStudents.java new file mode 100644 index 00000000000..00aa9608627 --- /dev/null +++ b/src/test/java/seedu/resireg/testutil/TypicalStudents.java @@ -0,0 +1,84 @@ +package seedu.resireg.testutil; + +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_EMAIL_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_EMAIL_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_FACULTY_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_FACULTY_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_NAME_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_NAME_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_PHONE_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_PHONE_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_STUDENT_ID_AMY; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_STUDENT_ID_BOB; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_TAG_FRIEND; +import static seedu.resireg.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import seedu.resireg.model.AddressBook; +import seedu.resireg.model.student.Student; + +/** + * A utility class containing a list of {@code Student} objects to be used in tests. + */ +public class TypicalStudents { + + public static final Student ALICE = new StudentBuilder().withName("Alice Pauline") + .withFaculty("FASS").withStudentId("E0111110") + .withEmail("alice@example.com") + .withPhone("94351253") + .withTags("friends").build(); + public static final Student BENSON = new StudentBuilder().withName("Benson Meier") + .withFaculty("FASS").withStudentId("E0222228") + .withEmail("benson@example.com").withPhone("98765432") + .withTags("owesMoney", "friends").build(); + public static final Student CARL = new StudentBuilder().withName("Carl Kurz").withPhone("95352563") + .withEmail("carl@example.com") + .withFaculty("FASS").withStudentId("E0111112").build(); + public static final Student DANIEL = new StudentBuilder().withName("Daniel Meier").withPhone("87652533") + .withFaculty("FASS").withStudentId("E0111113") + .withEmail("daniel@example.com") + .withTags("friends").build(); + public static final Student ELLE = new StudentBuilder().withName("Elle Meyer").withPhone("9482224") + .withEmail("elle@example.com").withFaculty("FASS").withStudentId("E0111114").build(); + public static final Student FIONA = new StudentBuilder().withName("Fiona Kunz").withPhone("9482427") + .withEmail("fiona@example.com") + .withFaculty("FASS").withStudentId("E0111115").build(); + public static final Student GEORGE = new StudentBuilder().withName("George Best").withPhone("9482442") + .withEmail("george@example.com").withFaculty("FASS").withStudentId("E0111101").build(); + + // Manually added + public static final Student HOON = new StudentBuilder().withName("Hoon Meier").withPhone("8482424") + .withEmail("stefan@example.com").withFaculty("FASS").withStudentId("E0111116").build(); + public static final Student IDA = new StudentBuilder().withName("Ida Mueller").withPhone("8482131") + .withEmail("hans@example.com").withFaculty("FASS").withStudentId("E0111117").build(); + + // Manually added - Student's details found in {@code CommandTestUtil} + public static final Student AMY = new StudentBuilder().withName(VALID_NAME_AMY).withPhone(VALID_PHONE_AMY) + .withEmail(VALID_EMAIL_AMY).withFaculty(VALID_FACULTY_AMY).withStudentId(VALID_STUDENT_ID_AMY) + .withTags(VALID_TAG_FRIEND).build(); + public static final Student BOB = new StudentBuilder().withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB) + .withEmail(VALID_EMAIL_BOB).withFaculty(VALID_FACULTY_BOB).withStudentId(VALID_STUDENT_ID_BOB) + .withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND).build(); + + public static final String KEYWORD_MATCHING_MEIER = "Meier"; // A keyword that matches MEIER + + private TypicalStudents() {} // prevents instantiation + + /** + * Returns an {@code AddressBook} with all the typical students. + */ + public static AddressBook getTypicalAddressBook() { + AddressBook ab = new AddressBook(); + for (Student student : getTypicalStudents()) { + ab.addStudent(student); + } + return ab; + } + + public static List getTypicalStudents() { + return new ArrayList<>(Arrays.asList(ALICE, BENSON, CARL, DANIEL, ELLE, FIONA, GEORGE)); + } +} diff --git a/src/test/java/seedu/address/ui/TestFxmlObject.java b/src/test/java/seedu/resireg/ui/TestFxmlObject.java similarity index 96% rename from src/test/java/seedu/address/ui/TestFxmlObject.java rename to src/test/java/seedu/resireg/ui/TestFxmlObject.java index 5ecd82656f2..73bc7e7e143 100644 --- a/src/test/java/seedu/address/ui/TestFxmlObject.java +++ b/src/test/java/seedu/resireg/ui/TestFxmlObject.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.resireg.ui; import javafx.beans.DefaultProperty; diff --git a/src/test/java/seedu/address/ui/UiPartTest.java b/src/test/java/seedu/resireg/ui/UiPartTest.java similarity index 97% rename from src/test/java/seedu/address/ui/UiPartTest.java rename to src/test/java/seedu/resireg/ui/UiPartTest.java index 33d82d911b8..0470b11c143 100644 --- a/src/test/java/seedu/address/ui/UiPartTest.java +++ b/src/test/java/seedu/resireg/ui/UiPartTest.java @@ -1,8 +1,8 @@ -package seedu.address.ui; +package seedu.resireg.ui; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static seedu.address.testutil.Assert.assertThrows; +import static seedu.resireg.testutil.Assert.assertThrows; import java.net.URL; import java.nio.file.Path; @@ -11,7 +11,7 @@ import org.junit.jupiter.api.io.TempDir; import javafx.fxml.FXML; -import seedu.address.MainApp; +import seedu.resireg.MainApp; public class UiPartTest { diff --git a/src/test/resources/view/UiPartTest/validFile.fxml b/src/test/resources/view/UiPartTest/validFile.fxml index bab836af0db..145f794536a 100644 --- a/src/test/resources/view/UiPartTest/validFile.fxml +++ b/src/test/resources/view/UiPartTest/validFile.fxml @@ -1,4 +1,4 @@ - + Hello World! diff --git a/src/test/resources/view/UiPartTest/validFileWithFxRoot.fxml b/src/test/resources/view/UiPartTest/validFileWithFxRoot.fxml index 151e09ce926..4d1167dc935 100644 --- a/src/test/resources/view/UiPartTest/validFileWithFxRoot.fxml +++ b/src/test/resources/view/UiPartTest/validFileWithFxRoot.fxml @@ -1,6 +1,6 @@ - Hello World! From 6fd95780ba5efa8aa85755a55934adcbd07fb579 Mon Sep 17 00:00:00 2001 From: Jing Yen Loh Date: Fri, 25 Sep 2020 12:12:18 +0800 Subject: [PATCH 026/326] Display results as appended history Currently, the result display functions as an echo area, similar to Emacs' minibuffer. We modify it so that it keeps the list of results displayed. --- .../java/seedu/address/ui/ResultDisplay.java | 17 +++++++++++++++-- src/main/resources/view/DarkTheme.css | 6 ++++++ src/main/resources/view/ResultDisplay.fxml | 19 ++++++++++++------- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/main/java/seedu/address/ui/ResultDisplay.java b/src/main/java/seedu/address/ui/ResultDisplay.java index 7d98e84eedf..cd0ea8aca74 100644 --- a/src/main/java/seedu/address/ui/ResultDisplay.java +++ b/src/main/java/seedu/address/ui/ResultDisplay.java @@ -3,8 +3,10 @@ import static java.util.Objects.requireNonNull; import javafx.fxml.FXML; +import javafx.scene.control.ScrollPane; import javafx.scene.control.TextArea; import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; /** * A ui for the status bar that is displayed at the header of the application. @@ -14,15 +16,26 @@ public class ResultDisplay extends UiPart { private static final String FXML = "ResultDisplay.fxml"; @FXML - private TextArea resultDisplay; + private VBox responseContainer; + @FXML + private ScrollPane resultDisplayScroll; + /** + * Creates a ResultDisplay to display the result of a user's input. + */ public ResultDisplay() { super(FXML); + resultDisplayScroll.vvalueProperty().bind(responseContainer.heightProperty()); } public void setFeedbackToUser(String feedbackToUser) { requireNonNull(feedbackToUser); - resultDisplay.setText(feedbackToUser); + TextArea response = new TextArea(feedbackToUser); + response.setEditable(false); + response.getStyleClass().add("result-display"); + responseContainer + .getChildren() + .add(response); } } diff --git a/src/main/resources/view/DarkTheme.css b/src/main/resources/view/DarkTheme.css index 36e6b001cd8..c79cc387c30 100644 --- a/src/main/resources/view/DarkTheme.css +++ b/src/main/resources/view/DarkTheme.css @@ -149,8 +149,10 @@ .result-display { -fx-background-color: transparent; -fx-font-family: "Segoe UI Light"; + -fx-control-inner-background: derive(#1d1d1d, 20%); -fx-font-size: 13pt; -fx-text-fill: white; + -fx-pref-height: 30px; } .result-display .label { @@ -350,3 +352,7 @@ -fx-background-radius: 2; -fx-font-size: 11; } + +#responseContainer { + -fx-background-color: derive(#1d1d1d, 20%); +} diff --git a/src/main/resources/view/ResultDisplay.fxml b/src/main/resources/view/ResultDisplay.fxml index 58d5ad3dc56..5d86b46af8e 100644 --- a/src/main/resources/view/ResultDisplay.fxml +++ b/src/main/resources/view/ResultDisplay.fxml @@ -1,9 +1,14 @@ - - - - -