From 8abedec1cef532f5167560d697cf3a46f0cd6b83 Mon Sep 17 00:00:00 2001 From: damithc Date: Tue, 12 Sep 2023 01:20:47 +0800 Subject: [PATCH 001/249] Migrate docs to MarkBind Let's migrate the docs site from Jekyll to MarkBind. Primary author: @tlylt in se-edu/addressbook-level3/pull/156 Further tweaks: @damithc in se-edu/addressbook-level3/pull/206 --- .github/workflows/docs.yml | 25 + .gitignore | 1 + docs/.gitignore | 23 + docs/AboutUs.md | 8 +- docs/Configuration.md | 6 +- docs/DevOps.md | 13 +- docs/DeveloperGuide.md | 116 +- docs/Documentation.md | 28 +- docs/Gemfile | 10 - docs/Logging.md | 6 +- docs/SettingUp.md | 27 +- docs/Testing.md | 19 +- docs/UserGuide.md | 52 +- docs/_config.yml | 15 - docs/_data/projects.yml | 23 - docs/_includes/custom-head.html | 6 - docs/_includes/head.html | 12 - docs/_includes/header.html | 36 - docs/_layouts/alt-page.html | 14 - docs/_layouts/default.html | 18 - docs/_layouts/page.html | 14 - docs/_markbind/layouts/default.md | 66 + docs/_markbind/variables.json | 3 + docs/_markbind/variables.md | 4 + docs/_sass/minima/_base.scss | 295 - docs/_sass/minima/_layout.scss | 263 - docs/_sass/minima/custom-mixins.scss | 21 - docs/_sass/minima/custom-styles.scss | 34 - docs/_sass/minima/custom-variables.scss | 76 - docs/_sass/minima/initialize.scss | 51 - docs/_sass/minima/skins/classic.scss | 84 - docs/_sass/minima/skins/solarized-dark.scss | 4 - docs/_sass/minima/skins/solarized.scss | 133 - docs/assets/css/style.scss | 12 - docs/images/ArchitectureDiagram.png | Bin 19887 -> 0 bytes docs/images/ArchitectureSequenceDiagram.png | Bin 15175 -> 0 bytes docs/images/BetterModelClassDiagram.png | Bin 14116 -> 0 bytes docs/images/CommitActivityDiagram.png | Bin 16227 -> 0 bytes docs/images/ComponentManagers.png | Bin 17411 -> 0 bytes docs/images/DeleteSequenceDiagram.png | Bin 28142 -> 0 bytes docs/images/LogicClassDiagram.png | Bin 36769 -> 0 bytes docs/images/LogicStorageDIP.png | Bin 5808 -> 0 bytes docs/images/ModelClassDiagram.png | Bin 27204 -> 0 bytes docs/images/ParserClasses.png | Bin 28856 -> 0 bytes docs/images/StorageClassDiagram.png | Bin 29426 -> 0 bytes docs/images/UiClassDiagram.png | Bin 48363 -> 0 bytes docs/images/UndoRedoState0.png | Bin 6619 -> 0 bytes docs/images/UndoRedoState1.png | Bin 7454 -> 0 bytes docs/images/UndoRedoState2.png | Bin 7855 -> 0 bytes docs/images/UndoRedoState3.png | Bin 7588 -> 0 bytes docs/images/UndoRedoState4.png | Bin 7605 -> 0 bytes docs/images/UndoRedoState5.png | Bin 9427 -> 0 bytes docs/index.md | 6 +- docs/package-lock.json | 8587 +++++++++++++++++++ docs/package.json | 14 + docs/site.json | 29 + docs/stylesheets/main.css | 144 + docs/team/johndoe.md | 4 +- 58 files changed, 9056 insertions(+), 1246 deletions(-) create mode 100644 .github/workflows/docs.yml create mode 100644 docs/.gitignore delete mode 100644 docs/Gemfile delete mode 100644 docs/_config.yml delete mode 100644 docs/_data/projects.yml delete mode 100644 docs/_includes/custom-head.html delete mode 100644 docs/_includes/head.html delete mode 100644 docs/_includes/header.html delete mode 100644 docs/_layouts/alt-page.html delete mode 100644 docs/_layouts/default.html delete mode 100644 docs/_layouts/page.html create mode 100644 docs/_markbind/layouts/default.md create mode 100644 docs/_markbind/variables.json create mode 100644 docs/_markbind/variables.md delete mode 100644 docs/_sass/minima/_base.scss delete mode 100644 docs/_sass/minima/_layout.scss delete mode 100644 docs/_sass/minima/custom-mixins.scss delete mode 100644 docs/_sass/minima/custom-styles.scss delete mode 100644 docs/_sass/minima/custom-variables.scss delete mode 100644 docs/_sass/minima/initialize.scss delete mode 100644 docs/_sass/minima/skins/classic.scss delete mode 100644 docs/_sass/minima/skins/solarized-dark.scss delete mode 100644 docs/_sass/minima/skins/solarized.scss delete mode 100644 docs/assets/css/style.scss delete mode 100644 docs/images/ArchitectureDiagram.png delete mode 100644 docs/images/ArchitectureSequenceDiagram.png delete mode 100644 docs/images/BetterModelClassDiagram.png delete mode 100644 docs/images/CommitActivityDiagram.png delete mode 100644 docs/images/ComponentManagers.png delete mode 100644 docs/images/DeleteSequenceDiagram.png delete mode 100644 docs/images/LogicClassDiagram.png delete mode 100644 docs/images/LogicStorageDIP.png delete mode 100644 docs/images/ModelClassDiagram.png delete mode 100644 docs/images/ParserClasses.png delete mode 100644 docs/images/StorageClassDiagram.png delete mode 100644 docs/images/UiClassDiagram.png delete mode 100644 docs/images/UndoRedoState0.png delete mode 100644 docs/images/UndoRedoState1.png delete mode 100644 docs/images/UndoRedoState2.png delete mode 100644 docs/images/UndoRedoState3.png delete mode 100644 docs/images/UndoRedoState4.png delete mode 100644 docs/images/UndoRedoState5.png create mode 100644 docs/package-lock.json create mode 100644 docs/package.json create mode 100644 docs/site.json create mode 100644 docs/stylesheets/main.css diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000000..57737a615fc --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,25 @@ +name: MarkBind Action + +on: + push: + branches: + - master + +jobs: + build_and_deploy: + runs-on: ubuntu-latest + steps: + - name: Install Graphviz + run: sudo apt-get install graphviz + - name: Install Java + uses: actions/setup-java@v3 + with: + java-version: '11' + distribution: 'temurin' + - name: Build & Deploy MarkBind site + uses: MarkBind/markbind-action@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + rootDirectory: './docs' + baseUrl: '/addressbook-level3' # replace with your repo name + version: '^5.1.0' diff --git a/.gitignore b/.gitignore index 284c4ca7cd9..eab4c7db6a5 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ src/test/data/sandbox/ # MacOS custom attributes files created by Finder .DS_Store docs/_site/ +docs/_markbind/logs/ diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000000..1748e487fbd --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,23 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +_markbind/logs/ + +# Dependency directories +node_modules/ + +# Production build files (change if you output the build to a different directory) +_site/ + +# Env +.env +.env.local + +# IDE configs +.vscode/ +.idea/* +*.iml diff --git a/docs/AboutUs.md b/docs/AboutUs.md index ff3f04abd02..8cf4ab68e9e 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,11 @@ --- -layout: page -title: About Us + layout: default.md + title: "About Us" --- -We are a team based in the [School of Computing, National University of Singapore](https://www.comp.nus.edu.sg). +# About Us + +We are a team based in the [School of Computing, National University of Singapore](http://www.comp.nus.edu.sg). You can reach us at the email `seer[at]comp.nus.edu.sg` diff --git a/docs/Configuration.md b/docs/Configuration.md index 13cf0faea16..32f6255f3b9 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -1,6 +1,8 @@ --- -layout: page -title: Configuration guide + layout: default.md + title: "Configuration guide" --- +# Configuration guide + Certain properties of the application can be controlled (e.g user preferences file location, logging level) through the configuration file (default: `config.json`). diff --git a/docs/DevOps.md b/docs/DevOps.md index d2fd91a6001..8228c845e86 100644 --- a/docs/DevOps.md +++ b/docs/DevOps.md @@ -1,12 +1,15 @@ --- -layout: page -title: DevOps guide + layout: default.md + title: "DevOps guide" + pageNav: 3 --- -* Table of Contents -{:toc} +# DevOps guide --------------------------------------------------------------------------------------------------------------------- + + + + ## Build automation diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 743c65a49d2..9fe677d1e4c 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,15 +1,19 @@ --- -layout: page -title: Developer Guide + layout: default.md + title: "Developer Guide" + pageNav: 3 --- -* Table of Contents -{:toc} + +# AB-3 Developer Guide + + + -------------------------------------------------------------------------------------------------------------------- ## **Acknowledgements** -* {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} +_{ list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well }_ -------------------------------------------------------------------------------------------------------------------- @@ -21,14 +25,9 @@ Refer to the guide [_Setting up and getting started_](SettingUp.md). ## **Design** -
- -:bulb: **Tip:** The `.puml` files used to create diagrams in this document `docs/diagrams` folder. Refer to the [_PlantUML Tutorial_ at se-edu/guides](https://se-education.org/guides/tutorials/plantUml.html) to learn how to create and edit diagrams. -
- ### Architecture - + The ***Architecture Diagram*** given above explains the high-level design of the App. @@ -53,7 +52,7 @@ The bulk of the app's work is done by the following four components: The *Sequence Diagram* below shows how the components interact with each other for the scenario where the user issues the command `delete 1`. - + Each of the four main components (also shown in the diagram above), @@ -62,7 +61,7 @@ Each of the four main components (also shown in the diagram above), For example, the `Logic` component defines its API in the `Logic.java` interface and implements its functionality using the `LogicManager.java` class which follows the `Logic` interface. Other components interact with a given component through its interface rather than the concrete class (reason: to prevent outside component's being coupled to the implementation of a component), as illustrated in the (partial) class diagram below. - + The sections below give more details of each component. @@ -70,7 +69,7 @@ The sections below give more details of each component. The **API** of this component is specified in [`Ui.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/Ui.java) -![Structure of the UI Component](images/UiClassDiagram.png) + The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `PersonListPanel`, `StatusBarFooter` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class which captures the commonalities between classes that represent parts of the visible GUI. @@ -89,14 +88,16 @@ The `UI` component, Here's a (partial) class diagram of the `Logic` component: - + The sequence diagram below illustrates the interactions within the `Logic` component, taking `execute("delete 1")` API call as an example. -![Interactions Inside the Logic Component for the `delete 1` Command](images/DeleteSequenceDiagram.png) + + + -
:information_source: **Note:** The lifeline for `DeleteCommandParser` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline continues till the end of diagram. -
+**Note:** The lifeline for `DeleteCommandParser` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline continues till the end of diagram. +
How the `Logic` component works: @@ -108,7 +109,7 @@ How the `Logic` component works: Here are the other classes in `Logic` (omitted from the class diagram above) that are used for parsing a user command: - + How the parsing works: * When called upon to parse a user command, the `AddressBookParser` class creates an `XYZCommandParser` (`XYZ` is a placeholder for the specific command name e.g., `AddCommandParser`) which uses the other classes shown above to parse the user command and create a `XYZCommand` object (e.g., `AddCommand`) which the `AddressBookParser` returns back as a `Command` object. @@ -117,7 +118,7 @@ How the parsing works: ### Model component **API** : [`Model.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/model/Model.java) - + The `Model` component, @@ -127,18 +128,20 @@ The `Model` component, * stores a `UserPref` object that represents the user’s preferences. This is exposed to the outside as a `ReadOnlyUserPref` objects. * does not depend on any of the other three components (as the `Model` represents data entities of the domain, they should make sense on their own without depending on other 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` objects.
+ + +**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` objects.
- + -
+ ### Storage component **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 both address book data and user preference data in JSON format, and read them back into corresponding objects. @@ -171,58 +174,67 @@ Given below is an example usage scenario and how the undo/redo mechanism behaves Step 1. The user launches the application for the first time. The `VersionedAddressBook` will be initialized with the initial address book state, and the `currentStatePointer` pointing to that single address book state. -![UndoRedoState0](images/UndoRedoState0.png) + Step 2. The user executes `delete 5` command to delete the 5th person in the address book. The `delete` command calls `Model#commitAddressBook()`, causing the modified state of the address book after the `delete 5` command executes to be saved in the `addressBookStateList`, and the `currentStatePointer` is shifted to the newly inserted address book state. -![UndoRedoState1](images/UndoRedoState1.png) + Step 3. The user executes `add n/David …​` to add a new person. The `add` command also calls `Model#commitAddressBook()`, causing another modified address book state to be saved into the `addressBookStateList`. -![UndoRedoState2](images/UndoRedoState2.png) + -
:information_source: **Note:** If a command fails its execution, it will not call `Model#commitAddressBook()`, so the address book state will not be saved into the `addressBookStateList`. + -
+**Note:** If a command fails its execution, it will not call `Model#commitAddressBook()`, so the address book state will not be saved into the `addressBookStateList`. + + Step 4. The user now decides that adding the person was a mistake, and decides to undo that action by executing the `undo` command. The `undo` command will call `Model#undoAddressBook()`, which will shift the `currentStatePointer` once to the left, pointing it to the previous address book state, and restores the address book to that state. -![UndoRedoState3](images/UndoRedoState3.png) + + + + -
:information_source: **Note:** If the `currentStatePointer` is at index 0, pointing to the initial AddressBook state, then there are no previous AddressBook states to restore. The `undo` command uses `Model#canUndoAddressBook()` to check if this is the case. If so, it will return an error to the user rather +**Note:** If the `currentStatePointer` is at index 0, pointing to the initial AddressBook state, then there are no previous AddressBook states to restore. The `undo` command uses `Model#canUndoAddressBook()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the undo. -
+
The following sequence diagram shows how an undo operation goes through the `Logic` component: -![UndoSequenceDiagram](images/UndoSequenceDiagram-Logic.png) + -
:information_source: **Note:** The lifeline for `UndoCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. + -
+**Note:** The lifeline for `UndoCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. + + Similarly, how an undo operation goes through the `Model` component is shown below: -![UndoSequenceDiagram](images/UndoSequenceDiagram-Model.png) + The `redo` command does the opposite — it calls `Model#redoAddressBook()`, which shifts the `currentStatePointer` once to the right, pointing to the previously undone state, and restores the address book to that state. -
:information_source: **Note:** If the `currentStatePointer` is at index `addressBookStateList.size() - 1`, pointing to the latest address book state, then there are no undone AddressBook states to restore. The `redo` command uses `Model#canRedoAddressBook()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo. + + +**Note:** If the `currentStatePointer` is at index `addressBookStateList.size() - 1`, pointing to the latest address book state, then there are no undone AddressBook states to restore. The `redo` command uses `Model#canRedoAddressBook()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo. -
+ Step 5. The user then decides to execute the command `list`. Commands that do not modify the address book, such as `list`, will usually not call `Model#commitAddressBook()`, `Model#undoAddressBook()` or `Model#redoAddressBook()`. Thus, the `addressBookStateList` remains unchanged. -![UndoRedoState4](images/UndoRedoState4.png) + Step 6. The user executes `clear`, which calls `Model#commitAddressBook()`. Since the `currentStatePointer` is not pointing at the end of the `addressBookStateList`, all address book states after the `currentStatePointer` will be purged. Reason: It no longer makes sense to redo the `add n/David …​` command. This is the behavior that most modern desktop applications follow. -![UndoRedoState5](images/UndoRedoState5.png) + The following activity diagram summarizes what happens when a user executes a new command: - + #### Design considerations: @@ -275,14 +287,14 @@ _{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 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}* @@ -334,10 +346,12 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli Given below are instructions to test the app manually. -
:information_source: **Note:** These instructions only provide a starting point for testers to work on; + + +**Note:** These instructions only provide a starting point for testers to work on; testers are expected to do more *exploratory* testing. -
+ ### Launch and shutdown diff --git a/docs/Documentation.md b/docs/Documentation.md index 3e68ea364e7..082e652d947 100644 --- a/docs/Documentation.md +++ b/docs/Documentation.md @@ -1,29 +1,21 @@ --- -layout: page -title: Documentation guide + layout: default.md + title: "Documentation guide" + pageNav: 3 --- -**Setting up and maintaining the project website:** - -* We use [**Jekyll**](https://jekyllrb.com/) to manage documentation. -* The `docs/` folder is used for documentation. -* To learn how set it up and maintain the project website, follow the guide [_[se-edu/guides] **Using Jekyll for project documentation**_](https://se-education.org/guides/tutorials/jekyll.html). -* Note these points when adapting the documentation to a different project/product: - * The 'Site-wide settings' section of the page linked above has information on how to update site-wide elements such as the top navigation bar. - * :bulb: In addition to updating content files, you might have to update the config files `docs\_config.yml` and `docs\_sass\minima\_base.scss` (which contains a reference to `AB-3` that comes into play when converting documentation pages to PDF format). -* If you are using Intellij for editing documentation files, you can consider enabling 'soft wrapping' for `*.md` files, as explained in [_[se-edu/guides] **Intellij IDEA: Useful settings**_](https://se-education.org/guides/tutorials/intellijUsefulSettings.html#enabling-soft-wrapping) +# Documentation Guide +* We use [**MarkBind**](https://markbind.org/) to manage documentation. +* The `docs/` folder contains the source files for the documentation website. +* To learn how set it up and maintain the project website, follow the guide [[se-edu/guides] Working with Forked MarkBind sites](https://se-education.org/guides/tutorials/markbind-forked-sites.html) for project documentation. **Style guidance:** * Follow the [**_Google developer documentation style guide_**](https://developers.google.com/style). +* Also relevant is the [_se-edu/guides **Markdown coding standard**_](https://se-education.org/guides/conventions/markdown.html). -* Also relevant is the [_[se-edu/guides] **Markdown coding standard**_](https://se-education.org/guides/conventions/markdown.html) - -**Diagrams:** - -* See the [_[se-edu/guides] **Using PlantUML**_](https://se-education.org/guides/tutorials/plantUml.html) -**Converting a document to the PDF format:** +**Converting to PDF** -* See the guide [_[se-edu/guides] **Saving web documents as PDF files**_](https://se-education.org/guides/tutorials/savingPdf.html) +* See the guide [_se-edu/guides **Saving web documents as PDF files**_](https://se-education.org/guides/tutorials/savingPdf.html). diff --git a/docs/Gemfile b/docs/Gemfile deleted file mode 100644 index c8385d85874..00000000000 --- a/docs/Gemfile +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -source "https://rubygems.org" - -git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } - -gem 'jekyll' -gem 'github-pages', group: :jekyll_plugins -gem 'wdm', '~> 0.1.0' if Gem.win_platform? -gem 'webrick' diff --git a/docs/Logging.md b/docs/Logging.md index 5e4fb9bc217..589644ad5c6 100644 --- a/docs/Logging.md +++ b/docs/Logging.md @@ -1,8 +1,10 @@ --- -layout: page -title: Logging guide + layout: default.md + title: "Logging guide" --- +# Logging guide + * We are using `java.util.logging` package for logging. * The `LogsCenter` class is used to manage the logging levels and logging destinations. * The `Logger` for a class can be obtained using `LogsCenter.getLogger(Class)` which will log messages according to the specified logging level. diff --git a/docs/SettingUp.md b/docs/SettingUp.md index aef33ec72fd..5e8b9d11991 100644 --- a/docs/SettingUp.md +++ b/docs/SettingUp.md @@ -1,27 +1,33 @@ --- -layout: page -title: Setting up and getting started + layout: default.md + title: "Setting up and getting started" + pageNav: 3 --- -* Table of Contents -{:toc} +# Setting up and getting started + + -------------------------------------------------------------------------------------------------------------------- ## Setting up the project in your computer -
:exclamation: **Caution:** + +**Caution:** Follow the steps in the following guide precisely. Things will not work out if you deviate in some steps. -
+ First, **fork** this repo, and **clone** the fork into your computer. If you plan to use Intellij IDEA (highly recommended): + 1. **Configure the JDK**: Follow the guide [_[se-edu/guides] IDEA: Configuring the JDK_](https://se-education.org/guides/tutorials/intellijJdk.html) to ensure Intellij is configured to use **JDK 17**. -1. **Import the project as a Gradle project**: Follow the guide [_[se-edu/guides] IDEA: Importing a Gradle project_](https://se-education.org/guides/tutorials/intellijImportGradleProject.html) to import the project into IDEA.
- :exclamation: Note: Importing a Gradle project is slightly different from importing a normal Java project. +1. **Import the project as a Gradle project**: Follow the guide [_[se-edu/guides] IDEA: Importing a Gradle project_](https://se-education.org/guides/tutorials/intellijImportGradleProject.html) to import the project into IDEA. + + Note: Importing a Gradle project is slightly different from importing a normal Java project. + 1. **Verify the setup**: 1. Run the `seedu.address.Main` and try a few commands. 1. [Run the tests](Testing.md) to ensure they all pass. @@ -34,10 +40,11 @@ If you plan to use Intellij IDEA (highly recommended): If using IDEA, follow the guide [_[se-edu/guides] IDEA: Configuring the code style_](https://se-education.org/guides/tutorials/intellijCodeStyle.html) to set up IDEA's coding style to match ours. -
:bulb: **Tip:** + + **Tip:** Optionally, you can follow the guide [_[se-edu/guides] Using Checkstyle_](https://se-education.org/guides/tutorials/checkstyle.html) to find how to use the CheckStyle within IDEA e.g., to report problems _as_ you write code. -
+ 1. **Set up CI** diff --git a/docs/Testing.md b/docs/Testing.md index 8a99e82438a..78ddc57e670 100644 --- a/docs/Testing.md +++ b/docs/Testing.md @@ -1,12 +1,15 @@ --- -layout: page -title: Testing guide + layout: default.md + title: "Testing guide" + pageNav: 3 --- -* Table of Contents -{:toc} +# Testing guide --------------------------------------------------------------------------------------------------------------------- + + + + ## Running tests @@ -19,8 +22,10 @@ There are two ways to run tests. * **Method 2: Using Gradle** * Open a console and run the command `gradlew clean test` (Mac/Linux: `./gradlew clean test`) -
:link: **Link**: Read [this Gradle Tutorial from the se-edu/guides](https://se-education.org/guides/tutorials/gradle.html) to learn more about using Gradle. -
+ + +**Link**: Read [this Gradle Tutorial from the se-edu/guides](https://se-education.org/guides/tutorials/gradle.html) to learn more about using Gradle. + -------------------------------------------------------------------------------------------------------------------- diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 27c2d1cf16c..aab9894c52b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,12 +1,15 @@ --- -layout: page -title: User Guide + layout: default.md + title: "User Guide" + pageNav: 3 --- -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. +# AB-3 User Guide -* Table of Contents -{:toc} +AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized for use via a 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. + + + -------------------------------------------------------------------------------------------------------------------- @@ -42,9 +45,9 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo ## Features -
+ -**:information_source: Notes about the command format:**
+**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`. @@ -62,7 +65,7 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo e.g. if the command specifies `help 123`, it will be interpreted as `help`. * If you are using a PDF version of this document, be careful when copying and pasting commands that span multiple lines as space characters surrounding line-breaks may be omitted when copied over to the application. -
+ ### Viewing help : `help` @@ -79,9 +82,10 @@ Adds a person to the address book. Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​` -
:bulb: **Tip:** -A person can have any number of tags (including 0) -
+ + +**Tip:** A person can have any number of tags (including 0) + Examples: * `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` @@ -162,10 +166,12 @@ AddressBook data are saved in the hard disk automatically after any command that AddressBook data are saved automatically as a JSON file `[JAR file location]/data/addressbook.json`. Advanced users are welcome to update data directly by editing that data file. -
:exclamation: **Caution:** -If your changes to the data file makes its format invalid, AddressBook will discard all data and start with an empty data file at the next run. Hence, it is recommended to take a backup of the file before editing it.
-Furthermore, certain edits can cause the AddressBook to behave in unexpected ways (e.g., if a value entered is outside of the acceptable range). Therefore, edit the data file only if you are confident that you can update it correctly. -
+ + +**Caution:** +If your changes to the data file makes its format invalid, AddressBook will discard all data and start with an empty data file at the next run. Hence, it is recommended to take a backup of the file before editing it.
+Furthermore, certain edits can cause the AddressBook to behave in unexpected ways (e.g., if a value entered is outside the acceptable range). Therefore, edit the data file only if you are confident that you can update it correctly. +
### Archiving data files `[coming in v2.0]` @@ -189,12 +195,12 @@ _Details coming soon ..._ ## 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` +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` +**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` diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index 6bd245d8f4e..00000000000 --- a/docs/_config.yml +++ /dev/null @@ -1,15 +0,0 @@ -title: "AB-3" -theme: minima - -header_pages: - - UserGuide.md - - DeveloperGuide.md - - AboutUs.md - -markdown: kramdown - -repository: "se-edu/addressbook-level3" -github_icon: "images/github-icon.png" - -plugins: - - jemoji diff --git a/docs/_data/projects.yml b/docs/_data/projects.yml deleted file mode 100644 index 8f3e50cb601..00000000000 --- a/docs/_data/projects.yml +++ /dev/null @@ -1,23 +0,0 @@ -- name: "AB-1" - url: https://se-edu.github.io/addressbook-level1 - -- name: "AB-2" - url: https://se-edu.github.io/addressbook-level2 - -- name: "AB-3" - url: https://se-edu.github.io/addressbook-level3 - -- name: "AB-4" - url: https://se-edu.github.io/addressbook-level4 - -- name: "Duke" - url: https://se-edu.github.io/duke - -- name: "Collate" - url: https://se-edu.github.io/collate - -- name: "Book" - url: https://se-edu.github.io/se-book - -- name: "Resources" - url: https://se-edu.github.io/resources diff --git a/docs/_includes/custom-head.html b/docs/_includes/custom-head.html deleted file mode 100644 index 8559a67ffad..00000000000 --- a/docs/_includes/custom-head.html +++ /dev/null @@ -1,6 +0,0 @@ -{% comment %} - Placeholder to allow defining custom head, in principle, you can add anything here, e.g. favicons: - - 1. Head over to https://realfavicongenerator.net/ to add your own favicons. - 2. Customize default _includes/custom-head.html in your source directory and insert the given code snippet. -{% endcomment %} diff --git a/docs/_includes/head.html b/docs/_includes/head.html deleted file mode 100644 index 83ac5326933..00000000000 --- a/docs/_includes/head.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - {%- include custom-head.html -%} - - {{page.title}} - - diff --git a/docs/_includes/header.html b/docs/_includes/header.html deleted file mode 100644 index 33badcd4f99..00000000000 --- a/docs/_includes/header.html +++ /dev/null @@ -1,36 +0,0 @@ - diff --git a/docs/_layouts/alt-page.html b/docs/_layouts/alt-page.html deleted file mode 100644 index 5dbc6ef245f..00000000000 --- a/docs/_layouts/alt-page.html +++ /dev/null @@ -1,14 +0,0 @@ ---- -layout: default ---- -
- -
-

{{ page.alt_title | escape }}

-
- -
- {{ content }} -
- -
diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html deleted file mode 100644 index e092cd572e0..00000000000 --- a/docs/_layouts/default.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - {%- include head.html -%} - - - - {%- include header.html -%} - -
-
- {{ content }} -
-
- - - - diff --git a/docs/_layouts/page.html b/docs/_layouts/page.html deleted file mode 100644 index 01e4b2a93b8..00000000000 --- a/docs/_layouts/page.html +++ /dev/null @@ -1,14 +0,0 @@ ---- -layout: default ---- -
- -
-

{{ page.title | escape }}

-
- -
- {{ content }} -
- -
diff --git a/docs/_markbind/layouts/default.md b/docs/_markbind/layouts/default.md new file mode 100644 index 00000000000..7348aace92c --- /dev/null +++ b/docs/_markbind/layouts/default.md @@ -0,0 +1,66 @@ + + + + +
+ + AB-3 +
  • User Guide
  • +
  • Developer Guide
  • +
  • About Us
  • +
  • :fab-github: +
  • +
  • + +
  • +
    +
    + +
    + +
    + {{ content }} +
    + + +
    + +
    + +
    + [**Powered by** {{MarkBind}}, generated on {{timestamp}}] +
    +
    diff --git a/docs/_markbind/variables.json b/docs/_markbind/variables.json new file mode 100644 index 00000000000..9d89eb0358b --- /dev/null +++ b/docs/_markbind/variables.json @@ -0,0 +1,3 @@ +{ + "jsonVariableExample": "Your variables can be defined here as well" +} diff --git a/docs/_markbind/variables.md b/docs/_markbind/variables.md new file mode 100644 index 00000000000..89ae5318fa4 --- /dev/null +++ b/docs/_markbind/variables.md @@ -0,0 +1,4 @@ + +To inject this HTML segment in your markbind files, use {{ example }} where you want to place it. +More generally, surround the segment's id with double curly braces. + diff --git a/docs/_sass/minima/_base.scss b/docs/_sass/minima/_base.scss deleted file mode 100644 index 0d3f6e80ced..00000000000 --- a/docs/_sass/minima/_base.scss +++ /dev/null @@ -1,295 +0,0 @@ -html { - font-size: $base-font-size; -} - -/** - * Reset some basic elements - */ -body, h1, h2, h3, h4, h5, h6, -p, blockquote, pre, hr, -dl, dd, ol, ul, figure { - margin: 0; - padding: 0; - -} - - - -/** - * Basic styling - */ -body { - font: $base-font-weight #{$base-font-size}/#{$base-line-height} $base-font-family; - color: $text-color; - background-color: $background-color; - -webkit-text-size-adjust: 100%; - -webkit-font-feature-settings: "kern" 1; - -moz-font-feature-settings: "kern" 1; - -o-font-feature-settings: "kern" 1; - font-feature-settings: "kern" 1; - font-kerning: normal; - display: flex; - min-height: 100vh; - flex-direction: column; - overflow-wrap: break-word; -} - - - -/** - * Set `margin-bottom` to maintain vertical rhythm - */ -h1, h2, h3, h4, h5, h6, -p, blockquote, pre, -ul, ol, dl, figure, -%vertical-rhythm { - margin-bottom: $spacing-unit / 2; -} - -hr { - margin-top: $spacing-unit; - margin-bottom: $spacing-unit; -} - -/** - * `main` element - */ -main { - display: block; /* Default value of `display` of `main` element is 'inline' in IE 11. */ -} - - - -/** - * Images - */ -img { - max-width: 100%; - vertical-align: middle; -} - - - -/** - * Figures - */ -figure > img { - display: block; -} - -figcaption { - font-size: $small-font-size; -} - - - -/** - * Lists - */ -ul, ol { - margin-left: $spacing-unit; -} - -li { - > ul, - > ol { - margin-bottom: 0; - } -} - - - -/** - * Headings - */ -h1, h2, h3, h4, h5, h6 { - font-weight: $base-font-weight; -} - - - -/** - * Links - */ -a { - color: $link-base-color; - text-decoration: none; - - &:visited { - color: $link-visited-color; - } - - &:hover { - color: $text-color; - text-decoration: underline; - } - - .social-media-list &:hover { - text-decoration: none; - - .username { - text-decoration: underline; - } - } -} - - -/** - * Blockquotes - */ -blockquote { - color: $brand-color; - border-left: 4px solid $brand-color-light; - padding-left: $spacing-unit / 2; - @include relative-font-size(1.125); - font-style: italic; - - > :last-child { - margin-bottom: 0; - } - - i, em { - font-style: normal; - } -} - - - -/** - * Code formatting - */ -pre, -code { - font-family: $code-font-family; - font-size: 0.9375em; - border: 1px solid $brand-color-light; - border-radius: 3px; - background-color: $code-background-color; -} - -code { - padding: 1px 5px; -} - -pre { - padding: 8px 12px; - overflow-x: auto; - - > code { - border: 0; - padding-right: 0; - padding-left: 0; - } -} - -.highlight { - border-radius: 3px; - background: $code-background-color; - @extend %vertical-rhythm; - - .highlighter-rouge & { - background: $code-background-color; - } -} - - - -/** - * Wrapper - */ -.wrapper { - max-width: calc(#{$content-width} - (#{$spacing-unit})); - margin-right: auto; - margin-left: auto; - padding-right: $spacing-unit / 2; - padding-left: $spacing-unit / 2; - @extend %clearfix; - - @media screen and (min-width: $on-large) { - max-width: calc(#{$content-width} - (#{$spacing-unit} * 2)); - padding-right: $spacing-unit; - padding-left: $spacing-unit; - } -} - - - -/** - * Clearfix - */ -%clearfix:after { - content: ""; - display: table; - clear: both; -} - - - -/** - * Icons - */ - -.orange { - color: #f66a0a; -} - -.grey { - color: #828282; -} - -/** - * Tables - */ -table { - margin-bottom: $spacing-unit; - width: 100%; - text-align: $table-text-align; - color: $table-text-color; - border-collapse: collapse; - border: 1px solid $table-border-color; - tr { - &:nth-child(even) { - background-color: $table-zebra-color; - } - } - th, td { - padding: ($spacing-unit / 3) ($spacing-unit / 2); - } - th { - background-color: $table-header-bg-color; - border: 1px solid $table-header-border; - } - td { - border: 1px solid $table-border-color; - } - - @include media-query($on-laptop) { - display: block; - overflow-x: auto; - -webkit-overflow-scrolling: touch; - -ms-overflow-style: -ms-autohiding-scrollbar; - } -} - -@media print { - /** - * Prevents page break from cutting through content when printing - */ - body { - display: block; - } - /** - * Replaces the top navigation menu with the project name when printing - */ - .site-header .wrapper { - display: none; - } - .site-header { - text-align: center; - } - .site-header:before { - content: "AB-3"; - font-size: 32px; - } -} - diff --git a/docs/_sass/minima/_layout.scss b/docs/_sass/minima/_layout.scss deleted file mode 100644 index ca99f981701..00000000000 --- a/docs/_sass/minima/_layout.scss +++ /dev/null @@ -1,263 +0,0 @@ -/** - * Site header - */ -.site-header { - border-top: 5px solid $brand-color-dark; - border-bottom: 1px solid $brand-color-light; - min-height: $spacing-unit * 1.865; - line-height: $base-line-height * $base-font-size * 2.25; - - // Positioning context for the mobile navigation icon - position: relative; -} - -.site-title { - @include relative-font-size(1.625); - font-weight: 300; - letter-spacing: -1px; - margin-bottom: 0; - float: left; - - @include media-query($on-palm) { - padding-right: 45px; - } - - &, - &:visited { - color: $brand-color-dark; - } -} - -.site-nav { - position: absolute; - top: 9px; - right: $spacing-unit / 2; - background-color: $background-color; - border: 1px solid $brand-color-light; - border-radius: 5px; - text-align: right; - - .nav-trigger { - display: none; - } - - .menu-icon { - float: right; - width: 36px; - height: 26px; - line-height: 0; - padding-top: 10px; - text-align: center; - - > svg path { - fill: $brand-color-dark; - } - } - - label[for="nav-trigger"] { - display: block; - float: right; - width: 36px; - height: 36px; - z-index: 2; - cursor: pointer; - } - - input ~ .trigger { - clear: both; - display: none; - } - - input:checked ~ .trigger { - display: block; - padding-bottom: 5px; - } - - .page-link { - color: $text-color; - line-height: $base-line-height; - display: block; - padding: 5px 10px; - - // Gaps between nav items, but not on the last one - &:not(:last-child) { - margin-right: 0; - } - margin-left: 20px; - } - - @media screen and (min-width: $on-medium) { - position: static; - float: right; - border: none; - background-color: inherit; - - label[for="nav-trigger"] { - display: none; - } - - .menu-icon { - display: none; - } - - input ~ .trigger { - display: block; - } - - .page-link { - display: inline; - padding: 0; - - &:not(:last-child) { - margin-right: 20px; - } - margin-left: auto; - } - } -} - - - -/** - * Page content - */ -.page-content { - padding: $spacing-unit 0; - flex: 1 0 auto; -} - -.page-heading { - @include relative-font-size(2); -} - -.post-list-heading { - @include relative-font-size(1.75); -} - -.post-list { - margin-left: 0; - list-style: none; - - > li { - margin-bottom: $spacing-unit; - } -} - -.post-meta { - font-size: $small-font-size; - color: $brand-color; -} - -.post-link { - display: block; - @include relative-font-size(1.5); -} - - - -/** - * Posts - */ -.post-header { - margin-bottom: $spacing-unit; -} - -.post-title, -.post-content h1 { - @include relative-font-size(2.625); - letter-spacing: -1px; - line-height: 1.15; - - @media screen and (min-width: $on-large) { - @include relative-font-size(2.625); - } -} - -.post-content { - margin-bottom: $spacing-unit; - - h1, h2, h3 { margin-top: $spacing-unit * 2 } - h4, h5, h6 { margin-top: $spacing-unit } - - h2 { - @include relative-font-size(1.75); - - @media screen and (min-width: $on-large) { - @include relative-font-size(2); - } - } - - h3 { - @include relative-font-size(1.375); - - @media screen and (min-width: $on-large) { - @include relative-font-size(1.625); - } - } - - h4 { - @include relative-font-size(1.25); - } - - h5 { - @include relative-font-size(1.125); - } - h6 { - @include relative-font-size(1.0625); - } -} - - -.social-media-list { - display: table; - margin: 0 auto; - li { - float: left; - margin: 5px 10px 5px 0; - &:last-of-type { margin-right: 0 } - a { - display: block; - padding: $spacing-unit / 4; - border: 1px solid $brand-color-light; - &:hover { border-color: darken($brand-color-light, 10%) } - } - } -} - - - -/** - * Pagination navbar - */ -.pagination { - margin-bottom: $spacing-unit; - @extend .social-media-list; - li { - a, div { - min-width: 41px; - text-align: center; - box-sizing: border-box; - } - div { - display: block; - padding: $spacing-unit / 4; - border: 1px solid transparent; - - &.pager-edge { - color: darken($brand-color-light, 5%); - border: 1px dashed; - } - } - } -} - - - -/** - * Grid helpers - */ -@media screen and (min-width: $on-large) { - .one-half { - width: calc(50% - (#{$spacing-unit} / 2)); - } -} diff --git a/docs/_sass/minima/custom-mixins.scss b/docs/_sass/minima/custom-mixins.scss deleted file mode 100644 index 9d4bedc1c67..00000000000 --- a/docs/_sass/minima/custom-mixins.scss +++ /dev/null @@ -1,21 +0,0 @@ -@mixin alert-variant($background, $border, $color) { - color: $color; - @include gradient-bg($background); - border-color: $border; - - .alert-link { - color: darken($color, 10%); - } -} - -@mixin gradient-bg($color, $foreground: null) { - @if $enable-gradients { - @if $foreground { - background-image: $foreground, linear-gradient(180deg, mix($body-bg, $color, 15%), $color); - } @else { - background-image: linear-gradient(180deg, mix($body-bg, $color, 15%), $color); - } - } @else { - background-color: $color; - } -} diff --git a/docs/_sass/minima/custom-styles.scss b/docs/_sass/minima/custom-styles.scss deleted file mode 100644 index 56b5d56b430..00000000000 --- a/docs/_sass/minima/custom-styles.scss +++ /dev/null @@ -1,34 +0,0 @@ -// Placeholder to allow defining custom styles that override everything else. -// (Use `_sass/minima/custom-variables.scss` to override variable defaults) -h2, h3, h4, h5, h6 { - color: #e46c0a; -} - -// Bootstrap style alerts -.alert { - position: relative; - padding: $alert-padding-y $alert-padding-x; - margin-bottom: $alert-margin-bottom; - border: $alert-border-width solid transparent; - border-radius : $alert-border-radius; -} - -// Headings for larger alerts -.alert-heading { - // Specified to prevent conflicts of changing $headings-color - color: inherit; -} - -// Provide class for links that match alerts -.alert-link { - font-weight: $alert-link-font-weight; -} - -// Generate contextual modifier classes for colorizing the alert. - -@each $color, $value in $theme-colors { - .alert-#{$color} { - @include alert-variant(color-level($value, $alert-bg-level), color-level($value, $alert-border-level), color-level($value, $alert-color-level)); - } -} - diff --git a/docs/_sass/minima/custom-variables.scss b/docs/_sass/minima/custom-variables.scss deleted file mode 100644 index a128970cbe7..00000000000 --- a/docs/_sass/minima/custom-variables.scss +++ /dev/null @@ -1,76 +0,0 @@ -// Placeholder to allow overriding predefined variables smoothly. - -//Bootstrap's default -$white: #fff !default; -$gray-100: #f8f9fa !default; -$gray-200: #e9ecef !default; -$gray-300: #dee2e6 !default; -$gray-400: #ced4da !default; -$gray-500: #adb5bd !default; -$gray-600: #6c757d !default; -$gray-700: #495057 !default; -$gray-800: #343a40 !default; -$gray-900: #212529 !default; -$black: #000 !default; -$blue: #0d6efd !default; -$indigo: #6610f2 !default; -$purple: #6f42c1 !default; -$pink: #d63384 !default; -$red: #dc3545 !default; -$orange: #fd7e14 !default; -$yellow: #ffc107 !default; -$green: #28a745 !default; -$teal: #20c997 !default; -$cyan: #17a2b8 !default; - -$primary: $blue !default; -$secondary: $gray-600 !default; -$success: $green !default; -$info: $cyan !default; -$warning: $yellow !default; -$danger: $red !default; -$light: $gray-100 !default; -$dark: $gray-800 !default; - -$theme-colors: ( - "primary": $primary, - "secondary": $secondary, - "success": $success, - "info": $info, - "warning": $warning, - "danger": $danger, - "light": $light, - "dark": $dark -) !default; - -$theme-color-interval: 8% !default; - -$body-bg: $white !default; -$body-color: $gray-900 !default; -$body-text-align: null !default; - -$enable-gradients: true; - -// Define alert colors, border radius, and padding. -$border-radius: .25rem !default; -$border-width: 1px !default; -$font-weight-bold: 700 !default; - -$alert-padding-y: .75rem !default; -$alert-padding-x: 1.25rem !default; -$alert-margin-bottom: 1rem !default; -$alert-border-radius: $border-radius !default; -$alert-link-font-weight: $font-weight-bold !default; -$alert-border-width: $border-width !default; - -$alert-bg-level: -10 !default; -$alert-border-level: -9 !default; -$alert-color-level: 6 !default; - -// Request a color level -// scss-docs-start color-level -@function color-level($color: $primary, $level: 0) { - $color-base: if($level > 0, $black, $white); - $level: abs($level); - @return mix($color-base, $color, $level * $theme-color-interval); -} diff --git a/docs/_sass/minima/initialize.scss b/docs/_sass/minima/initialize.scss deleted file mode 100644 index 30288811151..00000000000 --- a/docs/_sass/minima/initialize.scss +++ /dev/null @@ -1,51 +0,0 @@ -@charset "utf-8"; - -// Define defaults for each variable. - -$base-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Segoe UI Symbol", "Segoe UI Emoji", "Apple Color Emoji", Roboto, Helvetica, Arial, sans-serif !default; -$code-font-family: "Menlo", "Inconsolata", "Consolas", "Roboto Mono", "Ubuntu Mono", "Liberation Mono", "Courier New", monospace; -$base-font-size: 16px !default; -$base-font-weight: 400 !default; -$small-font-size: $base-font-size * 0.875 !default; -$base-line-height: 1.5 !default; - -$spacing-unit: 30px !default; - -$table-text-align: left !default; - -// Width of the content area -$content-width: 800px !default; - -$on-palm: 600px !default; -$on-laptop: 800px !default; - -$on-medium: $on-palm !default; -$on-large: $on-laptop !default; - -// Use media queries like this: -// @include media-query($on-palm) { -// .wrapper { -// padding-right: $spacing-unit / 2; -// padding-left: $spacing-unit / 2; -// } -// } -// Notice the following mixin uses max-width, in a deprecated, desktop-first -// approach, whereas media queries used elsewhere now use min-width. -@mixin media-query($device) { - @media screen and (max-width: $device) { - @content; - } -} - -@mixin relative-font-size($ratio) { - font-size: #{$ratio}rem; -} - -// Import pre-styling-overrides hook and style-partials. -@import - "minima/custom-variables", // Hook to override predefined variables. - "minima/custom-mixins", // Hook to add custom mixins. - "minima/base", // Defines element resets. - "minima/layout", // Defines structure and style based on CSS selectors. - "minima/custom-styles" // Hook to override existing styles. -; diff --git a/docs/_sass/minima/skins/classic.scss b/docs/_sass/minima/skins/classic.scss deleted file mode 100644 index 37ea9c5244c..00000000000 --- a/docs/_sass/minima/skins/classic.scss +++ /dev/null @@ -1,84 +0,0 @@ -@charset "utf-8"; - -$brand-color: #828282 !default; -$brand-color-light: lighten($brand-color, 40%) !default; -$brand-color-dark: darken($brand-color, 25%) !default; - -$text-color: #111 !default; -$background-color: #fdfdfd !default; -$code-background-color: #eef !default; - -$link-base-color: #2a7ae2 !default; -$link-visited-color: darken($link-base-color, 15%) !default; - -$table-text-color: lighten($text-color, 18%) !default; -$table-zebra-color: lighten($brand-color, 46%) !default; -$table-header-bg-color: lighten($brand-color, 43%) !default; -$table-header-border: lighten($brand-color, 36%) !default; -$table-border-color: $brand-color-light !default; - - -// Syntax highlighting styles should be adjusted appropriately for every "skin" -// ---------------------------------------------------------------------------- - -.highlight { - .c { color: #998; font-style: italic } // Comment - .err { color: #a61717; background-color: #e3d2d2 } // Error - .k { font-weight: bold } // Keyword - .o { font-weight: bold } // Operator - .cm { color: #998; font-style: italic } // Comment.Multiline - .cp { color: #999; font-weight: bold } // Comment.Preproc - .c1 { color: #998; font-style: italic } // Comment.Single - .cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special - .gd { color: #000; background-color: #fdd } // Generic.Deleted - .gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific - .ge { font-style: italic } // Generic.Emph - .gr { color: #a00 } // Generic.Error - .gh { color: #999 } // Generic.Heading - .gi { color: #000; background-color: #dfd } // Generic.Inserted - .gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific - .go { color: #888 } // Generic.Output - .gp { color: #555 } // Generic.Prompt - .gs { font-weight: bold } // Generic.Strong - .gu { color: #aaa } // Generic.Subheading - .gt { color: #a00 } // Generic.Traceback - .kc { font-weight: bold } // Keyword.Constant - .kd { font-weight: bold } // Keyword.Declaration - .kp { font-weight: bold } // Keyword.Pseudo - .kr { font-weight: bold } // Keyword.Reserved - .kt { color: #458; font-weight: bold } // Keyword.Type - .m { color: #099 } // Literal.Number - .s { color: #d14 } // Literal.String - .na { color: #008080 } // Name.Attribute - .nb { color: #0086B3 } // Name.Builtin - .nc { color: #458; font-weight: bold } // Name.Class - .no { color: #008080 } // Name.Constant - .ni { color: #800080 } // Name.Entity - .ne { color: #900; font-weight: bold } // Name.Exception - .nf { color: #900; font-weight: bold } // Name.Function - .nn { color: #555 } // Name.Namespace - .nt { color: #000080 } // Name.Tag - .nv { color: #008080 } // Name.Variable - .ow { font-weight: bold } // Operator.Word - .w { color: #bbb } // Text.Whitespace - .mf { color: #099 } // Literal.Number.Float - .mh { color: #099 } // Literal.Number.Hex - .mi { color: #099 } // Literal.Number.Integer - .mo { color: #099 } // Literal.Number.Oct - .sb { color: #d14 } // Literal.String.Backtick - .sc { color: #d14 } // Literal.String.Char - .sd { color: #d14 } // Literal.String.Doc - .s2 { color: #d14 } // Literal.String.Double - .se { color: #d14 } // Literal.String.Escape - .sh { color: #d14 } // Literal.String.Heredoc - .si { color: #d14 } // Literal.String.Interpol - .sx { color: #d14 } // Literal.String.Other - .sr { color: #009926 } // Literal.String.Regex - .s1 { color: #d14 } // Literal.String.Single - .ss { color: #990073 } // Literal.String.Symbol - .bp { color: #999 } // Name.Builtin.Pseudo - .vc { color: #008080 } // Name.Variable.Class - .vg { color: #008080 } // Name.Variable.Global - .vi { color: #008080 } // Name.Variable.Instance - .il { color: #099 } // Literal.Number.Integer.Long -} diff --git a/docs/_sass/minima/skins/solarized-dark.scss b/docs/_sass/minima/skins/solarized-dark.scss deleted file mode 100644 index f3b1f387de0..00000000000 --- a/docs/_sass/minima/skins/solarized-dark.scss +++ /dev/null @@ -1,4 +0,0 @@ -@charset "utf-8"; - -$sol-is-dark: true; -@import "minima/skins/solarized"; diff --git a/docs/_sass/minima/skins/solarized.scss b/docs/_sass/minima/skins/solarized.scss deleted file mode 100644 index 982bd7f2990..00000000000 --- a/docs/_sass/minima/skins/solarized.scss +++ /dev/null @@ -1,133 +0,0 @@ -@charset "utf-8"; - -// Solarized skin -// ============== -// Created by Sander Voerman using the Solarized -// color scheme by Ethan Schoonover . - -// This style sheet implements two options for the minima.skin setting: -// "solarized" for light mode and "solarized-dark" for dark mode. -$sol-is-dark: false !default; - - -// Color scheme -// ------------ -// The inline comments show the canonical L*a*b values for each color. - -$sol-base03: #002b36; // 15 -12 -12 -$sol-base02: #073642; // 20 -12 -12 -$sol-base01: #586e75; // 45 -07 -07 -$sol-base00: #657b83; // 50 -07 -07 -$sol-base0: #839496; // 60 -06 -03 -$sol-base1: #93a1a1; // 65 -05 -02 -$sol-base2: #eee8d5; // 92 -00 10 -$sol-base3: #fdf6e3; // 97 00 10 -$sol-yellow: #b58900; // 60 10 65 -$sol-orange: #cb4b16; // 50 50 55 -$sol-red: #dc322f; // 50 65 45 -$sol-magenta: #d33682; // 50 65 -05 -$sol-violet: #6c71c4; // 50 15 -45 -$sol-blue: #268bd2; // 55 -10 -45 -$sol-cyan: #2aa198; // 60 -35 -05 -$sol-green: #859900; // 60 -20 65 - -$sol-mono3: $sol-base3; -$sol-mono2: $sol-base2; -$sol-mono1: $sol-base1; -$sol-mono00: $sol-base00; -$sol-mono01: $sol-base01; - -@if $sol-is-dark { - $sol-mono3: $sol-base03; - $sol-mono2: $sol-base02; - $sol-mono1: $sol-base01; - $sol-mono00: $sol-base0; - $sol-mono01: $sol-base1; -} - - -// Minima color variables -// ---------------------- - -$brand-color: $sol-mono1 !default; -$brand-color-light: mix($sol-mono1, $sol-mono3) !default; -$brand-color-dark: $sol-mono00 !default; - -$text-color: $sol-mono01 !default; -$background-color: $sol-mono3 !default; -$code-background-color: $sol-mono2 !default; - -$link-base-color: $sol-blue !default; -$link-visited-color: mix($sol-blue, $sol-mono00) !default; - -$table-text-color: $sol-mono00 !default; -$table-zebra-color: mix($sol-mono2, $sol-mono3) !default; -$table-header-bg-color: $sol-mono2 !default; -$table-header-border: $sol-mono1 !default; -$table-border-color: $sol-mono1 !default; - - -// Syntax highlighting styles -// -------------------------- - -.highlight { - .c { color: $sol-mono1; font-style: italic } // Comment - .err { color: $sol-red } // Error - .k { color: $sol-mono01; font-weight: bold } // Keyword - .o { color: $sol-mono01; font-weight: bold } // Operator - .cm { color: $sol-mono1; font-style: italic } // Comment.Multiline - .cp { color: $sol-mono1; font-weight: bold } // Comment.Preproc - .c1 { color: $sol-mono1; font-style: italic } // Comment.Single - .cs { color: $sol-mono1; font-weight: bold; font-style: italic } // Comment.Special - .gd { color: $sol-red } // Generic.Deleted - .gd .x { color: $sol-red } // Generic.Deleted.Specific - .ge { color: $sol-mono00; font-style: italic } // Generic.Emph - .gr { color: $sol-red } // Generic.Error - .gh { color: $sol-mono1 } // Generic.Heading - .gi { color: $sol-green } // Generic.Inserted - .gi .x { color: $sol-green } // Generic.Inserted.Specific - .go { color: $sol-mono00 } // Generic.Output - .gp { color: $sol-mono00 } // Generic.Prompt - .gs { color: $sol-mono01; font-weight: bold } // Generic.Strong - .gu { color: $sol-mono1 } // Generic.Subheading - .gt { color: $sol-red } // Generic.Traceback - .kc { color: $sol-mono01; font-weight: bold } // Keyword.Constant - .kd { color: $sol-mono01; font-weight: bold } // Keyword.Declaration - .kp { color: $sol-mono01; font-weight: bold } // Keyword.Pseudo - .kr { color: $sol-mono01; font-weight: bold } // Keyword.Reserved - .kt { color: $sol-violet; font-weight: bold } // Keyword.Type - .m { color: $sol-cyan } // Literal.Number - .s { color: $sol-magenta } // Literal.String - .na { color: $sol-cyan } // Name.Attribute - .nb { color: $sol-blue } // Name.Builtin - .nc { color: $sol-violet; font-weight: bold } // Name.Class - .no { color: $sol-cyan } // Name.Constant - .ni { color: $sol-violet } // Name.Entity - .ne { color: $sol-violet; font-weight: bold } // Name.Exception - .nf { color: $sol-blue; font-weight: bold } // Name.Function - .nn { color: $sol-mono00 } // Name.Namespace - .nt { color: $sol-blue } // Name.Tag - .nv { color: $sol-cyan } // Name.Variable - .ow { color: $sol-mono01; font-weight: bold } // Operator.Word - .w { color: $sol-mono1 } // Text.Whitespace - .mf { color: $sol-cyan } // Literal.Number.Float - .mh { color: $sol-cyan } // Literal.Number.Hex - .mi { color: $sol-cyan } // Literal.Number.Integer - .mo { color: $sol-cyan } // Literal.Number.Oct - .sb { color: $sol-magenta } // Literal.String.Backtick - .sc { color: $sol-magenta } // Literal.String.Char - .sd { color: $sol-magenta } // Literal.String.Doc - .s2 { color: $sol-magenta } // Literal.String.Double - .se { color: $sol-magenta } // Literal.String.Escape - .sh { color: $sol-magenta } // Literal.String.Heredoc - .si { color: $sol-magenta } // Literal.String.Interpol - .sx { color: $sol-magenta } // Literal.String.Other - .sr { color: $sol-green } // Literal.String.Regex - .s1 { color: $sol-magenta } // Literal.String.Single - .ss { color: $sol-magenta } // Literal.String.Symbol - .bp { color: $sol-mono1 } // Name.Builtin.Pseudo - .vc { color: $sol-cyan } // Name.Variable.Class - .vg { color: $sol-cyan } // Name.Variable.Global - .vi { color: $sol-cyan } // Name.Variable.Instance - .il { color: $sol-cyan } // Literal.Number.Integer.Long -} diff --git a/docs/assets/css/style.scss b/docs/assets/css/style.scss deleted file mode 100644 index b5ec6976efa..00000000000 --- a/docs/assets/css/style.scss +++ /dev/null @@ -1,12 +0,0 @@ ---- -# Only the main Sass file needs front matter (the dashes are enough) ---- - -@import - "minima/skins/{{ site.minima.skin | default: 'classic' }}", - "minima/initialize"; - -.icon { - height: 21px; - width: 21px -} diff --git a/docs/images/ArchitectureDiagram.png b/docs/images/ArchitectureDiagram.png deleted file mode 100644 index cd540665053ef53e3c0eb01ec3607b02f44a3ada..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19887 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 diff --git a/docs/images/ArchitectureSequenceDiagram.png b/docs/images/ArchitectureSequenceDiagram.png deleted file mode 100644 index 37ad06a2803cb13da66978062b40b9555ecbd55a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15175 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 diff --git a/docs/images/BetterModelClassDiagram.png b/docs/images/BetterModelClassDiagram.png deleted file mode 100644 index 02a42e35e76b2a1b61e7feade34a0271e0640aec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14116 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 diff --git a/docs/images/CommitActivityDiagram.png b/docs/images/CommitActivityDiagram.png deleted file mode 100644 index 5b464126b35fc8025f8b92e7261f5ed6287c5eae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16227 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 diff --git a/docs/images/ComponentManagers.png b/docs/images/ComponentManagers.png deleted file mode 100644 index ae52a35718a82846d19185f2e5bed573d67cfbcc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17411 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

    L`n{HvGzzHFon;CZ>OTfI1 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 diff --git a/docs/images/LogicStorageDIP.png b/docs/images/LogicStorageDIP.png deleted file mode 100644 index 871157f5a9c35321a8004b0017fe6a0533129e1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5808 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 TX#zhdLZYs$rBtk7`R2a>OJ+-` diff --git a/docs/images/ParserClasses.png b/docs/images/ParserClasses.png deleted file mode 100644 index 2caeeb1a067e5e2459376de1a91699a661b41855..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28856 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 diff --git a/docs/images/StorageClassDiagram.png b/docs/images/StorageClassDiagram.png deleted file mode 100644 index 18fa4d0d51f03505593ab4dbadd5821491548e4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29426 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�y3#e%kgElqe^sH=7 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 DN7m$8 diff --git a/docs/images/UiClassDiagram.png b/docs/images/UiClassDiagram.png deleted file mode 100644 index 11f06d686714cf02d88c4b32879bb71b11f56e13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48363 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 diff --git a/docs/images/UndoRedoState0.png b/docs/images/UndoRedoState0.png deleted file mode 100644 index c5f91b5853370c1d6a8b9f5f9a9724e4a4a2c429..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6619 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 diff --git a/docs/images/UndoRedoState2.png b/docs/images/UndoRedoState2.png deleted file mode 100644 index 20853694e0338a708b62ce3a20c72bff00c0b8e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7855 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 diff --git a/docs/images/UndoRedoState3.png b/docs/images/UndoRedoState3.png deleted file mode 100644 index 1a9551b31bea8ffedd9db1094f06ef6b74431fe8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7588 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 E2LvS7wEzGB diff --git a/docs/images/UndoRedoState4.png b/docs/images/UndoRedoState4.png deleted file mode 100644 index 46dfae78c94886758c6d6c3c525db41b361d14e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7605 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 diff --git a/docs/images/UndoRedoState5.png b/docs/images/UndoRedoState5.png deleted file mode 100644 index f45889b5fdff0652cf017fd906297d229e49c8fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9427 zcmd^lc{r4B{O(8;Lb4?xB-slody?$?z6?<)W6dCjp^%WJER&t=jD3r-WJ}1t?@L(* zL&jKUFwU#K%Q@HY`kix~-*wJ){y6{4%=OOmKJW8Fv;^OMgp~f zBI4?3?F{vBauj~z;^f)e1x#@!`?-M$^zZ8+5@4Q}$ruAomn*j~HXIsjpm`+kdm%ok z2?RZOrotFZY5V*|p3kjy62bbtQ3!9A?gXN!rdCPz`i30nk z+rZ?F&c}1FQl_WE?jR&b!~@@_E8R94d>5;8WtMzt;#@Lck4_U!2HGb-E)Mx7Vupo= z;`a3UpoNz7HwLyWaTm<;?-!T{{S*!prn{s_&D6gI(V&h~e-%g~bIFx=cS7L)`N{yJ zIhs|Ow;}JI0CiUU5NoVK*s$*q@tFt z=mRbPC^*bBGjY_{cvwzaZ0sRgKv~Xw8!E)caxvbhBsS>e{&{T~0oawiA&H;EDxaw^ z4SMsTgI5MZf1Hi;{R1h~fBX%_gbU*d-_SwlLzN_-+6FPx-93w7s=b0xak2)yj()$zZY1iZ;7vkMsg+ zFCiCFTupm-;>9XnTmJH0a@s6KYa7Mp!(1$NbRW0w&@m5FinT`Yg?7~wAmyHUKAZ+l zU>5`l=cW~>V63QnRlYEbo%^tohia{-z|x83A!2{h;NE~=f<)f{duKEW2v>~7M*N7C(G1j?RI1^%9e=D)C$c-Yhlcyom)hT;{nrBm$=%Y$hI~dZyv6eG|58o3Zk%&At==WgZQpXZSmbj;wAre#xFIpH?N(Q7 z9`kzvUeLM$9jTh=iw~lN=7#;(M`z^Xyczfyiz`4N&I;9s3I;DNG1C-KhW1ACUz|_5 zIjPQ;hg?2uGk%8u!9`n&OVww$DVZ5bB0fUy4+OmSp`+7{UgB53fAJ|J7bF$+Vot%J zg}?m#8<}Ft@=THk5-Orw{`z|2BQr7R&ZmPj@Fx8ZeSNV05O^ftCGi@Q00!cAM?(?F=aw|C8hW)|Qs~`g%P*z15}BB6F0-y5|okf7N(3o5Cz`QDCgBpZEX{ z4T@}zAWL+b{`?-J_H-ymvp(fTuo?UibC*eSycW3@^JQv8N@Ze5nO-xEX8!WDN%}-) zl$@IR;FnjV=%&^;)K4ND)AU*iNVBQ}rEsRy)YKyLn%>^tWzurF6XJf8;)4g94f~d} zy+W4t_qez|DFl+E(P-lm%O%YESc%I}4t2Jfg~jw6YSx$1thdC(#6(50qvkHM(A9pi zJ{iS6bAyxRB$tgX_l@x~%LX6(;h{b(goe#?bDGc3#mH#Xsb=O8tt+?=I??1WFa2=& zdjh@1^Udj6B(HqiK%9j0w27HDLy5uVhfY_V(u$xyBXVqCLK!w;Al70q>Jf~?X*E|X z1-rMGBUNRBQ9+0_9qCQ#)i}>MO;wlO&c^r=aPQ$)@f#I=S!_9)Nna|uJl1}B z7Wf}xYBr*?4*jbfCqC@Ii;Ajg(gxGP33iZ5F|ie2{7rAt|i zg@ib@b7i+9_L7B?EZeouxe5m#vVVC~(ntuC$cG;jbY*#Xg4fKe9j!ygiR~~-5tJuJ zO=Jvds;{S4?!9AIKzsSt{mGq9-n9Cc+l$*jI`HO~eMHkU3yn*1Xg^WkoJ^_iPnS^wtxx;kd1HzkuWQDL92 z#nDVtMnXkN+11r$ay*!=j(gX>wztoTdm8=zy+R)ecAs6&_v4z9lG32!t5>fKPVg&f z`NSb@c~x4&zt>aPQ(>578F0mB%a8UxKR-Vg7nif6V;mPZcm522IQ>F)Q`1SrzQGGG zFT`H#R>6fS_Y#X*uF69^-n2NE$_Z!SGMq;T7zYWL6%&hD`|&kms>UU)p7xMiVL^zR zRU(TJO3#~@ia_wn8t_yJ#L?J1IgOx6+?nBvuq_yhtjPt4+%J9=KjfJMJ{m)4L>novl>LWAEAn zV?FMd9CLY6MA4f+)nCiG2v$!Pm-I0f5gnPEAH z;hPyzM?5J)DGo6=G=V(kzFP2MF^)1YPct*co@)Ne=av6MQ2D=utZ6UmVq;_9UB1mF zBO}8A0y$_vp}2H~z{snTT$?RlbCZQjnuvrv-ORA?@ODxF#bt1Y#8z5)$Ce^3OD-y zf_Qf?GEYy^e#YOo^&{SME1Nk>Sht+@eA`f8i#j8XB3TW?dxDoZ9_)a5F9)ZkaoD!r zo%7Wc9$#8|OD(wUNk^)Tx89_1RD@QFl&bknNd}Z3 zehD!cU+1yzJXIYL;SFG^I_*Hf2imi)e1F|qSt;H)bN5;QO3%$ahAoV6**a1Pj{Ak3^;B*21!5E7Q%g)?Ug1SW&$Q!?BjpZxPCVC zp8N9m&u%}QYnPaqF8!RaPqPgP8o!2P_yFLIw$PyBgPQd8YojgOQ%O85vOUutV_^Lp zjapy4s6TT+c*3bG0<@NvmNXN^Lp@J`!>XJqp1NMq&hAD-*3C%(H*nGY5whtjwJ21D zVs>^mfanegVesmk+`YE8heTlzv)Ej5IF!UMG&Ho#fT+OabPS+;hEzMLv_Y;Gn~(S2 z#>CN)uMf-R%PJyXz_tKPu*s~ix0n^;yL?< zeTeA+&qt97xw*VEA(_fi!h(WNLjcDzv#_8sn3)Ecmrp`W%uuzHxz7X;1v4lweVKPx z?x@X12!iXxg@q%@FHlfqAQzjgB;6Lz@?4Z9B|CfeIxjDWJUqFI^m8f@X8@hKkNLBC zP@doNl*fC3>s0mmqJ#m8lfL)cwEr>6K{|)uYu32{a^#Tqe|?hTp~0p3=Ht*%aD79A zppKZY?;14=c7Jiv#%&F9VYD*GTC=BP;f}}Su@T9YEUKCE=H^%3h$wzxOQ$OMTRr;h zyk{f*8KFNqny&T2d%h&rr9al}F}`Z4UxX?qO7enz_Ud61<+|9=M{drYJ$}45Zm1<6 zC%(Glq1l|6SaPpA$IJ_S?5oSLESUBJgLboZnNK|2>r;Q@C%KuEQq- zttx@XnqZ^SoMizTWd11F_#`&>{<_Cvv4^SKe6h!c(P3LMh(qJzmqdpdk6mqV%1TS# zO)~`JxlOZ<|D!ifdXE)&2=JTj_A7cF9*#l!zjz(|Dz@(xjNiAm#Z1~ikEWIP)q=le zuF}?pco~(cynHzv5$T-#ejrU)b9N~8lV^1tra0a6jM@sf1Xj?BehoimF?`s8>;G7yTok%0yCID{x+r2YwEoX!z2~zs8*QOvNH}^B`-XbG`_QB; z=k8?HK;8OU8kXT%gO+tz6uTcU&r4 zMD3fxVs1nnfL|_ksjYcpCKJ~MpijnY-8ndJe_}OUZQ5DR#(MfJs;Z-+oR{Y31C+uC z4^YFC`Q@$)-vU5s&NF6Z@v1T8x;6d%U$%doD~-x2cl&YA$2F&Sc(%snFz}rHgfn8! zexh zj>RJ8{H?l%$RJ&6cg76Xiwpg`^wW2xg2^Cra(2WcgDwifYcY>C#meixU#BXcV~4a| zn3+r9TMhpG4rQJk93_RuC-uf%U88z6VU)r4h)A|1mnn$^e)F2f$$WkHS*^MEcU|DA z>@U!{JaTf0Y46OW4OcJ9&aW)>WFQ2L-dQ#fSk@ldE720g>}0y?28vYg-Zad!w_Bz! zGE)M!rF8~O170Sjh5kJG_4Ru~R3ys~0v=6CWjv^Sfj#*#DkW;K#Gjhuu5d!s#uxDV zM~7l`53jF&c;(~M4Zf}z#VxkmKIyp8L|D6)k-~^X?|M2_Zq^ZUWys7*hQ87~@KQ{X z@;G>RvUQ?m<58!uRlj3orImf84Q#o7c8lG)ZaXDYC$eZ+#6nLn*xxPTtQ-I+Q<2=vcGw6V4HN zS3M;ZXRj{L*plXKTn*3zl6ITEM6At|tH}JU8OCvnn@ope(D^T@)%;+l#c%KBo0`QJeI4p19&e?) z+{ev??HfZ@e&}a(?CIyuW^V-wnLjFL5)q*#kSr^svoW4moH{?`Cf=dS?r@S5gfQDT z*{O(xFls`4b|~hCTc}23Yr-q6#Ig{rVNW1x@L-wpNGax|;XmP`Z&Df^9T3AiXS=HyVy9|sGgf@p^tdIMr>txN31lLS=%pLUVRb*Ma&REe zagOM-KI%^_;}gLl6Jx~U_yJ66A|`giuu=LD=H6;B%KYWss&cO_C|;AVvRk@eX`6R- z$|XwD(^0r^2>eaDuu4Bzwok}1IX)gpw4qn1(c2>yLrK~PIZVJ=PdL z1tI=?P(><{5n|SGXXIaWYF?e{3S-Pfhm#8x{DRcMwjwf>bqRLjUYkGqWXGbanvVC* z`xIwA;x|xLdB({W(WS4wYvWI%YQ`jZIUzOmVca?P)qB=0$2hW|D`_iUYs1O@$z~|m zYH=FbCjGmFR~hzCiT+dl$FT|cvxnTTHIq{Jf8{|?U@1q_2{VF@6vo)nJGx5H;+`JC zT!9c;KGUn52}8)ehad1@igkMKEGb$9e5b zF5GXc7;L^dd%UuLWAAIB@mRlp?vZ~^cE~frc6uhWh%gM>nTl&uJ~d6|{|XDq4GEDx znJdw8C*}&oblfB*F>wJ4CkHC8E!NKU_#@Gd9 zK7?|#va8&EMcg|xHT(&rz+-GgekDs?S9gF)B@isdiHnKh{zJb& zqm^pT&d$xv%{Z&=087dGzquMfS%YvmTwY!t(9Z}zr_u3;&_W9;D=SrFZh%pq5m8aO zbuY&){_xoQxj@ZEXT~Qf>D`lfXVKdI_V0QCloA#ZVT;Dj2hw_O&4Ohdh5s<*bmb%o zCrT=+@V9T%F*kvhSSoB2PgpN$*ScZzy9@;R43|AoRzolenU!`h`*?aEEQI{~XPx`} z7m~@~LOLM6Rj#cwv1>@TX6ofc{UL5eS43 zo2wQuHZWkIr|14%9ACe2!_MA594MNF?FrD%?rwE$ZEbaRdfLlC<-9Rb5pw3nU-h^i z&{WFRNYJye5Oi)M2kLPUNQ%y3&z`yBK^-Wdm=k<~66m7Vy@B4o36vtMR|ebDfo^L$ zM1?u<|M`Fib>EXE8MBSLj`wqq_NH70t4gU)7keYC`(1*Fu}M_M=f)%VMKPe{EtP-# z*RoR>67h2<%T8x605uu3C=vZ)dyuG`$xcm0wTHt!8x~FS}%kB z7SO)vuX4!gPFL`oOWr%_3<<|FE#$JyCkG=@z0_?aBdjl*s` z3*mbQha7YAJKuk0C~hH|y7$iSag0ET)gc9W8q8JLLG?ZydMNkPrw4U3H3e$XboUVr zgi%pq(-HP2G1t1@r1*)5yQiay%CoKYb$TYIdPls5cSty5PyW|^z54-k$NO_$XesNGc8hf?dPz%SNe+#YZ{?O;ocI%^kBK&ekvmc%x(Z*)6eSODL zcJd|HxP%Q{c@P1#XDHKbo&;I9k~3LI9(3la4-JJ-x_EmH42RMycZaBHvK>vvzH9l! zk>Ap%uzhwzreIWIJMgLiV4zzc9dfAR%CYqr$#ttVslCR-x|c6M`cD;Vu+ONVpN5^0@dn0|@V)ov&$bVPX+OF9hx$V2s`Z0s zyF>J3NTj0*Jamq(bx;Dab0LR-<`SA}>|8|EL*-@ttwsF8{pVk0ef)T{9lDLhR$8o} z(VQHnPG>2T!n%TX_VyN2_zd1$K>K42B7Lv&Z*F=_pz>Hb)c)h*)pc|pyLHkLv1$t$ z0U&uJ#AYtIZd%fL`r8Tq**1|h4eR+l@e5Gwt;gr@JEM-z!tTW zy&V`_B2B~c-aTPIkq zc)qJyGii=ZdXK^Ze-v)Jz3o<+)U7-pJS%G5BEMRZ>a#}o`|)ySOaDV$oW@U@9GH~! zcxHO~!GkNdPqUa9IqX7+#C^D&+^&h=3;|zOrin%!Atyw3{EQ|STDD;4F07h1HTGd@ zYNT*Kn6b2aS6}ht#NE4v-jkl&v+>s#kdkV7A%@q%GyAX399mv+a2mZj3j~KFM-ldj zQC?*`wm|Uj_y~jib|N|2=Iv_$Kmrx&E`I_*<_iEBZ*HCrx||ix`JW7ViWX&23i%!4 z+*wqY$xe}k8f~LlCcWga07YWrqL%2I#o{nr{Z$fi5mC>Q0$Zx+II< zjt={8(VXq=?Tg~CqyPked(-T7U?9*$k35d$+hiXH^Iw0J!Jj`Q?q z{}Uo?Z-WjtTnb1cZ#BpKi1?M6I*&rDCb*7HKhOw=A8jkczkNmBgAq&&bI68Ir@lV- zD1??{whA%^G{@`G)90sa-GTlrq(8lR4>J|)d`As#bRp$J_DrMSAwY6=c6MqUCtj?i zcsWm2hO!yL5P&p^^zJAmpSE)G39*anoGA6sU%FKht`6i7dSU5qQ6UpKj1?DpfUII{oS`7J3Q+%q*b zO0uZjTzd-(3s2AL`Y6LCq=~j=2*35|t{pQ0o(Ry9nCkOE#3LTVH#BT!Iy%vSg5+Oo z(;hZbXpD%BWngBufBFHkilv|@y9^f$H#yIFv#>O0xIb`A5aM< zlmn7OtT+}x*M)t4bt;R#=#kNpD!~(pTzxd6;o(CHEw}JTh_^@-RXl*%skYUzw z2^f|08PaVn&4Br;V6*OM? zEDaeIoD9ZmVHOt3fLI6%qYR4&5|Mv%5{sZ>5`6h1;w~j6WpA3iyvN!wklpRhN2k(b zlsxez0rwoOD+)-+@j~VRolU#v_9-v#E#U%(obPPC_eLHLjGHgFX{W3U0^IVoqvOv? zCPH61{k0N6?x>lAqW~>hPEL-Fj;_*g$12HOfW!IbV?fC>t9(`lh{DoC!C#YaSwGOx z(K#mU#>B*Er$}XwM>Hi%I9=Jr?e500+r|rnCxLQ7US3{AL`15SM?LKsL-fL@3(!+=}D(%4cry?V=cn?x{%4T#b74W( z#N=i*u?o;Hw*9v+Y`g-{UiZZdEO(R)*O7a)zniJ4De!)RjX)moK0^RdJ*@^aTRxku vuO;ILG64V#VP0P4WImn$?45@b+DNTQ)pxfU9s_R|fmD^W9u_}%{QAEE6qlTH diff --git a/docs/index.md b/docs/index.md index 7601dbaad0d..8acbdd73507 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,8 +1,10 @@ --- -layout: page -title: AddressBook Level-3 + layout: default.md + title: "" --- +# AddressBook Level-3 + [![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) diff --git a/docs/package-lock.json b/docs/package-lock.json new file mode 100644 index 00000000000..63a232e05dc --- /dev/null +++ b/docs/package-lock.json @@ -0,0 +1,8587 @@ +{ + "name": "docs", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "docs", + "version": "1.0.0", + "devDependencies": { + "markbind-cli": "^5.1.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@fortawesome/fontawesome-free": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.4.2.tgz", + "integrity": "sha512-m5cPn3e2+FDCOgi1mz0RexTUvvQibBebOUlUlW0+YrMjDTPkiJ6VTKukA1GRsvRw+12KyJndNjj0O4AgTxm2Pg==", + "dev": true, + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1" + } + }, + "node_modules/@kwsites/file-exists/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@kwsites/file-exists/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "dev": true + }, + "node_modules/@markbind/core": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@markbind/core/-/core-5.1.0.tgz", + "integrity": "sha512-YAXjH+qCXnrBzpKIAJkayVLmyIUaG/8Dms3Gpd2VIufeZyW8w0diXdgKSsymjzodTMgghZMdxG3Qpng833ARPg==", + "dev": true, + "dependencies": { + "@fortawesome/fontawesome-free": "^6.4.0", + "@markbind/core-web": "5.1.0", + "@primer/octicons": "^15.0.1", + "@sindresorhus/slugify": "^0.9.1", + "@tlylt/markdown-it-imsize": "^3.0.0", + "bluebird": "^3.7.2", + "bootswatch": "5.1.3", + "cheerio": "^0.22.0", + "crypto-js": "^4.0.0", + "csv-parse": "^4.14.2", + "ensure-posix-path": "^1.1.1", + "fastmatter": "^2.1.1", + "fs-extra": "^9.0.1", + "gh-pages": "^2.1.1", + "highlight.js": "^10.4.1", + "htmlparser2": "^3.10.1", + "ignore": "^5.1.4", + "js-beautify": "1.14.3", + "katex": "^0.15.6", + "lodash": "^4.17.15", + "markdown-it": "^12.3.2", + "markdown-it-attrs": "^4.1.3", + "markdown-it-emoji": "^1.4.0", + "markdown-it-linkify-images": "^3.0.0", + "markdown-it-mark": "^3.0.0", + "markdown-it-regexp": "^0.4.0", + "markdown-it-sub": "^1.0.0", + "markdown-it-sup": "^1.0.0", + "markdown-it-table-of-contents": "^0.4.4", + "markdown-it-task-lists": "^2.1.1", + "markdown-it-texmath": "^1.0.0", + "markdown-it-video": "^0.6.3", + "material-icons": "^1.9.1", + "moment": "^2.29.4", + "nunjucks": "3.2.2", + "path-is-inside": "^1.0.2", + "simple-git": "^2.17.0", + "url-parse": "^1.5.10", + "uuid": "^8.3.1", + "vue": "2.6.14", + "vue-server-renderer": "2.6.14", + "vue-template-compiler": "2.6.14", + "walk-sync": "^2.0.2", + "winston": "^2.4.4" + } + }, + "node_modules/@markbind/core-web": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@markbind/core-web/-/core-web-5.1.0.tgz", + "integrity": "sha512-TRzz8ZCr25pylKvFxF/WwXDi4Gbtsb2OLXV61WyTFqVy03tFoEJ2mqncpbliI9DrfDdKWcm1YZPgDCedVkYjKA==", + "dev": true + }, + "node_modules/@primer/octicons": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-15.2.0.tgz", + "integrity": "sha512-4cHZzcZ3F/HQNL4EKSaFyVsW7XtITiJkTeB1JDDmRuP/XobyWyF9gWxuV9c+byUa8dOB5KNQn37iRvNrIehPUQ==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.1" + } + }, + "node_modules/@sindresorhus/slugify": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-0.9.1.tgz", + "integrity": "sha512-b6heYM9dzZD13t2GOiEQTDE0qX+I1GyOotMwKh9VQqzuNiVdPVT8dM43fe9HNb/3ul+Qwd5oKSEDrDIfhq3bnQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5", + "lodash.deburr": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@tlylt/markdown-it-imsize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@tlylt/markdown-it-imsize/-/markdown-it-imsize-3.0.0.tgz", + "integrity": "sha512-6kTM+vRJTuN2UxNPyJ8yC+NHrzS+MxVHV+z+bDxSr/Fd7eTah2+otLKC2B17YI/1lQnSumA2qokPGuzsA98c6g==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/apache-crypt": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.5.tgz", + "integrity": "sha512-ICnYQH+DFVmw+S4Q0QY2XRXD8Ne8ewh8HgbuFH4K7022zCxgHM0Hz1xkRnUlEfAXNbwp1Cnhbedu60USIfDxvg==", + "dev": true, + "dependencies": { + "unix-crypt-td-js": "^1.1.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/apache-md5": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.7.tgz", + "integrity": "sha512-JtHjzZmJxtzfTSjsCyHgPR155HBe5WGyUyHTaEkfy46qhwCFKx1Epm6nAxgUG3WfUZP1dWhGqj9Z2NOBeZ+uBw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dev": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/bootswatch": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bootswatch/-/bootswatch-5.1.3.tgz", + "integrity": "sha512-NmZFN6rOCoXWQ/PkzmD8FFWDe24kocX9OXWHNVaLxVVnpqpAzEbMFsf8bAfKwVtpNXibasZCzv09B5fLieAh2g==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==", + "dev": true, + "dependencies": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==", + "dev": true + }, + "node_modules/css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "node_modules/css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/csv-parse": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.3.tgz", + "integrity": "sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==", + "dev": true + }, + "node_modules/cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha512-TVF6svNzeQCOpjCqsy0/CSy8VgObG3wXusJ73xW2GbG5rGx7lC8zxDSURicsXI2UsGdi2L0QNRCi745/wUDvsA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "dev": true, + "dependencies": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "node_modules/editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "dev": true, + "dependencies": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "bin": { + "editorconfig": "bin/editorconfig" + } + }, + "node_modules/editorconfig/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/email-addresses": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", + "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ensure-posix-path": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ensure-posix-path/-/ensure-posix-path-1.1.1.tgz", + "integrity": "sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw==", + "dev": true + }, + "node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", + "dev": true, + "dependencies": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + } + }, + "node_modules/event-stream/node_modules/split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", + "dev": true, + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/event-stream/node_modules/stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", + "dev": true, + "dependencies": { + "duplexer": "~0.1.1" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", + "dev": true, + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, + "node_modules/fastmatter": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fastmatter/-/fastmatter-2.1.1.tgz", + "integrity": "sha512-NFrjZEPJZTexoJEuyM5J7n4uFaLf0dOI7Ok4b2IZXOYBqCp1Bh5RskANmQ2TuDsz3M35B1yL2AP/Rn+kp85KeA==", + "dev": true, + "dependencies": { + "js-yaml": "^3.13.0", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through2": "^3.0.1" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fecha": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", + "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==", + "dev": true + }, + "node_modules/figlet": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.2.tgz", + "integrity": "sha512-WOn21V8AhyE1QqVfPIVxe3tupJacq1xGkPTB4iagT6o+P2cAgEOOwIxMftr4+ZCTI6d551ij9j61DFr0nsP2uQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/file-stream-rotator": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.4.1.tgz", + "integrity": "sha512-W3aa3QJEc8BS2MmdVpQiYLKHj3ijpto1gMDlsgCRSKfIUe6MwkcpODGPQ3vZfb0XvCeCqlu9CBQTN7oQri2TZQ==", + "dev": true, + "dependencies": { + "moment": "^2.11.2" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "node_modules/filename-reserved-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz", + "integrity": "sha512-UZArj7+U+2reBBVCvVmRlyq9D7EYQdUtuNN+1iz7pF1jGcJ2L0TjiRCxsTZfj2xFbM4c25uGCUDpKTHA7L2TKg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/filenamify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz", + "integrity": "sha512-DKVP0WQcB7WaIMSwDETqImRej2fepPqvXQjaVib7LRZn9Rxn5UbvK2tYTqGf1A1DkIprQQkG4XSQXSOZp7Q3GQ==", + "dev": true, + "dependencies": { + "filename-reserved-regex": "^1.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/filenamify-url": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/filenamify-url/-/filenamify-url-1.0.0.tgz", + "integrity": "sha512-O9K9JcZeF5VdZWM1qR92NSv1WY2EofwudQayPx5dbnnFl9k0IcZha4eV/FGkjnBK+1irOQInij0yiooCHu/0Fg==", + "dev": true, + "dependencies": { + "filenamify": "^1.0.0", + "humanize-url": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gh-pages": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-2.2.0.tgz", + "integrity": "sha512-c+yPkNOPMFGNisYg9r4qvsMIjVYikJv7ImFOhPIVPt0+AcRUamZ7zkGRLHz7FKB0xrlZ+ddSOJsZv9XAFVXLmA==", + "dev": true, + "dependencies": { + "async": "^2.6.1", + "commander": "^2.18.0", + "email-addresses": "^3.0.1", + "filenamify-url": "^1.0.0", + "fs-extra": "^8.1.0", + "globby": "^6.1.0" + }, + "bin": { + "gh-pages": "bin/gh-pages.js", + "gh-pages-clean": "bin/gh-pages-clean.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/gh-pages/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/gh-pages/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/gh-pages/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/gh-pages/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==", + "dev": true + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/http-auth": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.1.3.tgz", + "integrity": "sha512-Jbx0+ejo2IOx+cRUYAGS1z6RGc6JfYUNkysZM4u4Sfk1uLlGv814F7/PIjQQAuThLdAWxb74JMGd5J8zex1VQg==", + "dev": true, + "dependencies": { + "apache-crypt": "^1.1.2", + "apache-md5": "^1.0.6", + "bcryptjs": "^2.3.0", + "uuid": "^3.0.0" + }, + "engines": { + "node": ">=4.6.1" + } + }, + "node_modules/http-auth/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/humanize-url": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz", + "integrity": "sha512-RtgTzXCPVb/te+e82NDhAc5paj+DuKSratIGAr+v+HZK24eAQ8LMoBGYoL7N/O+9iEc33AKHg45dOMKw3DNldQ==", + "dev": true, + "dependencies": { + "normalize-url": "^1.0.0", + "strip-url-auth": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "node_modules/js-beautify": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.3.tgz", + "integrity": "sha512-f1ra8PHtOEu/70EBnmiUlV8nJePS58y9qKjl4JHfYWlFH6bo7ogZBz//FAZp7jDuXtYnGYKymZPlrg2I/9Zo4g==", + "dev": true, + "dependencies": { + "config-chain": "^1.1.13", + "editorconfig": "^0.15.3", + "glob": "^7.1.3", + "nopt": "^5.0.0" + }, + "bin": { + "css-beautify": "js/bin/css-beautify.js", + "html-beautify": "js/bin/html-beautify.js", + "js-beautify": "js/bin/js-beautify.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/katex": { + "version": "0.15.6", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.15.6.tgz", + "integrity": "sha512-UpzJy4yrnqnhXvRPhjEuLA4lcPn6eRngixW7Q3TJErjg3Aw2PuLFBzTkdUb89UtumxjhHTqL3a5GDGETMSwgJA==", + "dev": true, + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "dependencies": { + "commander": "^8.0.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/live-server": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/live-server/-/live-server-1.2.1.tgz", + "integrity": "sha512-Yn2XCVjErTkqnM3FfTmM7/kWy3zP7+cEtC7x6u+wUzlQ+1UW3zEYbbyJrc0jNDwiMDZI0m4a0i3dxlGHVyXczw==", + "dev": true, + "dependencies": { + "chokidar": "^2.0.4", + "colors": "latest", + "connect": "^3.6.6", + "cors": "latest", + "event-stream": "3.3.4", + "faye-websocket": "0.11.x", + "http-auth": "3.1.x", + "morgan": "^1.9.1", + "object-assign": "latest", + "opn": "latest", + "proxy-middleware": "latest", + "send": "latest", + "serve-index": "^1.9.1" + }, + "bin": { + "live-server": "live-server.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/live-server/node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", + "dev": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/live-server/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/live-server/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/live-server/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "dev": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/live-server/node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/live-server/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/live-server/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", + "dev": true + }, + "node_modules/lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg==", + "dev": true + }, + "node_modules/lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha512-lxdsn7xxlCymgLYo1gGvVrfHmkjDiyqVv62FAeF2i5ta72BipE1SLxw8hPEPLhD4/247Ijw07UQH7Hq/chT5LA==", + "dev": true + }, + "node_modules/lodash.deburr": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-4.1.0.tgz", + "integrity": "sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==", + "dev": true + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "dev": true + }, + "node_modules/lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha512-pXYUy7PR8BCLwX5mgJ/aNtyOvuJTdZAo9EQFUvMIYugqmJxnrYaANvTbgndOzHSCSR0wnlBBfRXJL5SbWxo3FQ==", + "dev": true + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "dev": true + }, + "node_modules/lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==", + "dev": true + }, + "node_modules/lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", + "dev": true + }, + "node_modules/lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==", + "dev": true + }, + "node_modules/lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha512-qkTuvgEzYdyhiJBx42YPzPo71R1aEr0z79kAv7Ixg8wPFEjgRgJdUsGMG3Hf3OYSF/kHI79XhNlt+5Ar6OzwxQ==", + "dev": true + }, + "node_modules/lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==", + "dev": true + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "node_modules/logform": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-1.10.0.tgz", + "integrity": "sha512-em5ojIhU18fIMOw/333mD+ZLE2fis0EzXl1ZwHx4iQzmpQi6odNiY/t+ITNr33JZhT9/KEaH+UPIipr6a9EjWg==", + "dev": true, + "dependencies": { + "colors": "^1.2.1", + "fast-safe-stringify": "^2.0.4", + "fecha": "^2.3.3", + "ms": "^2.1.1", + "triple-beam": "^1.2.0" + } + }, + "node_modules/logform/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", + "dev": true + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/markbind-cli": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/markbind-cli/-/markbind-cli-5.1.0.tgz", + "integrity": "sha512-6POI1Q++2aZa+Udk/oQ6LX1oNPbKUBDY0mN3Up7VOFeK+XYW51faxuCk2Q91JTBxYRKLNtshxf0y12kB4Cj9Qw==", + "dev": true, + "dependencies": { + "@markbind/core": "5.1.0", + "@markbind/core-web": "5.1.0", + "bluebird": "^3.7.2", + "chalk": "^3.0.0", + "cheerio": "^0.22.0", + "chokidar": "^3.3.0", + "colors": "1.4.0", + "commander": "^8.1.0", + "figlet": "^1.2.4", + "find-up": "^4.1.0", + "fs-extra": "^9.0.1", + "live-server": "1.2.1", + "lodash": "^4.17.15", + "url-parse": "^1.5.10", + "winston": "^2.4.4", + "winston-daily-rotate-file": "^3.10.0" + }, + "bin": { + "markbind": "index.js" + } + }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-attrs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.1.6.tgz", + "integrity": "sha512-O7PDKZlN8RFMyDX13JnctQompwrrILuz2y43pW2GagcwpIIElkAdfeek+erHfxUOlXWPsjFeWmZ8ch1xtRLWpA==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "markdown-it": ">= 9.0.0" + } + }, + "node_modules/markdown-it-emoji": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz", + "integrity": "sha512-QCz3Hkd+r5gDYtS2xsFXmBYrgw6KuWcJZLCEkdfAuwzZbShCmCfta+hwAMq4NX/4xPzkSHduMKgMkkPUJxSXNg==", + "dev": true + }, + "node_modules/markdown-it-linkify-images": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-linkify-images/-/markdown-it-linkify-images-3.0.0.tgz", + "integrity": "sha512-Vs5yGJa5MWjFgytzgtn8c1U6RcStj3FZKhhx459U8dYbEE5FTWZ6mMRkYMiDlkFO0j4VCsQT1LT557bY0ETgtg==", + "dev": true, + "dependencies": { + "markdown-it": "^13.0.1" + } + }, + "node_modules/markdown-it-linkify-images/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/markdown-it-linkify-images/node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/markdown-it-linkify-images/node_modules/linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/markdown-it-linkify-images/node_modules/markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-mark": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-3.0.1.tgz", + "integrity": "sha512-HyxjAu6BRsdt6Xcv6TKVQnkz/E70TdGXEFHRYBGLncRE9lBFwDNLVtFojKxjJWgJ+5XxUwLaHXy+2sGBbDn+4A==", + "dev": true + }, + "node_modules/markdown-it-regexp": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/markdown-it-regexp/-/markdown-it-regexp-0.4.0.tgz", + "integrity": "sha512-0XQmr46K/rMKnI93Y3CLXsHj4jIioRETTAiVnJnjrZCEkGaDOmUxTbZj/aZ17G5NlRcVpWBYjqpwSlQ9lj+Kxw==", + "dev": true + }, + "node_modules/markdown-it-sub": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz", + "integrity": "sha512-z2Rm/LzEE1wzwTSDrI+FlPEveAAbgdAdPhdWarq/ZGJrGW/uCQbKAnhoCsE4hAbc3SEym26+W2z/VQB0cQiA9Q==", + "dev": true + }, + "node_modules/markdown-it-sup": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz", + "integrity": "sha512-E32m0nV9iyhRR7CrhnzL5msqic7rL1juWre6TQNxsnApg7Uf+F97JOKxUijg5YwXz86lZ0mqfOnutoryyNdntQ==", + "dev": true + }, + "node_modules/markdown-it-table-of-contents": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.4.tgz", + "integrity": "sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw==", + "dev": true, + "engines": { + "node": ">6.4.0" + } + }, + "node_modules/markdown-it-task-lists": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz", + "integrity": "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==", + "dev": true + }, + "node_modules/markdown-it-texmath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-texmath/-/markdown-it-texmath-1.0.0.tgz", + "integrity": "sha512-4hhkiX8/gus+6e53PLCUmUrsa6ZWGgJW2XCW6O0ASvZUiezIK900ZicinTDtG3kAO2kon7oUA/ReWmpW2FByxg==", + "dev": true + }, + "node_modules/markdown-it-video": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/markdown-it-video/-/markdown-it-video-0.6.3.tgz", + "integrity": "sha512-T4th1kwy0OcvyWSN4u3rqPGxvbDclpucnVSSaH3ZacbGsAts964dxokx9s/I3GYsrDCJs4ogtEeEeVP18DQj0Q==", + "dev": true + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/matcher-collection": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-2.0.1.tgz", + "integrity": "sha512-daE62nS2ZQsDg9raM0IlZzLmI2u+7ZapXBwdoeBUKAYERPDDIc0qNqA8E0Rp2D+gspKR7BgIFP52GeujaGXWeQ==", + "dev": true, + "dependencies": { + "@types/minimatch": "^3.0.3", + "minimatch": "^3.0.2" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/material-icons": { + "version": "1.13.11", + "resolved": "https://registry.npmjs.org/material-icons/-/material-icons-1.13.11.tgz", + "integrity": "sha512-kp2oAdaqo/Zp6hpTZW01rOgDPWmxBUszSdDzkRm1idCjjNvdUMnqu8qu58cll6CObo+o0cydOiPLdoSugLm+mQ==", + "dev": true + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, + "node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "dev": true, + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/nan": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", + "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", + "dev": true, + "optional": true + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha512-A48My/mtCklowHBlI8Fq2jFWK4tX4lJ5E6ytFsSOq1fzpvT0SQSgKhSg7lN5c2uYFOrUAOQp6zhhJnpp1eMloQ==", + "dev": true, + "dependencies": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/nunjucks": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.2.tgz", + "integrity": "sha512-KUi85OoF2NMygwODAy28Lh9qHmq5hO3rBlbkYoC8v377h4l8Pt5qFjILl0LWpMbOrZ18CzfVVUvIHUIrtED3sA==", + "dev": true, + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "optionalDependencies": { + "chokidar": "^3.3.0" + } + }, + "node_modules/nunjucks/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", + "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/opn": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", + "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", + "deprecated": "The package has been renamed to `open`", + "dev": true, + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", + "dev": true + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "dev": true, + "dependencies": { + "through": "~2.3" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, + "node_modules/proxy-middleware": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", + "integrity": "sha512-EGCG8SeoIRVMhsqHQUdDigB2i7qU7fCsWASwn54+nPutYO8n4q6EiwMzyfWlC+dzRFExP+kvcnDFdBDHoZBU7Q==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true + }, + "node_modules/query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz", + "integrity": "sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/send/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", + "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==", + "dev": true + }, + "node_modules/simple-git": { + "version": "2.48.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.48.0.tgz", + "integrity": "sha512-z4qtrRuaAFJS4PUd0g+xy7aN4y+RvEt/QTJpR184lhJguBA1S/LsVlvE/CM95RsYMOFJG3NGGDjqFCzKU19S/A==", + "dev": true, + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.3.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/steveukx/" + } + }, + "node_modules/simple-git/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/simple-git/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "dev": true + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-combiner": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", + "dev": true, + "dependencies": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-url-auth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-url-auth/-/strip-url-auth-1.0.1.tgz", + "integrity": "sha512-++41PnXftlL3pvI6lpvhSEO+89g1kIJC4MYB5E6yH+WHa5InIqz51yGd1YOGd7VNSNdoEOfzTMqbAM/2PbgaHQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==", + "dev": true + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/union-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unix-crypt-td-js": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz", + "integrity": "sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==", + "dev": true + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", + "dev": true, + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vue": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz", + "integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==", + "dev": true + }, + "node_modules/vue-server-renderer": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.14.tgz", + "integrity": "sha512-HifYRa/LW7cKywg9gd4ZtvtRuBlstQBao5ZCWlg40fyB4OPoGfEXAzxb0emSLv4pBDOHYx0UjpqvxpiQFEuoLA==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "hash-sum": "^1.0.2", + "he": "^1.1.0", + "lodash.template": "^4.5.0", + "lodash.uniq": "^4.5.0", + "resolve": "^1.2.0", + "serialize-javascript": "^3.1.0", + "source-map": "0.5.6" + } + }, + "node_modules/vue-server-renderer/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vue-server-renderer/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vue-server-renderer/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/vue-template-compiler": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz", + "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==", + "dev": true, + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, + "node_modules/walk-sync": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz", + "integrity": "sha512-IC8sL7aB4/ZgFcGI2T1LczZeFWZ06b3zoHH7jBPyHxOtIIz1jppWHjjEXkOFvFojBVAK9pV7g47xOZ4LW3QLfg==", + "dev": true, + "dependencies": { + "@types/minimatch": "^3.0.3", + "ensure-posix-path": "^1.1.0", + "matcher-collection": "^2.0.0", + "minimatch": "^3.0.4" + }, + "engines": { + "node": "8.* || >= 10.*" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/winston": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.6.tgz", + "integrity": "sha512-J5Zu4p0tojLde8mIOyDSsmLmcP8I3Z6wtwpTDHx1+hGcdhxcJaAmG4CFtagkb+NiN1M9Ek4b42pzMWqfc9jm8w==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "colors": "1.0.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "stack-trace": "0.0.x" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/winston-compat": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/winston-compat/-/winston-compat-0.1.5.tgz", + "integrity": "sha512-EPvPcHT604AV3Ji6d3+vX8ENKIml9VSxMRnPQ+cuK/FX6f3hvPP2hxyoeeCOCFvDrJEujalfcKWlWPvAnFyS9g==", + "dev": true, + "dependencies": { + "cycle": "~1.0.3", + "logform": "^1.6.0", + "triple-beam": "^1.2.0" + }, + "engines": { + "node": ">= 6.4.0" + } + }, + "node_modules/winston-daily-rotate-file": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-3.10.0.tgz", + "integrity": "sha512-KO8CfbI2CvdR3PaFApEH02GPXiwJ+vbkF1mCkTlvRIoXFI8EFlf1ACcuaahXTEiDEKCii6cNe95gsL4ZkbnphA==", + "dev": true, + "dependencies": { + "file-stream-rotator": "^0.4.1", + "object-hash": "^1.3.0", + "semver": "^6.2.0", + "triple-beam": "^1.3.0", + "winston-compat": "^0.1.4", + "winston-transport": "^4.2.0" + }, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "winston": "^2 || ^3" + } + }, + "node_modules/winston-daily-rotate-file/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/winston-transport": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", + "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", + "dev": true, + "dependencies": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 6.4.0" + } + }, + "node_modules/winston-transport/node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", + "dev": true + }, + "node_modules/winston-transport/node_modules/logform": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.2.tgz", + "integrity": "sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==", + "dev": true, + "dependencies": { + "@colors/colors": "1.5.0", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + } + }, + "node_modules/winston-transport/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/winston/node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "dev": true + }, + "node_modules/winston/node_modules/colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true + } + }, + "dependencies": { + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true + }, + "@fortawesome/fontawesome-free": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.4.2.tgz", + "integrity": "sha512-m5cPn3e2+FDCOgi1mz0RexTUvvQibBebOUlUlW0+YrMjDTPkiJ6VTKukA1GRsvRw+12KyJndNjj0O4AgTxm2Pg==", + "dev": true + }, + "@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "dev": true, + "requires": { + "debug": "^4.1.1" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "dev": true + }, + "@markbind/core": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@markbind/core/-/core-5.1.0.tgz", + "integrity": "sha512-YAXjH+qCXnrBzpKIAJkayVLmyIUaG/8Dms3Gpd2VIufeZyW8w0diXdgKSsymjzodTMgghZMdxG3Qpng833ARPg==", + "dev": true, + "requires": { + "@fortawesome/fontawesome-free": "^6.4.0", + "@markbind/core-web": "5.1.0", + "@primer/octicons": "^15.0.1", + "@sindresorhus/slugify": "^0.9.1", + "@tlylt/markdown-it-imsize": "^3.0.0", + "bluebird": "^3.7.2", + "bootswatch": "5.1.3", + "cheerio": "^0.22.0", + "crypto-js": "^4.0.0", + "csv-parse": "^4.14.2", + "ensure-posix-path": "^1.1.1", + "fastmatter": "^2.1.1", + "fs-extra": "^9.0.1", + "gh-pages": "^2.1.1", + "highlight.js": "^10.4.1", + "htmlparser2": "^3.10.1", + "ignore": "^5.1.4", + "js-beautify": "1.14.3", + "katex": "^0.15.6", + "lodash": "^4.17.15", + "markdown-it": "^12.3.2", + "markdown-it-attrs": "^4.1.3", + "markdown-it-emoji": "^1.4.0", + "markdown-it-linkify-images": "^3.0.0", + "markdown-it-mark": "^3.0.0", + "markdown-it-regexp": "^0.4.0", + "markdown-it-sub": "^1.0.0", + "markdown-it-sup": "^1.0.0", + "markdown-it-table-of-contents": "^0.4.4", + "markdown-it-task-lists": "^2.1.1", + "markdown-it-texmath": "^1.0.0", + "markdown-it-video": "^0.6.3", + "material-icons": "^1.9.1", + "moment": "^2.29.4", + "nunjucks": "3.2.2", + "path-is-inside": "^1.0.2", + "simple-git": "^2.17.0", + "url-parse": "^1.5.10", + "uuid": "^8.3.1", + "vue": "2.6.14", + "vue-server-renderer": "2.6.14", + "vue-template-compiler": "2.6.14", + "walk-sync": "^2.0.2", + "winston": "^2.4.4" + } + }, + "@markbind/core-web": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@markbind/core-web/-/core-web-5.1.0.tgz", + "integrity": "sha512-TRzz8ZCr25pylKvFxF/WwXDi4Gbtsb2OLXV61WyTFqVy03tFoEJ2mqncpbliI9DrfDdKWcm1YZPgDCedVkYjKA==", + "dev": true + }, + "@primer/octicons": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-15.2.0.tgz", + "integrity": "sha512-4cHZzcZ3F/HQNL4EKSaFyVsW7XtITiJkTeB1JDDmRuP/XobyWyF9gWxuV9c+byUa8dOB5KNQn37iRvNrIehPUQ==", + "dev": true, + "requires": { + "object-assign": "^4.1.1" + } + }, + "@sindresorhus/slugify": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-0.9.1.tgz", + "integrity": "sha512-b6heYM9dzZD13t2GOiEQTDE0qX+I1GyOotMwKh9VQqzuNiVdPVT8dM43fe9HNb/3ul+Qwd5oKSEDrDIfhq3bnQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "lodash.deburr": "^4.1.0" + } + }, + "@tlylt/markdown-it-imsize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@tlylt/markdown-it-imsize/-/markdown-it-imsize-3.0.0.tgz", + "integrity": "sha512-6kTM+vRJTuN2UxNPyJ8yC+NHrzS+MxVHV+z+bDxSr/Fd7eTah2+otLKC2B17YI/1lQnSumA2qokPGuzsA98c6g==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "apache-crypt": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.5.tgz", + "integrity": "sha512-ICnYQH+DFVmw+S4Q0QY2XRXD8Ne8ewh8HgbuFH4K7022zCxgHM0Hz1xkRnUlEfAXNbwp1Cnhbedu60USIfDxvg==", + "dev": true, + "requires": { + "unix-crypt-td-js": "^1.1.4" + } + }, + "apache-md5": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.7.tgz", + "integrity": "sha512-JtHjzZmJxtzfTSjsCyHgPR155HBe5WGyUyHTaEkfy46qhwCFKx1Epm6nAxgUG3WfUZP1dWhGqj9Z2NOBeZ+uBw==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "dev": true + }, + "async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "bootswatch": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bootswatch/-/bootswatch-5.1.3.tgz", + "integrity": "sha512-NmZFN6rOCoXWQ/PkzmD8FFWDe24kocX9OXWHNVaLxVVnpqpAzEbMFsf8bAfKwVtpNXibasZCzv09B5fLieAh2g==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==", + "dev": true, + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "dev": true + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==", + "dev": true + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==", + "dev": true, + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true + }, + "csv-parse": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.3.tgz", + "integrity": "sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==", + "dev": true + }, + "cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha512-TVF6svNzeQCOpjCqsy0/CSy8VgObG3wXusJ73xW2GbG5rGx7lC8zxDSURicsXI2UsGdi2L0QNRCi745/wUDvsA==", + "dev": true + }, + "de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true + }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "dev": true, + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "dev": true, + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "email-addresses": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", + "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true + }, + "ensure-posix-path": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ensure-posix-path/-/ensure-posix-path-1.1.1.tgz", + "integrity": "sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw==", + "dev": true + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true + }, + "event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", + "dev": true, + "requires": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + }, + "dependencies": { + "split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", + "dev": true, + "requires": { + "through": "2" + } + }, + "stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", + "dev": true, + "requires": { + "duplexer": "~0.1.1" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + } + } + }, + "eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", + "dev": true + }, + "fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, + "fastmatter": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fastmatter/-/fastmatter-2.1.1.tgz", + "integrity": "sha512-NFrjZEPJZTexoJEuyM5J7n4uFaLf0dOI7Ok4b2IZXOYBqCp1Bh5RskANmQ2TuDsz3M35B1yL2AP/Rn+kp85KeA==", + "dev": true, + "requires": { + "js-yaml": "^3.13.0", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through2": "^3.0.1" + } + }, + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fecha": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", + "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==", + "dev": true + }, + "figlet": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.2.tgz", + "integrity": "sha512-WOn21V8AhyE1QqVfPIVxe3tupJacq1xGkPTB4iagT6o+P2cAgEOOwIxMftr4+ZCTI6d551ij9j61DFr0nsP2uQ==", + "dev": true + }, + "file-stream-rotator": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.4.1.tgz", + "integrity": "sha512-W3aa3QJEc8BS2MmdVpQiYLKHj3ijpto1gMDlsgCRSKfIUe6MwkcpODGPQ3vZfb0XvCeCqlu9CBQTN7oQri2TZQ==", + "dev": true, + "requires": { + "moment": "^2.11.2" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "filename-reserved-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz", + "integrity": "sha512-UZArj7+U+2reBBVCvVmRlyq9D7EYQdUtuNN+1iz7pF1jGcJ2L0TjiRCxsTZfj2xFbM4c25uGCUDpKTHA7L2TKg==", + "dev": true + }, + "filenamify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz", + "integrity": "sha512-DKVP0WQcB7WaIMSwDETqImRej2fepPqvXQjaVib7LRZn9Rxn5UbvK2tYTqGf1A1DkIprQQkG4XSQXSOZp7Q3GQ==", + "dev": true, + "requires": { + "filename-reserved-regex": "^1.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" + } + }, + "filenamify-url": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/filenamify-url/-/filenamify-url-1.0.0.tgz", + "integrity": "sha512-O9K9JcZeF5VdZWM1qR92NSv1WY2EofwudQayPx5dbnnFl9k0IcZha4eV/FGkjnBK+1irOQInij0yiooCHu/0Fg==", + "dev": true, + "requires": { + "filenamify": "^1.0.0", + "humanize-url": "^1.0.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", + "dev": true + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "dev": true + }, + "gh-pages": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-2.2.0.tgz", + "integrity": "sha512-c+yPkNOPMFGNisYg9r4qvsMIjVYikJv7ImFOhPIVPt0+AcRUamZ7zkGRLHz7FKB0xrlZ+ddSOJsZv9XAFVXLmA==", + "dev": true, + "requires": { + "async": "^2.6.1", + "commander": "^2.18.0", + "email-addresses": "^3.0.1", + "filenamify-url": "^1.0.0", + "fs-extra": "^8.1.0", + "globby": "^6.1.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + } + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "dev": true + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "http-auth": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.1.3.tgz", + "integrity": "sha512-Jbx0+ejo2IOx+cRUYAGS1z6RGc6JfYUNkysZM4u4Sfk1uLlGv814F7/PIjQQAuThLdAWxb74JMGd5J8zex1VQg==", + "dev": true, + "requires": { + "apache-crypt": "^1.1.2", + "apache-md5": "^1.0.6", + "bcryptjs": "^2.3.0", + "uuid": "^3.0.0" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "dependencies": { + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + } + } + }, + "http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "humanize-url": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz", + "integrity": "sha512-RtgTzXCPVb/te+e82NDhAc5paj+DuKSratIGAr+v+HZK24eAQ8LMoBGYoL7N/O+9iEc33AKHg45dOMKw3DNldQ==", + "dev": true, + "requires": { + "normalize-url": "^1.0.0", + "strip-url-auth": "^1.0.0" + } + }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "js-beautify": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.3.tgz", + "integrity": "sha512-f1ra8PHtOEu/70EBnmiUlV8nJePS58y9qKjl4JHfYWlFH6bo7ogZBz//FAZp7jDuXtYnGYKymZPlrg2I/9Zo4g==", + "dev": true, + "requires": { + "config-chain": "^1.1.13", + "editorconfig": "^0.15.3", + "glob": "^7.1.3", + "nopt": "^5.0.0" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "katex": { + "version": "0.15.6", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.15.6.tgz", + "integrity": "sha512-UpzJy4yrnqnhXvRPhjEuLA4lcPn6eRngixW7Q3TJErjg3Aw2PuLFBzTkdUb89UtumxjhHTqL3a5GDGETMSwgJA==", + "dev": true, + "requires": { + "commander": "^8.0.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, + "live-server": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/live-server/-/live-server-1.2.1.tgz", + "integrity": "sha512-Yn2XCVjErTkqnM3FfTmM7/kWy3zP7+cEtC7x6u+wUzlQ+1UW3zEYbbyJrc0jNDwiMDZI0m4a0i3dxlGHVyXczw==", + "dev": true, + "requires": { + "chokidar": "^2.0.4", + "colors": "latest", + "connect": "^3.6.6", + "cors": "latest", + "event-stream": "3.3.4", + "faye-websocket": "0.11.x", + "http-auth": "3.1.x", + "morgan": "^1.9.1", + "object-assign": "latest", + "opn": "latest", + "proxy-middleware": "latest", + "send": "latest", + "serve-index": "^1.9.1" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", + "dev": true + }, + "lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg==", + "dev": true + }, + "lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha512-lxdsn7xxlCymgLYo1gGvVrfHmkjDiyqVv62FAeF2i5ta72BipE1SLxw8hPEPLhD4/247Ijw07UQH7Hq/chT5LA==", + "dev": true + }, + "lodash.deburr": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-4.1.0.tgz", + "integrity": "sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==", + "dev": true + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "dev": true + }, + "lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha512-pXYUy7PR8BCLwX5mgJ/aNtyOvuJTdZAo9EQFUvMIYugqmJxnrYaANvTbgndOzHSCSR0wnlBBfRXJL5SbWxo3FQ==", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "dev": true + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==", + "dev": true + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", + "dev": true + }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==", + "dev": true + }, + "lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha512-qkTuvgEzYdyhiJBx42YPzPo71R1aEr0z79kAv7Ixg8wPFEjgRgJdUsGMG3Hf3OYSF/kHI79XhNlt+5Ar6OzwxQ==", + "dev": true + }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==", + "dev": true + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "logform": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-1.10.0.tgz", + "integrity": "sha512-em5ojIhU18fIMOw/333mD+ZLE2fis0EzXl1ZwHx4iQzmpQi6odNiY/t+ITNr33JZhT9/KEaH+UPIipr6a9EjWg==", + "dev": true, + "requires": { + "colors": "^1.2.1", + "fast-safe-stringify": "^2.0.4", + "fecha": "^2.3.3", + "ms": "^2.1.1", + "triple-beam": "^1.2.0" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true + }, + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "markbind-cli": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/markbind-cli/-/markbind-cli-5.1.0.tgz", + "integrity": "sha512-6POI1Q++2aZa+Udk/oQ6LX1oNPbKUBDY0mN3Up7VOFeK+XYW51faxuCk2Q91JTBxYRKLNtshxf0y12kB4Cj9Qw==", + "dev": true, + "requires": { + "@markbind/core": "5.1.0", + "@markbind/core-web": "5.1.0", + "bluebird": "^3.7.2", + "chalk": "^3.0.0", + "cheerio": "^0.22.0", + "chokidar": "^3.3.0", + "colors": "1.4.0", + "commander": "^8.1.0", + "figlet": "^1.2.4", + "find-up": "^4.1.0", + "fs-extra": "^9.0.1", + "live-server": "1.2.1", + "lodash": "^4.17.15", + "url-parse": "^1.5.10", + "winston": "^2.4.4", + "winston-daily-rotate-file": "^3.10.0" + } + }, + "markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "requires": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true + } + } + }, + "markdown-it-attrs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.1.6.tgz", + "integrity": "sha512-O7PDKZlN8RFMyDX13JnctQompwrrILuz2y43pW2GagcwpIIElkAdfeek+erHfxUOlXWPsjFeWmZ8ch1xtRLWpA==", + "dev": true, + "requires": {} + }, + "markdown-it-emoji": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz", + "integrity": "sha512-QCz3Hkd+r5gDYtS2xsFXmBYrgw6KuWcJZLCEkdfAuwzZbShCmCfta+hwAMq4NX/4xPzkSHduMKgMkkPUJxSXNg==", + "dev": true + }, + "markdown-it-linkify-images": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-linkify-images/-/markdown-it-linkify-images-3.0.0.tgz", + "integrity": "sha512-Vs5yGJa5MWjFgytzgtn8c1U6RcStj3FZKhhx459U8dYbEE5FTWZ6mMRkYMiDlkFO0j4VCsQT1LT557bY0ETgtg==", + "dev": true, + "requires": { + "markdown-it": "^13.0.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true + }, + "linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, + "markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "dev": true, + "requires": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + } + } + }, + "markdown-it-mark": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-3.0.1.tgz", + "integrity": "sha512-HyxjAu6BRsdt6Xcv6TKVQnkz/E70TdGXEFHRYBGLncRE9lBFwDNLVtFojKxjJWgJ+5XxUwLaHXy+2sGBbDn+4A==", + "dev": true + }, + "markdown-it-regexp": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/markdown-it-regexp/-/markdown-it-regexp-0.4.0.tgz", + "integrity": "sha512-0XQmr46K/rMKnI93Y3CLXsHj4jIioRETTAiVnJnjrZCEkGaDOmUxTbZj/aZ17G5NlRcVpWBYjqpwSlQ9lj+Kxw==", + "dev": true + }, + "markdown-it-sub": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz", + "integrity": "sha512-z2Rm/LzEE1wzwTSDrI+FlPEveAAbgdAdPhdWarq/ZGJrGW/uCQbKAnhoCsE4hAbc3SEym26+W2z/VQB0cQiA9Q==", + "dev": true + }, + "markdown-it-sup": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz", + "integrity": "sha512-E32m0nV9iyhRR7CrhnzL5msqic7rL1juWre6TQNxsnApg7Uf+F97JOKxUijg5YwXz86lZ0mqfOnutoryyNdntQ==", + "dev": true + }, + "markdown-it-table-of-contents": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.4.tgz", + "integrity": "sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw==", + "dev": true + }, + "markdown-it-task-lists": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz", + "integrity": "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==", + "dev": true + }, + "markdown-it-texmath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-texmath/-/markdown-it-texmath-1.0.0.tgz", + "integrity": "sha512-4hhkiX8/gus+6e53PLCUmUrsa6ZWGgJW2XCW6O0ASvZUiezIK900ZicinTDtG3kAO2kon7oUA/ReWmpW2FByxg==", + "dev": true + }, + "markdown-it-video": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/markdown-it-video/-/markdown-it-video-0.6.3.tgz", + "integrity": "sha512-T4th1kwy0OcvyWSN4u3rqPGxvbDclpucnVSSaH3ZacbGsAts964dxokx9s/I3GYsrDCJs4ogtEeEeVP18DQj0Q==", + "dev": true + }, + "matcher-collection": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-2.0.1.tgz", + "integrity": "sha512-daE62nS2ZQsDg9raM0IlZzLmI2u+7ZapXBwdoeBUKAYERPDDIc0qNqA8E0Rp2D+gspKR7BgIFP52GeujaGXWeQ==", + "dev": true, + "requires": { + "@types/minimatch": "^3.0.3", + "minimatch": "^3.0.2" + } + }, + "material-icons": { + "version": "1.13.11", + "resolved": "https://registry.npmjs.org/material-icons/-/material-icons-1.13.11.tgz", + "integrity": "sha512-kp2oAdaqo/Zp6hpTZW01rOgDPWmxBUszSdDzkRm1idCjjNvdUMnqu8qu58cll6CObo+o0cydOiPLdoSugLm+mQ==", + "dev": true + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + } + }, + "moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "dev": true + }, + "morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "dev": true, + "requires": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "nan": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", + "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true + }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha512-A48My/mtCklowHBlI8Fq2jFWK4tX4lJ5E6ytFsSOq1fzpvT0SQSgKhSg7lN5c2uYFOrUAOQp6zhhJnpp1eMloQ==", + "dev": true, + "requires": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "nunjucks": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.2.tgz", + "integrity": "sha512-KUi85OoF2NMygwODAy28Lh9qHmq5hO3rBlbkYoC8v377h4l8Pt5qFjILl0LWpMbOrZ18CzfVVUvIHUIrtED3sA==", + "dev": true, + "requires": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "chokidar": "^3.3.0", + "commander": "^5.1.0" + }, + "dependencies": { + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-hash": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", + "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opn": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", + "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "dev": true, + "requires": { + "through": "~2.3" + } + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, + "proxy-middleware": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", + "integrity": "sha512-EGCG8SeoIRVMhsqHQUdDigB2i7qU7fCsWASwn54+nPutYO8n4q6EiwMzyfWlC+dzRFExP+kvcnDFdBDHoZBU7Q==", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==", + "dev": true, + "requires": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true + }, + "repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "resolve": { + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "dev": true, + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safe-stable-stringify": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz", + "integrity": "sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==", + "dev": true + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", + "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + } + } + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + } + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==", + "dev": true + }, + "simple-git": { + "version": "2.48.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.48.0.tgz", + "integrity": "sha512-z4qtrRuaAFJS4PUd0g+xy7aN4y+RvEt/QTJpR184lhJguBA1S/LsVlvE/CM95RsYMOFJG3NGGDjqFCzKU19S/A==", + "dev": true, + "requires": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.3.2" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dev": true, + "requires": { + "is-plain-obj": "^1.0.0" + } + }, + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "dev": true + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true + }, + "stream-combiner": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", + "dev": true, + "requires": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "strip-url-auth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-url-auth/-/strip-url-auth-1.0.1.tgz", + "integrity": "sha512-++41PnXftlL3pvI6lpvhSEO+89g1kIJC4MYB5E6yH+WHa5InIqz51yGd1YOGd7VNSNdoEOfzTMqbAM/2PbgaHQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true + }, + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==", + "dev": true + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + } + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "unix-crypt-td-js": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz", + "integrity": "sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "dev": true + }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true + }, + "vue": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz", + "integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==", + "dev": true + }, + "vue-server-renderer": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.14.tgz", + "integrity": "sha512-HifYRa/LW7cKywg9gd4ZtvtRuBlstQBao5ZCWlg40fyB4OPoGfEXAzxb0emSLv4pBDOHYx0UjpqvxpiQFEuoLA==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "hash-sum": "^1.0.2", + "he": "^1.1.0", + "lodash.template": "^4.5.0", + "lodash.uniq": "^4.5.0", + "resolve": "^1.2.0", + "serialize-javascript": "^3.1.0", + "source-map": "0.5.6" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true + } + } + }, + "vue-template-compiler": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz", + "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==", + "dev": true, + "requires": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, + "walk-sync": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz", + "integrity": "sha512-IC8sL7aB4/ZgFcGI2T1LczZeFWZ06b3zoHH7jBPyHxOtIIz1jppWHjjEXkOFvFojBVAK9pV7g47xOZ4LW3QLfg==", + "dev": true, + "requires": { + "@types/minimatch": "^3.0.3", + "ensure-posix-path": "^1.1.0", + "matcher-collection": "^2.0.0", + "minimatch": "^3.0.4" + } + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "winston": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.6.tgz", + "integrity": "sha512-J5Zu4p0tojLde8mIOyDSsmLmcP8I3Z6wtwpTDHx1+hGcdhxcJaAmG4CFtagkb+NiN1M9Ek4b42pzMWqfc9jm8w==", + "dev": true, + "requires": { + "async": "^3.2.3", + "colors": "1.0.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "stack-trace": "0.0.x" + }, + "dependencies": { + "async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "dev": true + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", + "dev": true + } + } + }, + "winston-compat": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/winston-compat/-/winston-compat-0.1.5.tgz", + "integrity": "sha512-EPvPcHT604AV3Ji6d3+vX8ENKIml9VSxMRnPQ+cuK/FX6f3hvPP2hxyoeeCOCFvDrJEujalfcKWlWPvAnFyS9g==", + "dev": true, + "requires": { + "cycle": "~1.0.3", + "logform": "^1.6.0", + "triple-beam": "^1.2.0" + } + }, + "winston-daily-rotate-file": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-3.10.0.tgz", + "integrity": "sha512-KO8CfbI2CvdR3PaFApEH02GPXiwJ+vbkF1mCkTlvRIoXFI8EFlf1ACcuaahXTEiDEKCii6cNe95gsL4ZkbnphA==", + "dev": true, + "requires": { + "file-stream-rotator": "^0.4.1", + "object-hash": "^1.3.0", + "semver": "^6.2.0", + "triple-beam": "^1.3.0", + "winston-compat": "^0.1.4", + "winston-transport": "^4.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "winston-transport": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", + "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", + "dev": true, + "requires": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "dependencies": { + "fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", + "dev": true + }, + "logform": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.2.tgz", + "integrity": "sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==", + "dev": true, + "requires": { + "@colors/colors": "1.5.0", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true + } + } +} diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 00000000000..aa7083fd8a7 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,14 @@ +{ + "name": "docs", + "version": "1.0.0", + "description": "AB-3 docs", + "scripts": { + "init": "markbind init", + "build": "markbind build", + "serve": "markbind serve", + "deploy": "markbind deploy" + }, + "devDependencies": { + "markbind-cli": "^5.1.0" + } +} diff --git a/docs/site.json b/docs/site.json new file mode 100644 index 00000000000..ffe411c3f82 --- /dev/null +++ b/docs/site.json @@ -0,0 +1,29 @@ +{ + "baseUrl": "", + "titlePrefix": "", + "titleSuffix": "AddressBook Level-3", + "faviconPath": "images/SeEduLogo.png", + "style": { + "codeTheme": "light" + }, + "ignore": [ + "_markbind/layouts/*", + "_markbind/logs/*", + "_site/*", + "site.json", + "*.md", + "*.njk", + ".git/*", + "node_modules/*" + ], + "pagesExclude": ["node_modules/*"], + "pages": [ + { + "glob": ["**/index.md", "**/*.md"] + } + ], + "deploy": { + "message": "Site Update." + }, + "timeZone": "Asia/Singapore" +} diff --git a/docs/stylesheets/main.css b/docs/stylesheets/main.css new file mode 100644 index 00000000000..1074ade42dd --- /dev/null +++ b/docs/stylesheets/main.css @@ -0,0 +1,144 @@ +mark { + background-color: #ff0; + border-radius: 5px; + padding-top: 0; + padding-bottom: 0; +} + +.indented { + padding-left: 20px; +} + +.theme-card img { + width: 100%; +} + +/* Scrollbar */ + +.slim-scroll::-webkit-scrollbar { + width: 5px; +} + +.slim-scroll::-webkit-scrollbar-thumb { + background: #808080; + border-radius: 20px; +} + +.slim-scroll::-webkit-scrollbar-track { + background: transparent; + border-radius: 20px; +} + +.slim-scroll-blue::-webkit-scrollbar { + width: 5px; +} + +.slim-scroll-blue::-webkit-scrollbar-thumb { + background: #00b0ef; + border-radius: 20px; +} + +.slim-scroll-blue::-webkit-scrollbar-track { + background: transparent; + border-radius: 20px; +} + +/* Layout containers */ + +#flex-body { + display: flex; + flex: 1; + align-items: start; +} + +#content-wrapper { + flex: 1; + margin: 0 auto; + min-width: 0; + max-width: 1000px; + overflow-x: auto; + padding: 0.8rem 20px 0 20px; + transition: 0.4s; + -webkit-transition: 0.4s; +} + +#site-nav, +#page-nav { + display: flex; + flex-direction: column; + position: sticky; + top: var(--sticky-header-height); + flex: 0 0 auto; + max-width: 300px; + max-height: calc(100vh - var(--sticky-header-height)); + width: 300px; +} + +#site-nav { + border-right: 1px solid lightgrey; + padding-bottom: 20px; + z-index: 999; +} + +.site-nav-top { + margin: 0.8rem 0; + padding: 0 12px 12px 12px; +} + +.nav-component { + overflow-y: auto; +} + +#page-nav { + border-left: 1px solid lightgrey; +} + +@media screen and (max-width: 1299.98px) { + #page-nav { + display: none; + } +} + +/* Bootstrap medium(md) responsive breakpoint */ +@media screen and (max-width: 991.98px) { + #site-nav { + display: none; + } +} + +/* Bootstrap small(sm) responsive breakpoint */ +@media (max-width: 767.98px) { + .indented { + padding-left: 10px; + } + + #content-wrapper { + padding: 0 10px; + } +} + +/* Bootstrap extra small(xs) responsive breakpoint */ +@media screen and (max-width: 575.98px) { + #site-nav { + display: none; + } +} + +/* Hide site navigation when printing */ +@media print { + #site-nav { + display: none; + } + + #page-nav { + display: none; + } +} + +h2, +h3, +h4, +h5, +h6 { + color: #e46c0a; +} diff --git a/docs/team/johndoe.md b/docs/team/johndoe.md index 773a07794e2..86aa7ebfc34 100644 --- a/docs/team/johndoe.md +++ b/docs/team/johndoe.md @@ -1,6 +1,6 @@ --- -layout: page -title: John Doe's Project Portfolio Page + layout: default.md + title: "John Doe's Project Portfolio Page" --- ### Project: AddressBook Level 3 From 2960c20f5144f0362b9f37fe3b1fac0471afa676 Mon Sep 17 00:00:00 2001 From: damithc Date: Fri, 9 Feb 2024 18:07:35 +0800 Subject: [PATCH 002/249] Bump MarkBind version --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 57737a615fc..0cd51c5fb97 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -21,5 +21,5 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} rootDirectory: './docs' - baseUrl: '/addressbook-level3' # replace with your repo name - version: '^5.1.0' + baseUrl: '/tp' # assuming your repo name is tp + version: '^5.2.0' From 339cd23c87a0fa8459545632ea42937103b87e22 Mon Sep 17 00:00:00 2001 From: damithc Date: Fri, 9 Feb 2024 18:08:02 +0800 Subject: [PATCH 003/249] Add a Home button in the top NavBar --- docs/_markbind/layouts/default.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/_markbind/layouts/default.md b/docs/_markbind/layouts/default.md index 7348aace92c..8576932d696 100644 --- a/docs/_markbind/layouts/default.md +++ b/docs/_markbind/layouts/default.md @@ -5,6 +5,7 @@

    AB-3 +
  • Home
  • User Guide
  • Developer Guide
  • About Us
  • From b7068b1103d74064ed74a77840df8246ae33e96e Mon Sep 17 00:00:00 2001 From: damithc Date: Fri, 9 Feb 2024 18:09:08 +0800 Subject: [PATCH 004/249] Reduce font size for printing --- docs/stylesheets/main.css | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docs/stylesheets/main.css b/docs/stylesheets/main.css index 1074ade42dd..ba6f8385d2d 100644 --- a/docs/stylesheets/main.css +++ b/docs/stylesheets/main.css @@ -133,6 +133,32 @@ mark { #page-nav { display: none; } + + /* Reduce font size when printing */ + h1 { + font-size: 1.2rem !important; + } + h2 { + font-size: 1.0rem !important; + } + h3 { + font-size: 0.9rem !important; + } + h4 { + font-size: 0.8rem !important; + } + h5 { + font-size: 0.7rem !important; + } + body { + font-size: 0.65rem !important; + } + .btn { + font-size: 0.65rem !important; + } + img { + zoom: 0.8; /* might not work on some browsers */ + } } h2, From 7f920ec896d0d61a5bf17504daa3110125c035c9 Mon Sep 17 00:00:00 2001 From: damithc Date: Thu, 8 Aug 2024 19:48:55 +0800 Subject: [PATCH 005/249] docs.yml: Bump MarkBind and Java versions --- .github/workflows/docs.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 0cd51c5fb97..109efdf7bbb 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -14,12 +14,12 @@ jobs: - name: Install Java uses: actions/setup-java@v3 with: - java-version: '11' - distribution: 'temurin' + java-version: '17' + distribution: 'zulu' - name: Build & Deploy MarkBind site uses: MarkBind/markbind-action@v2 with: token: ${{ secrets.GITHUB_TOKEN }} rootDirectory: './docs' baseUrl: '/tp' # assuming your repo name is tp - version: '^5.2.0' + version: '^5.5.2' From e211b882f34b58aa8d1f5458347f32254d17f4c3 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 16 Feb 2025 19:27:09 +0800 Subject: [PATCH 006/249] Update configs to match fork --- docs/_markbind/layouts/default.md | 2 +- docs/site.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_markbind/layouts/default.md b/docs/_markbind/layouts/default.md index 8576932d696..89d23afbb30 100644 --- a/docs/_markbind/layouts/default.md +++ b/docs/_markbind/layouts/default.md @@ -4,7 +4,7 @@
    - AB-3 + WealthVault
  • Home
  • User Guide
  • Developer Guide
  • diff --git a/docs/site.json b/docs/site.json index ffe411c3f82..013e07bd09f 100644 --- a/docs/site.json +++ b/docs/site.json @@ -1,7 +1,7 @@ { "baseUrl": "", "titlePrefix": "", - "titleSuffix": "AddressBook Level-3", + "titleSuffix": "WealthVault", "faviconPath": "images/SeEduLogo.png", "style": { "codeTheme": "light" From 9c7182b2ab578ac811488aeeb0902831a5cfa542 Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Wed, 5 Mar 2025 19:34:58 +0800 Subject: [PATCH 007/249] Add Ming Huan's photo --- docs/images/sciphi-123.png | Bin 0 -> 153105 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/images/sciphi-123.png diff --git a/docs/images/sciphi-123.png b/docs/images/sciphi-123.png new file mode 100644 index 0000000000000000000000000000000000000000..cac25c01fb455815dedfd35f29037ffe09551893 GIT binary patch literal 153105 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�geJ2BaLIEHDto8|1tD%A5;&G6DX%Qva=_3?= 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 YTP5$5V$dDuW8mv5&frSEriJhS2R&I`w*UYD literal 0 HcmV?d00001 From 1351c0f4561e487e539803872481f89f665e8c2e Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Wed, 5 Mar 2025 20:07:08 +0800 Subject: [PATCH 008/249] Add Justyn's photo edit --- docs/images/curiousfun88.png | Bin 0 -> 84950 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/images/curiousfun88.png diff --git a/docs/images/curiousfun88.png b/docs/images/curiousfun88.png new file mode 100644 index 0000000000000000000000000000000000000000..c9c0ad54422cbdb8f32636adbef3b3f807997332 GIT binary patch literal 84950 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%0D*A!Y3Nb6H9R*F`VT%u?NCtu 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 literal 0 HcmV?d00001 From e238c39aef5f98b0f0a74ac45b35e8d4615dd3cc Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Wed, 5 Mar 2025 20:08:05 +0800 Subject: [PATCH 009/249] Add details to AboutUs --- docs/AboutUs.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 8cf4ab68e9e..8d1dcc47ef2 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -11,15 +11,15 @@ You can reach us at the email `seer[at]comp.nus.edu.sg` ## Project team -### John Doe +### Bek Ming Huan - + [[homepage](http://www.comp.nus.edu.sg/~damithch)] -[[github](https://github.com/johndoe)] +[[github](https://github.com/sciphi-123)] [[portfolio](team/johndoe.md)] -* Role: Project Advisor +* Role: Project Member ### Jane Doe From dc905fe04e374a450610991e2d12195a74f63203 Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Wed, 5 Mar 2025 20:12:21 +0800 Subject: [PATCH 010/249] Add aboutus edits --- docs/AboutUs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 8cf4ab68e9e..2e37f5bbe1d 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -21,14 +21,14 @@ You can reach us at the email `seer[at]comp.nus.edu.sg` * Role: Project Advisor -### Jane Doe +### Lae Zong Hon Justyn - + -[[github](http://github.com/johndoe)] -[[portfolio](team/johndoe.md)] +[[github](https://github.com/curiousfun88)] +[[portfolio](team/johndoe.m)] -* Role: Team Lead +* Role: Project Member * Responsibilities: UI ### Johnny Doe From b4fd2993c7711ce8005717d2c540c698ab32b2a4 Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Wed, 5 Mar 2025 20:58:31 +0800 Subject: [PATCH 011/249] Update Build Status Link edits --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 16208adb9b6..48149f35ac0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![CI Status](https://github.com/se-edu/addressbook-level3/workflows/Java%20CI/badge.svg)](https://github.com/se-edu/addressbook-level3/actions) +[![Java CI](https://github.com/AY2425S2-CS2103T-W12-2/tp/actions/workflows/gradle.yml/badge.svg)](https://github.com/AY2425S2-CS2103T-W12-2/tp/actions/workflows/gradle.yml) ![Ui](docs/images/Ui.png) From cee632b91070f0cf409a3e902c02dce9be2f4aa4 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Wed, 5 Mar 2025 23:28:05 +0800 Subject: [PATCH 012/249] Add Yi Han Photo --- docs/images/sean-g-han.png | Bin 0 -> 97108 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/images/sean-g-han.png diff --git a/docs/images/sean-g-han.png b/docs/images/sean-g-han.png new file mode 100644 index 0000000000000000000000000000000000000000..c3dbb5430d30827973b908be58e359e9ab847b3b GIT binary patch literal 97108 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 z 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 S^fbi_9}g2e=g_7Z|!}V6PL1W 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 O+vG{U4#87essGs<1P^@x literal 0 HcmV?d00001 From 07e7fac280c62b2c133a201476c8501d87ec4376 Mon Sep 17 00:00:00 2001 From: Nicholas Foo Date: Thu, 6 Mar 2025 00:03:33 +0800 Subject: [PATCH 013/249] Add Nicholas' Photo --- docs/images/foonicholas.png | Bin 0 -> 76391 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/images/foonicholas.png diff --git a/docs/images/foonicholas.png b/docs/images/foonicholas.png new file mode 100644 index 0000000000000000000000000000000000000000..2c961953529c9e439822e60379e5d2ea137f2aa3 GIT binary patch literal 76391 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

    IC-#>-7tpB6G1D+wwgM-w^PVuGv@2Cbl>qo)! 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/view/ClientListPanel.fxml b/src/main/resources/view/ClientListPanel.fxml index 8f6f00f1faf..47d76a43b7f 100644 --- a/src/main/resources/view/ClientListPanel.fxml +++ b/src/main/resources/view/ClientListPanel.fxml @@ -4,5 +4,5 @@ - + diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml index 475a6bf3ca6..f302fbc3ae9 100644 --- a/src/main/resources/view/MainWindow.fxml +++ b/src/main/resources/view/MainWindow.fxml @@ -19,7 +19,7 @@ - + diff --git a/src/main/resources/view/ResultDisplay.fxml b/src/main/resources/view/ResultDisplay.fxml index 01b691792a9..2883b3d6e56 100644 --- a/src/main/resources/view/ResultDisplay.fxml +++ b/src/main/resources/view/ResultDisplay.fxml @@ -3,7 +3,6 @@ - -

    Ta&SEy6n1n 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 literal 0 HcmV?d00001 From a033de16db627ab94864fc56756799ef06e83c4e Mon Sep 17 00:00:00 2001 From: Nicholas Foo Date: Thu, 6 Mar 2025 01:00:54 +0800 Subject: [PATCH 014/249] Update AboutUs page for Nicholas --- docs/AboutUs.md | 8 +++---- docs/team/foonicholas.md | 46 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 docs/team/foonicholas.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 8cf4ab68e9e..e2125370245 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -40,12 +40,12 @@ You can reach us at the email `seer[at]comp.nus.edu.sg` * Role: Developer * Responsibilities: Data -### Jean Doe +### Nicholas Foo - + -[[github](http://github.com/johndoe)] -[[portfolio](team/johndoe.md)] +[[github](https://github.com/FooNicholas)] +[[portfolio](team/foonicholas.md)] * Role: Developer * Responsibilities: Dev Ops + Threading diff --git a/docs/team/foonicholas.md b/docs/team/foonicholas.md new file mode 100644 index 00000000000..86aa7ebfc34 --- /dev/null +++ b/docs/team/foonicholas.md @@ -0,0 +1,46 @@ +--- + layout: default.md + title: "John Doe'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 c7b389235ab49d6a324b2a7df93c32fa0b47a60a Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Thu, 6 Mar 2025 11:46:22 +0800 Subject: [PATCH 015/249] Add DG edits v1.1 --- docs/DeveloperGuide.md | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 9fe677d1e4c..f95b0ca55a3 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -272,29 +272,37 @@ _{Explain here how the data archiving feature will be implemented}_ ### Product scope -**Target user profile**: +**Target user profile**: Financial advisors -* 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 +* Managing a significant number of client contacts +* Requires a one-stop platform to track and update client's financial details +* Experiences difficulties to keep track of client's financial needs across multiple platforms +* Easy-to-use, fast and organized interface to maintain efficiency in their work +* Keen to provide fast and efficient service to customers -**Value proposition**: manage contacts faster than a typical mouse/GUI driven app +**Value proposition**: Manage clients and their financial needs faster than a typical mouse/GUI driven app ### User stories 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…​ | +|----------|-------------------|-------------------------------------------------------|-----------------------------------------------| +| `* * *` | Financial Advisor | Add a new client with contact details | Keep track of my clients | +| `* * *` | Financial Advisor | Read client’s contact details | View them when necessary | +| `* * *` | Financial Advisor | Delete a client’s record | Remove outdated or incorrect information | +| `* *` | Financial Advisor | Edit a client’s contact details | Update them when necessary | +| `* *` | Financial Advisor | Search for a client by name | Quickly find their details | +| `* *` | Financial Advisor | Filter clients by location | Easily find clients within a specific region | +| `*` | Financial Advisor | Store multiple contact numbers for a client | Have alternative ways to reach them | +| `*` | Financial Advisor | Store multiple addresses for a client | Keep track of their home and office locations | +| `*` | Financial Advisor | Categorize clients based on communication preferences | Contact them in their preferred way | +| `*` | Financial Advisor | Send an email to a client directly from the app | Communicate with them efficiently | +| `*` | Financial Advisor | Initiate a phone call to a client from the app | Reach them easily | +| `*` | Financial Advisor | Set reminders for following up with clients | Don’t miss important meetings | +| `*` | Financial Advisor | Receive notifications about upcoming meetings | Prepare in advance | +| `*` | Financial Advisor | Schedule recurring reminders for periodic check-ins | Maintain regular contact | *{More to be added}* From 3326f70bde7f6ee1f63be1f697d781ae5e298439 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Thu, 6 Mar 2025 13:26:48 +0800 Subject: [PATCH 016/249] Update AboutUs --- docs/AboutUs.md | 8 +++---- docs/team/sean-g-han.md | 46 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 docs/team/sean-g-han.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 8cf4ab68e9e..a27956c55cc 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -50,12 +50,12 @@ You can reach us at the email `seer[at]comp.nus.edu.sg` * Role: Developer * Responsibilities: Dev Ops + Threading -### James Doe +### Tan Yi Han - + -[[github](http://github.com/johndoe)] -[[portfolio](team/johndoe.md)] +[[github](http://github.com/Sean-G-Han)] +[[portfolio](team/sean-g-han.md)] * Role: Developer * Responsibilities: UI diff --git a/docs/team/sean-g-han.md b/docs/team/sean-g-han.md new file mode 100644 index 00000000000..86aa7ebfc34 --- /dev/null +++ b/docs/team/sean-g-han.md @@ -0,0 +1,46 @@ +--- + layout: default.md + title: "John Doe'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 242955ccae53b77bffddd8116ff377610dc8e92f Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Thu, 6 Mar 2025 13:33:57 +0800 Subject: [PATCH 017/249] Revert "Update AboutUs" This reverts commit 3326f70bde7f6ee1f63be1f697d781ae5e298439. --- docs/AboutUs.md | 8 +++---- docs/team/sean-g-han.md | 46 ----------------------------------------- 2 files changed, 4 insertions(+), 50 deletions(-) delete mode 100644 docs/team/sean-g-han.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index a27956c55cc..8cf4ab68e9e 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -50,12 +50,12 @@ You can reach us at the email `seer[at]comp.nus.edu.sg` * Role: Developer * Responsibilities: Dev Ops + Threading -### Tan Yi Han +### James Doe - + -[[github](http://github.com/Sean-G-Han)] -[[portfolio](team/sean-g-han.md)] +[[github](http://github.com/johndoe)] +[[portfolio](team/johndoe.md)] * Role: Developer * Responsibilities: UI diff --git a/docs/team/sean-g-han.md b/docs/team/sean-g-han.md deleted file mode 100644 index 86aa7ebfc34..00000000000 --- a/docs/team/sean-g-han.md +++ /dev/null @@ -1,46 +0,0 @@ ---- - layout: default.md - title: "John Doe'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 39414e9f30e5d107a44ee1ca418a024370129ce8 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Thu, 6 Mar 2025 13:40:22 +0800 Subject: [PATCH 018/249] Update AboutUs page --- docs/AboutUs.md | 6 +++--- docs/images/sean-g-han.png | Bin 0 -> 97108 bytes 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 docs/images/sean-g-han.png diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 8cf4ab68e9e..c0e7b39151e 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -50,11 +50,11 @@ You can reach us at the email `seer[at]comp.nus.edu.sg` * Role: Developer * Responsibilities: Dev Ops + Threading -### James Doe +### Tan Yi Han - + -[[github](http://github.com/johndoe)] +[[github](http://github.com/sean-g-han)] [[portfolio](team/johndoe.md)] * Role: Developer diff --git a/docs/images/sean-g-han.png b/docs/images/sean-g-han.png new file mode 100644 index 0000000000000000000000000000000000000000..c3dbb5430d30827973b908be58e359e9ab847b3b GIT binary patch literal 97108 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 z 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 S^fbi_9}g2e=g_7Z|!}V6PL1W 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 O+vG{U4#87essGs<1P^@x literal 0 HcmV?d00001 From e8ab2e4510db8f342fb787484d98c147070b3188 Mon Sep 17 00:00:00 2001 From: joshua Date: Thu, 6 Mar 2025 23:09:21 +0800 Subject: [PATCH 019/249] add joshua's aboutme and photo --- docs/AboutUs.md | 4 ++-- docs/images/j4joshua.png | Bin 0 -> 38156 bytes docs/team/j4joshua.md | 46 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 docs/images/j4joshua.png create mode 100644 docs/team/j4joshua.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 8cf4ab68e9e..18418e9f097 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -33,9 +33,9 @@ You can reach us at the email `seer[at]comp.nus.edu.sg` ### Johnny Doe - + -[[github](http://github.com/johndoe)] [[portfolio](team/johndoe.md)] +[[github](http://github.com/J4Joshua)] [[portfolio](team/j4joshua.md)] * Role: Developer * Responsibilities: Data diff --git a/docs/images/j4joshua.png b/docs/images/j4joshua.png new file mode 100644 index 0000000000000000000000000000000000000000..5fadd84c6ef987bc1dd4cbe1f4ef1b7502a355eb GIT binary patch literal 38156 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 literal 0 HcmV?d00001 diff --git a/docs/team/j4joshua.md b/docs/team/j4joshua.md new file mode 100644 index 00000000000..83762db0c83 --- /dev/null +++ b/docs/team/j4joshua.md @@ -0,0 +1,46 @@ +--- + layout: default.md + title: "Joshua'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 bd6ec34f1569f1d400d0766c72568ff2fc2c8e84 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 9 Mar 2025 13:20:02 +0800 Subject: [PATCH 020/249] Add Priority Command Command currently only prints "Trial" --- .../address/logic/commands/PriorityCommand.java | 16 ++++++++++++++++ .../address/logic/parser/AddressBookParser.java | 13 ++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/PriorityCommand.java diff --git a/src/main/java/seedu/address/logic/commands/PriorityCommand.java b/src/main/java/seedu/address/logic/commands/PriorityCommand.java new file mode 100644 index 00000000000..68e4af780e3 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/PriorityCommand.java @@ -0,0 +1,16 @@ +package seedu.address.logic.commands; + +import seedu.address.model.Model; + +/** + * Marks a client as a priority + */ +public class PriorityCommand extends Command { + + public static final String COMMAND_WORD = "priority"; + + @Override + public CommandResult execute(Model model) { + return new CommandResult("TRIAL"); + } +} \ No newline at end of file diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 3149ee07e0b..08ffafefded 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -8,15 +8,7 @@ import java.util.regex.Pattern; import seedu.address.commons.core.LogsCenter; -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.commands.*; import seedu.address.logic.parser.exceptions.ParseException; /** @@ -77,6 +69,9 @@ public Command parseCommand(String userInput) throws ParseException { case HelpCommand.COMMAND_WORD: return new HelpCommand(); + case PriorityCommand.COMMAND_WORD: + return new PriorityCommand(); + default: logger.finer("This user input caused a ParseException: " + userInput); throw new ParseException(MESSAGE_UNKNOWN_COMMAND); From 35185c54750a43c789a017c1b0b6f28a4b1db7fe Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 9 Mar 2025 14:00:04 +0800 Subject: [PATCH 021/249] Update PriorityCommand and AddressBookParser to accept parameters --- .../logic/commands/PriorityCommand.java | 44 ++++++++++++++++++- .../logic/parser/AddressBookParser.java | 2 +- .../logic/parser/PriorityCommandParser.java | 27 ++++++++++++ 3 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 src/main/java/seedu/address/logic/parser/PriorityCommandParser.java diff --git a/src/main/java/seedu/address/logic/commands/PriorityCommand.java b/src/main/java/seedu/address/logic/commands/PriorityCommand.java index 68e4af780e3..5bd5b145256 100644 --- a/src/main/java/seedu/address/logic/commands/PriorityCommand.java +++ b/src/main/java/seedu/address/logic/commands/PriorityCommand.java @@ -1,5 +1,11 @@ package seedu.address.logic.commands; +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; + +import seedu.address.commons.core.index.Index; +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; /** @@ -9,8 +15,42 @@ public class PriorityCommand extends Command { public static final String COMMAND_WORD = "priority"; + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Marks the person identified by the index number used in the displayed person list as a priority.\n" + + "Parameters: INDEX (must be a positive integer)\n" + + "Example: " + COMMAND_WORD + " 1"; + + public static final String MESSAGE_ARGUMENTS = "Index: %1$d"; + + private final Index index; + + /** + * @param index of the person in the filtered person list to mark as priority + */ + public PriorityCommand(Index index) { + requireNonNull(index); + + this.index = index; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + throw new CommandException( + String.format(MESSAGE_ARGUMENTS, index.getOneBased())); + } + @Override - public CommandResult execute(Model model) { - return new CommandResult("TRIAL"); + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof PriorityCommand)) { + return false; + } + + PriorityCommand e = (PriorityCommand) other; + return index.equals(e.index); } } \ No newline at end of file diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 08ffafefded..0da298631b8 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -70,7 +70,7 @@ public Command parseCommand(String userInput) throws ParseException { return new HelpCommand(); case PriorityCommand.COMMAND_WORD: - return new PriorityCommand(); + return new PriorityCommandParser().parse(arguments); default: logger.finer("This user input caused a ParseException: " + userInput); diff --git a/src/main/java/seedu/address/logic/parser/PriorityCommandParser.java b/src/main/java/seedu/address/logic/parser/PriorityCommandParser.java new file mode 100644 index 00000000000..09baf2de168 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/PriorityCommandParser.java @@ -0,0 +1,27 @@ +package seedu.address.logic.parser; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.PriorityCommand; +import seedu.address.logic.parser.exceptions.ParseException; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +/** + * Parses input arguments and creates a new PriorityCommand object + */ +public class PriorityCommandParser implements Parser { + /** + * Parses the given {@code String} of arguments in the context of the PriorityCommand + * and returns a PriorityCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public PriorityCommand parse(String args) throws ParseException { + try { + Index index = ParserUtil.parseIndex(args); + return new PriorityCommand(index); + } catch (ParseException pe) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, PriorityCommand.MESSAGE_USAGE), pe); + } + } +} From a276f1440d20d7afc33dc32f7038d456885e4848 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 9 Mar 2025 14:11:15 +0800 Subject: [PATCH 022/249] Fix Check style errors --- .../seedu/address/logic/commands/PriorityCommand.java | 4 +--- .../seedu/address/logic/parser/AddressBookParser.java | 11 ++++++++++- .../address/logic/parser/PriorityCommandParser.java | 4 ++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/PriorityCommand.java b/src/main/java/seedu/address/logic/commands/PriorityCommand.java index 5bd5b145256..69bbc790a00 100644 --- a/src/main/java/seedu/address/logic/commands/PriorityCommand.java +++ b/src/main/java/seedu/address/logic/commands/PriorityCommand.java @@ -1,10 +1,8 @@ package seedu.address.logic.commands; import static java.util.Objects.requireNonNull; -import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; import seedu.address.commons.core.index.Index; -import seedu.address.commons.util.ToStringBuilder; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; @@ -53,4 +51,4 @@ public boolean equals(Object other) { PriorityCommand e = (PriorityCommand) other; return index.equals(e.index); } -} \ No newline at end of file +} diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 0da298631b8..a6a62769e5c 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -8,7 +8,16 @@ import java.util.regex.Pattern; import seedu.address.commons.core.LogsCenter; -import seedu.address.logic.commands.*; +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.commands.PriorityCommand; import seedu.address.logic.parser.exceptions.ParseException; /** diff --git a/src/main/java/seedu/address/logic/parser/PriorityCommandParser.java b/src/main/java/seedu/address/logic/parser/PriorityCommandParser.java index 09baf2de168..e7515efa7f2 100644 --- a/src/main/java/seedu/address/logic/parser/PriorityCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/PriorityCommandParser.java @@ -1,11 +1,11 @@ package seedu.address.logic.parser; +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.PriorityCommand; import seedu.address.logic.parser.exceptions.ParseException; -import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; - /** * Parses input arguments and creates a new PriorityCommand object */ From 8765dcd6d2d6a973eda5fd56e49c726b7532a9b1 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 9 Mar 2025 14:37:33 +0800 Subject: [PATCH 023/249] Add new test for PriorityCommandParser and AddressBookParser --- .../logic/parser/AddressBookParserTest.java | 8 +++++++ .../parser/PriorityCommandParserTest.java | 24 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/test/java/seedu/address/logic/parser/PriorityCommandParserTest.java diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 5a1ab3dbc0c..2aa28adfa40 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -22,6 +22,7 @@ import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; +import seedu.address.logic.commands.PriorityCommand; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.person.NameContainsKeywordsPredicate; import seedu.address.model.person.Person; @@ -88,6 +89,13 @@ public void parseCommand_list() throws Exception { assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD + " 3") instanceof ListCommand); } + @Test + public void parseCommand_priority() throws Exception { + PriorityCommand command = (PriorityCommand) parser.parseCommand( + PriorityCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased()); + assertEquals(new PriorityCommand(INDEX_FIRST_PERSON), command); + } + @Test public void parseCommand_unrecognisedInput_throwsParseException() { assertThrows(ParseException.class, String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE), () diff --git a/src/test/java/seedu/address/logic/parser/PriorityCommandParserTest.java b/src/test/java/seedu/address/logic/parser/PriorityCommandParserTest.java new file mode 100644 index 00000000000..2ed617acba5 --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/PriorityCommandParserTest.java @@ -0,0 +1,24 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.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 org.junit.jupiter.api.Test; + +import seedu.address.logic.commands.PriorityCommand; + +public class PriorityCommandParserTest { + private PriorityCommandParser parser = new PriorityCommandParser(); + + @Test + public void parse_validArgs_returnsDeleteCommand() { + assertParseSuccess(parser, "1", new PriorityCommand(INDEX_FIRST_PERSON)); + } + + @Test + public void parse_invalidArgs_throwsParseException() { + assertParseFailure(parser, "a", String.format(MESSAGE_INVALID_COMMAND_FORMAT, PriorityCommand.MESSAGE_USAGE)); + } +} From 71bea969a77195df89966605740e8b48bf70a374 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 9 Mar 2025 16:38:18 +0800 Subject: [PATCH 024/249] Implement priority command --- .../java/seedu/address/logic/Messages.java | 2 +- .../logic/commands/PriorityCommand.java | 57 ++++++++++++++++++- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/address/logic/Messages.java b/src/main/java/seedu/address/logic/Messages.java index ecd32c31b53..5540db9f842 100644 --- a/src/main/java/seedu/address/logic/Messages.java +++ b/src/main/java/seedu/address/logic/Messages.java @@ -18,7 +18,7 @@ public class Messages { public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; public static final String MESSAGE_DUPLICATE_FIELDS = "Multiple values specified for the following single-valued field(s): "; - + public static final String MESSAGE_PERSON_ALREADY_PRIORITY = "The person is already tagged as a priority"; /** * Returns an error message indicating the duplicate prefixes. */ diff --git a/src/main/java/seedu/address/logic/commands/PriorityCommand.java b/src/main/java/seedu/address/logic/commands/PriorityCommand.java index 69bbc790a00..528cb06f9cb 100644 --- a/src/main/java/seedu/address/logic/commands/PriorityCommand.java +++ b/src/main/java/seedu/address/logic/commands/PriorityCommand.java @@ -1,10 +1,22 @@ package seedu.address.logic.commands; import static java.util.Objects.requireNonNull; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; import seedu.address.commons.core.index.Index; +import seedu.address.logic.Messages; 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; /** * Marks a client as a priority @@ -13,6 +25,8 @@ public class PriorityCommand extends Command { public static final String COMMAND_WORD = "priority"; + public static final String MESSAGE_PRIORITY_PERSON_SUCCESS = "Prioritised Person: %1$s"; + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Marks the person identified by the index number used in the displayed person list as a priority.\n" + "Parameters: INDEX (must be a positive integer)\n" @@ -22,19 +36,56 @@ public class PriorityCommand extends Command { private final Index index; + private Set tags; + /** * @param index of the person in the filtered person list to mark as priority */ public PriorityCommand(Index index) { requireNonNull(index); - this.index = index; } @Override public CommandResult execute(Model model) throws CommandException { - throw new CommandException( - String.format(MESSAGE_ARGUMENTS, index.getOneBased())); + 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 = addPriorityTag(personToEdit); + + model.setPerson(personToEdit, editedPerson); + model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); + return new CommandResult(String.format(MESSAGE_PRIORITY_PERSON_SUCCESS, Messages.format(editedPerson))); + } + + /** + * Creates and returns a {@code Person} with the details of {@code personToEdit} + * With a new tag called priority + */ + private static Person addPriorityTag(Person personToEdit) throws CommandException { + assert personToEdit != null; + + // Create a mutable set + Set tags = new HashSet<>(personToEdit.getTags()); + + if (tags.stream().anyMatch(tag -> "Priority".equals(tag.tagName))) { + throw new CommandException(Messages.MESSAGE_PERSON_ALREADY_PRIORITY); + } + + tags.add(new Tag("Priority")); + + return new Person( + personToEdit.getName(), + personToEdit.getPhone(), + personToEdit.getEmail(), + personToEdit.getAddress(), + tags + ); } @Override From efc534124075b76d648e8a70d7b95288c6010e60 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 9 Mar 2025 16:47:25 +0800 Subject: [PATCH 025/249] Update priority command to be able to toggle priority --- .../address/logic/commands/PriorityCommand.java | 15 +++++++++++---- src/main/java/seedu/address/model/tag/Tag.java | 3 +++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/PriorityCommand.java b/src/main/java/seedu/address/logic/commands/PriorityCommand.java index 528cb06f9cb..57f1a0e7450 100644 --- a/src/main/java/seedu/address/logic/commands/PriorityCommand.java +++ b/src/main/java/seedu/address/logic/commands/PriorityCommand.java @@ -6,6 +6,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import seedu.address.commons.core.index.Index; import seedu.address.logic.Messages; @@ -73,11 +74,17 @@ private static Person addPriorityTag(Person personToEdit) throws CommandExceptio // Create a mutable set Set tags = new HashSet<>(personToEdit.getTags()); - if (tags.stream().anyMatch(tag -> "Priority".equals(tag.tagName))) { - throw new CommandException(Messages.MESSAGE_PERSON_ALREADY_PRIORITY); - } + boolean isPriority = tags.stream() + .anyMatch(tag -> tag.isEqualTo("Priority")); - tags.add(new Tag("Priority")); + // Toggles priority + if (!isPriority) { + tags.add(new Tag("Priority")); + } else { + tags = tags.stream() + .filter(tag -> !tag.isEqualTo("Priority")) + .collect(Collectors.toSet()); + } return new Person( personToEdit.getName(), diff --git a/src/main/java/seedu/address/model/tag/Tag.java b/src/main/java/seedu/address/model/tag/Tag.java index f1a0d4e233b..840c71d0e08 100644 --- a/src/main/java/seedu/address/model/tag/Tag.java +++ b/src/main/java/seedu/address/model/tag/Tag.java @@ -59,4 +59,7 @@ public String toString() { return '[' + tagName + ']'; } + public boolean isEqualTo(String string) { + return tagName.equals(string); + } } From a76a0eede8d0317ad4574d36a4051056fd4bf39b Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 9 Mar 2025 18:03:30 +0800 Subject: [PATCH 026/249] Add test for Priority Command Also fixed small bug where VALID_TAG_FRIEND was set to "friend" instead of "friends" --- .../logic/commands/PriorityCommand.java | 8 +--- .../logic/commands/CommandTestUtil.java | 3 +- .../logic/commands/PriorityCommandTest.java | 40 +++++++++++++++++++ 3 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 src/test/java/seedu/address/logic/commands/PriorityCommandTest.java diff --git a/src/main/java/seedu/address/logic/commands/PriorityCommand.java b/src/main/java/seedu/address/logic/commands/PriorityCommand.java index 57f1a0e7450..6cc459c1ecc 100644 --- a/src/main/java/seedu/address/logic/commands/PriorityCommand.java +++ b/src/main/java/seedu/address/logic/commands/PriorityCommand.java @@ -12,11 +12,7 @@ import seedu.address.logic.Messages; 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; /** @@ -57,7 +53,7 @@ public CommandResult execute(Model model) throws CommandException { } Person personToEdit = lastShownList.get(index.getZeroBased()); - Person editedPerson = addPriorityTag(personToEdit); + Person editedPerson = togglePriorityTag(personToEdit); model.setPerson(personToEdit, editedPerson); model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); @@ -68,7 +64,7 @@ public CommandResult execute(Model model) throws CommandException { * Creates and returns a {@code Person} with the details of {@code personToEdit} * With a new tag called priority */ - private static Person addPriorityTag(Person personToEdit) throws CommandException { + private static Person togglePriorityTag(Person personToEdit) throws CommandException { assert personToEdit != null; // Create a mutable set diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java index 643a1d08069..5e77cdb6f88 100644 --- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java +++ b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java @@ -35,7 +35,8 @@ public class CommandTestUtil { 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_TAG_HUSBAND = "husband"; - public static final String VALID_TAG_FRIEND = "friend"; + public static final String VALID_TAG_PRIORITY = "Priority"; + public static final String VALID_TAG_FRIEND = "friends"; public static final String NAME_DESC_AMY = " " + PREFIX_NAME + VALID_NAME_AMY; public static final String NAME_DESC_BOB = " " + PREFIX_NAME + VALID_NAME_BOB; diff --git a/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java b/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java new file mode 100644 index 00000000000..571adf2611e --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java @@ -0,0 +1,40 @@ +package seedu.address.logic.commands; + +import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND; +import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_PRIORITY; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; +import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; + +import org.junit.jupiter.api.Test; + +import seedu.address.logic.Messages; +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.PersonBuilder; + +public class PriorityCommandTest { + + private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + + @Test + public void execute_toggleOnPriorityUnfilteredList_success() { + Person firstPerson = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); + Person priorityPerson = new PersonBuilder(firstPerson).withTags(VALID_TAG_FRIEND, + VALID_TAG_PRIORITY).build(); + + PriorityCommand priorityCommand = new PriorityCommand(INDEX_FIRST_PERSON); + + String expectedMessage = String.format(PriorityCommand.MESSAGE_PRIORITY_PERSON_SUCCESS, + Messages.format(priorityPerson)); + + Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs()); + expectedModel.setPerson(firstPerson, priorityPerson); + + assertCommandSuccess(priorityCommand, model, expectedMessage, expectedModel); + + } +} From 631559104fd8519b480328e53cd24e60c3efc8b8 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 9 Mar 2025 18:07:04 +0800 Subject: [PATCH 027/249] Fix success message to be more accurate to purpose --- src/main/java/seedu/address/logic/commands/PriorityCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/logic/commands/PriorityCommand.java b/src/main/java/seedu/address/logic/commands/PriorityCommand.java index 6cc459c1ecc..33001e584fe 100644 --- a/src/main/java/seedu/address/logic/commands/PriorityCommand.java +++ b/src/main/java/seedu/address/logic/commands/PriorityCommand.java @@ -22,7 +22,7 @@ public class PriorityCommand extends Command { public static final String COMMAND_WORD = "priority"; - public static final String MESSAGE_PRIORITY_PERSON_SUCCESS = "Prioritised Person: %1$s"; + public static final String MESSAGE_PRIORITY_PERSON_SUCCESS = "Toggle Priority of Person: %1$s"; public static final String MESSAGE_USAGE = COMMAND_WORD + ": Marks the person identified by the index number used in the displayed person list as a priority.\n" From 289d929021ff382dbe3d7140431c3b2a7f134b87 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 9 Mar 2025 18:34:26 +0800 Subject: [PATCH 028/249] Add extra test cases for CoderCov --- .../address/logic/commands/PriorityCommandTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java b/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java index 571adf2611e..4aeb79c0a48 100644 --- a/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java @@ -1,19 +1,24 @@ package seedu.address.logic.commands; +import static org.junit.jupiter.api.Assertions.assertFalse; import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND; import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_PRIORITY; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; import org.junit.jupiter.api.Test; +import seedu.address.commons.core.index.Index; import seedu.address.logic.Messages; +import seedu.address.logic.commands.exceptions.CommandException; 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.model.tag.Tag; import seedu.address.testutil.PersonBuilder; public class PriorityCommandTest { @@ -35,6 +40,13 @@ public void execute_toggleOnPriorityUnfilteredList_success() { expectedModel.setPerson(firstPerson, priorityPerson); assertCommandSuccess(priorityCommand, model, expectedMessage, expectedModel); + } + + @Test + public void execute_invalidIndex_throwsCommandException() { + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); + PriorityCommand priorityCommand = new PriorityCommand(outOfBoundIndex); + assertCommandFailure(priorityCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); } } From 8b67e5d9c59d981a2bbd3036d50a39fb60a844e9 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 9 Mar 2025 18:38:55 +0800 Subject: [PATCH 029/249] Fix Checkstyle --- .../java/seedu/address/logic/commands/PriorityCommandTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java b/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java index 4aeb79c0a48..e6e136bff89 100644 --- a/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java @@ -1,6 +1,5 @@ package seedu.address.logic.commands; -import static org.junit.jupiter.api.Assertions.assertFalse; import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND; import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_PRIORITY; import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; @@ -12,13 +11,11 @@ import seedu.address.commons.core.index.Index; import seedu.address.logic.Messages; -import seedu.address.logic.commands.exceptions.CommandException; 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.model.tag.Tag; import seedu.address.testutil.PersonBuilder; public class PriorityCommandTest { From 5cc46eb2c4e391e2f37ff581d08754a7ae894cc2 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 9 Mar 2025 18:56:14 +0800 Subject: [PATCH 030/249] Add more test cases for PriorityCommand --- .../typicalPersonsAddressBook.json | 2 +- .../logic/commands/PriorityCommandTest.java | 37 +++++++++++++++++++ .../address/testutil/TypicalIndexes.java | 1 + .../address/testutil/TypicalPersons.java | 2 +- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json index 72262099d35..ede71906488 100644 --- a/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json +++ b/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json @@ -23,7 +23,7 @@ "phone" : "87652533", "email" : "cornelia@example.com", "address" : "10th street", - "tags" : [ "friends" ] + "tags" : [ "friends", "Priority" ] }, { "name" : "Elle Meyer", "phone" : "9482224", diff --git a/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java b/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java index e6e136bff89..74675c4c45c 100644 --- a/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java @@ -1,10 +1,14 @@ 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.VALID_TAG_FRIEND; import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_PRIORITY; import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; +import static seedu.address.testutil.TypicalIndexes.INDEX_FOURTH_PERSON; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON; import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; import org.junit.jupiter.api.Test; @@ -39,6 +43,22 @@ public void execute_toggleOnPriorityUnfilteredList_success() { assertCommandSuccess(priorityCommand, model, expectedMessage, expectedModel); } + @Test + public void execute_toggleOffPriorityUnfilteredList_success() { + Person firstPerson = model.getFilteredPersonList().get(INDEX_FOURTH_PERSON.getZeroBased()); + Person priorityPerson = new PersonBuilder(firstPerson).withTags(VALID_TAG_FRIEND).build(); + + PriorityCommand priorityCommand = new PriorityCommand(INDEX_FOURTH_PERSON); + + String expectedMessage = String.format(PriorityCommand.MESSAGE_PRIORITY_PERSON_SUCCESS, + Messages.format(priorityPerson)); + + Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs()); + expectedModel.setPerson(firstPerson, priorityPerson); + + assertCommandSuccess(priorityCommand, model, expectedMessage, expectedModel); + } + @Test public void execute_invalidIndex_throwsCommandException() { Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); @@ -46,4 +66,21 @@ public void execute_invalidIndex_throwsCommandException() { assertCommandFailure(priorityCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); } + + @Test + public void equals() { + final PriorityCommand standardCommand = new PriorityCommand(INDEX_FIRST_PERSON); + + // same object -> returns true + assertTrue(standardCommand.equals(standardCommand)); + + // null -> returns false + assertFalse(standardCommand.equals(null)); + + // different types -> returns false + assertFalse(standardCommand.equals(new ClearCommand())); + + // different index -> returns false + assertFalse(standardCommand.equals(new PriorityCommand(INDEX_SECOND_PERSON))); + } } diff --git a/src/test/java/seedu/address/testutil/TypicalIndexes.java b/src/test/java/seedu/address/testutil/TypicalIndexes.java index 1e613937657..ed886e8cf5c 100644 --- a/src/test/java/seedu/address/testutil/TypicalIndexes.java +++ b/src/test/java/seedu/address/testutil/TypicalIndexes.java @@ -9,4 +9,5 @@ public class TypicalIndexes { public static final Index INDEX_FIRST_PERSON = Index.fromOneBased(1); public static final Index INDEX_SECOND_PERSON = Index.fromOneBased(2); public static final Index INDEX_THIRD_PERSON = Index.fromOneBased(3); + public static final Index INDEX_FOURTH_PERSON = Index.fromOneBased(4); } diff --git a/src/test/java/seedu/address/testutil/TypicalPersons.java b/src/test/java/seedu/address/testutil/TypicalPersons.java index fec76fb7129..e10d6271fba 100644 --- a/src/test/java/seedu/address/testutil/TypicalPersons.java +++ b/src/test/java/seedu/address/testutil/TypicalPersons.java @@ -34,7 +34,7 @@ public class TypicalPersons { 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(); + .withEmail("cornelia@example.com").withAddress("10th street").withTags("friends", "Priority").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") From efd4f3e80a3e54c021ab248a111a426dcdc435e6 Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Tue, 11 Mar 2025 15:17:38 +0800 Subject: [PATCH 031/249] Add use cases to DG --- docs/DeveloperGuide.md | 80 ++++++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 23 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 9fe677d1e4c..75cacb8fd91 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -299,31 +299,65 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli *{More to be added}* ### Use cases - (For all use cases below, the **System** is the `AddressBook` and the **Actor** is the `user`, unless specified otherwise) -**Use case: Delete a person** - -**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 - - Use case ends. - -**Extensions** - -* 2a. The list is empty. - - Use case ends. - -* 3a. The given index is invalid. - - * 3a1. AddressBook shows an error message. - - Use case resumes at step 2. +### UC01 - Add Client ### + +#### Main Success Scenario (MSS): +1. User chooses to add a new client. +2. AB3 requests client details. +3. User enters the required client details. +4. AB3 verifies the details. +5. AB3 adds the client to the address book and confirms successful addition. + **Use case ends.** + +#### Extensions: +- **3a. AB3 detects an error in the entered details.** + - 3a1. AB3 requests for the correct data. + - 3a2. User enters new data. + - Steps 3a1-3a2 are repeated until the data entered are correct. + - **Use case resumes from step 4.** + +- **4a. AB3 detects that the client already exists.** + - 4a1. AB3 notifies the user of the duplicate entry. + - 4a2. User chooses to either modify details or cancel the operation. + - If modifying, **use case resumes from step 3.** + - If canceling, **use case ends.** + +- **\*a. At any time, User chooses to cancel the process.** + - *a1. AB3 requests to confirm the cancellation. + - *a2. User confirms the cancellation. + - **Use case ends.** + + +### UC02 - Delete Client ### + +#### Main Success Scenario (MSS): +1. User chooses to delete a client. +2. AB3 requests the client’s details for deletion. +3. User enters the required details. +4. AB3 requests confirmation of the deletion. +5. User confirms the deletion. +6. AB3 removes the client from the address book and confirms successful deletion. + **Use case ends.** + +#### Extensions: +- **3a. AB3 detects an error in the entered details.** + - 3a1. AB3 requests for the correct data. + - 3a2. User enters new data. + - Steps 3a1-3a2 are repeated until the data entered are correct. + - **Use case resumes from step 4.** + +- **3b. The client does not exist in the address book.** + - 3b1. AB3 notifies the user that the client is not found. + - 3b2. User chooses to either retry or cancel the operation. + - If retrying, **use case resumes from step 2.** + - If canceling, **use case ends.** + +- **\*a. At any time, User chooses to cancel the process.** + - *a1. AB3 requests to confirm the cancellation. + - *a2. User confirms the cancellation. + - **Use case ends.** *{More to be added}* From 50eee474c1009a0cf237322a99df152e20fee59c Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Tue, 11 Mar 2025 22:57:13 +0800 Subject: [PATCH 032/249] Add colour specifically to Priority tag Also added feature where priority tag always appear first amongst tags --- src/main/java/seedu/address/ui/PersonCard.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java index 094c42cda82..3009d0b076a 100644 --- a/src/main/java/seedu/address/ui/PersonCard.java +++ b/src/main/java/seedu/address/ui/PersonCard.java @@ -8,6 +8,7 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Region; import seedu.address.model.person.Person; +import seedu.address.model.tag.Tag; /** * An UI component that displays information of a {@code Person}. @@ -53,7 +54,14 @@ public PersonCard(Person person, int displayedIndex) { address.setText(person.getAddress().value); email.setText(person.getEmail().value); person.getTags().stream() - .sorted(Comparator.comparing(tag -> tag.tagName)) - .forEach(tag -> tags.getChildren().add(new Label(tag.tagName))); + .sorted(Comparator.comparing(tag -> !tag.tagName.equals("Priority")) + .thenComparing(tag -> tag.tagName)) + .forEach(tag -> { + Label label = new Label(tag.tagName); + if (tag.tagName.equals("Priority")) { + label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); + } + tags.getChildren().add(label); + }); } } From 92d38e8a3c51b1b85e1faedc4d663538c6e84625 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Thu, 13 Mar 2025 07:44:45 +0800 Subject: [PATCH 033/249] Update Ui.png --- docs/images/Ui.png | Bin 14607 -> 38391 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/Ui.png b/docs/images/Ui.png index 5bd77847aa2429edac366ebe3e00650b6dd909d8..595cd413fcb09f5c9b4274f8f9a74dce58e39a8c 100644 GIT binary patch literal 38391 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 RAXge19gVx{rMDi1{6Bg4z)AoB From 42a8af9611dce794fe4b2551645a880c4997cf64 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Thu, 13 Mar 2025 07:54:35 +0800 Subject: [PATCH 034/249] Update Ui.png to better fit the dimensions specified --- docs/images/Ui.png | Bin 38391 -> 43418 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/Ui.png b/docs/images/Ui.png index 595cd413fcb09f5c9b4274f8f9a74dce58e39a8c..24a77f73547e57c7ccdcb5c5d185e6833c65572d 100644 GIT binary patch literal 43418 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 E7gJKCIRF3v literal 38391 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 KxvX Date: Thu, 13 Mar 2025 07:56:57 +0800 Subject: [PATCH 035/249] Update Ui.png --- docs/images/Ui.png | Bin 43418 -> 40630 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/Ui.png b/docs/images/Ui.png index 24a77f73547e57c7ccdcb5c5d185e6833c65572d..27fa7663a363872582008397a8c9c70a0ee74d9a 100644 GIT binary patch literal 40630 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 E7gJKCIRF3v From e8351139d263e6a46e30dec221793f324cc87540 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Thu, 13 Mar 2025 08:40:13 +0800 Subject: [PATCH 036/249] Update README.md --- README.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 48149f35ac0..c4b1d66831c 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,17 @@ ![Ui](docs/images/Ui.png) -* This is **a sample project for Software Engineering (SE) students**.
    - 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. - * 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)**. -* 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/#contributing-to-se-edu) for more info. +# WealthVault + +*WealthVault* is a **contact management application** designed for financial advisors to efficiently store and manage client information. + +## Overview +WealthVault is based on AddressBook Level 3 (AB3) and follows **object-oriented programming (OOP) principles**. It provides a **well-structured** codebase (~6 KLoC), making it suitable for both learning and real-world contact management applications. + +## Features +- **Client Database:** Store and manage client contact details. +- **Tagging System:** Categorize clients based on financial needs or investment preferences. +- **Search and Filter:** Quickly find clients using name, tags, or custom filters. +- **User-Friendly Interface:** Desktop-based application with an intuitive UI. + +- This project is based on the AddressBook-Level3 project created by the [SE-EDU initiative](https://se-education.org). From a80573ec741318983f8504ac56a5c2b0851d6793 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Thu, 13 Mar 2025 12:02:13 +0800 Subject: [PATCH 037/249] Add gitignore for node module --- .gitignore | 1 + package-lock.json | 4922 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 + 3 files changed, 4928 insertions(+) create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.gitignore b/.gitignore index eab4c7db6a5..25e1d1a1658 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ src/test/data/sandbox/ .DS_Store docs/_site/ docs/_markbind/logs/ +node_modules \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000000..05f17fea4c5 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4922 @@ +{ + "name": "tp", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "markbind-cli": "^5.5.3" + } + }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@fortawesome/fontawesome-free": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz", + "integrity": "sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA==", + "dev": true, + "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)", + "engines": { + "node": ">=6" + } + }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1" + } + }, + "node_modules/@kwsites/file-exists/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@kwsites/file-exists/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@markbind/core": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@markbind/core/-/core-5.5.3.tgz", + "integrity": "sha512-XfXC8nbvQn3nXhsH9JL/N9x1TH5UeTYL24HzcIgkuWvm75/60pUZ/T1ji25gkQBjtNgPsvkPVeGXxzIRp2sqJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@fortawesome/fontawesome-free": "^6.5.2", + "@markbind/core-web": "5.5.3", + "@primer/octicons": "^15.0.1", + "@sindresorhus/slugify": "^0.9.1", + "@tlylt/markdown-it-imsize": "^3.0.0", + "bluebird": "^3.7.2", + "bootstrap-icons": "^1.11.3", + "bootswatch": "5.1.3", + "cheerio": "^0.22.0", + "crypto-js": "^4.0.0", + "csv-parse": "^4.14.2", + "ensure-posix-path": "^1.1.1", + "fastmatter": "^2.1.1", + "fs-extra": "^9.0.1", + "gh-pages": "^5.0.0", + "highlight.js": "^10.4.1", + "htmlparser2": "^3.10.1", + "ignore": "^5.1.4", + "js-beautify": "1.14.3", + "katex": "^0.15.6", + "lodash": "^4.17.15", + "markdown-it": "^12.3.2", + "markdown-it-attrs": "^4.1.3", + "markdown-it-emoji": "^1.4.0", + "markdown-it-linkify-images": "^3.0.0", + "markdown-it-mark": "^3.0.0", + "markdown-it-regexp": "^0.4.0", + "markdown-it-sub": "^1.0.0", + "markdown-it-sup": "^1.0.0", + "markdown-it-table-of-contents": "^0.4.4", + "markdown-it-task-lists": "^2.1.1", + "markdown-it-texmath": "^1.0.0", + "markdown-it-video": "^0.6.3", + "material-icons": "^1.9.1", + "moment": "^2.29.4", + "nunjucks": "3.2.4", + "path-is-inside": "^1.0.2", + "simple-git": "^3.22.0", + "url-parse": "^1.5.10", + "uuid": "^8.3.1", + "vue": "2.6.14", + "vue-server-renderer": "2.6.14", + "vue-template-compiler": "2.6.14", + "walk-sync": "^2.0.2", + "winston": "^2.4.4" + } + }, + "node_modules/@markbind/core-web": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@markbind/core-web/-/core-web-5.5.3.tgz", + "integrity": "sha512-pNJnz6ahEw68+veMEUU29D6jvvmqaWp+LwRGC7bUw2jyUk6BRdS2QkkdwP7X7fAXs1HKNdOfBzYx9CJb0Gf0Vw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@primer/octicons": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-15.2.0.tgz", + "integrity": "sha512-4cHZzcZ3F/HQNL4EKSaFyVsW7XtITiJkTeB1JDDmRuP/XobyWyF9gWxuV9c+byUa8dOB5KNQn37iRvNrIehPUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1" + } + }, + "node_modules/@sindresorhus/slugify": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-0.9.1.tgz", + "integrity": "sha512-b6heYM9dzZD13t2GOiEQTDE0qX+I1GyOotMwKh9VQqzuNiVdPVT8dM43fe9HNb/3ul+Qwd5oKSEDrDIfhq3bnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5", + "lodash.deburr": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@tlylt/markdown-it-imsize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@tlylt/markdown-it-imsize/-/markdown-it-imsize-3.0.0.tgz", + "integrity": "sha512-6kTM+vRJTuN2UxNPyJ8yC+NHrzS+MxVHV+z+bDxSr/Fd7eTah2+otLKC2B17YI/1lQnSumA2qokPGuzsA98c6g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/apache-crypt": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.6.tgz", + "integrity": "sha512-072WetlM4blL8PREJVeY+WHiUh1R5VNt2HfceGS8aKqttPHcmqE5pkKuXPz/ULmJOFkc8Hw3kfKl6vy7Qka6DA==", + "dev": true, + "license": "MIT", + "dependencies": { + "unix-crypt-td-js": "^1.1.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/apache-md5": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.8.tgz", + "integrity": "sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-each": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", + "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/bootstrap-icons": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.3.tgz", + "integrity": "sha512-+3lpHrCw/it2/7lBL15VR0HEumaBss0+f/Lb6ZvHISn1mlK83jjFpooTLsMWbIjJMDjDjOExMsTxnXSIT4k4ww==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "license": "MIT" + }, + "node_modules/bootswatch": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bootswatch/-/bootswatch-5.1.3.tgz", + "integrity": "sha512-NmZFN6rOCoXWQ/PkzmD8FFWDe24kocX9OXWHNVaLxVVnpqpAzEbMFsf8bAfKwVtpNXibasZCzv09B5fLieAh2g==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==", + "dev": true, + "license": "BSD-like", + "dependencies": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "node_modules/css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/csv-parse": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.3.tgz", + "integrity": "sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha512-TVF6svNzeQCOpjCqsy0/CSy8VgObG3wXusJ73xW2GbG5rGx7lC8zxDSURicsXI2UsGdi2L0QNRCi745/wUDvsA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true, + "license": "MIT" + }, + "node_modules/editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "bin": { + "editorconfig": "bin/editorconfig" + } + }, + "node_modules/editorconfig/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/email-addresses": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", + "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ensure-posix-path": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ensure-posix-path/-/ensure-posix-path-1.1.1.tgz", + "integrity": "sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw==", + "dev": true, + "license": "ISC" + }, + "node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + } + }, + "node_modules/event-stream/node_modules/split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/event-stream/node_modules/stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "~0.1.1" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/expand-brackets/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", + "dev": true, + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastmatter": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fastmatter/-/fastmatter-2.1.1.tgz", + "integrity": "sha512-NFrjZEPJZTexoJEuyM5J7n4uFaLf0dOI7Ok4b2IZXOYBqCp1Bh5RskANmQ2TuDsz3M35B1yL2AP/Rn+kp85KeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.0", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through2": "^3.0.1" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fecha": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", + "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==", + "dev": true, + "license": "MIT" + }, + "node_modules/figlet": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.8.0.tgz", + "integrity": "sha512-chzvGjd+Sp7KUvPHZv6EXV5Ir3Q7kYNpCr4aHrRW79qFtTefmQZNny+W1pW9kf5zeE6dikku2W50W/wAH2xWgw==", + "dev": true, + "license": "MIT", + "bin": { + "figlet": "bin/index.js" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/file-stream-rotator": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.4.1.tgz", + "integrity": "sha512-W3aa3QJEc8BS2MmdVpQiYLKHj3ijpto1gMDlsgCRSKfIUe6MwkcpODGPQ3vZfb0XvCeCqlu9CBQTN7oQri2TZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "moment": "^2.11.2" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "dev": true, + "license": "MIT", + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", + "dev": true, + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gh-pages": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-5.0.0.tgz", + "integrity": "sha512-Nqp1SjkPIB94Xw/3yYNTUL+G2dxlhjvv1zeN/4kMC1jfViTEqhtVz/Ba1zSXHuvXCN9ADNS1dN4r5/J/nZWEQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "^3.2.4", + "commander": "^2.18.0", + "email-addresses": "^5.0.0", + "filenamify": "^4.3.0", + "find-cache-dir": "^3.3.1", + "fs-extra": "^8.1.0", + "globby": "^6.1.0" + }, + "bin": { + "gh-pages": "bin/gh-pages.js", + "gh-pages-clean": "bin/gh-pages-clean.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gh-pages/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/gh-pages/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/gh-pages/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/gh-pages/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==", + "dev": true, + "license": "MIT" + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/http-auth": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.1.3.tgz", + "integrity": "sha512-Jbx0+ejo2IOx+cRUYAGS1z6RGc6JfYUNkysZM4u4Sfk1uLlGv814F7/PIjQQAuThLdAWxb74JMGd5J8zex1VQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "apache-crypt": "^1.1.2", + "apache-md5": "^1.0.6", + "bcryptjs": "^2.3.0", + "uuid": "^3.0.0" + }, + "engines": { + "node": ">=4.6.1" + } + }, + "node_modules/http-auth/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz", + "integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-accessor-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", + "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", + "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-beautify": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.3.tgz", + "integrity": "sha512-f1ra8PHtOEu/70EBnmiUlV8nJePS58y9qKjl4JHfYWlFH6bo7ogZBz//FAZp7jDuXtYnGYKymZPlrg2I/9Zo4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "config-chain": "^1.1.13", + "editorconfig": "^0.15.3", + "glob": "^7.1.3", + "nopt": "^5.0.0" + }, + "bin": { + "css-beautify": "js/bin/css-beautify.js", + "html-beautify": "js/bin/html-beautify.js", + "js-beautify": "js/bin/js-beautify.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/katex": { + "version": "0.15.6", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.15.6.tgz", + "integrity": "sha512-UpzJy4yrnqnhXvRPhjEuLA4lcPn6eRngixW7Q3TJErjg3Aw2PuLFBzTkdUb89UtumxjhHTqL3a5GDGETMSwgJA==", + "dev": true, + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.0.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/live-server": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/live-server/-/live-server-1.2.1.tgz", + "integrity": "sha512-Yn2XCVjErTkqnM3FfTmM7/kWy3zP7+cEtC7x6u+wUzlQ+1UW3zEYbbyJrc0jNDwiMDZI0m4a0i3dxlGHVyXczw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^2.0.4", + "colors": "latest", + "connect": "^3.6.6", + "cors": "latest", + "event-stream": "3.3.4", + "faye-websocket": "0.11.x", + "http-auth": "3.1.x", + "morgan": "^1.9.1", + "object-assign": "latest", + "opn": "latest", + "proxy-middleware": "latest", + "send": "latest", + "serve-index": "^1.9.1" + }, + "bin": { + "live-server": "live-server.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "license": "ISC", + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/live-server/node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/live-server/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "Upgrade to fsevents v2 to mitigate potential security issues", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/live-server/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/live-server/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/live-server/node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/live-server/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/live-server/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha512-lxdsn7xxlCymgLYo1gGvVrfHmkjDiyqVv62FAeF2i5ta72BipE1SLxw8hPEPLhD4/247Ijw07UQH7Hq/chT5LA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.deburr": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-4.1.0.tgz", + "integrity": "sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha512-pXYUy7PR8BCLwX5mgJ/aNtyOvuJTdZAo9EQFUvMIYugqmJxnrYaANvTbgndOzHSCSR0wnlBBfRXJL5SbWxo3FQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", + "deprecated": "This package is deprecated. Use destructuring assignment syntax instead.", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha512-qkTuvgEzYdyhiJBx42YPzPo71R1aEr0z79kAv7Ixg8wPFEjgRgJdUsGMG3Hf3OYSF/kHI79XhNlt+5Ar6OzwxQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "deprecated": "This package is deprecated. Use https://socket.dev/npm/package/eta instead.", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/logform": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-1.10.0.tgz", + "integrity": "sha512-em5ojIhU18fIMOw/333mD+ZLE2fis0EzXl1ZwHx4iQzmpQi6odNiY/t+ITNr33JZhT9/KEaH+UPIipr6a9EjWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "colors": "^1.2.1", + "fast-safe-stringify": "^2.0.4", + "fecha": "^2.3.3", + "ms": "^2.1.1", + "triple-beam": "^1.2.0" + } + }, + "node_modules/logform/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", + "dev": true + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/markbind-cli": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/markbind-cli/-/markbind-cli-5.5.3.tgz", + "integrity": "sha512-mJ6LzmgXHhUgzUtr6ACVCUwJXsQcF/qUhEnZ8/Nbq9aQUKObZ8Btzkj9pOBSYNuCgcksvw5EJKCdLbthnEkKvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@markbind/core": "5.5.3", + "@markbind/core-web": "5.5.3", + "bluebird": "^3.7.2", + "chalk": "^3.0.0", + "cheerio": "^0.22.0", + "chokidar": "^3.3.0", + "colors": "1.4.0", + "commander": "^8.1.0", + "figlet": "^1.2.4", + "find-up": "^4.1.0", + "fs-extra": "^9.0.1", + "live-server": "1.2.1", + "lodash": "^4.17.15", + "url-parse": "^1.5.10", + "winston": "^2.4.4", + "winston-daily-rotate-file": "^3.10.0" + }, + "bin": { + "markbind": "index.js" + } + }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-attrs": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.3.1.tgz", + "integrity": "sha512-/ko6cba+H6gdZ0DOw7BbNMZtfuJTRp9g/IrGIuz8lYc/EfnmWRpaR3CFPnNbVz0LDvF8Gf1hFGPqrQqq7De0rg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "markdown-it": ">= 9.0.0" + } + }, + "node_modules/markdown-it-emoji": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz", + "integrity": "sha512-QCz3Hkd+r5gDYtS2xsFXmBYrgw6KuWcJZLCEkdfAuwzZbShCmCfta+hwAMq4NX/4xPzkSHduMKgMkkPUJxSXNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/markdown-it-linkify-images": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-linkify-images/-/markdown-it-linkify-images-3.0.0.tgz", + "integrity": "sha512-Vs5yGJa5MWjFgytzgtn8c1U6RcStj3FZKhhx459U8dYbEE5FTWZ6mMRkYMiDlkFO0j4VCsQT1LT557bY0ETgtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "markdown-it": "^13.0.1" + } + }, + "node_modules/markdown-it-linkify-images/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/markdown-it-linkify-images/node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/markdown-it-linkify-images/node_modules/linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/markdown-it-linkify-images/node_modules/markdown-it": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz", + "integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-mark": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-3.0.1.tgz", + "integrity": "sha512-HyxjAu6BRsdt6Xcv6TKVQnkz/E70TdGXEFHRYBGLncRE9lBFwDNLVtFojKxjJWgJ+5XxUwLaHXy+2sGBbDn+4A==", + "dev": true, + "license": "MIT" + }, + "node_modules/markdown-it-regexp": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/markdown-it-regexp/-/markdown-it-regexp-0.4.0.tgz", + "integrity": "sha512-0XQmr46K/rMKnI93Y3CLXsHj4jIioRETTAiVnJnjrZCEkGaDOmUxTbZj/aZ17G5NlRcVpWBYjqpwSlQ9lj+Kxw==", + "dev": true, + "license": "MIT" + }, + "node_modules/markdown-it-sub": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz", + "integrity": "sha512-z2Rm/LzEE1wzwTSDrI+FlPEveAAbgdAdPhdWarq/ZGJrGW/uCQbKAnhoCsE4hAbc3SEym26+W2z/VQB0cQiA9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/markdown-it-sup": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz", + "integrity": "sha512-E32m0nV9iyhRR7CrhnzL5msqic7rL1juWre6TQNxsnApg7Uf+F97JOKxUijg5YwXz86lZ0mqfOnutoryyNdntQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/markdown-it-table-of-contents": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.4.tgz", + "integrity": "sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">6.4.0" + } + }, + "node_modules/markdown-it-task-lists": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz", + "integrity": "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==", + "dev": true, + "license": "ISC" + }, + "node_modules/markdown-it-texmath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-texmath/-/markdown-it-texmath-1.0.0.tgz", + "integrity": "sha512-4hhkiX8/gus+6e53PLCUmUrsa6ZWGgJW2XCW6O0ASvZUiezIK900ZicinTDtG3kAO2kon7oUA/ReWmpW2FByxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/markdown-it-video": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/markdown-it-video/-/markdown-it-video-0.6.3.tgz", + "integrity": "sha512-T4th1kwy0OcvyWSN4u3rqPGxvbDclpucnVSSaH3ZacbGsAts964dxokx9s/I3GYsrDCJs4ogtEeEeVP18DQj0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/matcher-collection": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-2.0.1.tgz", + "integrity": "sha512-daE62nS2ZQsDg9raM0IlZzLmI2u+7ZapXBwdoeBUKAYERPDDIc0qNqA8E0Rp2D+gspKR7BgIFP52GeujaGXWeQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@types/minimatch": "^3.0.3", + "minimatch": "^3.0.2" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/material-icons": { + "version": "1.13.14", + "resolved": "https://registry.npmjs.org/material-icons/-/material-icons-1.13.14.tgz", + "integrity": "sha512-kZOfc7xCC0rAT8Q3DQixYAeT+tBqZnxkseQtp2bxBxz7q5pMAC+wmit7vJn1g/l7wRU+HEPq23gER4iPjGs5Cg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/nan": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.2.tgz", + "integrity": "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/nunjucks": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", + "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/nunjucks/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", + "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/opn": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", + "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", + "deprecated": "The package has been renamed to `open`", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "dev": true, + "license": [ + "MIT", + "Apache2" + ], + "dependencies": { + "through": "~2.3" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true, + "license": "ISC" + }, + "node_modules/proxy-middleware": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", + "integrity": "sha512-EGCG8SeoIRVMhsqHQUdDigB2i7qU7fCsWASwn54+nPutYO8n4q6EiwMzyfWlC+dzRFExP+kvcnDFdBDHoZBU7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true, + "license": "ISC" + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true, + "license": "MIT" + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/send": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.1.0.tgz", + "integrity": "sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "destroy": "^1.2.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^0.5.2", + "http-errors": "^2.0.0", + "mime-types": "^2.1.35", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/send/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/send/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", + "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==", + "dev": true, + "license": "ISC" + }, + "node_modules/simple-git": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.27.0.tgz", + "integrity": "sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.3.5" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" + } + }, + "node_modules/simple-git/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/simple-git/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "license": "MIT", + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/snapdragon/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "license": "MIT", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "dev": true, + "license": "MIT" + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-combiner": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/union-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unix-crypt-td-js": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz", + "integrity": "sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true, + "license": "MIT" + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vue": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz", + "integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==", + "deprecated": "Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.", + "dev": true, + "license": "MIT" + }, + "node_modules/vue-server-renderer": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.14.tgz", + "integrity": "sha512-HifYRa/LW7cKywg9gd4ZtvtRuBlstQBao5ZCWlg40fyB4OPoGfEXAzxb0emSLv4pBDOHYx0UjpqvxpiQFEuoLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^1.1.3", + "hash-sum": "^1.0.2", + "he": "^1.1.0", + "lodash.template": "^4.5.0", + "lodash.uniq": "^4.5.0", + "resolve": "^1.2.0", + "serialize-javascript": "^3.1.0", + "source-map": "0.5.6" + } + }, + "node_modules/vue-server-renderer/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vue-server-renderer/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vue-server-renderer/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/vue-template-compiler": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz", + "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, + "node_modules/walk-sync": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz", + "integrity": "sha512-IC8sL7aB4/ZgFcGI2T1LczZeFWZ06b3zoHH7jBPyHxOtIIz1jppWHjjEXkOFvFojBVAK9pV7g47xOZ4LW3QLfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "^3.0.3", + "ensure-posix-path": "^1.1.0", + "matcher-collection": "^2.0.0", + "minimatch": "^3.0.4" + }, + "engines": { + "node": "8.* || >= 10.*" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/winston": { + "version": "2.4.7", + "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.7.tgz", + "integrity": "sha512-vLB4BqzCKDnnZH9PHGoS2ycawueX4HLqENXQitvFHczhgW2vFpSOn31LZtVr1KU8YTw7DS4tM+cqyovxo8taVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "^2.6.4", + "colors": "1.0.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "stack-trace": "0.0.x" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/winston-compat": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/winston-compat/-/winston-compat-0.1.5.tgz", + "integrity": "sha512-EPvPcHT604AV3Ji6d3+vX8ENKIml9VSxMRnPQ+cuK/FX6f3hvPP2hxyoeeCOCFvDrJEujalfcKWlWPvAnFyS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cycle": "~1.0.3", + "logform": "^1.6.0", + "triple-beam": "^1.2.0" + }, + "engines": { + "node": ">= 6.4.0" + } + }, + "node_modules/winston-daily-rotate-file": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-3.10.0.tgz", + "integrity": "sha512-KO8CfbI2CvdR3PaFApEH02GPXiwJ+vbkF1mCkTlvRIoXFI8EFlf1ACcuaahXTEiDEKCii6cNe95gsL4ZkbnphA==", + "dev": true, + "license": "MIT", + "dependencies": { + "file-stream-rotator": "^0.4.1", + "object-hash": "^1.3.0", + "semver": "^6.2.0", + "triple-beam": "^1.3.0", + "winston-compat": "^0.1.4", + "winston-transport": "^4.2.0" + }, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "winston": "^2 || ^3" + } + }, + "node_modules/winston-daily-rotate-file/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/winston-transport": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", + "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "logform": "^2.7.0", + "readable-stream": "^3.6.2", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport/node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", + "dev": true, + "license": "MIT" + }, + "node_modules/winston-transport/node_modules/logform": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", + "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/winston/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/winston/node_modules/colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true, + "license": "ISC" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000000..8f25afa9f5c --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "markbind-cli": "^5.5.3" + } +} From f780a7735767e3c3c9386d87f99286bec4c449a4 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Thu, 13 Mar 2025 12:31:31 +0800 Subject: [PATCH 038/249] Update site wide settings --- docs/DeveloperGuide.md | 2 +- docs/UserGuide.md | 2 +- docs/index.md | 13 ++++++------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 3bdc97a7f99..33d24782291 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -4,7 +4,7 @@ pageNav: 3 --- -# AB-3 Developer Guide +# WealthVault Developer Guide diff --git a/docs/UserGuide.md b/docs/UserGuide.md index aab9894c52b..bcaa1bbd470 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -4,7 +4,7 @@ pageNav: 3 --- -# AB-3 User Guide +# WealthVault User Guide AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized for use via a 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. diff --git a/docs/index.md b/docs/index.md index 8acbdd73507..bc16846b11b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,17 +3,16 @@ title: "" --- -# AddressBook Level-3 +# WealthVaullt -[![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) +[![Java CI](https://github.com/AY2425S2-CS2103T-W12-2/tp/actions/workflows/gradle.yml/badge.svg)](https://github.com/AY2425S2-CS2103T-W12-2/tp/actions/workflows/gradle.yml) +[![codecov](https://codecov.io/gh/AY2425S2-CS2103T-W12-2/tp/graph/badge.svg?token=H8A87ZR6Z5)](https://codecov.io/gh/AY2425S2-CS2103T-W12-2/tp) ![Ui](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). - -* 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. +**WealthVault is a contact management application** designed for financial advisors to efficiently store and manage client information. +* If you are interested in using WealthVault, head over to the [_Quick Start_ section of the **User Guide**](UserGuide.html#quick-start). +* If you are interested about developing WealthVault, the [**Developer Guide**](DeveloperGuide.html) is a good place to start. **Acknowledgements** From 4fc4e170a2af8776f8e49e519bb8718780f23486 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Thu, 13 Mar 2025 12:39:28 +0800 Subject: [PATCH 039/249] Fix whitespaces --- .gitignore | 2 +- docs/DeveloperGuide.md | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 25e1d1a1658..d69d8b814ec 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,4 @@ src/test/data/sandbox/ .DS_Store docs/_site/ docs/_markbind/logs/ -node_modules \ No newline at end of file +node_modules diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 33d24782291..8d6a0dd410c 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -274,11 +274,11 @@ _{Explain here how the data archiving feature will be implemented}_ **Target user profile**: Financial advisors -* Managing a significant number of client contacts -* Requires a one-stop platform to track and update client's financial details +* Managing a significant number of client contacts +* Requires a one-stop platform to track and update client's financial details * Experiences difficulties to keep track of client's financial needs across multiple platforms * Easy-to-use, fast and organized interface to maintain efficiency in their work -* Keen to provide fast and efficient service to customers +* Keen to provide fast and efficient service to customers **Value proposition**: Manage clients and their financial needs faster than a typical mouse/GUI driven app @@ -309,14 +309,14 @@ 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) -### UC01 - Add Client ### +### UC01 - Add Client ### #### Main Success Scenario (MSS): 1. User chooses to add a new client. 2. AB3 requests client details. 3. User enters the required client details. 4. AB3 verifies the details. -5. AB3 adds the client to the address book and confirms successful addition. +5. AB3 adds the client to the address book and confirms successful addition. **Use case ends.** #### Extensions: @@ -338,7 +338,7 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli - **Use case ends.** -### UC02 - Delete Client ### +### UC02 - Delete Client ### #### Main Success Scenario (MSS): 1. User chooses to delete a client. @@ -346,7 +346,7 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli 3. User enters the required details. 4. AB3 requests confirmation of the deletion. 5. User confirms the deletion. -6. AB3 removes the client from the address book and confirms successful deletion. +6. AB3 removes the client from the address book and confirms successful deletion. **Use case ends.** #### Extensions: From e4d8bf5bb4f1b828402d8ec5e9832d88436ddcbb Mon Sep 17 00:00:00 2001 From: Nicholas Foo Date: Thu, 13 Mar 2025 18:48:03 +0800 Subject: [PATCH 040/249] Add Glossary to DG --- docs/DeveloperGuide.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 8d6a0dd410c..e71bdb06e04 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -379,8 +379,23 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli ### Glossary -* **Mainstream OS**: Windows, Linux, Unix, MacOS -* **Private contact detail**: A contact detail that is not meant to be shared with others +- **API (Application Programming Interface)**: A set of protocols and tools that allow different software components to communicate and interact with each other. In the context of WealthVault, it defines how various system components exchange data and functionality. + +- **Client**: An individual who is a financial advisor’s contact and recipient of financial guidance or services. + +- **Financial Advisor**: A primary user of the application, responsible for managing client financial data, providing investment advice, and overseeing financial planning. + +- **Financial Needs**: A client’s specific financial goals or requirements, including investment planning, retirement savings, risk management, and debt reduction strategies. + +- **GUI (Graphical User Interface)**: The visual interface of the application that enables users to interact with the system through graphical elements such as buttons, menus, and forms. + +- **Mainstream OS**: Windows, Linux, Unix, MacOS + +- **PlantUML**: A tool used for creating UML (Unified Modeling Language) diagrams, such as sequence diagrams and class diagrams, to document system design and architecture. + +- **Private Contact Detail**: A contact detail that is not meant to be shared with others. + + -------------------------------------------------------------------------------------------------------------------- From c3fd0400b3a3d53d6f211299f83bdc26786423d4 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Mon, 17 Mar 2025 01:04:51 +0800 Subject: [PATCH 041/249] Fix priority command for better code standard --- .../seedu/address/logic/commands/Command.java | 17 +++++++++++ .../logic/commands/PriorityCommand.java | 28 ++++++++++--------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/Command.java b/src/main/java/seedu/address/logic/commands/Command.java index 64f18992160..8e9bcab6959 100644 --- a/src/main/java/seedu/address/logic/commands/Command.java +++ b/src/main/java/seedu/address/logic/commands/Command.java @@ -1,7 +1,12 @@ package seedu.address.logic.commands; +import java.util.List; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.Messages; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; +import seedu.address.model.person.Person; /** * Represents a command with hidden internal logic and the ability to be executed. @@ -17,4 +22,16 @@ public abstract class Command { */ public abstract CommandResult execute(Model model) throws CommandException; + /** + * Returns the person for a given index + * + * @throws CommandException If an error occurs during command execution. + */ + protected Person getPersonFromIndex(List list, Index index) throws CommandException { + if (index.getZeroBased() >= list.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + } + return list.get(index.getZeroBased()); + } + } diff --git a/src/main/java/seedu/address/logic/commands/PriorityCommand.java b/src/main/java/seedu/address/logic/commands/PriorityCommand.java index 33001e584fe..b5edf11ffca 100644 --- a/src/main/java/seedu/address/logic/commands/PriorityCommand.java +++ b/src/main/java/seedu/address/logic/commands/PriorityCommand.java @@ -48,16 +48,12 @@ 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 = togglePriorityTag(personToEdit); + Person personToPrioritise = getPersonFromIndex(lastShownList, index); + Person priorityPerson = togglePriorityTag(personToPrioritise); - model.setPerson(personToEdit, editedPerson); + model.setPerson(personToPrioritise, priorityPerson); model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); - return new CommandResult(String.format(MESSAGE_PRIORITY_PERSON_SUCCESS, Messages.format(editedPerson))); + return new CommandResult(String.format(MESSAGE_PRIORITY_PERSON_SUCCESS, Messages.format(priorityPerson))); } /** @@ -67,14 +63,11 @@ public CommandResult execute(Model model) throws CommandException { private static Person togglePriorityTag(Person personToEdit) throws CommandException { assert personToEdit != null; - // Create a mutable set + // Creates a mutable set Set tags = new HashSet<>(personToEdit.getTags()); - boolean isPriority = tags.stream() - .anyMatch(tag -> tag.isEqualTo("Priority")); - // Toggles priority - if (!isPriority) { + if (!isPriority(tags)) { tags.add(new Tag("Priority")); } else { tags = tags.stream() @@ -91,6 +84,15 @@ private static Person togglePriorityTag(Person personToEdit) throws CommandExcep ); } + /** + * Returns whether a tag with tagName "Priority" exists in a list of tags + * + * @param tags the list of tags + */ + private static boolean isPriority(Set tags) { + return tags.stream().anyMatch(t -> t.isEqualTo("Priority")); + } + @Override public boolean equals(Object other) { if (other == this) { From 439b5be4c3f18f62f6e62e3aae66f3e1aa403d6a Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Mon, 17 Mar 2025 01:23:43 +0800 Subject: [PATCH 042/249] Fix repeated code in Priority command --- .../logic/commands/PriorityCommandTest.java | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java b/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java index 74675c4c45c..ef23a5c7ecf 100644 --- a/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java @@ -20,45 +20,42 @@ import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; import seedu.address.model.person.Person; +import seedu.address.model.tag.Tag; import seedu.address.testutil.PersonBuilder; +import java.util.HashSet; +import java.util.Set; + public class PriorityCommandTest { private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); - @Test - public void execute_toggleOnPriorityUnfilteredList_success() { - Person firstPerson = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); - Person priorityPerson = new PersonBuilder(firstPerson).withTags(VALID_TAG_FRIEND, - VALID_TAG_PRIORITY).build(); + private void execute_togglePriorityUnfilteredList(Index personIndex, String... tags) { + Person person = model.getFilteredPersonList().get(personIndex.getZeroBased()); + Person priorityPerson = new PersonBuilder(person).withTags(tags).build(); - PriorityCommand priorityCommand = new PriorityCommand(INDEX_FIRST_PERSON); + PriorityCommand priorityCommand = new PriorityCommand(personIndex); String expectedMessage = String.format(PriorityCommand.MESSAGE_PRIORITY_PERSON_SUCCESS, Messages.format(priorityPerson)); Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs()); - expectedModel.setPerson(firstPerson, priorityPerson); + expectedModel.setPerson(person, priorityPerson); assertCommandSuccess(priorityCommand, model, expectedMessage, expectedModel); } @Test - public void execute_toggleOffPriorityUnfilteredList_success() { - Person firstPerson = model.getFilteredPersonList().get(INDEX_FOURTH_PERSON.getZeroBased()); - Person priorityPerson = new PersonBuilder(firstPerson).withTags(VALID_TAG_FRIEND).build(); - - PriorityCommand priorityCommand = new PriorityCommand(INDEX_FOURTH_PERSON); - - String expectedMessage = String.format(PriorityCommand.MESSAGE_PRIORITY_PERSON_SUCCESS, - Messages.format(priorityPerson)); - - Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs()); - expectedModel.setPerson(firstPerson, priorityPerson); + public void execute_toggleOnPriorityUnfilteredList() { + execute_togglePriorityUnfilteredList(INDEX_FIRST_PERSON, VALID_TAG_FRIEND, VALID_TAG_PRIORITY); + } - assertCommandSuccess(priorityCommand, model, expectedMessage, expectedModel); + @Test + public void execute_toggleOffPriorityUnfilteredList() { + execute_togglePriorityUnfilteredList(INDEX_FOURTH_PERSON, VALID_TAG_FRIEND); } + @Test public void execute_invalidIndex_throwsCommandException() { Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); From 48f6d5fdaac00a666ac0e2053b04fc83f6ccc509 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Mon, 17 Mar 2025 01:24:58 +0800 Subject: [PATCH 043/249] Fix checkstyle error --- .../seedu/address/logic/commands/PriorityCommandTest.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java b/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java index ef23a5c7ecf..75fd9622f22 100644 --- a/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java @@ -20,12 +20,8 @@ import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; import seedu.address.model.person.Person; -import seedu.address.model.tag.Tag; import seedu.address.testutil.PersonBuilder; -import java.util.HashSet; -import java.util.Set; - public class PriorityCommandTest { private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); From 56a6d19ba0e61f0612333ff7b46252aa3b64c379 Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Tue, 18 Mar 2025 00:03:50 +0800 Subject: [PATCH 044/249] Add delete-client-command edits --- .../logic/commands/DeleteClientCommand.java | 69 +++++++++++++++++++ .../address/logic/commands/DeleteCommand.java | 44 +++--------- .../logic/parser/AddressBookParser.java | 6 +- ...er.java => DeleteClientCommandParser.java} | 10 +-- .../seedu/address/logic/LogicManagerTest.java | 4 +- ...Test.java => DeleteClientCommandTest.java} | 34 ++++----- .../logic/parser/AddressBookParserTest.java | 16 ++--- ...ava => DeleteClientCommandParserTest.java} | 12 ++-- .../parser/PriorityCommandParserTest.java | 2 +- 9 files changed, 115 insertions(+), 82 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/DeleteClientCommand.java rename src/main/java/seedu/address/logic/parser/{DeleteCommandParser.java => DeleteClientCommandParser.java} (71%) rename src/test/java/seedu/address/logic/commands/{DeleteCommandTest.java => DeleteClientCommandTest.java} (69%) rename src/test/java/seedu/address/logic/parser/{DeleteCommandParserTest.java => DeleteClientCommandParserTest.java} (70%) diff --git a/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java b/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java new file mode 100644 index 00000000000..4e326dc5c1e --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java @@ -0,0 +1,69 @@ +package seedu.address.logic.commands; + +import seedu.address.commons.core.index.Index; +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.person.Person; + +import java.util.List; + +import static java.util.Objects.requireNonNull; + +/** + * Deletes a person identified using it's displayed index from the address book. + */ +public class DeleteClientCommand extends DeleteCommand { + + public static final String COMMAND_WORD = "deleteclient"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Deletes the person identified by the index number used in the displayed person list.\n" + + "Parameters: INDEX (must be a positive integer)\n" + + "Example: " + COMMAND_WORD + " 1"; + + public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Client: %1$s"; + + private final Index targetIndex; + + public DeleteClientCommand(Index targetIndex) { + this.targetIndex = targetIndex; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + List lastShownList = model.getFilteredPersonList(); + + 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, Messages.format(personToDelete))); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof DeleteClientCommand)) { + return false; + } + + DeleteClientCommand otherDeleteCommand = (DeleteClientCommand) other; + return targetIndex.equals(otherDeleteCommand.targetIndex); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("targetIndex", targetIndex) + .toString(); + } +} diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java index 1135ac19b74..76fd09c95ab 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteCommand.java @@ -14,7 +14,7 @@ /** * Deletes a person identified using it's displayed index from the address book. */ -public class DeleteCommand extends Command { +public abstract class DeleteCommand extends Command { public static final String COMMAND_WORD = "delete"; @@ -23,47 +23,19 @@ public class DeleteCommand extends Command { + "Parameters: INDEX (must be a positive integer)\n" + "Example: " + COMMAND_WORD + " 1"; - public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s"; - - private final Index targetIndex; - - public DeleteCommand(Index targetIndex) { - this.targetIndex = targetIndex; - } - @Override - public CommandResult execute(Model model) throws CommandException { - requireNonNull(model); - List lastShownList = model.getFilteredPersonList(); - - if (targetIndex.getZeroBased() >= lastShownList.size()) { - throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); - } + public abstract CommandResult execute(Model model) throws CommandException; - Person personToDelete = lastShownList.get(targetIndex.getZeroBased()); - model.deletePerson(personToDelete); - return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, Messages.format(personToDelete))); - } + @Override + public abstract boolean equals(Object other); @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } + public abstract String toString(); - // instanceof handles nulls - if (!(other instanceof DeleteCommand)) { - return false; - } + private static String messageUsage; - DeleteCommand otherDeleteCommand = (DeleteCommand) other; - return targetIndex.equals(otherDeleteCommand.targetIndex); + public static String getMessageUsage() { + return messageUsage; } - @Override - public String toString() { - return new ToStringBuilder(this) - .add("targetIndex", targetIndex) - .toString(); - } } diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index a6a62769e5c..5ab44667105 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -11,7 +11,7 @@ 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.DeleteClientCommand; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.ExitCommand; import seedu.address.logic.commands.FindCommand; @@ -60,8 +60,8 @@ public Command parseCommand(String userInput) throws ParseException { case EditCommand.COMMAND_WORD: return new EditCommandParser().parse(arguments); - case DeleteCommand.COMMAND_WORD: - return new DeleteCommandParser().parse(arguments); + case DeleteClientCommand.COMMAND_WORD: + return new DeleteClientCommandParser().parse(arguments); case ClearCommand.COMMAND_WORD: return new ClearCommand(); diff --git a/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteClientCommandParser.java similarity index 71% rename from src/main/java/seedu/address/logic/parser/DeleteCommandParser.java rename to src/main/java/seedu/address/logic/parser/DeleteClientCommandParser.java index 3527fe76a3e..b9334d344a7 100644 --- a/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/DeleteClientCommandParser.java @@ -3,26 +3,26 @@ import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; import seedu.address.commons.core.index.Index; -import seedu.address.logic.commands.DeleteCommand; +import seedu.address.logic.commands.DeleteClientCommand; import seedu.address.logic.parser.exceptions.ParseException; /** * Parses input arguments and creates a new DeleteCommand object */ -public class DeleteCommandParser implements Parser { +public class DeleteClientCommandParser implements Parser { /** * Parses the given {@code String} of arguments in the context of the DeleteCommand * and returns a DeleteCommand object for execution. * @throws ParseException if the user input does not conform the expected format */ - public DeleteCommand parse(String args) throws ParseException { + public DeleteClientCommand parse(String args) throws ParseException { try { Index index = ParserUtil.parseIndex(args); - return new DeleteCommand(index); + return new DeleteClientCommand(index); } catch (ParseException pe) { throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE), pe); + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteClientCommand.MESSAGE_USAGE), pe); } } diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/address/logic/LogicManagerTest.java index baf8ce336a2..b56238b84cd 100644 --- a/src/test/java/seedu/address/logic/LogicManagerTest.java +++ b/src/test/java/seedu/address/logic/LogicManagerTest.java @@ -60,8 +60,8 @@ public void execute_invalidCommandFormat_throwsParseException() { @Test public void execute_commandExecutionError_throwsCommandException() { - String deleteCommand = "delete 9"; - assertCommandException(deleteCommand, MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + String deleteClientCommand = "delete 9"; + assertCommandException(deleteClientCommand, MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); } @Test diff --git a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteClientCommandTest.java similarity index 69% rename from src/test/java/seedu/address/logic/commands/DeleteCommandTest.java rename to src/test/java/seedu/address/logic/commands/DeleteClientCommandTest.java index b6f332eabca..9a2abd60958 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteClientCommandTest.java @@ -23,30 +23,30 @@ * Contains integration tests (interaction with the Model) and unit tests for * {@code DeleteCommand}. */ -public class DeleteCommandTest { +public class DeleteClientCommandTest { private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); @Test public void execute_validIndexUnfilteredList_success() { Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); - DeleteCommand deleteCommand = new DeleteCommand(INDEX_FIRST_PERSON); + DeleteClientCommand deleteClientCommand = new DeleteClientCommand(INDEX_FIRST_PERSON); - String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, + String expectedMessage = String.format(DeleteClientCommand.MESSAGE_DELETE_PERSON_SUCCESS, Messages.format(personToDelete)); ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); expectedModel.deletePerson(personToDelete); - assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel); + assertCommandSuccess(deleteClientCommand, model, expectedMessage, expectedModel); } @Test public void execute_invalidIndexUnfilteredList_throwsCommandException() { Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); - DeleteCommand deleteCommand = new DeleteCommand(outOfBoundIndex); + DeleteClientCommand deleteClientCommand = new DeleteClientCommand(outOfBoundIndex); - assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandFailure(deleteClientCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); } @Test @@ -54,16 +54,16 @@ public void execute_validIndexFilteredList_success() { showPersonAtIndex(model, INDEX_FIRST_PERSON); Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); - DeleteCommand deleteCommand = new DeleteCommand(INDEX_FIRST_PERSON); + DeleteClientCommand deleteClientCommand = new DeleteClientCommand(INDEX_FIRST_PERSON); - String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, + String expectedMessage = String.format(DeleteClientCommand.MESSAGE_DELETE_PERSON_SUCCESS, Messages.format(personToDelete)); Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); expectedModel.deletePerson(personToDelete); showNoPerson(expectedModel); - assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel); + assertCommandSuccess(deleteClientCommand, model, expectedMessage, expectedModel); } @Test @@ -74,21 +74,21 @@ public void execute_invalidIndexFilteredList_throwsCommandException() { // ensures that outOfBoundIndex is still in bounds of address book list assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size()); - DeleteCommand deleteCommand = new DeleteCommand(outOfBoundIndex); + DeleteClientCommand deleteClientCommand = new DeleteClientCommand(outOfBoundIndex); - assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandFailure(deleteClientCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); } @Test public void equals() { - DeleteCommand deleteFirstCommand = new DeleteCommand(INDEX_FIRST_PERSON); - DeleteCommand deleteSecondCommand = new DeleteCommand(INDEX_SECOND_PERSON); + DeleteClientCommand deleteFirstCommand = new DeleteClientCommand(INDEX_FIRST_PERSON); + DeleteClientCommand deleteSecondCommand = new DeleteClientCommand(INDEX_SECOND_PERSON); // same object -> returns true assertTrue(deleteFirstCommand.equals(deleteFirstCommand)); // same values -> returns true - DeleteCommand deleteFirstCommandCopy = new DeleteCommand(INDEX_FIRST_PERSON); + DeleteClientCommand deleteFirstCommandCopy = new DeleteClientCommand(INDEX_FIRST_PERSON); assertTrue(deleteFirstCommand.equals(deleteFirstCommandCopy)); // different types -> returns false @@ -104,9 +104,9 @@ public void equals() { @Test public void toStringMethod() { Index targetIndex = Index.fromOneBased(1); - DeleteCommand deleteCommand = new DeleteCommand(targetIndex); - String expected = DeleteCommand.class.getCanonicalName() + "{targetIndex=" + targetIndex + "}"; - assertEquals(expected, deleteCommand.toString()); + DeleteClientCommand deleteClientCommand = new DeleteClientCommand(targetIndex); + String expected = DeleteClientCommand.class.getCanonicalName() + "{targetIndex=" + targetIndex + "}"; + assertEquals(expected, deleteClientCommand.toString()); } /** diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 2aa28adfa40..7cea062bc8d 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -13,16 +13,8 @@ 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.*; 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.commands.PriorityCommand; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.person.NameContainsKeywordsPredicate; import seedu.address.model.person.Person; @@ -49,9 +41,9 @@ public void parseCommand_clear() throws Exception { @Test public void parseCommand_delete() throws Exception { - DeleteCommand command = (DeleteCommand) parser.parseCommand( - DeleteCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased()); - assertEquals(new DeleteCommand(INDEX_FIRST_PERSON), command); + DeleteClientCommand command = (DeleteClientCommand) parser.parseCommand( + DeleteClientCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased()); + assertEquals(new DeleteClientCommand(INDEX_FIRST_PERSON), command); } @Test diff --git a/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteClientCommandParserTest.java similarity index 70% rename from src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java rename to src/test/java/seedu/address/logic/parser/DeleteClientCommandParserTest.java index 6a40e14a649..1a89e001398 100644 --- a/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/DeleteClientCommandParserTest.java @@ -7,7 +7,7 @@ import org.junit.jupiter.api.Test; -import seedu.address.logic.commands.DeleteCommand; +import seedu.address.logic.commands.DeleteClientCommand; /** * As we are only doing white-box testing, our test cases do not cover path variations @@ -16,17 +16,17 @@ * The path variation for those two cases occur inside the ParserUtil, and * therefore should be covered by the ParserUtilTest. */ -public class DeleteCommandParserTest { +public class DeleteClientCommandParserTest { - private DeleteCommandParser parser = new DeleteCommandParser(); + private DeleteClientCommandParser parser = new DeleteClientCommandParser(); @Test - public void parse_validArgs_returnsDeleteCommand() { - assertParseSuccess(parser, "1", new DeleteCommand(INDEX_FIRST_PERSON)); + public void parse_validArgs_returnsDeleteClientCommand() { + assertParseSuccess(parser, "1", new DeleteClientCommand(INDEX_FIRST_PERSON)); } @Test public void parse_invalidArgs_throwsParseException() { - assertParseFailure(parser, "a", String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE)); + assertParseFailure(parser, "a", String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteClientCommand.MESSAGE_USAGE)); } } diff --git a/src/test/java/seedu/address/logic/parser/PriorityCommandParserTest.java b/src/test/java/seedu/address/logic/parser/PriorityCommandParserTest.java index 2ed617acba5..33802dfe80f 100644 --- a/src/test/java/seedu/address/logic/parser/PriorityCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/PriorityCommandParserTest.java @@ -13,7 +13,7 @@ public class PriorityCommandParserTest { private PriorityCommandParser parser = new PriorityCommandParser(); @Test - public void parse_validArgs_returnsDeleteCommand() { + public void parse_validArgs_returnsDeleteClientCommand() { assertParseSuccess(parser, "1", new PriorityCommand(INDEX_FIRST_PERSON)); } From 67640461a82830207e0db44310e14b884931a31f Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Tue, 18 Mar 2025 00:45:00 +0800 Subject: [PATCH 045/249] Customise codebase --- .../java/seedu/address/model/AddressBook.java | 37 +++- .../address/model/ReadOnlyAddressBook.java | 6 + .../seedu/address/model/client/Address.java | 65 +++++++ .../seedu/address/model/client/Client.java | 103 +++++++++++ .../seedu/address/model/client/Email.java | 80 ++++++++ .../java/seedu/address/model/client/Name.java | 67 +++++++ .../seedu/address/model/client/Phone.java | 61 +++++++ .../model/client/UniqueClientList.java | 150 +++++++++++++++ .../exceptions/ClientNotFoundException.java | 6 + .../exceptions/DuplicateClientException.java | 11 ++ .../seedu/address/model/AddressBookTest.java | 10 +- .../address/model/client/AddressTest.java | 56 ++++++ .../address/model/client/ClientTest.java | 88 +++++++++ .../seedu/address/model/client/EmailTest.java | 89 +++++++++ .../seedu/address/model/client/NameTest.java | 60 ++++++ .../seedu/address/model/client/PhoneTest.java | 61 +++++++ .../model/client/UniqueClientListTest.java | 172 ++++++++++++++++++ .../seedu/address/testutil/ClientBuilder.java | 80 ++++++++ .../address/testutil/TypicalClients.java | 72 ++++++++ 19 files changed, 1271 insertions(+), 3 deletions(-) create mode 100644 src/main/java/seedu/address/model/client/Address.java create mode 100644 src/main/java/seedu/address/model/client/Client.java create mode 100644 src/main/java/seedu/address/model/client/Email.java create mode 100644 src/main/java/seedu/address/model/client/Name.java create mode 100644 src/main/java/seedu/address/model/client/Phone.java create mode 100644 src/main/java/seedu/address/model/client/UniqueClientList.java create mode 100644 src/main/java/seedu/address/model/client/exceptions/ClientNotFoundException.java create mode 100644 src/main/java/seedu/address/model/client/exceptions/DuplicateClientException.java create mode 100644 src/test/java/seedu/address/model/client/AddressTest.java create mode 100644 src/test/java/seedu/address/model/client/ClientTest.java create mode 100644 src/test/java/seedu/address/model/client/EmailTest.java create mode 100644 src/test/java/seedu/address/model/client/NameTest.java create mode 100644 src/test/java/seedu/address/model/client/PhoneTest.java create mode 100644 src/test/java/seedu/address/model/client/UniqueClientListTest.java create mode 100644 src/test/java/seedu/address/testutil/ClientBuilder.java create mode 100644 src/test/java/seedu/address/testutil/TypicalClients.java diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index 73397161e84..a4ca8bbc9a9 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -6,6 +6,8 @@ import javafx.collections.ObservableList; import seedu.address.commons.util.ToStringBuilder; +import seedu.address.model.client.Client; +import seedu.address.model.client.UniqueClientList; import seedu.address.model.person.Person; import seedu.address.model.person.UniquePersonList; @@ -16,7 +18,7 @@ public class AddressBook implements ReadOnlyAddressBook { private final UniquePersonList persons; - + private final UniqueClientList clients; /* * 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 @@ -26,6 +28,7 @@ public class AddressBook implements ReadOnlyAddressBook { */ { persons = new UniquePersonList(); + clients = new UniqueClientList(); } public AddressBook() {} @@ -48,6 +51,10 @@ public void setPersons(List persons) { this.persons.setPersons(persons); } + public void setClients(List clients) { + this.clients.setClients(clients); + } + /** * Resets the existing data of this {@code AddressBook} with {@code newData}. */ @@ -55,6 +62,7 @@ public void resetData(ReadOnlyAddressBook newData) { requireNonNull(newData); setPersons(newData.getPersonList()); + setClients(newData.getClientList()); } //// person-level operations @@ -94,12 +102,32 @@ public void removePerson(Person key) { persons.remove(key); } + //// client-level operations + public boolean hasClient(Client client) { + requireNonNull(client); + return clients.contains(client); + } + + public void addClient(Client c) { + clients.add(c); + } + + public void setClient(Client target, Client editedClient) { + requireNonNull(editedClient); + clients.setClient(target, editedClient); + } + + public void removeClient(Client key) { + clients.remove(key); + } + //// util methods @Override public String toString() { return new ToStringBuilder(this) .add("persons", persons) + .add("clients", clients) .toString(); } @@ -108,6 +136,11 @@ public ObservableList getPersonList() { return persons.asUnmodifiableObservableList(); } + @Override + public ObservableList getClientList() { + return clients.asUnmodifiableObservableList(); + } + @Override public boolean equals(Object other) { if (other == this) { @@ -120,7 +153,7 @@ public boolean equals(Object other) { } AddressBook otherAddressBook = (AddressBook) other; - return persons.equals(otherAddressBook.persons); + return persons.equals(otherAddressBook.persons) && clients.equals(otherAddressBook.clients); } @Override diff --git a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java index 6ddc2cd9a29..3f0fc82d2a3 100644 --- a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java +++ b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java @@ -1,6 +1,7 @@ package seedu.address.model; import javafx.collections.ObservableList; +import seedu.address.model.client.Client; import seedu.address.model.person.Person; /** @@ -14,4 +15,9 @@ public interface ReadOnlyAddressBook { */ ObservableList getPersonList(); + /** + * Returns an unmodifiable view of the clients list. + * This list will not contain any duplicate clients. + */ + ObservableList getClientList(); } diff --git a/src/main/java/seedu/address/model/client/Address.java b/src/main/java/seedu/address/model/client/Address.java new file mode 100644 index 00000000000..b9e476d5ee7 --- /dev/null +++ b/src/main/java/seedu/address/model/client/Address.java @@ -0,0 +1,65 @@ +package seedu.address.model.client; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.AppUtil.checkArgument; + +/** + * Represents a Client'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 address. + */ + public static boolean isValidAddress(String test) { + return test.matches(VALIDATION_REGEX); + } + + @Override + public String toString() { + return value; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof Address)) { + return false; + } + + Address otherAddress = (Address) other; + return value.equals(otherAddress.value); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + +} diff --git a/src/main/java/seedu/address/model/client/Client.java b/src/main/java/seedu/address/model/client/Client.java new file mode 100644 index 00000000000..29939725d24 --- /dev/null +++ b/src/main/java/seedu/address/model/client/Client.java @@ -0,0 +1,103 @@ +package seedu.address.model.client; + +import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; + +import java.util.Objects; + +import seedu.address.commons.util.ToStringBuilder; + +/** + * Represents a Client in the address book. + * Guarantees: details are present and not null, field values are validated, immutable. + */ +public class Client { + + // Identity fields + private final Name name; + private final Phone phone; + private final Email email; + + // Data fields + private final Address address; + + /** + * Every field must be present and not null. + */ + public Client(Name name, Phone phone, Email email, Address address) { + requireAllNonNull(name, phone, email, address); + this.name = name; + this.phone = phone; + this.email = email; + this.address = address; + } + + public Name getName() { + return name; + } + + public Phone getPhone() { + return phone; + } + + public Email getEmail() { + return email; + } + + public Address getAddress() { + return address; + } + + + /** + * Returns true if both clients have the same name. + * This defines a weaker notion of equality between two clients. + */ + public boolean isSameClient(Client otherClient) { + if (otherClient == this) { + return true; + } + + return otherClient != null + && otherClient.getName().equals(getName()); + } + + /** + * Returns true if both Clients have the same identity and data fields. + * This defines a stronger notion of equality between two Clients. + */ + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof Client)) { + return false; + } + + Client otherClient = (Client) other; + return name.equals(otherClient.name) + && phone.equals(otherClient.phone) + && email.equals(otherClient.email) + && address.equals(otherClient.address); + } + + @Override + public int hashCode() { + // use this method for custom fields hashing instead of implementing your own + return Objects.hash(name, phone, email, address); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("name", name) + .add("phone", phone) + .add("email", email) + .add("address", address) + .toString(); + } + +} + diff --git a/src/main/java/seedu/address/model/client/Email.java b/src/main/java/seedu/address/model/client/Email.java new file mode 100644 index 00000000000..80cb480fe83 --- /dev/null +++ b/src/main/java/seedu/address/model/client/Email.java @@ -0,0 +1,80 @@ +package seedu.address.model.client; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.AppUtil.checkArgument; + +/** + * Represents a Client's email in the address book. + * Guarantees: immutable; is valid as declared in {@link #isValidEmail(String)} + */ +public class Email { + + private static final String SPECIAL_CHARACTERS = "+_.-"; + public static final String MESSAGE_CONSTRAINTS = "Emails should be of the format local-part@domain " + + "and adhere to the following constraints:\n" + + "1. The local-part should only contain alphanumeric characters and these special characters, excluding " + + "the parentheses, (" + SPECIAL_CHARACTERS + "). The local-part may not start or end with any special " + + "characters.\n" + + "2. This is followed by a '@' and then a domain name. The domain name is made up of domain labels " + + "separated by periods.\n" + + "The domain name must:\n" + + " - end with a domain label at least 2 characters long\n" + + " - have each domain label start and end with alphanumeric characters\n" + + " - have each domain label consist of alphanumeric characters, separated only by hyphens, if any."; + // alphanumeric and special characters + private static final String ALPHANUMERIC_NO_UNDERSCORE = "[^\\W_]+"; // alphanumeric characters except underscore + private static final String LOCAL_PART_REGEX = "^" + ALPHANUMERIC_NO_UNDERSCORE + "([" + SPECIAL_CHARACTERS + "]" + + ALPHANUMERIC_NO_UNDERSCORE + ")*"; + private static final String DOMAIN_PART_REGEX = ALPHANUMERIC_NO_UNDERSCORE + + "(-" + ALPHANUMERIC_NO_UNDERSCORE + ")*"; + private static final String DOMAIN_LAST_PART_REGEX = "(" + DOMAIN_PART_REGEX + "){2,}$"; // At least two chars + private static final String DOMAIN_REGEX = "(" + DOMAIN_PART_REGEX + "\\.)*" + DOMAIN_LAST_PART_REGEX; + public static final String VALIDATION_REGEX = LOCAL_PART_REGEX + "@" + DOMAIN_REGEX; + + public final String value; + + /** + * Constructs an {@code Email}. + * + * @param email A valid email address. + */ + public Email(String email) { + requireNonNull(email); + checkArgument(isValidEmail(email), MESSAGE_CONSTRAINTS); + value = email; + } + + /** + * Returns if a given string is a valid email. + */ + public static boolean isValidEmail(String test) { + return test.matches(VALIDATION_REGEX); + } + + @Override + public String toString() { + return value; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof seedu.address.model.person.Email)) { + return false; + } + + seedu.address.model.person.Email otherEmail = (seedu.address.model.person.Email) other; + return value.equals(otherEmail.value); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + +} + diff --git a/src/main/java/seedu/address/model/client/Name.java b/src/main/java/seedu/address/model/client/Name.java new file mode 100644 index 00000000000..09e11a470d0 --- /dev/null +++ b/src/main/java/seedu/address/model/client/Name.java @@ -0,0 +1,67 @@ +package seedu.address.model.client; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.AppUtil.checkArgument; + +/** + * Represents a Client's name in the address book. + * Guarantees: immutable; is valid as declared in {@link #isValidName(String)} + */ +public class Name { + + public static final String MESSAGE_CONSTRAINTS = + "Names should only contain alphanumeric characters and spaces, 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 = "[\\p{Alnum}][\\p{Alnum} ]*"; + + public final String fullName; + + /** + * Constructs a {@code Name}. + * + * @param name A valid name. + */ + public Name(String name) { + requireNonNull(name); + checkArgument(isValidName(name), MESSAGE_CONSTRAINTS); + fullName = name; + } + + /** + * Returns true if a given string is a valid name. + */ + public static boolean isValidName(String test) { + return test.matches(VALIDATION_REGEX); + } + + + @Override + public String toString() { + return fullName; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof Name)) { + return false; + } + + Name otherName = (Name) other; + return fullName.equals(otherName.fullName); + } + + @Override + public int hashCode() { + return fullName.hashCode(); + } + +} diff --git a/src/main/java/seedu/address/model/client/Phone.java b/src/main/java/seedu/address/model/client/Phone.java new file mode 100644 index 00000000000..1cdb883112c --- /dev/null +++ b/src/main/java/seedu/address/model/client/Phone.java @@ -0,0 +1,61 @@ +package seedu.address.model.client; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.AppUtil.checkArgument; + +/** + * Represents a Client's phone number in the address book. + * Guarantees: immutable; is valid as declared in {@link #isValidPhone(String)} + */ +public class Phone { + + + public static final String MESSAGE_CONSTRAINTS = + "Phone numbers should only contain numbers, and it should be at least 3 digits long"; + public static final String VALIDATION_REGEX = "\\d{3,}"; + public final String value; + + /** + * Constructs a {@code Phone}. + * + * @param phone A valid phone number. + */ + public Phone(String phone) { + requireNonNull(phone); + checkArgument(isValidPhone(phone), MESSAGE_CONSTRAINTS); + value = phone; + } + + /** + * Returns true if a given string is a valid phone number. + */ + public static boolean isValidPhone(String test) { + return test.matches(VALIDATION_REGEX); + } + + @Override + public String toString() { + return value; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof seedu.address.model.client.Phone)) { + return false; + } + + seedu.address.model.client.Phone otherPhone = (seedu.address.model.client.Phone) other; + return value.equals(otherPhone.value); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + +} diff --git a/src/main/java/seedu/address/model/client/UniqueClientList.java b/src/main/java/seedu/address/model/client/UniqueClientList.java new file mode 100644 index 00000000000..ab3639c32b4 --- /dev/null +++ b/src/main/java/seedu/address/model/client/UniqueClientList.java @@ -0,0 +1,150 @@ +package seedu.address.model.client; + +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.client.exceptions.DuplicateClientException; +import seedu.address.model.client.exceptions.ClientNotFoundException; + +/** + * A list of clients that enforces uniqueness between its elements and does not allow nulls. + * A client is considered unique by comparing using {@code Client#isSameClient(Client)}. As such, adding and updating of + * clients uses Client#isSameClient(Client) for equality so as to ensure that the client being added or updated is + * unique in terms of identity in the UniqueClientList. However, the removal of a client uses Client#equals(Object) so + * as to ensure that the client with exactly the same fields will be removed. + * + * Supports a minimal set of list operations. + * + * @see Client#isSameClient(Client) + */ +public class UniqueClientList implements Iterable { + + private final ObservableList internalList = FXCollections.observableArrayList(); + private final ObservableList internalUnmodifiableList = + FXCollections.unmodifiableObservableList(internalList); + + /** + * Returns true if the list contains an equivalent client as the given argument. + */ + public boolean contains(Client toCheck) { + requireNonNull(toCheck); + return internalList.stream().anyMatch(toCheck::isSameClient); + } + + /** + * Adds a client to the list. + * The client must not already exist in the list. + */ + public void add(Client toAdd) { + requireNonNull(toAdd); + if (contains(toAdd)) { + throw new DuplicateClientException(); + } + internalList.add(toAdd); + } + + /** + * Replaces the client {@code target} in the list with {@code editedClient}. + * {@code target} must exist in the list. + * The client identity of {@code editedClient} must not be the same as another existing client in the list. + */ + public void setClient(Client target, Client editedClient) { + requireAllNonNull(target, editedClient); + + int index = internalList.indexOf(target); + if (index == -1) { + throw new ClientNotFoundException(); + } + + if (!target.isSameClient(editedClient) && contains(editedClient)) { + throw new DuplicateClientException(); + } + + internalList.set(index, editedClient); + } + + /** + * Removes the equivalent client from the list. + * The client must exist in the list. + */ + public void remove(Client toRemove) { + requireNonNull(toRemove); + if (!internalList.remove(toRemove)) { + throw new ClientNotFoundException(); + } + } + + public void setClients(UniqueClientList replacement) { + requireNonNull(replacement); + internalList.setAll(replacement.internalList); + } + + /** + * Replaces the contents of this list with {@code clients}. + * {@code clients} must not contain duplicate clients. + */ + public void setClients(List clients) { + requireAllNonNull(clients); + if (!clientsAreUnique(clients)) { + throw new DuplicateClientException(); + } + + internalList.setAll(clients); + } + + /** + * 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) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof UniqueClientList)) { + return false; + } + + UniqueClientList otherUniqueClientList = (UniqueClientList) other; + return internalList.equals(otherUniqueClientList.internalList); + } + + @Override + public int hashCode() { + return internalList.hashCode(); + } + + @Override + public String toString() { + return internalList.toString(); + } + + /** + * Returns true if {@code clients} contains only unique clients. + */ + private boolean clientsAreUnique(List clients) { + for (int i = 0; i < clients.size() - 1; i++) { + for (int j = i + 1; j < clients.size(); j++) { + if (clients.get(i).isSameClient(clients.get(j))) { + return false; + } + } + } + return true; + } +} diff --git a/src/main/java/seedu/address/model/client/exceptions/ClientNotFoundException.java b/src/main/java/seedu/address/model/client/exceptions/ClientNotFoundException.java new file mode 100644 index 00000000000..84f9ae2c085 --- /dev/null +++ b/src/main/java/seedu/address/model/client/exceptions/ClientNotFoundException.java @@ -0,0 +1,6 @@ +package seedu.address.model.client.exceptions; + +/** + * Signals that the operation is unable to find the specified client. + */ +public class ClientNotFoundException extends RuntimeException {} diff --git a/src/main/java/seedu/address/model/client/exceptions/DuplicateClientException.java b/src/main/java/seedu/address/model/client/exceptions/DuplicateClientException.java new file mode 100644 index 00000000000..802f83fbe15 --- /dev/null +++ b/src/main/java/seedu/address/model/client/exceptions/DuplicateClientException.java @@ -0,0 +1,11 @@ +package seedu.address.model.client.exceptions; + +/** + * Signals that the operation will result in duplicate Clients (Clients are considered duplicates if they have the same + * identity). + */ +public class DuplicateClientException extends RuntimeException { + public DuplicateClientException() { + super("Operation would result in duplicate clients"); + } +} \ No newline at end of file diff --git a/src/test/java/seedu/address/model/AddressBookTest.java b/src/test/java/seedu/address/model/AddressBookTest.java index 68c8c5ba4d5..c96f8b00ca8 100644 --- a/src/test/java/seedu/address/model/AddressBookTest.java +++ b/src/test/java/seedu/address/model/AddressBookTest.java @@ -18,6 +18,7 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; +import seedu.address.model.client.Client; import seedu.address.model.person.Person; import seedu.address.model.person.exceptions.DuplicatePersonException; import seedu.address.testutil.PersonBuilder; @@ -85,7 +86,8 @@ public void getPersonList_modifyList_throwsUnsupportedOperationException() { @Test public void toStringMethod() { - String expected = AddressBook.class.getCanonicalName() + "{persons=" + addressBook.getPersonList() + "}"; + String expected = AddressBook.class.getCanonicalName() + "{persons=" + addressBook.getPersonList() + + ", clients=" + addressBook.getClientList() + "}"; assertEquals(expected, addressBook.toString()); } @@ -94,6 +96,7 @@ public void toStringMethod() { */ private static class AddressBookStub implements ReadOnlyAddressBook { private final ObservableList persons = FXCollections.observableArrayList(); + private final ObservableList clients = FXCollections.observableArrayList(); AddressBookStub(Collection persons) { this.persons.setAll(persons); @@ -103,6 +106,11 @@ private static class AddressBookStub implements ReadOnlyAddressBook { public ObservableList getPersonList() { return persons; } + + @Override + public ObservableList getClientList() { + return clients; + } } } diff --git a/src/test/java/seedu/address/model/client/AddressTest.java b/src/test/java/seedu/address/model/client/AddressTest.java new file mode 100644 index 00000000000..9490850b18f --- /dev/null +++ b/src/test/java/seedu/address/model/client/AddressTest.java @@ -0,0 +1,56 @@ +package seedu.address.model.client; + +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 + } + + @Test + public void equals() { + Address address = new Address("Valid Address"); + + // same values -> returns true + assertTrue(address.equals(new Address("Valid Address"))); + + // same object -> returns true + assertTrue(address.equals(address)); + + // null -> returns false + assertFalse(address.equals(null)); + + // different types -> returns false + assertFalse(address.equals(5.0f)); + + // different values -> returns false + assertFalse(address.equals(new Address("Other Valid Address"))); + } +} \ No newline at end of file diff --git a/src/test/java/seedu/address/model/client/ClientTest.java b/src/test/java/seedu/address/model/client/ClientTest.java new file mode 100644 index 00000000000..6d77b354b85 --- /dev/null +++ b/src/test/java/seedu/address/model/client/ClientTest.java @@ -0,0 +1,88 @@ +package seedu.address.model.client; + +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_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.testutil.TypicalClients.ALICE; +import static seedu.address.testutil.TypicalClients.BOB; + +import org.junit.jupiter.api.Test; + +import seedu.address.testutil.ClientBuilder; + + +public class ClientTest { + + @Test + public void isSameClient() { + // same object -> returns true + assertTrue(ALICE.isSameClient(ALICE)); + + // null -> returns false + assertFalse(ALICE.isSameClient(null)); + + // same name, all other attributes different -> returns true + Client editedAlice = new ClientBuilder(ALICE).withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB) + .withAddress(VALID_ADDRESS_BOB).build(); + assertTrue(ALICE.isSameClient(editedAlice)); + + // different name, all other attributes same -> returns false + editedAlice = new ClientBuilder(ALICE).withName(VALID_NAME_BOB).build(); + assertFalse(ALICE.isSameClient(editedAlice)); + + // name differs in case, all other attributes same -> returns false + Client editedBob = new ClientBuilder(BOB).withName(VALID_NAME_BOB.toLowerCase()).build(); + assertFalse(BOB.isSameClient(editedBob)); + + // name has trailing spaces, all other attributes same -> returns false + String nameWithTrailingSpaces = VALID_NAME_BOB + " "; + editedBob = new ClientBuilder(BOB).withName(nameWithTrailingSpaces).build(); + assertFalse(BOB.isSameClient(editedBob)); + } + + @Test + public void equals() { + // same values -> returns true + Client aliceCopy = new ClientBuilder(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 Client -> returns false + assertFalse(ALICE.equals(BOB)); + + // different name -> returns false + Client editedAlice = new ClientBuilder(ALICE).withName(VALID_NAME_BOB).build(); + assertFalse(ALICE.equals(editedAlice)); + + // different phone -> returns false + editedAlice = new ClientBuilder(ALICE).withPhone(VALID_PHONE_BOB).build(); + assertFalse(ALICE.equals(editedAlice)); + + // different email -> returns false + editedAlice = new ClientBuilder(ALICE).withEmail(VALID_EMAIL_BOB).build(); + assertFalse(ALICE.equals(editedAlice)); + + // different address -> returns false + editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).build(); + assertFalse(ALICE.equals(editedAlice)); + } + + @Test + public void toStringMethod() { + String expected = Client.class.getCanonicalName() + "{name=" + ALICE.getName() + ", phone=" + ALICE.getPhone() + + ", email=" + ALICE.getEmail() + ", address=" + ALICE.getAddress() + "}"; + assertEquals(expected, ALICE.toString()); + } +} \ No newline at end of file diff --git a/src/test/java/seedu/address/model/client/EmailTest.java b/src/test/java/seedu/address/model/client/EmailTest.java new file mode 100644 index 00000000000..f5478983d43 --- /dev/null +++ b/src/test/java/seedu/address/model/client/EmailTest.java @@ -0,0 +1,89 @@ +package seedu.address.model.client; + +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 EmailTest { + + @Test + public void constructor_null_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> new Email(null)); + } + + @Test + public void constructor_invalidEmail_throwsIllegalArgumentException() { + String invalidEmail = ""; + assertThrows(IllegalArgumentException.class, () -> new Email(invalidEmail)); + } + + @Test + public void isValidEmail() { + // null email + assertThrows(NullPointerException.class, () -> Email.isValidEmail(null)); + + // blank email + assertFalse(Email.isValidEmail("")); // empty string + assertFalse(Email.isValidEmail(" ")); // spaces only + + // missing parts + assertFalse(Email.isValidEmail("@example.com")); // missing local part + assertFalse(Email.isValidEmail("peterjackexample.com")); // missing '@' symbol + assertFalse(Email.isValidEmail("peterjack@")); // missing domain name + + // invalid parts + assertFalse(Email.isValidEmail("peterjack@-")); // invalid domain name + assertFalse(Email.isValidEmail("peterjack@exam_ple.com")); // underscore in domain name + assertFalse(Email.isValidEmail("peter jack@example.com")); // spaces in local part + assertFalse(Email.isValidEmail("peterjack@exam ple.com")); // spaces in domain name + assertFalse(Email.isValidEmail(" peterjack@example.com")); // leading space + assertFalse(Email.isValidEmail("peterjack@example.com ")); // trailing space + assertFalse(Email.isValidEmail("peterjack@@example.com")); // double '@' symbol + assertFalse(Email.isValidEmail("peter@jack@example.com")); // '@' symbol in local part + assertFalse(Email.isValidEmail("-peterjack@example.com")); // local part starts with a hyphen + assertFalse(Email.isValidEmail("peterjack-@example.com")); // local part ends with a hyphen + assertFalse(Email.isValidEmail("peter..jack@example.com")); // local part has two consecutive periods + assertFalse(Email.isValidEmail("peterjack@example@com")); // '@' symbol in domain name + assertFalse(Email.isValidEmail("peterjack@.example.com")); // domain name starts with a period + assertFalse(Email.isValidEmail("peterjack@example.com.")); // domain name ends with a period + assertFalse(Email.isValidEmail("peterjack@-example.com")); // domain name starts with a hyphen + assertFalse(Email.isValidEmail("peterjack@example.com-")); // domain name ends with a hyphen + assertFalse(Email.isValidEmail("peterjack@example.c")); // top level domain has less than two chars + + // valid email + assertTrue(Email.isValidEmail("PeterJack_1190@example.com")); // underscore in local part + assertTrue(Email.isValidEmail("PeterJack.1190@example.com")); // period in local part + assertTrue(Email.isValidEmail("PeterJack+1190@example.com")); // '+' symbol in local part + assertTrue(Email.isValidEmail("PeterJack-1190@example.com")); // hyphen in local part + assertTrue(Email.isValidEmail("a@bc")); // minimal + assertTrue(Email.isValidEmail("test@localhost")); // alphabets only + assertTrue(Email.isValidEmail("123@145")); // numeric local part and domain name + assertTrue(Email.isValidEmail("a1+be.d@example1.com")); // mixture of alphanumeric and special characters + assertTrue(Email.isValidEmail("peter_jack@very-very-very-long-example.com")); // long domain name + assertTrue(Email.isValidEmail("if.you.dream.it_you.can.do.it@example.com")); // long local part + assertTrue(Email.isValidEmail("e1234567@u.nus.edu")); // more than one period in domain + } + + @Test + public void equals() { + Email email = new Email("valid@email"); + + // same values -> returns true + assertTrue(email.equals(new Email("valid@email"))); + + // same object -> returns true + assertTrue(email.equals(email)); + + // null -> returns false + assertFalse(email.equals(null)); + + // different types -> returns false + assertFalse(email.equals(5.0f)); + + // different values -> returns false + assertFalse(email.equals(new Email("other.valid@email"))); + } +} diff --git a/src/test/java/seedu/address/model/client/NameTest.java b/src/test/java/seedu/address/model/client/NameTest.java new file mode 100644 index 00000000000..95603a076a3 --- /dev/null +++ b/src/test/java/seedu/address/model/client/NameTest.java @@ -0,0 +1,60 @@ +package seedu.address.model.client; + +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 NameTest { + + @Test + public void constructor_null_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> new Name(null)); + } + + @Test + public void constructor_invalidName_throwsIllegalArgumentException() { + String invalidName = ""; + assertThrows(IllegalArgumentException.class, () -> new Name(invalidName)); + } + + @Test + public void isValidName() { + // null name + assertThrows(NullPointerException.class, () -> Name.isValidName(null)); + + // invalid name + assertFalse(Name.isValidName("")); // empty string + assertFalse(Name.isValidName(" ")); // spaces only + assertFalse(Name.isValidName("^")); // only non-alphanumeric characters + assertFalse(Name.isValidName("peter*")); // contains non-alphanumeric characters + + // valid name + assertTrue(Name.isValidName("peter jack")); // alphabets only + assertTrue(Name.isValidName("12345")); // numbers only + assertTrue(Name.isValidName("peter the 2nd")); // alphanumeric characters + assertTrue(Name.isValidName("Capital Tan")); // with capital letters + assertTrue(Name.isValidName("David Roger Jackson Ray Jr 2nd")); // long names + } + + @Test + public void equals() { + Name name = new Name("Valid Name"); + + // same values -> returns true + assertTrue(name.equals(new Name("Valid Name"))); + + // same object -> returns true + assertTrue(name.equals(name)); + + // null -> returns false + assertFalse(name.equals(null)); + + // different types -> returns false + assertFalse(name.equals(5.0f)); + + // different values -> returns false + assertFalse(name.equals(new Name("Other Valid Name"))); + } +} diff --git a/src/test/java/seedu/address/model/client/PhoneTest.java b/src/test/java/seedu/address/model/client/PhoneTest.java new file mode 100644 index 00000000000..45ce56b1bae --- /dev/null +++ b/src/test/java/seedu/address/model/client/PhoneTest.java @@ -0,0 +1,61 @@ +package seedu.address.model.client; + +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 PhoneTest { + + @Test + public void constructor_null_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> new Phone(null)); + } + + @Test + public void constructor_invalidPhone_throwsIllegalArgumentException() { + String invalidPhone = ""; + assertThrows(IllegalArgumentException.class, () -> new Phone(invalidPhone)); + } + + @Test + public void isValidPhone() { + // null phone number + assertThrows(NullPointerException.class, () -> Phone.isValidPhone(null)); + + // invalid phone numbers + assertFalse(Phone.isValidPhone("")); // empty string + assertFalse(Phone.isValidPhone(" ")); // spaces only + assertFalse(Phone.isValidPhone("91")); // less than 3 numbers + assertFalse(Phone.isValidPhone("phone")); // non-numeric + assertFalse(Phone.isValidPhone("9011p041")); // alphabets within digits + assertFalse(Phone.isValidPhone("9312 1534")); // spaces within digits + assertFalse(Phone.isValidPhone("+198765432")); // with country code + // valid phone numbers + assertTrue(Phone.isValidPhone("911")); // exactly 3 numbers + assertTrue(Phone.isValidPhone("93121534")); + assertTrue(Phone.isValidPhone("124293842033123")); // long phone numbers + } + + @Test + public void equals() { + Phone phone = new Phone("999"); + + // same values -> returns true + assertTrue(phone.equals(new Phone("999"))); + + // same object -> returns true + assertTrue(phone.equals(phone)); + + // null -> returns false + assertFalse(phone.equals(null)); + + // different types -> returns false + assertFalse(phone.equals(5.0f)); + + // different values -> returns false + assertFalse(phone.equals(new Phone("995"))); + } +} \ No newline at end of file diff --git a/src/test/java/seedu/address/model/client/UniqueClientListTest.java b/src/test/java/seedu/address/model/client/UniqueClientListTest.java new file mode 100644 index 00000000000..5298b85f607 --- /dev/null +++ b/src/test/java/seedu/address/model/client/UniqueClientListTest.java @@ -0,0 +1,172 @@ +package seedu.address.model.client; + +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.testutil.Assert.assertThrows; +import static seedu.address.testutil.TypicalClients.ALICE; +import static seedu.address.testutil.TypicalClients.BOB; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import seedu.address.model.client.exceptions.DuplicateClientException; +import seedu.address.model.client.exceptions.ClientNotFoundException; +import seedu.address.testutil.ClientBuilder; + +public class UniqueClientListTest { + + private final UniqueClientList uniqueClientList = new UniqueClientList(); + + @Test + public void contains_nullPerson_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> uniqueClientList.contains(null)); + } + + @Test + public void contains_personNotInList_returnsFalse() { + assertFalse(uniqueClientList.contains(ALICE)); + } + + @Test + public void contains_personInList_returnsTrue() { + uniqueClientList.add(ALICE); + assertTrue(uniqueClientList.contains(ALICE)); + } + + @Test + public void contains_personWithSameIdentityFieldsInList_returnsTrue() { + uniqueClientList.add(ALICE); + Client editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).build(); + assertTrue(uniqueClientList.contains(editedAlice)); + } + + @Test + public void add_nullPerson_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> uniqueClientList.add(null)); + } + + @Test + public void add_duplicatePerson_throwsDuplicatePersonException() { + uniqueClientList.add(ALICE); + assertThrows(DuplicateClientException.class, () -> uniqueClientList.add(ALICE)); + } + + @Test + public void setPerson_nullTargetPerson_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> uniqueClientList.setClient(null, ALICE)); + } + + @Test + public void setPerson_nullEditedPerson_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> uniqueClientList.setClient(ALICE, null)); + } + + @Test + public void setPerson_targetPersonNotInList_throwsPersonNotFoundException() { + assertThrows(ClientNotFoundException.class, () -> uniqueClientList.setClient(ALICE, ALICE)); + } + + @Test + public void setPerson_editedPersonIsSamePerson_success() { + uniqueClientList.add(ALICE); + uniqueClientList.setClient(ALICE, ALICE); + UniqueClientList expectedUniquePersonList = new UniqueClientList(); + expectedUniquePersonList.add(ALICE); + assertEquals(expectedUniquePersonList, uniqueClientList); + } + + @Test + public void setPerson_editedPersonHasSameIdentity_success() { + uniqueClientList.add(ALICE); + Client editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).build(); + uniqueClientList.setClient(ALICE, editedAlice); + UniqueClientList expectedUniquePersonList = new UniqueClientList(); + expectedUniquePersonList.add(editedAlice); + assertEquals(expectedUniquePersonList, uniqueClientList); + } + + @Test + public void setPerson_editedPersonHasDifferentIdentity_success() { + uniqueClientList.add(ALICE); + uniqueClientList.setClient(ALICE, BOB); + UniqueClientList expectedUniquePersonList = new UniqueClientList(); + expectedUniquePersonList.add(BOB); + assertEquals(expectedUniquePersonList, uniqueClientList); + } + + @Test + public void setPerson_editedPersonHasNonUniqueIdentity_throwsDuplicatePersonException() { + uniqueClientList.add(ALICE); + uniqueClientList.add(BOB); + assertThrows(DuplicateClientException.class, () -> uniqueClientList.setClient(ALICE, BOB)); + } + + @Test + public void remove_nullPerson_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> uniqueClientList.remove(null)); + } + + @Test + public void remove_personDoesNotExist_throwsPersonNotFoundException() { + assertThrows(ClientNotFoundException.class, () -> uniqueClientList.remove(ALICE)); + } + + @Test + public void remove_existingPerson_removesPerson() { + uniqueClientList.add(ALICE); + uniqueClientList.remove(ALICE); + UniqueClientList expectedUniquePersonList = new UniqueClientList(); + assertEquals(expectedUniquePersonList, uniqueClientList); + } + + @Test + public void setPersons_nullUniquePersonList_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> uniqueClientList.setClients((UniqueClientList) null)); + } + + @Test + public void setPersons_uniquePersonList_replacesOwnListWithProvidedUniquePersonList() { + uniqueClientList.add(ALICE); + UniqueClientList expectedUniquePersonList = new UniqueClientList(); + expectedUniquePersonList.add(BOB); + uniqueClientList.setClients(expectedUniquePersonList); + assertEquals(expectedUniquePersonList, uniqueClientList); + } + + @Test + public void setPersons_nullList_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> uniqueClientList.setClients((List) null)); + } + + @Test + public void setPersons_list_replacesOwnListWithProvidedList() { + uniqueClientList.add(ALICE); + List personList = Collections.singletonList(BOB); + uniqueClientList.setClients(personList); + UniqueClientList expectedUniquePersonList = new UniqueClientList(); + expectedUniquePersonList.add(BOB); + assertEquals(expectedUniquePersonList, uniqueClientList); + } + + @Test + public void setPersons_listWithDuplicatePersons_throwsDuplicatePersonException() { + List listWithDuplicatePersons = Arrays.asList(ALICE, ALICE); + assertThrows(DuplicateClientException.class, () -> uniqueClientList.setClients(listWithDuplicatePersons)); + } + + @Test + public void asUnmodifiableObservableList_modifyList_throwsUnsupportedOperationException() { + assertThrows(UnsupportedOperationException.class, () + -> uniqueClientList.asUnmodifiableObservableList().remove(0)); + } + + @Test + public void toStringMethod() { + assertEquals(uniqueClientList.asUnmodifiableObservableList().toString(), uniqueClientList.toString()); + } +} \ No newline at end of file diff --git a/src/test/java/seedu/address/testutil/ClientBuilder.java b/src/test/java/seedu/address/testutil/ClientBuilder.java new file mode 100644 index 00000000000..fa6a77cf48c --- /dev/null +++ b/src/test/java/seedu/address/testutil/ClientBuilder.java @@ -0,0 +1,80 @@ +package seedu.address.testutil; + +import seedu.address.model.client.Address; +import seedu.address.model.client.Email; +import seedu.address.model.client.Name; +import seedu.address.model.client.Client; +import seedu.address.model.client.Phone; + +/** + * A utility class to help with building Client objects. + */ +public class ClientBuilder { + + public static final String DEFAULT_NAME = "Amy Bee"; + public static final String DEFAULT_PHONE = "85355255"; + public static final String DEFAULT_EMAIL = "amy@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; + + /** + * Creates a {@code ClientBuilder} with the default details. + */ + public ClientBuilder() { + name = new Name(DEFAULT_NAME); + phone = new Phone(DEFAULT_PHONE); + email = new Email(DEFAULT_EMAIL); + address = new Address(DEFAULT_ADDRESS); + } + + /** + * Initializes the PersonBuilder with the data of {@code personToCopy}. + */ + public ClientBuilder(Client personToCopy) { + name = personToCopy.getName(); + phone = personToCopy.getPhone(); + email = personToCopy.getEmail(); + address = personToCopy.getAddress(); + } + + /** + * Sets the {@code Name} of the {@code Client} that we are building. + */ + public ClientBuilder withName(String name) { + this.name = new Name(name); + return this; + } + + /** + * Sets the {@code Address} of the {@code Client} that we are building. + */ + public ClientBuilder withAddress(String address) { + this.address = new Address(address); + return this; + } + + /** + * Sets the {@code Phone} of the {@code Client} that we are building. + */ + public ClientBuilder withPhone(String phone) { + this.phone = new Phone(phone); + return this; + } + + /** + * Sets the {@code Email} of the {@code Client} that we are building. + */ + public ClientBuilder withEmail(String email) { + this.email = new Email(email); + return this; + } + + public Client build() { + return new Client(name, phone, email, address); + } + +} \ No newline at end of file diff --git a/src/test/java/seedu/address/testutil/TypicalClients.java b/src/test/java/seedu/address/testutil/TypicalClients.java new file mode 100644 index 00000000000..c836081fc52 --- /dev/null +++ b/src/test/java/seedu/address/testutil/TypicalClients.java @@ -0,0 +1,72 @@ +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 java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import seedu.address.model.AddressBook; +import seedu.address.model.client.Client; + +/** + * A utility class containing a list of {@code Client} objects to be used in tests. + */ +public class TypicalClients { + + public static final Client ALICE = new ClientBuilder().withName("Alice Pauline") + .withAddress("123, Jurong West Ave 6, #08-111").withEmail("alice@example.com") + .withPhone("94351253").build(); + public static final Client BENSON = new ClientBuilder().withName("Benson Meier") + .withAddress("311, Clementi Ave 2, #02-25") + .withEmail("johnd@example.com").withPhone("98765432").build(); + public static final Client CARL = new ClientBuilder().withName("Carl Kurz").withPhone("95352563") + .withEmail("heinz@example.com").withAddress("wall street").build(); + public static final Client DANIEL = new ClientBuilder().withName("Daniel Meier").withPhone("87652533") + .withEmail("cornelia@example.com").withAddress("10th street").build(); + public static final Client ELLE = new ClientBuilder().withName("Elle Meyer").withPhone("9482224") + .withEmail("werner@example.com").withAddress("michegan ave").build(); + public static final Client FIONA = new ClientBuilder().withName("Fiona Kunz").withPhone("9482427") + .withEmail("lydia@example.com").withAddress("little tokyo").build(); + public static final Client GEORGE = new ClientBuilder().withName("George Best").withPhone("9482442") + .withEmail("anna@example.com").withAddress("4th street").build(); + + // Manually added + public static final Client HOON = new ClientBuilder().withName("Hoon Meier").withPhone("8482424") + .withEmail("stefan@example.com").withAddress("little india").build(); + public static final Client IDA = new ClientBuilder().withName("Ida Mueller").withPhone("8482131") + .withEmail("hans@example.com").withAddress("chicago ave").build(); + + // Manually added - Client's details found in {@code CommandTestUtil} + public static final Client AMY = new ClientBuilder().withName(VALID_NAME_AMY).withPhone(VALID_PHONE_AMY) + .withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY).build(); + public static final Client BOB = new ClientBuilder().withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB) + .withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB).build(); + + public static final String KEYWORD_MATCHING_MEIER = "Meier"; // A keyword that matches MEIER + + private TypicalClients() { + } // prevents instantiation + + /** + * Returns an {@code AddressBook} with all the typical persons. + */ + public static AddressBook getTypicalAddressBook() { + AddressBook ab = new AddressBook(); + for (Client client : getTypicalClients()) { + ab.addClient(client); + } + return ab; + } + + public static List getTypicalClients() { + return new ArrayList<>(Arrays.asList(ALICE, BENSON, CARL, DANIEL, ELLE, FIONA, GEORGE)); + } +} \ No newline at end of file From c2806fd848c1d62a3b8c118a3b3e46ce3a26c7ba Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Tue, 18 Mar 2025 00:50:27 +0800 Subject: [PATCH 046/249] Make minor edits --- .../seedu/address/model/client/Email.java | 4 +- .../model/client/UniqueClientListTest.java | 86 +++++++++---------- .../seedu/address/testutil/ClientBuilder.java | 12 +-- .../address/testutil/TypicalClients.java | 2 +- 4 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/main/java/seedu/address/model/client/Email.java b/src/main/java/seedu/address/model/client/Email.java index 80cb480fe83..9ea195364f9 100644 --- a/src/main/java/seedu/address/model/client/Email.java +++ b/src/main/java/seedu/address/model/client/Email.java @@ -63,11 +63,11 @@ public boolean equals(Object other) { } // instanceof handles nulls - if (!(other instanceof seedu.address.model.person.Email)) { + if (!(other instanceof seedu.address.model.client.Email)) { return false; } - seedu.address.model.person.Email otherEmail = (seedu.address.model.person.Email) other; + seedu.address.model.client.Email otherEmail = (seedu.address.model.client.Email) other; return value.equals(otherEmail.value); } diff --git a/src/test/java/seedu/address/model/client/UniqueClientListTest.java b/src/test/java/seedu/address/model/client/UniqueClientListTest.java index 5298b85f607..73155f9cf3f 100644 --- a/src/test/java/seedu/address/model/client/UniqueClientListTest.java +++ b/src/test/java/seedu/address/model/client/UniqueClientListTest.java @@ -23,140 +23,140 @@ public class UniqueClientListTest { private final UniqueClientList uniqueClientList = new UniqueClientList(); @Test - public void contains_nullPerson_throwsNullPointerException() { + public void contains_nullClient_throwsNullPointerException() { assertThrows(NullPointerException.class, () -> uniqueClientList.contains(null)); } @Test - public void contains_personNotInList_returnsFalse() { + public void contains_clientNotInList_returnsFalse() { assertFalse(uniqueClientList.contains(ALICE)); } @Test - public void contains_personInList_returnsTrue() { + public void contains_clientInList_returnsTrue() { uniqueClientList.add(ALICE); assertTrue(uniqueClientList.contains(ALICE)); } @Test - public void contains_personWithSameIdentityFieldsInList_returnsTrue() { + public void contains_clientWithSameIdentityFieldsInList_returnsTrue() { uniqueClientList.add(ALICE); Client editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).build(); assertTrue(uniqueClientList.contains(editedAlice)); } @Test - public void add_nullPerson_throwsNullPointerException() { + public void add_nullClient_throwsNullPointerException() { assertThrows(NullPointerException.class, () -> uniqueClientList.add(null)); } @Test - public void add_duplicatePerson_throwsDuplicatePersonException() { + public void add_duplicateClient_throwsDuplicateClientException() { uniqueClientList.add(ALICE); assertThrows(DuplicateClientException.class, () -> uniqueClientList.add(ALICE)); } @Test - public void setPerson_nullTargetPerson_throwsNullPointerException() { + public void setClient_nullTargetClient_throwsNullPointerException() { assertThrows(NullPointerException.class, () -> uniqueClientList.setClient(null, ALICE)); } @Test - public void setPerson_nullEditedPerson_throwsNullPointerException() { + public void setClient_nullEditedClient_throwsNullPointerException() { assertThrows(NullPointerException.class, () -> uniqueClientList.setClient(ALICE, null)); } @Test - public void setPerson_targetPersonNotInList_throwsPersonNotFoundException() { + public void setClient_targetClientNotInList_throwsClientNotFoundException() { assertThrows(ClientNotFoundException.class, () -> uniqueClientList.setClient(ALICE, ALICE)); } @Test - public void setPerson_editedPersonIsSamePerson_success() { + public void setClient_editedClientIsSameClient_success() { uniqueClientList.add(ALICE); uniqueClientList.setClient(ALICE, ALICE); - UniqueClientList expectedUniquePersonList = new UniqueClientList(); - expectedUniquePersonList.add(ALICE); - assertEquals(expectedUniquePersonList, uniqueClientList); + UniqueClientList expectedUniqueClientList = new UniqueClientList(); + expectedUniqueClientList.add(ALICE); + assertEquals(expectedUniqueClientList, uniqueClientList); } @Test - public void setPerson_editedPersonHasSameIdentity_success() { + public void setClient_editedClientHasSameIdentity_success() { uniqueClientList.add(ALICE); Client editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).build(); uniqueClientList.setClient(ALICE, editedAlice); - UniqueClientList expectedUniquePersonList = new UniqueClientList(); - expectedUniquePersonList.add(editedAlice); - assertEquals(expectedUniquePersonList, uniqueClientList); + UniqueClientList expectedUniqueClientList = new UniqueClientList(); + expectedUniqueClientList.add(editedAlice); + assertEquals(expectedUniqueClientList, uniqueClientList); } @Test - public void setPerson_editedPersonHasDifferentIdentity_success() { + public void setClient_editedClientHasDifferentIdentity_success() { uniqueClientList.add(ALICE); uniqueClientList.setClient(ALICE, BOB); - UniqueClientList expectedUniquePersonList = new UniqueClientList(); - expectedUniquePersonList.add(BOB); - assertEquals(expectedUniquePersonList, uniqueClientList); + UniqueClientList expectedUniqueClientList = new UniqueClientList(); + expectedUniqueClientList.add(BOB); + assertEquals(expectedUniqueClientList, uniqueClientList); } @Test - public void setPerson_editedPersonHasNonUniqueIdentity_throwsDuplicatePersonException() { + public void setClient_editedClientHasNonUniqueIdentity_throwsDuplicateClientException() { uniqueClientList.add(ALICE); uniqueClientList.add(BOB); assertThrows(DuplicateClientException.class, () -> uniqueClientList.setClient(ALICE, BOB)); } @Test - public void remove_nullPerson_throwsNullPointerException() { + public void remove_nullClient_throwsNullPointerException() { assertThrows(NullPointerException.class, () -> uniqueClientList.remove(null)); } @Test - public void remove_personDoesNotExist_throwsPersonNotFoundException() { + public void remove_clientDoesNotExist_throwsClientNotFoundException() { assertThrows(ClientNotFoundException.class, () -> uniqueClientList.remove(ALICE)); } @Test - public void remove_existingPerson_removesPerson() { + public void remove_existingClient_removesClient() { uniqueClientList.add(ALICE); uniqueClientList.remove(ALICE); - UniqueClientList expectedUniquePersonList = new UniqueClientList(); - assertEquals(expectedUniquePersonList, uniqueClientList); + UniqueClientList expectedUniqueClientList = new UniqueClientList(); + assertEquals(expectedUniqueClientList, uniqueClientList); } @Test - public void setPersons_nullUniquePersonList_throwsNullPointerException() { + public void setClients_nullUniqueClientList_throwsNullPointerException() { assertThrows(NullPointerException.class, () -> uniqueClientList.setClients((UniqueClientList) null)); } @Test - public void setPersons_uniquePersonList_replacesOwnListWithProvidedUniquePersonList() { + public void setClients_uniqueClientList_replacesOwnListWithProvidedUniqueClientList() { uniqueClientList.add(ALICE); - UniqueClientList expectedUniquePersonList = new UniqueClientList(); - expectedUniquePersonList.add(BOB); - uniqueClientList.setClients(expectedUniquePersonList); - assertEquals(expectedUniquePersonList, uniqueClientList); + UniqueClientList expectedUniqueClientList = new UniqueClientList(); + expectedUniqueClientList.add(BOB); + uniqueClientList.setClients(expectedUniqueClientList); + assertEquals(expectedUniqueClientList, uniqueClientList); } @Test - public void setPersons_nullList_throwsNullPointerException() { + public void setClients_nullList_throwsNullPointerException() { assertThrows(NullPointerException.class, () -> uniqueClientList.setClients((List) null)); } @Test - public void setPersons_list_replacesOwnListWithProvidedList() { + public void setClients_list_replacesOwnListWithProvidedList() { uniqueClientList.add(ALICE); - List personList = Collections.singletonList(BOB); - uniqueClientList.setClients(personList); - UniqueClientList expectedUniquePersonList = new UniqueClientList(); - expectedUniquePersonList.add(BOB); - assertEquals(expectedUniquePersonList, uniqueClientList); + List clientList = Collections.singletonList(BOB); + uniqueClientList.setClients(clientList); + UniqueClientList expectedUniqueClientList = new UniqueClientList(); + expectedUniqueClientList.add(BOB); + assertEquals(expectedUniqueClientList, uniqueClientList); } @Test - public void setPersons_listWithDuplicatePersons_throwsDuplicatePersonException() { - List listWithDuplicatePersons = Arrays.asList(ALICE, ALICE); - assertThrows(DuplicateClientException.class, () -> uniqueClientList.setClients(listWithDuplicatePersons)); + public void setClients_listWithDuplicateClients_throwsDuplicateClientException() { + List listWithDuplicateClients = Arrays.asList(ALICE, ALICE); + assertThrows(DuplicateClientException.class, () -> uniqueClientList.setClients(listWithDuplicateClients)); } @Test diff --git a/src/test/java/seedu/address/testutil/ClientBuilder.java b/src/test/java/seedu/address/testutil/ClientBuilder.java index fa6a77cf48c..0e8a86ff273 100644 --- a/src/test/java/seedu/address/testutil/ClientBuilder.java +++ b/src/test/java/seedu/address/testutil/ClientBuilder.java @@ -32,13 +32,13 @@ public ClientBuilder() { } /** - * Initializes the PersonBuilder with the data of {@code personToCopy}. + * Initializes the ClientBuilder with the data of {@code clientToCopy}. */ - public ClientBuilder(Client personToCopy) { - name = personToCopy.getName(); - phone = personToCopy.getPhone(); - email = personToCopy.getEmail(); - address = personToCopy.getAddress(); + public ClientBuilder(Client clientToCopy) { + name = clientToCopy.getName(); + phone = clientToCopy.getPhone(); + email = clientToCopy.getEmail(); + address = clientToCopy.getAddress(); } /** diff --git a/src/test/java/seedu/address/testutil/TypicalClients.java b/src/test/java/seedu/address/testutil/TypicalClients.java index c836081fc52..82f01ce7b05 100644 --- a/src/test/java/seedu/address/testutil/TypicalClients.java +++ b/src/test/java/seedu/address/testutil/TypicalClients.java @@ -56,7 +56,7 @@ private TypicalClients() { } // prevents instantiation /** - * Returns an {@code AddressBook} with all the typical persons. + * Returns an {@code AddressBook} with all the typical clients. */ public static AddressBook getTypicalAddressBook() { AddressBook ab = new AddressBook(); From dffacfecffb38e6fea8e08339d366c851f452f76 Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Tue, 18 Mar 2025 18:58:06 +0800 Subject: [PATCH 047/249] Add checkstyle edits --- build.gradle | 4 +- .../java/seedu/address/model/AddressBook.java | 52 ++++++++++++++++++- .../model/client/UniqueClientList.java | 3 +- .../exceptions/DuplicateClientException.java | 2 +- .../address/model/client/AddressTest.java | 2 +- .../address/model/client/ClientTest.java | 3 +- .../seedu/address/model/client/NameTest.java | 1 + .../seedu/address/model/client/PhoneTest.java | 2 +- .../model/client/UniqueClientListTest.java | 4 +- .../seedu/address/testutil/ClientBuilder.java | 4 +- .../address/testutil/TypicalClients.java | 2 +- 11 files changed, 65 insertions(+), 14 deletions(-) diff --git a/build.gradle b/build.gradle index 0db3743584e..6b182d845af 100644 --- a/build.gradle +++ b/build.gradle @@ -8,8 +8,8 @@ plugins { mainClassName = 'seedu.address.Main' -sourceCompatibility = JavaVersion.VERSION_17 -targetCompatibility = JavaVersion.VERSION_17 +//sourceCompatibility = JavaVersion.VERSION_17 +//targetCompatibility = JavaVersion.VERSION_17 repositories { mavenCentral() diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index a4ca8bbc9a9..e1112253a9c 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -103,26 +103,53 @@ public void removePerson(Person key) { } //// client-level operations + /** + * Checks if the address book contains a specific client. + * + * @param client The client to check for. + * @return True if the client exists in the address book, false otherwise. + * @throws NullPointerException if the provided client is null. + */ public boolean hasClient(Client client) { requireNonNull(client); return clients.contains(client); } + /** + * Adds a client to the address book. + * + * @param c The client to be added. + */ public void addClient(Client c) { clients.add(c); } + /** + * Replaces an existing client with an edited client. + * + * @param target The client to be replaced. + * @param editedClient The new client to replace the existing one. + * @throws NullPointerException if the edited client is null. + */ public void setClient(Client target, Client editedClient) { requireNonNull(editedClient); clients.setClient(target, editedClient); } + /** + * Removes a client from the address book. + * + * @param key The client to be removed. + */ public void removeClient(Client key) { clients.remove(key); } - //// util methods - + /** + * Returns a string representation of the address book. + * + * @return A string containing details of persons and clients. + */ @Override public String toString() { return new ToStringBuilder(this) @@ -131,16 +158,32 @@ public String toString() { .toString(); } + /** + * Retrieves an unmodifiable list of persons in the address book. + * + * @return An observable list of persons. + */ @Override public ObservableList getPersonList() { return persons.asUnmodifiableObservableList(); } + /** + * Retrieves an unmodifiable list of clients in the address book. + * + * @return An observable list of clients. + */ @Override public ObservableList getClientList() { return clients.asUnmodifiableObservableList(); } + /** + * Compares this address book to another object for equality. + * + * @param other The object to compare with. + * @return True if the other object is an AddressBook with the same data, false otherwise. + */ @Override public boolean equals(Object other) { if (other == this) { @@ -156,6 +199,11 @@ public boolean equals(Object other) { return persons.equals(otherAddressBook.persons) && clients.equals(otherAddressBook.clients); } + /** + * Computes the hash code for the address book. + * + * @return The hash code based on persons and clients. + */ @Override public int hashCode() { return persons.hashCode(); diff --git a/src/main/java/seedu/address/model/client/UniqueClientList.java b/src/main/java/seedu/address/model/client/UniqueClientList.java index ab3639c32b4..8b89dac3ec6 100644 --- a/src/main/java/seedu/address/model/client/UniqueClientList.java +++ b/src/main/java/seedu/address/model/client/UniqueClientList.java @@ -8,8 +8,9 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import seedu.address.model.client.exceptions.DuplicateClientException; import seedu.address.model.client.exceptions.ClientNotFoundException; +import seedu.address.model.client.exceptions.DuplicateClientException; + /** * A list of clients that enforces uniqueness between its elements and does not allow nulls. diff --git a/src/main/java/seedu/address/model/client/exceptions/DuplicateClientException.java b/src/main/java/seedu/address/model/client/exceptions/DuplicateClientException.java index 802f83fbe15..ef4e36ea4aa 100644 --- a/src/main/java/seedu/address/model/client/exceptions/DuplicateClientException.java +++ b/src/main/java/seedu/address/model/client/exceptions/DuplicateClientException.java @@ -8,4 +8,4 @@ public class DuplicateClientException extends RuntimeException { public DuplicateClientException() { super("Operation would result in duplicate clients"); } -} \ No newline at end of file +} diff --git a/src/test/java/seedu/address/model/client/AddressTest.java b/src/test/java/seedu/address/model/client/AddressTest.java index 9490850b18f..eaafabb803c 100644 --- a/src/test/java/seedu/address/model/client/AddressTest.java +++ b/src/test/java/seedu/address/model/client/AddressTest.java @@ -53,4 +53,4 @@ public void equals() { // different values -> returns false assertFalse(address.equals(new Address("Other Valid Address"))); } -} \ No newline at end of file +} diff --git a/src/test/java/seedu/address/model/client/ClientTest.java b/src/test/java/seedu/address/model/client/ClientTest.java index 6d77b354b85..e8175be422a 100644 --- a/src/test/java/seedu/address/model/client/ClientTest.java +++ b/src/test/java/seedu/address/model/client/ClientTest.java @@ -85,4 +85,5 @@ public void toStringMethod() { + ", email=" + ALICE.getEmail() + ", address=" + ALICE.getAddress() + "}"; assertEquals(expected, ALICE.toString()); } -} \ No newline at end of file +} + diff --git a/src/test/java/seedu/address/model/client/NameTest.java b/src/test/java/seedu/address/model/client/NameTest.java index 95603a076a3..8fc8c27c835 100644 --- a/src/test/java/seedu/address/model/client/NameTest.java +++ b/src/test/java/seedu/address/model/client/NameTest.java @@ -58,3 +58,4 @@ public void equals() { assertFalse(name.equals(new Name("Other Valid Name"))); } } + diff --git a/src/test/java/seedu/address/model/client/PhoneTest.java b/src/test/java/seedu/address/model/client/PhoneTest.java index 45ce56b1bae..f27c4a9a6cb 100644 --- a/src/test/java/seedu/address/model/client/PhoneTest.java +++ b/src/test/java/seedu/address/model/client/PhoneTest.java @@ -58,4 +58,4 @@ public void equals() { // different values -> returns false assertFalse(phone.equals(new Phone("995"))); } -} \ No newline at end of file +} diff --git a/src/test/java/seedu/address/model/client/UniqueClientListTest.java b/src/test/java/seedu/address/model/client/UniqueClientListTest.java index 73155f9cf3f..997666f54ac 100644 --- a/src/test/java/seedu/address/model/client/UniqueClientListTest.java +++ b/src/test/java/seedu/address/model/client/UniqueClientListTest.java @@ -14,8 +14,8 @@ import org.junit.jupiter.api.Test; -import seedu.address.model.client.exceptions.DuplicateClientException; import seedu.address.model.client.exceptions.ClientNotFoundException; +import seedu.address.model.client.exceptions.DuplicateClientException; import seedu.address.testutil.ClientBuilder; public class UniqueClientListTest { @@ -169,4 +169,4 @@ public void asUnmodifiableObservableList_modifyList_throwsUnsupportedOperationEx public void toStringMethod() { assertEquals(uniqueClientList.asUnmodifiableObservableList().toString(), uniqueClientList.toString()); } -} \ No newline at end of file +} diff --git a/src/test/java/seedu/address/testutil/ClientBuilder.java b/src/test/java/seedu/address/testutil/ClientBuilder.java index 0e8a86ff273..2f317032934 100644 --- a/src/test/java/seedu/address/testutil/ClientBuilder.java +++ b/src/test/java/seedu/address/testutil/ClientBuilder.java @@ -1,9 +1,9 @@ package seedu.address.testutil; import seedu.address.model.client.Address; +import seedu.address.model.client.Client; import seedu.address.model.client.Email; import seedu.address.model.client.Name; -import seedu.address.model.client.Client; import seedu.address.model.client.Phone; /** @@ -77,4 +77,4 @@ public Client build() { return new Client(name, phone, email, address); } -} \ No newline at end of file +} diff --git a/src/test/java/seedu/address/testutil/TypicalClients.java b/src/test/java/seedu/address/testutil/TypicalClients.java index 82f01ce7b05..9c8e0a53579 100644 --- a/src/test/java/seedu/address/testutil/TypicalClients.java +++ b/src/test/java/seedu/address/testutil/TypicalClients.java @@ -69,4 +69,4 @@ public static AddressBook getTypicalAddressBook() { public static List getTypicalClients() { return new ArrayList<>(Arrays.asList(ALICE, BENSON, CARL, DANIEL, ELLE, FIONA, GEORGE)); } -} \ No newline at end of file +} From 1d3ac97f76cc948b36fbb4387d4dfa6ac0a4233b Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Tue, 18 Mar 2025 19:13:19 +0800 Subject: [PATCH 048/249] add gradle edits --- build.gradle | 4 +- gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 59821 bytes .../logic/commands/DeletePolicyCommand.java | 69 ++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java diff --git a/build.gradle b/build.gradle index 0db3743584e..6b182d845af 100644 --- a/build.gradle +++ b/build.gradle @@ -8,8 +8,8 @@ plugins { mainClassName = 'seedu.address.Main' -sourceCompatibility = JavaVersion.VERSION_17 -targetCompatibility = JavaVersion.VERSION_17 +//sourceCompatibility = JavaVersion.VERSION_17 +//targetCompatibility = JavaVersion.VERSION_17 repositories { mavenCentral() diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..41d9927a4d4fb3f96a785543079b8df6723c946b 100644 GIT binary patch delta 20926 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 i_W%EDg1>@4`_NK(#)z|gdCiK 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 diff --git a/src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java b/src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java new file mode 100644 index 00000000000..4e326dc5c1e --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java @@ -0,0 +1,69 @@ +package seedu.address.logic.commands; + +import seedu.address.commons.core.index.Index; +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.person.Person; + +import java.util.List; + +import static java.util.Objects.requireNonNull; + +/** + * Deletes a person identified using it's displayed index from the address book. + */ +public class DeleteClientCommand extends DeleteCommand { + + public static final String COMMAND_WORD = "deleteclient"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Deletes the person identified by the index number used in the displayed person list.\n" + + "Parameters: INDEX (must be a positive integer)\n" + + "Example: " + COMMAND_WORD + " 1"; + + public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Client: %1$s"; + + private final Index targetIndex; + + public DeleteClientCommand(Index targetIndex) { + this.targetIndex = targetIndex; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + List lastShownList = model.getFilteredPersonList(); + + 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, Messages.format(personToDelete))); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof DeleteClientCommand)) { + return false; + } + + DeleteClientCommand otherDeleteCommand = (DeleteClientCommand) other; + return targetIndex.equals(otherDeleteCommand.targetIndex); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("targetIndex", targetIndex) + .toString(); + } +} From faf7cbeb46de108243c9ac5818d4e9a15ae61b0e Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Tue, 18 Mar 2025 19:31:11 +0800 Subject: [PATCH 049/249] add delete-client-command edits --- .../logic/commands/DeleteClientCommand.java | 8 +-- .../address/logic/commands/DeleteCommand.java | 15 ---- .../logic/commands/DeletePolicyCommand.java | 69 ------------------- .../logic/parser/AddressBookParserTest.java | 10 ++- .../parser/DeleteClientCommandParserTest.java | 3 +- 5 files changed, 15 insertions(+), 90 deletions(-) delete mode 100644 src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java diff --git a/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java b/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java index 4e326dc5c1e..2c675a251f3 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java @@ -1,5 +1,9 @@ package seedu.address.logic.commands; +import static java.util.Objects.requireNonNull; + +import java.util.List; + import seedu.address.commons.core.index.Index; import seedu.address.commons.util.ToStringBuilder; import seedu.address.logic.Messages; @@ -7,10 +11,6 @@ import seedu.address.model.Model; import seedu.address.model.person.Person; -import java.util.List; - -import static java.util.Objects.requireNonNull; - /** * Deletes a person identified using it's displayed index from the address book. */ diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java index 76fd09c95ab..b2f9e5db011 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteCommand.java @@ -1,15 +1,7 @@ package seedu.address.logic.commands; -import static java.util.Objects.requireNonNull; - -import java.util.List; - -import seedu.address.commons.core.index.Index; -import seedu.address.commons.util.ToStringBuilder; -import seedu.address.logic.Messages; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; -import seedu.address.model.person.Person; /** * Deletes a person identified using it's displayed index from the address book. @@ -31,11 +23,4 @@ public abstract class DeleteCommand extends Command { @Override public abstract String toString(); - - private static String messageUsage; - - public static String getMessageUsage() { - return messageUsage; - } - } diff --git a/src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java b/src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java deleted file mode 100644 index 4e326dc5c1e..00000000000 --- a/src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java +++ /dev/null @@ -1,69 +0,0 @@ -package seedu.address.logic.commands; - -import seedu.address.commons.core.index.Index; -import seedu.address.commons.util.ToStringBuilder; -import seedu.address.logic.Messages; -import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.model.Model; -import seedu.address.model.person.Person; - -import java.util.List; - -import static java.util.Objects.requireNonNull; - -/** - * Deletes a person identified using it's displayed index from the address book. - */ -public class DeleteClientCommand extends DeleteCommand { - - public static final String COMMAND_WORD = "deleteclient"; - - public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Deletes the person identified by the index number used in the displayed person list.\n" - + "Parameters: INDEX (must be a positive integer)\n" - + "Example: " + COMMAND_WORD + " 1"; - - public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Client: %1$s"; - - private final Index targetIndex; - - public DeleteClientCommand(Index targetIndex) { - this.targetIndex = targetIndex; - } - - @Override - public CommandResult execute(Model model) throws CommandException { - requireNonNull(model); - List lastShownList = model.getFilteredPersonList(); - - 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, Messages.format(personToDelete))); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof DeleteClientCommand)) { - return false; - } - - DeleteClientCommand otherDeleteCommand = (DeleteClientCommand) other; - return targetIndex.equals(otherDeleteCommand.targetIndex); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .add("targetIndex", targetIndex) - .toString(); - } -} diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 7cea062bc8d..d1ee7833d8a 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -13,8 +13,16 @@ import org.junit.jupiter.api.Test; -import seedu.address.logic.commands.*; +import seedu.address.logic.commands.AddCommand; +import seedu.address.logic.commands.ClearCommand; +import seedu.address.logic.commands.DeleteClientCommand; +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.commands.PriorityCommand; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.person.NameContainsKeywordsPredicate; import seedu.address.model.person.Person; diff --git a/src/test/java/seedu/address/logic/parser/DeleteClientCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteClientCommandParserTest.java index 1a89e001398..755482a998d 100644 --- a/src/test/java/seedu/address/logic/parser/DeleteClientCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/DeleteClientCommandParserTest.java @@ -27,6 +27,7 @@ public void parse_validArgs_returnsDeleteClientCommand() { @Test public void parse_invalidArgs_throwsParseException() { - assertParseFailure(parser, "a", String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteClientCommand.MESSAGE_USAGE)); + assertParseFailure(parser, "a", String.format(MESSAGE_INVALID_COMMAND_FORMAT, + DeleteClientCommand.MESSAGE_USAGE)); } } From 76ff1ffebd35e8e840e80b47d4d7c52927324579 Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Tue, 18 Mar 2025 19:39:15 +0800 Subject: [PATCH 050/249] add delete-client-command debug edit --- src/test/java/seedu/address/logic/LogicManagerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/address/logic/LogicManagerTest.java index b56238b84cd..f0e50b86462 100644 --- a/src/test/java/seedu/address/logic/LogicManagerTest.java +++ b/src/test/java/seedu/address/logic/LogicManagerTest.java @@ -60,7 +60,7 @@ public void execute_invalidCommandFormat_throwsParseException() { @Test public void execute_commandExecutionError_throwsCommandException() { - String deleteClientCommand = "delete 9"; + String deleteClientCommand = "deleteclient 9"; assertCommandException(deleteClientCommand, MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); } From 3115d425e9cb3660327eb37f02268c147128044f Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Wed, 19 Mar 2025 15:05:01 +0800 Subject: [PATCH 051/249] Add edits --- ...{AddCommand.java => AddClientCommand.java} | 12 +++++----- ...arser.java => AddClientCommandParser.java} | 16 +++++++------- ...a => AddClientCommandIntegrationTest.java} | 12 +++++----- ...andTest.java => AddClientCommandTest.java} | 22 +++++++++---------- ...t.java => AddClientCommandParserTest.java} | 16 +++++++------- 5 files changed, 39 insertions(+), 39 deletions(-) rename src/main/java/seedu/address/logic/commands/{AddCommand.java => AddClientCommand.java} (87%) rename src/main/java/seedu/address/logic/parser/{AddCommandParser.java => AddClientCommandParser.java} (83%) rename src/test/java/seedu/address/logic/commands/{AddCommandIntegrationTest.java => AddClientCommandIntegrationTest.java} (77%) rename src/test/java/seedu/address/logic/commands/{AddCommandTest.java => AddClientCommandTest.java} (87%) rename src/test/java/seedu/address/logic/parser/{AddCommandParserTest.java => AddClientCommandParserTest.java} (95%) diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/address/logic/commands/AddClientCommand.java similarity index 87% rename from src/main/java/seedu/address/logic/commands/AddCommand.java rename to src/main/java/seedu/address/logic/commands/AddClientCommand.java index 5d7185a9680..fcd9bc8b77f 100644 --- a/src/main/java/seedu/address/logic/commands/AddCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddClientCommand.java @@ -16,7 +16,7 @@ /** * Adds a person to the address book. */ -public class AddCommand extends Command { +public class AddClientCommand extends Command { public static final String COMMAND_WORD = "add"; @@ -41,9 +41,9 @@ public class AddCommand extends Command { private final Person toAdd; /** - * Creates an AddCommand to add the specified {@code Person} + * Creates an AddClientCommand to add the specified {@code Person} */ - public AddCommand(Person person) { + public AddClientCommand(Person person) { requireNonNull(person); toAdd = person; } @@ -67,12 +67,12 @@ public boolean equals(Object other) { } // instanceof handles nulls - if (!(other instanceof AddCommand)) { + if (!(other instanceof AddClientCommand)) { return false; } - AddCommand otherAddCommand = (AddCommand) other; - return toAdd.equals(otherAddCommand.toAdd); + AddClientCommand otherAddClientCommand = (AddClientCommand) other; + return toAdd.equals(otherAddClientCommand.toAdd); } @Override diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddClientCommandParser.java similarity index 83% rename from src/main/java/seedu/address/logic/parser/AddCommandParser.java rename to src/main/java/seedu/address/logic/parser/AddClientCommandParser.java index 4ff1a97ed77..994c8c88a65 100644 --- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddClientCommandParser.java @@ -10,7 +10,7 @@ import java.util.Set; import java.util.stream.Stream; -import seedu.address.logic.commands.AddCommand; +import seedu.address.logic.commands.AddClientCommand; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.person.Address; import seedu.address.model.person.Email; @@ -20,22 +20,22 @@ import seedu.address.model.tag.Tag; /** - * Parses input arguments and creates a new AddCommand object + * Parses input arguments and creates a new AddClientCommand object */ -public class AddCommandParser implements Parser { +public class AddClientCommandParser implements Parser { /** - * Parses the given {@code String} of arguments in the context of the AddCommand - * and returns an AddCommand object for execution. + * Parses the given {@code String} of arguments in the context of the AddClientCommand + * and returns an AddClientCommand object for execution. * @throws ParseException if the user input does not conform the expected format */ - public AddCommand parse(String args) throws ParseException { + public AddClientCommand parse(String args) throws ParseException { ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG); if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ADDRESS, PREFIX_PHONE, PREFIX_EMAIL) || !argMultimap.getPreamble().isEmpty()) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE)); + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddClientCommand.MESSAGE_USAGE)); } argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS); @@ -47,7 +47,7 @@ public AddCommand parse(String args) throws ParseException { Person person = new Person(name, phone, email, address, tagList); - return new AddCommand(person); + return new AddClientCommand(person); } /** diff --git a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/AddClientCommandIntegrationTest.java similarity index 77% rename from src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java rename to src/test/java/seedu/address/logic/commands/AddClientCommandIntegrationTest.java index 162a0c86031..55b574bd910 100644 --- a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java +++ b/src/test/java/seedu/address/logic/commands/AddClientCommandIntegrationTest.java @@ -15,9 +15,9 @@ import seedu.address.testutil.PersonBuilder; /** - * Contains integration tests (interaction with the Model) for {@code AddCommand}. + * Contains integration tests (interaction with the Model) for {@code AddClientCommand}. */ -public class AddCommandIntegrationTest { +public class AddClientCommandIntegrationTest { private Model model; @@ -33,16 +33,16 @@ public void execute_newPerson_success() { Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); expectedModel.addPerson(validPerson); - assertCommandSuccess(new AddCommand(validPerson), model, - String.format(AddCommand.MESSAGE_SUCCESS, Messages.format(validPerson)), + assertCommandSuccess(new AddClientCommand(validPerson), model, + String.format(AddClientCommand.MESSAGE_SUCCESS, Messages.format(validPerson)), expectedModel); } @Test public void execute_duplicatePerson_throwsCommandException() { Person personInList = model.getAddressBook().getPersonList().get(0); - assertCommandFailure(new AddCommand(personInList), model, - AddCommand.MESSAGE_DUPLICATE_PERSON); + assertCommandFailure(new AddClientCommand(personInList), model, + AddClientCommand.MESSAGE_DUPLICATE_PERSON); } } diff --git a/src/test/java/seedu/address/logic/commands/AddCommandTest.java b/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java similarity index 87% rename from src/test/java/seedu/address/logic/commands/AddCommandTest.java rename to src/test/java/seedu/address/logic/commands/AddClientCommandTest.java index 90e8253f48e..b7122f9ecf5 100644 --- a/src/test/java/seedu/address/logic/commands/AddCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java @@ -25,11 +25,11 @@ import seedu.address.model.person.Person; import seedu.address.testutil.PersonBuilder; -public class AddCommandTest { +public class AddClientCommandTest { @Test public void constructor_nullPerson_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> new AddCommand(null)); + assertThrows(NullPointerException.class, () -> new AddClientCommand(null)); } @Test @@ -37,9 +37,9 @@ public void execute_personAcceptedByModel_addSuccessful() throws Exception { ModelStubAcceptingPersonAdded modelStub = new ModelStubAcceptingPersonAdded(); Person validPerson = new PersonBuilder().build(); - CommandResult commandResult = new AddCommand(validPerson).execute(modelStub); + CommandResult commandResult = new AddClientCommand(validPerson).execute(modelStub); - assertEquals(String.format(AddCommand.MESSAGE_SUCCESS, Messages.format(validPerson)), + assertEquals(String.format(AddClientCommand.MESSAGE_SUCCESS, Messages.format(validPerson)), commandResult.getFeedbackToUser()); assertEquals(Arrays.asList(validPerson), modelStub.personsAdded); } @@ -47,24 +47,24 @@ public void execute_personAcceptedByModel_addSuccessful() throws Exception { @Test public void execute_duplicatePerson_throwsCommandException() { Person validPerson = new PersonBuilder().build(); - AddCommand addCommand = new AddCommand(validPerson); + AddClientCommand addCommand = new AddClientCommand(validPerson); ModelStub modelStub = new ModelStubWithPerson(validPerson); - assertThrows(CommandException.class, AddCommand.MESSAGE_DUPLICATE_PERSON, () -> addCommand.execute(modelStub)); + assertThrows(CommandException.class, AddClientCommand.MESSAGE_DUPLICATE_PERSON, () -> addCommand.execute(modelStub)); } @Test public void equals() { Person alice = new PersonBuilder().withName("Alice").build(); Person bob = new PersonBuilder().withName("Bob").build(); - AddCommand addAliceCommand = new AddCommand(alice); - AddCommand addBobCommand = new AddCommand(bob); + AddClientCommand addAliceCommand = new AddClientCommand(alice); + AddClientCommand addBobCommand = new AddClientCommand(bob); // same object -> returns true assertTrue(addAliceCommand.equals(addAliceCommand)); // same values -> returns true - AddCommand addAliceCommandCopy = new AddCommand(alice); + AddClientCommand addAliceCommandCopy = new AddClientCommand(alice); assertTrue(addAliceCommand.equals(addAliceCommandCopy)); // different types -> returns false @@ -79,8 +79,8 @@ public void equals() { @Test public void toStringMethod() { - AddCommand addCommand = new AddCommand(ALICE); - String expected = AddCommand.class.getCanonicalName() + "{toAdd=" + ALICE + "}"; + AddClientCommand addCommand = new AddClientCommand(ALICE); + String expected = AddClientCommand.class.getCanonicalName() + "{toAdd=" + ALICE + "}"; assertEquals(expected, addCommand.toString()); } diff --git a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddClientCommandParserTest.java similarity index 95% rename from src/test/java/seedu/address/logic/parser/AddCommandParserTest.java rename to src/test/java/seedu/address/logic/parser/AddClientCommandParserTest.java index 5bc11d3cdaa..e3c6caa0ce2 100644 --- a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddClientCommandParserTest.java @@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test; import seedu.address.logic.Messages; -import seedu.address.logic.commands.AddCommand; +import seedu.address.logic.commands.AddClientCommand; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -45,8 +45,8 @@ import seedu.address.model.tag.Tag; import seedu.address.testutil.PersonBuilder; -public class AddCommandParserTest { - private AddCommandParser parser = new AddCommandParser(); +public class AddClientCommandParserTest { + private AddClientCommandParser parser = new AddClientCommandParser(); @Test public void parse_allFieldsPresent_success() { @@ -54,7 +54,7 @@ public void parse_allFieldsPresent_success() { // 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)); + + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, new AddClientCommand(expectedPerson)); // multiple tags - all accepted @@ -62,7 +62,7 @@ public void parse_allFieldsPresent_success() { .build(); assertParseSuccess(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, - new AddCommand(expectedPersonMultipleTags)); + new AddClientCommand(expectedPersonMultipleTags)); } @Test @@ -134,12 +134,12 @@ 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)); + new AddClientCommand(expectedPerson)); } @Test public void parse_compulsoryFieldMissing_failure() { - String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE); + String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddClientCommand.MESSAGE_USAGE); // missing name prefix assertParseFailure(parser, VALID_NAME_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB, @@ -191,6 +191,6 @@ public void parse_invalidValue_failure() { // 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)); + String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddClientCommand.MESSAGE_USAGE)); } } From 9492d41c981e01e85f9a684c6f8c846b1a9207f2 Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Wed, 19 Mar 2025 15:05:21 +0800 Subject: [PATCH 052/249] Add edits --- .../java/seedu/address/logic/commands/AddClientCommand.java | 4 ++-- .../java/seedu/address/logic/parser/AddressBookParser.java | 6 +++--- src/test/java/seedu/address/logic/LogicManagerTest.java | 4 ++-- .../seedu/address/logic/commands/AddClientCommandTest.java | 3 ++- .../seedu/address/logic/parser/AddressBookParserTest.java | 6 +++--- .../seedu/address/logic/parser/EditCommandParserTest.java | 2 +- src/test/java/seedu/address/testutil/PersonUtil.java | 6 +++--- 7 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/AddClientCommand.java b/src/main/java/seedu/address/logic/commands/AddClientCommand.java index fcd9bc8b77f..9b21e7d8120 100644 --- a/src/main/java/seedu/address/logic/commands/AddClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddClientCommand.java @@ -18,9 +18,9 @@ */ public class AddClientCommand extends Command { - public static final String COMMAND_WORD = "add"; + public static final String COMMAND_WORD = "addclient"; - 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 client to the address book. " + "Parameters: " + PREFIX_NAME + "NAME " + PREFIX_PHONE + "PHONE " diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index a6a62769e5c..651743808b7 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -8,7 +8,7 @@ import java.util.regex.Pattern; import seedu.address.commons.core.LogsCenter; -import seedu.address.logic.commands.AddCommand; +import seedu.address.logic.commands.AddClientCommand; import seedu.address.logic.commands.ClearCommand; import seedu.address.logic.commands.Command; import seedu.address.logic.commands.DeleteCommand; @@ -54,8 +54,8 @@ public Command parseCommand(String userInput) throws ParseException { switch (commandWord) { - case AddCommand.COMMAND_WORD: - return new AddCommandParser().parse(arguments); + case AddClientCommand.COMMAND_WORD: + return new AddClientCommandParser().parse(arguments); case EditCommand.COMMAND_WORD: return new EditCommandParser().parse(arguments); diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/address/logic/LogicManagerTest.java index baf8ce336a2..4ef4f5f7830 100644 --- a/src/test/java/seedu/address/logic/LogicManagerTest.java +++ b/src/test/java/seedu/address/logic/LogicManagerTest.java @@ -18,7 +18,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import seedu.address.logic.commands.AddCommand; +import seedu.address.logic.commands.AddClientCommand; import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.exceptions.CommandException; @@ -165,7 +165,7 @@ public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) logic = new LogicManager(model, storage); // Triggers the saveAddressBook method by executing an add command - String addCommand = AddCommand.COMMAND_WORD + NAME_DESC_AMY + PHONE_DESC_AMY + String addCommand = AddClientCommand.COMMAND_WORD + NAME_DESC_AMY + PHONE_DESC_AMY + EMAIL_DESC_AMY + ADDRESS_DESC_AMY; Person expectedPerson = new PersonBuilder(AMY).withTags().build(); ModelManager expectedModel = new ModelManager(); diff --git a/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java b/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java index b7122f9ecf5..3cdf4a0c21e 100644 --- a/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java @@ -50,7 +50,8 @@ public void execute_duplicatePerson_throwsCommandException() { AddClientCommand addCommand = new AddClientCommand(validPerson); ModelStub modelStub = new ModelStubWithPerson(validPerson); - assertThrows(CommandException.class, AddClientCommand.MESSAGE_DUPLICATE_PERSON, () -> addCommand.execute(modelStub)); + assertThrows(CommandException.class, + AddClientCommand.MESSAGE_DUPLICATE_PERSON, () -> addCommand.execute(modelStub)); } @Test diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 2aa28adfa40..58855714308 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -13,7 +13,7 @@ import org.junit.jupiter.api.Test; -import seedu.address.logic.commands.AddCommand; +import seedu.address.logic.commands.AddClientCommand; import seedu.address.logic.commands.ClearCommand; import seedu.address.logic.commands.DeleteCommand; import seedu.address.logic.commands.EditCommand; @@ -37,8 +37,8 @@ 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); + AddClientCommand command = (AddClientCommand) parser.parseCommand(PersonUtil.getAddClientCommand(person)); + assertEquals(new AddClientCommand(person), command); } @Test diff --git a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java b/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java index cc7175172d4..010a06e7ebd 100644 --- a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java @@ -166,7 +166,7 @@ public void parse_oneFieldSpecified_success() { @Test public void parse_multipleRepeatedFields_failure() { // More extensive testing of duplicate parameter detections is done in - // AddCommandParserTest#parse_repeatedNonTagValue_failure() + // AddClientCommandParserTest#parse_repeatedNonTagValue_failure() // valid followed by invalid Index targetIndex = INDEX_FIRST_PERSON; diff --git a/src/test/java/seedu/address/testutil/PersonUtil.java b/src/test/java/seedu/address/testutil/PersonUtil.java index 90849945183..d47c55af5cd 100644 --- a/src/test/java/seedu/address/testutil/PersonUtil.java +++ b/src/test/java/seedu/address/testutil/PersonUtil.java @@ -8,7 +8,7 @@ import java.util.Set; -import seedu.address.logic.commands.AddCommand; +import seedu.address.logic.commands.AddClientCommand; import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; import seedu.address.model.person.Person; import seedu.address.model.tag.Tag; @@ -21,8 +21,8 @@ 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); + public static String getAddClientCommand(Person person) { + return AddClientCommand.COMMAND_WORD + " " + getPersonDetails(person); } /** From e3fd1229cc73ccebc460fde262d2debfe85e856a Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Wed, 19 Mar 2025 15:12:22 +0800 Subject: [PATCH 053/249] Add minor updates --- .../java/seedu/address/logic/commands/AddClientCommand.java | 6 +++--- .../seedu/address/logic/commands/DeleteClientCommand.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/AddClientCommand.java b/src/main/java/seedu/address/logic/commands/AddClientCommand.java index 9b21e7d8120..445c1790396 100644 --- a/src/main/java/seedu/address/logic/commands/AddClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddClientCommand.java @@ -14,7 +14,7 @@ import seedu.address.model.person.Person; /** - * Adds a person to the address book. + * Adds a client to the address book. */ public class AddClientCommand extends Command { @@ -35,8 +35,8 @@ public class AddClientCommand extends Command { + 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 client added: %1$s"; + public static final String MESSAGE_DUPLICATE_PERSON = "This client already exists in the address book"; private final Person toAdd; diff --git a/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java b/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java index 2c675a251f3..033b08e1b32 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java @@ -12,14 +12,14 @@ import seedu.address.model.person.Person; /** - * Deletes a person identified using it's displayed index from the address book. + * Deletes a client identified using its displayed index from the address book. */ public class DeleteClientCommand extends DeleteCommand { public static final String COMMAND_WORD = "deleteclient"; 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 client identified by the index number used in the displayed person list.\n" + "Parameters: INDEX (must be a positive integer)\n" + "Example: " + COMMAND_WORD + " 1"; From 073b364a552b609c88256b7dc3ebd9f3e770a70c Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Thu, 20 Mar 2025 03:52:56 +0800 Subject: [PATCH 054/249] add customise-codebase-v2 edits --- src/main/java/seedu/address/logic/Logic.java | 6 +- .../seedu/address/logic/LogicManager.java | 6 +- .../java/seedu/address/logic/Messages.java | 22 +-- .../logic/commands/AddClientCommand.java | 20 +- .../seedu/address/logic/commands/Command.java | 8 +- .../logic/commands/DeleteClientCommand.java | 16 +- .../address/logic/commands/DeleteCommand.java | 4 +- .../address/logic/commands/EditCommand.java | 100 +++++----- .../address/logic/commands/FindCommand.java | 10 +- .../address/logic/commands/ListCommand.java | 8 +- .../logic/commands/PriorityCommand.java | 40 ++-- .../logic/parser/AddClientCommandParser.java | 14 +- .../logic/parser/EditCommandParser.java | 18 +- .../logic/parser/FindCommandParser.java | 2 +- .../address/logic/parser/ParserUtil.java | 8 +- .../java/seedu/address/model/AddressBook.java | 73 +------- src/main/java/seedu/address/model/Model.java | 34 ++-- .../seedu/address/model/ModelManager.java | 42 ++--- .../address/model/ReadOnlyAddressBook.java | 7 - .../seedu/address/model/client/Address.java | 2 +- .../seedu/address/model/client/Client.java | 28 ++- .../seedu/address/model/client/Email.java | 5 +- .../NameContainsKeywordsPredicate.java | 10 +- .../seedu/address/model/client/Phone.java | 4 +- .../model/client/UniqueClientList.java | 1 - .../seedu/address/model/person/Address.java | 65 ------- .../seedu/address/model/person/Email.java | 79 -------- .../java/seedu/address/model/person/Name.java | 67 ------- .../seedu/address/model/person/Person.java | 117 ------------ .../seedu/address/model/person/Phone.java | 61 ------ .../model/person/UniquePersonList.java | 150 --------------- .../exceptions/DuplicatePersonException.java | 11 -- .../exceptions/PersonNotFoundException.java | 6 - .../address/model/util/SampleDataUtil.java | 30 +-- ...ptedPerson.java => JsonAdaptedClient.java} | 38 ++-- .../storage/JsonSerializableAddressBook.java | 24 +-- .../ui/{PersonCard.java => ClientCard.java} | 26 +-- .../seedu/address/ui/ClientListPanel.java | 49 +++++ .../java/seedu/address/ui/MainWindow.java | 12 +- .../seedu/address/ui/PersonListPanel.java | 49 ----- ...ersonListCard.fxml => ClientListCard.fxml} | 0 ...sonListPanel.fxml => ClientListPanel.fxml} | 2 +- src/main/resources/view/MainWindow.fxml | 4 +- ... => invalidAndValidClientAddressBook.json} | 6 +- ...ook.json => invalidClientAddressBook.json} | 4 +- ...k.json => duplicateClientAddressBook.json} | 2 +- ...ook.json => invalidClientAddressBook.json} | 2 +- ...ok.json => typicalClientsAddressBook.json} | 4 +- .../address/commons/core/index/IndexTest.java | 14 +- .../seedu/address/logic/LogicManagerTest.java | 18 +- .../AddClientCommandIntegrationTest.java | 24 +-- .../logic/commands/AddClientCommandTest.java | 84 ++++----- .../logic/commands/ClearCommandTest.java | 2 +- .../logic/commands/CommandTestUtil.java | 34 ++-- .../commands/DeleteClientCommandTest.java | 60 +++--- ...est.java => EditClientDescriptorTest.java} | 34 ++-- .../logic/commands/EditCommandTest.java | 124 ++++++------- .../logic/commands/FindCommandTest.java | 30 +-- .../logic/commands/ListCommandTest.java | 8 +- .../logic/commands/PriorityCommandTest.java | 38 ++-- .../parser/AddClientCommandParserTest.java | 58 +++--- .../logic/parser/AddressBookParserTest.java | 36 ++-- .../parser/DeleteClientCommandParserTest.java | 4 +- .../logic/parser/EditCommandParserTest.java | 46 ++--- .../logic/parser/FindCommandParserTest.java | 2 +- .../address/logic/parser/ParserUtilTest.java | 14 +- .../parser/PriorityCommandParserTest.java | 4 +- .../seedu/address/model/AddressBookTest.java | 64 +++---- .../seedu/address/model/ModelManagerTest.java | 32 ++-- .../address/model/client/ClientTest.java | 20 +- .../seedu/address/model/client/EmailTest.java | 1 - .../NameContainsKeywordsPredicateTest.java | 20 +- .../seedu/address/model/client/NameTest.java | 1 - .../seedu/address/model/client/PhoneTest.java | 3 +- .../model/client/UniqueClientListTest.java | 9 +- .../address/model/person/AddressTest.java | 56 ------ .../seedu/address/model/person/EmailTest.java | 88 --------- .../seedu/address/model/person/NameTest.java | 60 ------ .../address/model/person/PersonTest.java | 99 ---------- .../seedu/address/model/person/PhoneTest.java | 60 ------ .../model/person/UniquePersonListTest.java | 175 ------------------ ...onTest.java => JsonAdaptedClientTest.java} | 66 +++---- .../storage/JsonAddressBookStorageTest.java | 22 +-- .../JsonSerializableAddressBookTest.java | 26 +-- .../address/storage/StorageManagerTest.java | 2 +- .../address/testutil/AddressBookBuilder.java | 10 +- .../seedu/address/testutil/ClientBuilder.java | 18 +- .../{PersonUtil.java => ClientUtil.java} | 32 ++-- .../testutil/EditClientDescriptorBuilder.java | 87 +++++++++ .../testutil/EditPersonDescriptorBuilder.java | 87 --------- .../seedu/address/testutil/PersonBuilder.java | 96 ---------- .../java/seedu/address/testutil/TestUtil.java | 16 +- .../address/testutil/TypicalClients.java | 18 +- .../address/testutil/TypicalIndexes.java | 8 +- .../address/testutil/TypicalPersons.java | 76 -------- 95 files changed, 943 insertions(+), 2239 deletions(-) rename src/main/java/seedu/address/model/{person => client}/NameContainsKeywordsPredicate.java (84%) delete mode 100644 src/main/java/seedu/address/model/person/Address.java delete mode 100644 src/main/java/seedu/address/model/person/Email.java delete mode 100644 src/main/java/seedu/address/model/person/Name.java delete mode 100644 src/main/java/seedu/address/model/person/Person.java delete mode 100644 src/main/java/seedu/address/model/person/Phone.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 rename src/main/java/seedu/address/storage/{JsonAdaptedPerson.java => JsonAdaptedClient.java} (72%) rename src/main/java/seedu/address/ui/{PersonCard.java => ClientCard.java} (70%) create mode 100644 src/main/java/seedu/address/ui/ClientListPanel.java delete mode 100644 src/main/java/seedu/address/ui/PersonListPanel.java rename src/main/resources/view/{PersonListCard.fxml => ClientListCard.fxml} (100%) rename src/main/resources/view/{PersonListPanel.fxml => ClientListPanel.fxml} (77%) rename src/test/data/JsonAddressBookStorageTest/{invalidAndValidPersonAddressBook.json => invalidAndValidClientAddressBook.json} (67%) rename src/test/data/JsonAddressBookStorageTest/{invalidPersonAddressBook.json => invalidClientAddressBook.json} (54%) rename src/test/data/JsonSerializableAddressBookTest/{duplicatePersonAddressBook.json => duplicateClientAddressBook.json} (94%) rename src/test/data/JsonSerializableAddressBookTest/{invalidPersonAddressBook.json => invalidClientAddressBook.json} (87%) rename src/test/data/JsonSerializableAddressBookTest/{typicalPersonsAddressBook.json => typicalClientsAddressBook.json} (88%) rename src/test/java/seedu/address/logic/commands/{EditPersonDescriptorTest.java => EditClientDescriptorTest.java} (65%) rename src/test/java/seedu/address/model/{person => client}/NameContainsKeywordsPredicateTest.java (84%) delete mode 100644 src/test/java/seedu/address/model/person/AddressTest.java delete mode 100644 src/test/java/seedu/address/model/person/EmailTest.java delete mode 100644 src/test/java/seedu/address/model/person/NameTest.java delete mode 100644 src/test/java/seedu/address/model/person/PersonTest.java delete mode 100644 src/test/java/seedu/address/model/person/PhoneTest.java delete mode 100644 src/test/java/seedu/address/model/person/UniquePersonListTest.java rename src/test/java/seedu/address/storage/{JsonAdaptedPersonTest.java => JsonAdaptedClientTest.java} (70%) rename src/test/java/seedu/address/testutil/{PersonUtil.java => ClientUtil.java} (63%) create mode 100644 src/test/java/seedu/address/testutil/EditClientDescriptorBuilder.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/TypicalPersons.java diff --git a/src/main/java/seedu/address/logic/Logic.java b/src/main/java/seedu/address/logic/Logic.java index 92cd8fa605a..41b7ba8caf7 100644 --- a/src/main/java/seedu/address/logic/Logic.java +++ b/src/main/java/seedu/address/logic/Logic.java @@ -8,7 +8,7 @@ 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.address.model.client.Client; /** * API of the Logic component @@ -30,8 +30,8 @@ public interface Logic { */ ReadOnlyAddressBook getAddressBook(); - /** Returns an unmodifiable view of the filtered list of persons */ - ObservableList getFilteredPersonList(); + /** Returns an unmodifiable view of the filtered list of clients */ + ObservableList getFilteredClientList(); /** * Returns the user prefs' address book file path. diff --git a/src/main/java/seedu/address/logic/LogicManager.java b/src/main/java/seedu/address/logic/LogicManager.java index 5aa3b91c7d0..69116c0b40b 100644 --- a/src/main/java/seedu/address/logic/LogicManager.java +++ b/src/main/java/seedu/address/logic/LogicManager.java @@ -15,7 +15,7 @@ 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.model.client.Client; import seedu.address.storage.Storage; /** @@ -67,8 +67,8 @@ public ReadOnlyAddressBook getAddressBook() { } @Override - public ObservableList getFilteredPersonList() { - return model.getFilteredPersonList(); + public ObservableList getFilteredClientList() { + return model.getFilteredClientList(); } @Override diff --git a/src/main/java/seedu/address/logic/Messages.java b/src/main/java/seedu/address/logic/Messages.java index 5540db9f842..278eca98c21 100644 --- a/src/main/java/seedu/address/logic/Messages.java +++ b/src/main/java/seedu/address/logic/Messages.java @@ -5,7 +5,7 @@ import java.util.stream.Stream; import seedu.address.logic.parser.Prefix; -import seedu.address.model.person.Person; +import seedu.address.model.client.Client; /** * Container for user visible messages. @@ -14,11 +14,11 @@ 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_CLIENT_DISPLAYED_INDEX = "The client index provided is invalid"; + public static final String MESSAGE_CLIENTS_LISTED_OVERVIEW = "%1$d clients listed!"; public static final String MESSAGE_DUPLICATE_FIELDS = "Multiple values specified for the following single-valued field(s): "; - public static final String MESSAGE_PERSON_ALREADY_PRIORITY = "The person is already tagged as a priority"; + public static final String MESSAGE_CLIENT_ALREADY_PRIORITY = "The client is already tagged as a priority"; /** * Returns an error message indicating the duplicate prefixes. */ @@ -32,19 +32,19 @@ public static String getErrorMessageForDuplicatePrefixes(Prefix... duplicatePref } /** - * Formats the {@code person} for display to the user. + * Formats the {@code client} for display to the user. */ - public static String format(Person person) { + public static String format(Client client) { final StringBuilder builder = new StringBuilder(); - builder.append(person.getName()) + builder.append(client.getName()) .append("; Phone: ") - .append(person.getPhone()) + .append(client.getPhone()) .append("; Email: ") - .append(person.getEmail()) + .append(client.getEmail()) .append("; Address: ") - .append(person.getAddress()) + .append(client.getAddress()) .append("; Tags: "); - person.getTags().forEach(builder::append); + client.getTags().forEach(builder::append); return builder.toString(); } diff --git a/src/main/java/seedu/address/logic/commands/AddClientCommand.java b/src/main/java/seedu/address/logic/commands/AddClientCommand.java index 445c1790396..3d96f9486c0 100644 --- a/src/main/java/seedu/address/logic/commands/AddClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddClientCommand.java @@ -11,7 +11,7 @@ import seedu.address.logic.Messages; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; -import seedu.address.model.person.Person; +import seedu.address.model.client.Client; /** * Adds a client to the address book. @@ -36,27 +36,27 @@ public class AddClientCommand extends Command { + PREFIX_TAG + "owesMoney"; public static final String MESSAGE_SUCCESS = "New client added: %1$s"; - public static final String MESSAGE_DUPLICATE_PERSON = "This client already exists in the address book"; + public static final String MESSAGE_DUPLICATE_CLIENT = "This client already exists in the address book"; - private final Person toAdd; + private final Client toAdd; /** - * Creates an AddClientCommand to add the specified {@code Person} + * Creates an AddClientCommand to add the specified {@code Client} */ - public AddClientCommand(Person person) { - requireNonNull(person); - toAdd = person; + public AddClientCommand(Client client) { + requireNonNull(client); + toAdd = client; } @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); - if (model.hasPerson(toAdd)) { - throw new CommandException(MESSAGE_DUPLICATE_PERSON); + if (model.hasClient(toAdd)) { + throw new CommandException(MESSAGE_DUPLICATE_CLIENT); } - model.addPerson(toAdd); + model.addClient(toAdd); return new CommandResult(String.format(MESSAGE_SUCCESS, Messages.format(toAdd))); } diff --git a/src/main/java/seedu/address/logic/commands/Command.java b/src/main/java/seedu/address/logic/commands/Command.java index 8e9bcab6959..93a4b710cfe 100644 --- a/src/main/java/seedu/address/logic/commands/Command.java +++ b/src/main/java/seedu/address/logic/commands/Command.java @@ -6,7 +6,7 @@ import seedu.address.logic.Messages; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; -import seedu.address.model.person.Person; +import seedu.address.model.client.Client; /** * Represents a command with hidden internal logic and the ability to be executed. @@ -23,13 +23,13 @@ public abstract class Command { public abstract CommandResult execute(Model model) throws CommandException; /** - * Returns the person for a given index + * Returns the client for a given index * * @throws CommandException If an error occurs during command execution. */ - protected Person getPersonFromIndex(List list, Index index) throws CommandException { + protected Client getClientFromIndex(List list, Index index) throws CommandException { if (index.getZeroBased() >= list.size()) { - throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + throw new CommandException(Messages.MESSAGE_INVALID_CLIENT_DISPLAYED_INDEX); } return list.get(index.getZeroBased()); } diff --git a/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java b/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java index 033b08e1b32..a9139c83513 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java @@ -9,7 +9,7 @@ import seedu.address.logic.Messages; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; -import seedu.address.model.person.Person; +import seedu.address.model.client.Client; /** * Deletes a client identified using its displayed index from the address book. @@ -19,11 +19,11 @@ public class DeleteClientCommand extends DeleteCommand { public static final String COMMAND_WORD = "deleteclient"; public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Deletes the client identified by the index number used in the displayed person list.\n" + + ": Deletes the client identified by the index number used in the displayed client list.\n" + "Parameters: INDEX (must be a positive integer)\n" + "Example: " + COMMAND_WORD + " 1"; - public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Client: %1$s"; + public static final String MESSAGE_DELETE_CLIENT_SUCCESS = "Deleted Client: %1$s"; private final Index targetIndex; @@ -34,15 +34,15 @@ public DeleteClientCommand(Index targetIndex) { @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); - List lastShownList = model.getFilteredPersonList(); + List lastShownList = model.getFilteredClientList(); if (targetIndex.getZeroBased() >= lastShownList.size()) { - throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + throw new CommandException(Messages.MESSAGE_INVALID_CLIENT_DISPLAYED_INDEX); } - Person personToDelete = lastShownList.get(targetIndex.getZeroBased()); - model.deletePerson(personToDelete); - return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, Messages.format(personToDelete))); + Client clientToDelete = lastShownList.get(targetIndex.getZeroBased()); + model.deleteClient(clientToDelete); + return new CommandResult(String.format(MESSAGE_DELETE_CLIENT_SUCCESS, Messages.format(clientToDelete))); } @Override diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java index b2f9e5db011..5e973e0aac1 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteCommand.java @@ -4,14 +4,14 @@ import seedu.address.model.Model; /** - * Deletes a person identified using it's displayed index from the address book. + * Deletes a client identified using it's displayed index from the address book. */ public abstract 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 client identified by the index number used in the displayed client list.\n" + "Parameters: INDEX (must be a positive integer)\n" + "Example: " + COMMAND_WORD + " 1"; diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index 4b581c7331e..1f010f6890a 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -6,7 +6,7 @@ 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 static seedu.address.model.Model.PREDICATE_SHOW_ALL_CLIENTS; import java.util.Collections; import java.util.HashSet; @@ -21,22 +21,22 @@ import seedu.address.logic.Messages; 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.client.Address; +import seedu.address.model.client.Client; +import seedu.address.model.client.Email; +import seedu.address.model.client.Name; +import seedu.address.model.client.Phone; import seedu.address.model.tag.Tag; /** - * Edits the details of an existing person in the address book. + * Edits the details of an existing client 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. " + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the details of the client identified " + + "by the index number used in the displayed client list. " + "Existing values will be overwritten by the input values.\n" + "Parameters: INDEX (must be a positive integer) " + "[" + PREFIX_NAME + "NAME] " @@ -48,60 +48,60 @@ public class EditCommand extends Command { + 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_EDIT_CLIENT_SUCCESS = "Edited Client: %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."; + public static final String MESSAGE_DUPLICATE_CLIENT = "This client already exists in the address book."; private final Index index; - private final EditPersonDescriptor editPersonDescriptor; + private final EditClientDescriptor editClientDescriptor; /** - * @param index of the person in the filtered person list to edit - * @param editPersonDescriptor details to edit the person with + * @param index of the client in the filtered client list to edit + * @param editClientDescriptor details to edit the client with */ - public EditCommand(Index index, EditPersonDescriptor editPersonDescriptor) { + public EditCommand(Index index, EditClientDescriptor editClientDescriptor) { requireNonNull(index); - requireNonNull(editPersonDescriptor); + requireNonNull(editClientDescriptor); this.index = index; - this.editPersonDescriptor = new EditPersonDescriptor(editPersonDescriptor); + this.editClientDescriptor = new EditClientDescriptor(editClientDescriptor); } @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); - List lastShownList = model.getFilteredPersonList(); + List lastShownList = model.getFilteredClientList(); if (index.getZeroBased() >= lastShownList.size()) { - throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + throw new CommandException(Messages.MESSAGE_INVALID_CLIENT_DISPLAYED_INDEX); } - Person personToEdit = lastShownList.get(index.getZeroBased()); - Person editedPerson = createEditedPerson(personToEdit, editPersonDescriptor); + Client clientToEdit = lastShownList.get(index.getZeroBased()); + Client editedClient = createEditedClient(clientToEdit, editClientDescriptor); - if (!personToEdit.isSamePerson(editedPerson) && model.hasPerson(editedPerson)) { - throw new CommandException(MESSAGE_DUPLICATE_PERSON); + if (!clientToEdit.isSameClient(editedClient) && model.hasClient(editedClient)) { + throw new CommandException(MESSAGE_DUPLICATE_CLIENT); } - model.setPerson(personToEdit, editedPerson); - model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); - return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson))); + model.setClient(clientToEdit, editedClient); + model.updateFilteredClientList(PREDICATE_SHOW_ALL_CLIENTS); + return new CommandResult(String.format(MESSAGE_EDIT_CLIENT_SUCCESS, Messages.format(editedClient))); } /** - * Creates and returns a {@code Person} with the details of {@code personToEdit} - * edited with {@code editPersonDescriptor}. + * Creates and returns a {@code Client} with the details of {@code clientToEdit} + * edited with {@code editClientDescriptor}. */ - private static Person createEditedPerson(Person personToEdit, EditPersonDescriptor editPersonDescriptor) { - assert personToEdit != null; + private static Client createEditedClient(Client clientToEdit, EditClientDescriptor editClientDescriptor) { + assert clientToEdit != 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()); + Name updatedName = editClientDescriptor.getName().orElse(clientToEdit.getName()); + Phone updatedPhone = editClientDescriptor.getPhone().orElse(clientToEdit.getPhone()); + Email updatedEmail = editClientDescriptor.getEmail().orElse(clientToEdit.getEmail()); + Address updatedAddress = editClientDescriptor.getAddress().orElse(clientToEdit.getAddress()); + Set updatedTags = editClientDescriptor.getTags().orElse(clientToEdit.getTags()); - return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags); + return new Client(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags); } @Override @@ -117,35 +117,35 @@ public boolean equals(Object other) { EditCommand otherEditCommand = (EditCommand) other; return index.equals(otherEditCommand.index) - && editPersonDescriptor.equals(otherEditCommand.editPersonDescriptor); + && editClientDescriptor.equals(otherEditCommand.editClientDescriptor); } @Override public String toString() { return new ToStringBuilder(this) .add("index", index) - .add("editPersonDescriptor", editPersonDescriptor) + .add("editClientDescriptor", editClientDescriptor) .toString(); } /** - * Stores the details to edit the person with. Each non-empty field value will replace the - * corresponding field value of the person. + * Stores the details to edit the client with. Each non-empty field value will replace the + * corresponding field value of the client. */ - public static class EditPersonDescriptor { + public static class EditClientDescriptor { private Name name; private Phone phone; private Email email; private Address address; private Set tags; - public EditPersonDescriptor() {} + public EditClientDescriptor() {} /** * Copy constructor. * A defensive copy of {@code tags} is used internally. */ - public EditPersonDescriptor(EditPersonDescriptor toCopy) { + public EditClientDescriptor(EditClientDescriptor toCopy) { setName(toCopy.name); setPhone(toCopy.phone); setEmail(toCopy.email); @@ -216,16 +216,16 @@ public boolean equals(Object other) { } // instanceof handles nulls - if (!(other instanceof EditPersonDescriptor)) { + if (!(other instanceof EditClientDescriptor)) { return false; } - EditPersonDescriptor otherEditPersonDescriptor = (EditPersonDescriptor) other; - return Objects.equals(name, otherEditPersonDescriptor.name) - && Objects.equals(phone, otherEditPersonDescriptor.phone) - && Objects.equals(email, otherEditPersonDescriptor.email) - && Objects.equals(address, otherEditPersonDescriptor.address) - && Objects.equals(tags, otherEditPersonDescriptor.tags); + EditClientDescriptor otherEditClientDescriptor = (EditClientDescriptor) other; + return Objects.equals(name, otherEditClientDescriptor.name) + && Objects.equals(phone, otherEditClientDescriptor.phone) + && Objects.equals(email, otherEditClientDescriptor.email) + && Objects.equals(address, otherEditClientDescriptor.address) + && Objects.equals(tags, otherEditClientDescriptor.tags); } @Override diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/seedu/address/logic/commands/FindCommand.java index 72b9eddd3a7..e6000eaffe8 100644 --- a/src/main/java/seedu/address/logic/commands/FindCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindCommand.java @@ -5,17 +5,17 @@ import seedu.address.commons.util.ToStringBuilder; import seedu.address.logic.Messages; import seedu.address.model.Model; -import seedu.address.model.person.NameContainsKeywordsPredicate; +import seedu.address.model.client.NameContainsKeywordsPredicate; /** - * Finds and lists all persons in address book whose name contains any of the argument keywords. + * Finds and lists all clients 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 clients 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"; @@ -29,9 +29,9 @@ public FindCommand(NameContainsKeywordsPredicate predicate) { @Override public CommandResult execute(Model model) { requireNonNull(model); - model.updateFilteredPersonList(predicate); + model.updateFilteredClientList(predicate); return new CommandResult( - String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size())); + String.format(Messages.MESSAGE_CLIENTS_LISTED_OVERVIEW, model.getFilteredClientList().size())); } @Override diff --git a/src/main/java/seedu/address/logic/commands/ListCommand.java b/src/main/java/seedu/address/logic/commands/ListCommand.java index 84be6ad2596..0b75ea2ceda 100644 --- a/src/main/java/seedu/address/logic/commands/ListCommand.java +++ b/src/main/java/seedu/address/logic/commands/ListCommand.java @@ -1,24 +1,24 @@ package seedu.address.logic.commands; import static java.util.Objects.requireNonNull; -import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_CLIENTS; import seedu.address.model.Model; /** - * Lists all persons in the address book to the user. + * Lists all clients 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"; + public static final String MESSAGE_SUCCESS = "Listed all clients"; @Override public CommandResult execute(Model model) { requireNonNull(model); - model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); + model.updateFilteredClientList(PREDICATE_SHOW_ALL_CLIENTS); return new CommandResult(MESSAGE_SUCCESS); } } diff --git a/src/main/java/seedu/address/logic/commands/PriorityCommand.java b/src/main/java/seedu/address/logic/commands/PriorityCommand.java index b5edf11ffca..bcc892df02a 100644 --- a/src/main/java/seedu/address/logic/commands/PriorityCommand.java +++ b/src/main/java/seedu/address/logic/commands/PriorityCommand.java @@ -1,7 +1,7 @@ package seedu.address.logic.commands; import static java.util.Objects.requireNonNull; -import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_CLIENTS; import java.util.HashSet; import java.util.List; @@ -12,7 +12,7 @@ import seedu.address.logic.Messages; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; -import seedu.address.model.person.Person; +import seedu.address.model.client.Client; import seedu.address.model.tag.Tag; /** @@ -22,10 +22,10 @@ public class PriorityCommand extends Command { public static final String COMMAND_WORD = "priority"; - public static final String MESSAGE_PRIORITY_PERSON_SUCCESS = "Toggle Priority of Person: %1$s"; + public static final String MESSAGE_PRIORITY_CLIENT_SUCCESS = "Toggle Priority of Client: %1$s"; public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Marks the person identified by the index number used in the displayed person list as a priority.\n" + + ": Marks the client identified by the index number used in the displayed client list as a priority.\n" + "Parameters: INDEX (must be a positive integer)\n" + "Example: " + COMMAND_WORD + " 1"; @@ -36,7 +36,7 @@ public class PriorityCommand extends Command { private Set tags; /** - * @param index of the person in the filtered person list to mark as priority + * @param index of the client in the filtered client list to mark as priority */ public PriorityCommand(Index index) { requireNonNull(index); @@ -46,25 +46,25 @@ public PriorityCommand(Index index) { @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); - List lastShownList = model.getFilteredPersonList(); + List lastShownList = model.getFilteredClientList(); - Person personToPrioritise = getPersonFromIndex(lastShownList, index); - Person priorityPerson = togglePriorityTag(personToPrioritise); + Client clientToPrioritise = getClientFromIndex(lastShownList, index); + Client priorityClient = togglePriorityTag(clientToPrioritise); - model.setPerson(personToPrioritise, priorityPerson); - model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); - return new CommandResult(String.format(MESSAGE_PRIORITY_PERSON_SUCCESS, Messages.format(priorityPerson))); + model.setClient(clientToPrioritise, priorityClient); + model.updateFilteredClientList(PREDICATE_SHOW_ALL_CLIENTS); + return new CommandResult(String.format(MESSAGE_PRIORITY_CLIENT_SUCCESS, Messages.format(priorityClient))); } /** - * Creates and returns a {@code Person} with the details of {@code personToEdit} + * Creates and returns a {@code Client} with the details of {@code ClientToEdit} * With a new tag called priority */ - private static Person togglePriorityTag(Person personToEdit) throws CommandException { - assert personToEdit != null; + private static Client togglePriorityTag(Client clientToEdit) throws CommandException { + assert clientToEdit != null; // Creates a mutable set - Set tags = new HashSet<>(personToEdit.getTags()); + Set tags = new HashSet<>(clientToEdit.getTags()); // Toggles priority if (!isPriority(tags)) { @@ -75,11 +75,11 @@ private static Person togglePriorityTag(Person personToEdit) throws CommandExcep .collect(Collectors.toSet()); } - return new Person( - personToEdit.getName(), - personToEdit.getPhone(), - personToEdit.getEmail(), - personToEdit.getAddress(), + return new Client( + clientToEdit.getName(), + clientToEdit.getPhone(), + clientToEdit.getEmail(), + clientToEdit.getAddress(), tags ); } diff --git a/src/main/java/seedu/address/logic/parser/AddClientCommandParser.java b/src/main/java/seedu/address/logic/parser/AddClientCommandParser.java index 994c8c88a65..4a0b1f75e39 100644 --- a/src/main/java/seedu/address/logic/parser/AddClientCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddClientCommandParser.java @@ -12,11 +12,11 @@ import seedu.address.logic.commands.AddClientCommand; 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.client.Address; +import seedu.address.model.client.Client; +import seedu.address.model.client.Email; +import seedu.address.model.client.Name; +import seedu.address.model.client.Phone; import seedu.address.model.tag.Tag; /** @@ -45,9 +45,9 @@ public AddClientCommand parse(String args) throws ParseException { Address address = ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get()); Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); - Person person = new Person(name, phone, email, address, tagList); + Client client = new Client(name, phone, email, address, tagList); - return new AddClientCommand(person); + return new AddClientCommand(client); } /** diff --git a/src/main/java/seedu/address/logic/parser/EditCommandParser.java b/src/main/java/seedu/address/logic/parser/EditCommandParser.java index 46b3309a78b..bbd826ba9c8 100644 --- a/src/main/java/seedu/address/logic/parser/EditCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/EditCommandParser.java @@ -15,7 +15,7 @@ import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.EditCommand; -import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; +import seedu.address.logic.commands.EditCommand.EditClientDescriptor; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.tag.Tag; @@ -44,27 +44,27 @@ public EditCommand parse(String args) throws ParseException { argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS); - EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor(); + EditClientDescriptor editClientDescriptor = new EditClientDescriptor(); if (argMultimap.getValue(PREFIX_NAME).isPresent()) { - editPersonDescriptor.setName(ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get())); + editClientDescriptor.setName(ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get())); } if (argMultimap.getValue(PREFIX_PHONE).isPresent()) { - editPersonDescriptor.setPhone(ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get())); + editClientDescriptor.setPhone(ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get())); } if (argMultimap.getValue(PREFIX_EMAIL).isPresent()) { - editPersonDescriptor.setEmail(ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get())); + editClientDescriptor.setEmail(ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get())); } if (argMultimap.getValue(PREFIX_ADDRESS).isPresent()) { - editPersonDescriptor.setAddress(ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get())); + editClientDescriptor.setAddress(ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get())); } - parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editPersonDescriptor::setTags); + parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editClientDescriptor::setTags); - if (!editPersonDescriptor.isAnyFieldEdited()) { + if (!editClientDescriptor.isAnyFieldEdited()) { throw new ParseException(EditCommand.MESSAGE_NOT_EDITED); } - return new EditCommand(index, editPersonDescriptor); + return new EditCommand(index, editClientDescriptor); } /** diff --git a/src/main/java/seedu/address/logic/parser/FindCommandParser.java b/src/main/java/seedu/address/logic/parser/FindCommandParser.java index 2867bde857b..72e69cf2a76 100644 --- a/src/main/java/seedu/address/logic/parser/FindCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/FindCommandParser.java @@ -6,7 +6,7 @@ import seedu.address.logic.commands.FindCommand; import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.NameContainsKeywordsPredicate; +import seedu.address.model.client.NameContainsKeywordsPredicate; /** * Parses input arguments and creates a new FindCommand object diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index b117acb9c55..c8d156f60f6 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -9,10 +9,10 @@ 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.client.Address; +import seedu.address.model.client.Email; +import seedu.address.model.client.Name; +import seedu.address.model.client.Phone; import seedu.address.model.tag.Tag; /** diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index e1112253a9c..75b4611f35d 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -8,16 +8,13 @@ import seedu.address.commons.util.ToStringBuilder; import seedu.address.model.client.Client; import seedu.address.model.client.UniqueClientList; -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) + * Duplicates are not allowed (by .isSameClient comparison) */ public class AddressBook implements ReadOnlyAddressBook { - private final UniquePersonList persons; private final UniqueClientList clients; /* * The 'unusual' code block below is a non-static initialization block, sometimes used to avoid duplication @@ -27,14 +24,13 @@ public class AddressBook implements ReadOnlyAddressBook { * among constructors. */ { - persons = new UniquePersonList(); clients = new UniqueClientList(); } public AddressBook() {} /** - * Creates an AddressBook using the Persons in the {@code toBeCopied} + * Creates an AddressBook using the Clients in the {@code toBeCopied} */ public AddressBook(ReadOnlyAddressBook toBeCopied) { this(); @@ -44,13 +40,9 @@ public AddressBook(ReadOnlyAddressBook toBeCopied) { //// list overwrite operations /** - * Replaces the contents of the person list with {@code persons}. - * {@code persons} must not contain duplicate persons. + * Replaces the contents of the client list with {@code clients}. + * {@code clients} must not contain duplicate clients. */ - public void setPersons(List persons) { - this.persons.setPersons(persons); - } - public void setClients(List clients) { this.clients.setClients(clients); } @@ -61,47 +53,9 @@ public void setClients(List clients) { public void resetData(ReadOnlyAddressBook newData) { requireNonNull(newData); - setPersons(newData.getPersonList()); setClients(newData.getClientList()); } - //// 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); - } - //// client-level operations /** * Checks if the address book contains a specific client. @@ -148,26 +102,15 @@ public void removeClient(Client key) { /** * Returns a string representation of the address book. * - * @return A string containing details of persons and clients. + * @return A string containing details of clients. */ @Override public String toString() { return new ToStringBuilder(this) - .add("persons", persons) .add("clients", clients) .toString(); } - /** - * Retrieves an unmodifiable list of persons in the address book. - * - * @return An observable list of persons. - */ - @Override - public ObservableList getPersonList() { - return persons.asUnmodifiableObservableList(); - } - /** * Retrieves an unmodifiable list of clients in the address book. * @@ -196,16 +139,16 @@ public boolean equals(Object other) { } AddressBook otherAddressBook = (AddressBook) other; - return persons.equals(otherAddressBook.persons) && clients.equals(otherAddressBook.clients); + return clients.equals(otherAddressBook.clients) && clients.equals(otherAddressBook.clients); } /** * Computes the hash code for the address book. * - * @return The hash code based on persons and clients. + * @return The hash code based on clients. */ @Override public int hashCode() { - return persons.hashCode(); + return clients.hashCode(); } } diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index d54df471c1f..70a893c5fc9 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -5,14 +5,14 @@ import javafx.collections.ObservableList; import seedu.address.commons.core.GuiSettings; -import seedu.address.model.person.Person; +import seedu.address.model.client.Client; /** * 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_CLIENTS = unused -> true; /** * Replaces user prefs data with the data in {@code userPrefs}. @@ -53,35 +53,35 @@ 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 client with the same identity as {@code client} exists in the address book. */ - boolean hasPerson(Person person); + boolean hasClient(Client client); /** - * Deletes the given person. - * The person must exist in the address book. + * Deletes the given client. + * The client must exist in the address book. */ - void deletePerson(Person target); + void deleteClient(Client target); /** - * Adds the given person. - * {@code person} must not already exist in the address book. + * Adds the given client. + * {@code client} must not already exist in the address book. */ - void addPerson(Person person); + void addClient(Client client); /** - * Replaces the given person {@code target} with {@code editedPerson}. + * Replaces the given client {@code target} with {@code editedClient}. * {@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 client identity of {@code editedClient} must not be the same as another existing client in the address book. */ - void setPerson(Person target, Person editedPerson); + void setClient(Client target, Client editedClient); - /** Returns an unmodifiable view of the filtered person list */ - ObservableList getFilteredPersonList(); + /** Returns an unmodifiable view of the filtered client list */ + ObservableList getFilteredClientList(); /** - * Updates the filter of the filtered person list to filter by the given {@code predicate}. + * Updates the filter of the filtered client list to filter by the given {@code predicate}. * @throws NullPointerException if {@code predicate} is null. */ - void updateFilteredPersonList(Predicate predicate); + void updateFilteredClientList(Predicate predicate); } diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index 57bc563fde6..2d425c8d37b 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -11,7 +11,7 @@ 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.address.model.client.Client; /** * 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 filteredClients; /** * Initializes a ModelManager with the given addressBook and userPrefs. @@ -33,7 +33,7 @@ public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyUserPrefs userPrefs this.addressBook = new AddressBook(addressBook); this.userPrefs = new UserPrefs(userPrefs); - filteredPersons = new FilteredList<>(this.addressBook.getPersonList()); + filteredClients = new FilteredList<>(this.addressBook.getClientList()); } public ModelManager() { @@ -88,44 +88,44 @@ public ReadOnlyAddressBook getAddressBook() { } @Override - public boolean hasPerson(Person person) { - requireNonNull(person); - return addressBook.hasPerson(person); + public boolean hasClient(Client client) { + requireNonNull(client); + return addressBook.hasClient(client); } @Override - public void deletePerson(Person target) { - addressBook.removePerson(target); + public void deleteClient(Client target) { + addressBook.removeClient(target); } @Override - public void addPerson(Person person) { - addressBook.addPerson(person); - updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); + public void addClient(Client client) { + addressBook.addClient(client); + updateFilteredClientList(PREDICATE_SHOW_ALL_CLIENTS); } @Override - public void setPerson(Person target, Person editedPerson) { - requireAllNonNull(target, editedPerson); + public void setClient(Client target, Client editedClient) { + requireAllNonNull(target, editedClient); - addressBook.setPerson(target, editedPerson); + addressBook.setClient(target, editedClient); } - //=========== Filtered Person List Accessors ============================================================= + //=========== Filtered Client 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 Client} backed by the internal list of * {@code versionedAddressBook} */ @Override - public ObservableList getFilteredPersonList() { - return filteredPersons; + public ObservableList getFilteredClientList() { + return filteredClients; } @Override - public void updateFilteredPersonList(Predicate predicate) { + public void updateFilteredClientList(Predicate predicate) { requireNonNull(predicate); - filteredPersons.setPredicate(predicate); + filteredClients.setPredicate(predicate); } @Override @@ -142,7 +142,7 @@ public boolean equals(Object other) { ModelManager otherModelManager = (ModelManager) other; return addressBook.equals(otherModelManager.addressBook) && userPrefs.equals(otherModelManager.userPrefs) - && filteredPersons.equals(otherModelManager.filteredPersons); + && filteredClients.equals(otherModelManager.filteredClients); } } diff --git a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java index 3f0fc82d2a3..305685bf782 100644 --- a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java +++ b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java @@ -2,19 +2,12 @@ import javafx.collections.ObservableList; import seedu.address.model.client.Client; -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(); - /** * Returns an unmodifiable view of the clients list. * This list will not contain any duplicate clients. diff --git a/src/main/java/seedu/address/model/client/Address.java b/src/main/java/seedu/address/model/client/Address.java index b9e476d5ee7..3d15fd9884d 100644 --- a/src/main/java/seedu/address/model/client/Address.java +++ b/src/main/java/seedu/address/model/client/Address.java @@ -31,7 +31,7 @@ public Address(String address) { } /** - * Returns true if a given string is a valid address. + * Returns true if a given string is a valid email. */ public static boolean isValidAddress(String test) { return test.matches(VALIDATION_REGEX); diff --git a/src/main/java/seedu/address/model/client/Client.java b/src/main/java/seedu/address/model/client/Client.java index 29939725d24..38a812f2062 100644 --- a/src/main/java/seedu/address/model/client/Client.java +++ b/src/main/java/seedu/address/model/client/Client.java @@ -2,9 +2,13 @@ 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.commons.util.ToStringBuilder; +import seedu.address.model.tag.Tag; /** * Represents a Client in the address book. @@ -19,16 +23,18 @@ public class Client { // Data fields private final Address address; + private final Set tags = new HashSet<>(); /** * Every field must be present and not null. */ - public Client(Name name, Phone phone, Email email, Address address) { - requireAllNonNull(name, phone, email, address); + public Client(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() { @@ -47,6 +53,13 @@ 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 clients have the same name. @@ -62,8 +75,8 @@ public boolean isSameClient(Client otherClient) { } /** - * Returns true if both Clients have the same identity and data fields. - * This defines a stronger notion of equality between two Clients. + * Returns true if both clients have the same identity and data fields. + * This defines a stronger notion of equality between two clients. */ @Override public boolean equals(Object other) { @@ -80,13 +93,14 @@ public boolean equals(Object other) { return name.equals(otherClient.name) && phone.equals(otherClient.phone) && email.equals(otherClient.email) - && address.equals(otherClient.address); + && address.equals(otherClient.address) + && tags.equals(otherClient.tags); } @Override public int hashCode() { // use this method for custom fields hashing instead of implementing your own - return Objects.hash(name, phone, email, address); + return Objects.hash(name, phone, email, address, tags); } @Override @@ -96,8 +110,8 @@ public String toString() { .add("phone", phone) .add("email", email) .add("address", address) + .add("tags", tags) .toString(); } } - diff --git a/src/main/java/seedu/address/model/client/Email.java b/src/main/java/seedu/address/model/client/Email.java index 9ea195364f9..5d3f02d7324 100644 --- a/src/main/java/seedu/address/model/client/Email.java +++ b/src/main/java/seedu/address/model/client/Email.java @@ -63,11 +63,11 @@ public boolean equals(Object other) { } // instanceof handles nulls - if (!(other instanceof seedu.address.model.client.Email)) { + if (!(other instanceof Email)) { return false; } - seedu.address.model.client.Email otherEmail = (seedu.address.model.client.Email) other; + Email otherEmail = (Email) other; return value.equals(otherEmail.value); } @@ -77,4 +77,3 @@ public int hashCode() { } } - diff --git a/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/client/NameContainsKeywordsPredicate.java similarity index 84% rename from src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java rename to src/main/java/seedu/address/model/client/NameContainsKeywordsPredicate.java index 62d19be2977..43216a4373a 100644 --- a/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java +++ b/src/main/java/seedu/address/model/client/NameContainsKeywordsPredicate.java @@ -1,4 +1,4 @@ -package seedu.address.model.person; +package seedu.address.model.client; import java.util.List; import java.util.function.Predicate; @@ -7,9 +7,9 @@ import seedu.address.commons.util.ToStringBuilder; /** - * Tests that a {@code Person}'s {@code Name} matches any of the keywords given. + * Tests that a {@code Client}'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) { @@ -17,9 +17,9 @@ public NameContainsKeywordsPredicate(List keywords) { } @Override - public boolean test(Person person) { + public boolean test(Client client) { return keywords.stream() - .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getName().fullName, keyword)); + .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(client.getName().fullName, keyword)); } @Override diff --git a/src/main/java/seedu/address/model/client/Phone.java b/src/main/java/seedu/address/model/client/Phone.java index 1cdb883112c..d6ede5e9299 100644 --- a/src/main/java/seedu/address/model/client/Phone.java +++ b/src/main/java/seedu/address/model/client/Phone.java @@ -45,11 +45,11 @@ public boolean equals(Object other) { } // instanceof handles nulls - if (!(other instanceof seedu.address.model.client.Phone)) { + if (!(other instanceof Phone)) { return false; } - seedu.address.model.client.Phone otherPhone = (seedu.address.model.client.Phone) other; + Phone otherPhone = (Phone) other; return value.equals(otherPhone.value); } diff --git a/src/main/java/seedu/address/model/client/UniqueClientList.java b/src/main/java/seedu/address/model/client/UniqueClientList.java index 8b89dac3ec6..1ff60ea30f7 100644 --- a/src/main/java/seedu/address/model/client/UniqueClientList.java +++ b/src/main/java/seedu/address/model/client/UniqueClientList.java @@ -11,7 +11,6 @@ import seedu.address.model.client.exceptions.ClientNotFoundException; import seedu.address.model.client.exceptions.DuplicateClientException; - /** * A list of clients that enforces uniqueness between its elements and does not allow nulls. * A client is considered unique by comparing using {@code Client#isSameClient(Client)}. As such, adding and updating of 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 469a2cc9a1e..00000000000 --- a/src/main/java/seedu/address/model/person/Address.java +++ /dev/null @@ -1,65 +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) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof Address)) { - return false; - } - - Address otherAddress = (Address) other; - return value.equals(otherAddress.value); - } - - @Override - public int hashCode() { - return value.hashCode(); - } - -} diff --git a/src/main/java/seedu/address/model/person/Email.java b/src/main/java/seedu/address/model/person/Email.java deleted file mode 100644 index c62e512bc29..00000000000 --- a/src/main/java/seedu/address/model/person/Email.java +++ /dev/null @@ -1,79 +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 email in the address book. - * Guarantees: immutable; is valid as declared in {@link #isValidEmail(String)} - */ -public class Email { - - private static final String SPECIAL_CHARACTERS = "+_.-"; - public static final String MESSAGE_CONSTRAINTS = "Emails should be of the format local-part@domain " - + "and adhere to the following constraints:\n" - + "1. The local-part should only contain alphanumeric characters and these special characters, excluding " - + "the parentheses, (" + SPECIAL_CHARACTERS + "). The local-part may not start or end with any special " - + "characters.\n" - + "2. This is followed by a '@' and then a domain name. The domain name is made up of domain labels " - + "separated by periods.\n" - + "The domain name must:\n" - + " - end with a domain label at least 2 characters long\n" - + " - have each domain label start and end with alphanumeric characters\n" - + " - have each domain label consist of alphanumeric characters, separated only by hyphens, if any."; - // alphanumeric and special characters - private static final String ALPHANUMERIC_NO_UNDERSCORE = "[^\\W_]+"; // alphanumeric characters except underscore - private static final String LOCAL_PART_REGEX = "^" + ALPHANUMERIC_NO_UNDERSCORE + "([" + SPECIAL_CHARACTERS + "]" - + ALPHANUMERIC_NO_UNDERSCORE + ")*"; - private static final String DOMAIN_PART_REGEX = ALPHANUMERIC_NO_UNDERSCORE - + "(-" + ALPHANUMERIC_NO_UNDERSCORE + ")*"; - private static final String DOMAIN_LAST_PART_REGEX = "(" + DOMAIN_PART_REGEX + "){2,}$"; // At least two chars - private static final String DOMAIN_REGEX = "(" + DOMAIN_PART_REGEX + "\\.)*" + DOMAIN_LAST_PART_REGEX; - public static final String VALIDATION_REGEX = LOCAL_PART_REGEX + "@" + DOMAIN_REGEX; - - public final String value; - - /** - * Constructs an {@code Email}. - * - * @param email A valid email address. - */ - public Email(String email) { - requireNonNull(email); - checkArgument(isValidEmail(email), MESSAGE_CONSTRAINTS); - value = email; - } - - /** - * Returns if a given string is a valid email. - */ - public static boolean isValidEmail(String test) { - return test.matches(VALIDATION_REGEX); - } - - @Override - public String toString() { - return value; - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof Email)) { - return false; - } - - Email otherEmail = (Email) other; - return value.equals(otherEmail.value); - } - - @Override - public int hashCode() { - return value.hashCode(); - } - -} diff --git a/src/main/java/seedu/address/model/person/Name.java b/src/main/java/seedu/address/model/person/Name.java deleted file mode 100644 index 173f15b9b00..00000000000 --- a/src/main/java/seedu/address/model/person/Name.java +++ /dev/null @@ -1,67 +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 name in the address book. - * Guarantees: immutable; is valid as declared in {@link #isValidName(String)} - */ -public class Name { - - public static final String MESSAGE_CONSTRAINTS = - "Names should only contain alphanumeric characters and spaces, 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 = "[\\p{Alnum}][\\p{Alnum} ]*"; - - public final String fullName; - - /** - * Constructs a {@code Name}. - * - * @param name A valid name. - */ - public Name(String name) { - requireNonNull(name); - checkArgument(isValidName(name), MESSAGE_CONSTRAINTS); - fullName = name; - } - - /** - * Returns true if a given string is a valid name. - */ - public static boolean isValidName(String test) { - return test.matches(VALIDATION_REGEX); - } - - - @Override - public String toString() { - return fullName; - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof Name)) { - return false; - } - - Name otherName = (Name) other; - return fullName.equals(otherName.fullName); - } - - @Override - public int hashCode() { - return fullName.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 abe8c46b535..00000000000 --- a/src/main/java/seedu/address/model/person/Person.java +++ /dev/null @@ -1,117 +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.commons.util.ToStringBuilder; -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 have the same name. - * 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()); - } - - /** - * 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; - } - - // instanceof handles nulls - if (!(other instanceof Person)) { - return false; - } - - Person otherPerson = (Person) other; - return name.equals(otherPerson.name) - && phone.equals(otherPerson.phone) - && email.equals(otherPerson.email) - && address.equals(otherPerson.address) - && tags.equals(otherPerson.tags); - } - - @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() { - return new ToStringBuilder(this) - .add("name", name) - .add("phone", phone) - .add("email", email) - .add("address", address) - .add("tags", tags) - .toString(); - } - -} diff --git a/src/main/java/seedu/address/model/person/Phone.java b/src/main/java/seedu/address/model/person/Phone.java deleted file mode 100644 index d733f63d739..00000000000 --- a/src/main/java/seedu/address/model/person/Phone.java +++ /dev/null @@ -1,61 +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 phone number in the address book. - * Guarantees: immutable; is valid as declared in {@link #isValidPhone(String)} - */ -public class Phone { - - - public static final String MESSAGE_CONSTRAINTS = - "Phone numbers should only contain numbers, and it should be at least 3 digits long"; - public static final String VALIDATION_REGEX = "\\d{3,}"; - public final String value; - - /** - * Constructs a {@code Phone}. - * - * @param phone A valid phone number. - */ - public Phone(String phone) { - requireNonNull(phone); - checkArgument(isValidPhone(phone), MESSAGE_CONSTRAINTS); - value = phone; - } - - /** - * Returns true if a given string is a valid phone number. - */ - public static boolean isValidPhone(String test) { - return test.matches(VALIDATION_REGEX); - } - - @Override - public String toString() { - return value; - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof Phone)) { - return false; - } - - Phone otherPhone = (Phone) other; - return value.equals(otherPhone.value); - } - - @Override - public int hashCode() { - return value.hashCode(); - } - -} 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 cc0a68d79f9..00000000000 --- a/src/main/java/seedu/address/model/person/UniquePersonList.java +++ /dev/null @@ -1,150 +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) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof UniquePersonList)) { - return false; - } - - UniquePersonList otherUniquePersonList = (UniquePersonList) other; - return internalList.equals(otherUniquePersonList.internalList); - } - - @Override - public int hashCode() { - return internalList.hashCode(); - } - - @Override - public String toString() { - return internalList.toString(); - } - - /** - * 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 index 1806da4facf..7d12623d7b7 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -6,35 +6,35 @@ 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.client.Address; +import seedu.address.model.client.Client; +import seedu.address.model.client.Email; +import seedu.address.model.client.Name; +import seedu.address.model.client.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"), + public static Client[] getSampleClients() { + return new Client[] { + new Client(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 Client(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 Client(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 Client(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 Client(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 Client(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"), new Address("Blk 45 Aljunied Street 85, #11-31"), getTagSet("colleagues")) }; @@ -42,8 +42,8 @@ public static Person[] getSamplePersons() { public static ReadOnlyAddressBook getSampleAddressBook() { AddressBook sampleAb = new AddressBook(); - for (Person samplePerson : getSamplePersons()) { - sampleAb.addPerson(samplePerson); + for (Client sampleClient : getSampleClients()) { + sampleAb.addClient(sampleClient); } return sampleAb; } diff --git a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java b/src/main/java/seedu/address/storage/JsonAdaptedClient.java similarity index 72% rename from src/main/java/seedu/address/storage/JsonAdaptedPerson.java rename to src/main/java/seedu/address/storage/JsonAdaptedClient.java index bd1ca0f56c8..9a890a826c7 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedClient.java @@ -10,19 +10,19 @@ 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.client.Address; +import seedu.address.model.client.Client; +import seedu.address.model.client.Email; +import seedu.address.model.client.Name; +import seedu.address.model.client.Phone; import seedu.address.model.tag.Tag; /** - * Jackson-friendly version of {@link Person}. + * Jackson-friendly version of {@link Client}. */ -class JsonAdaptedPerson { +class JsonAdaptedClient { - public static final String MISSING_FIELD_MESSAGE_FORMAT = "Person's %s field is missing!"; + public static final String MISSING_FIELD_MESSAGE_FORMAT = "Client's %s field is missing!"; private final String name; private final String phone; @@ -31,10 +31,10 @@ class JsonAdaptedPerson { private final List tags = new ArrayList<>(); /** - * Constructs a {@code JsonAdaptedPerson} with the given person details. + * Constructs a {@code JsonAdaptedClient} with the given client details. */ @JsonCreator - public JsonAdaptedPerson(@JsonProperty("name") String name, @JsonProperty("phone") String phone, + public JsonAdaptedClient(@JsonProperty("name") String name, @JsonProperty("phone") String phone, @JsonProperty("email") String email, @JsonProperty("address") String address, @JsonProperty("tags") List tags) { this.name = name; @@ -47,9 +47,9 @@ public JsonAdaptedPerson(@JsonProperty("name") String name, @JsonProperty("phone } /** - * Converts a given {@code Person} into this class for Jackson use. + * Converts a given {@code Client} into this class for Jackson use. */ - public JsonAdaptedPerson(Person source) { + public JsonAdaptedClient(Client source) { name = source.getName().fullName; phone = source.getPhone().value; email = source.getEmail().value; @@ -60,14 +60,14 @@ public JsonAdaptedPerson(Person source) { } /** - * Converts this Jackson-friendly adapted person object into the model's {@code Person} object. + * Converts this Jackson-friendly adapted client object into the model's {@code Client} object. * - * @throws IllegalValueException if there were any data constraints violated in the adapted person. + * @throws IllegalValueException if there were any data constraints violated in the adapted client. */ - public Person toModelType() throws IllegalValueException { - final List personTags = new ArrayList<>(); + public Client toModelType() throws IllegalValueException { + final List clientTags = new ArrayList<>(); for (JsonAdaptedTag tag : tags) { - personTags.add(tag.toModelType()); + clientTags.add(tag.toModelType()); } if (name == null) { @@ -102,8 +102,8 @@ public Person toModelType() throws IllegalValueException { } final Address modelAddress = new Address(address); - final Set modelTags = new HashSet<>(personTags); - return new Person(modelName, modelPhone, modelEmail, modelAddress, modelTags); + final Set modelTags = new HashSet<>(clientTags); + return new Client(modelName, modelPhone, modelEmail, modelAddress, modelTags); } } diff --git a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java b/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java index 5efd834091d..d9bc46d2dbf 100644 --- a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java +++ b/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java @@ -11,7 +11,7 @@ import seedu.address.commons.exceptions.IllegalValueException; import seedu.address.model.AddressBook; import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.person.Person; +import seedu.address.model.client.Client; /** * 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_CLIENT = "Clients list contains duplicate client(s)."; - private final List persons = new ArrayList<>(); + private final List clients = new ArrayList<>(); /** - * Constructs a {@code JsonSerializableAddressBook} with the given persons. + * Constructs a {@code JsonSerializableAddressBook} with the given clients. */ @JsonCreator - public JsonSerializableAddressBook(@JsonProperty("persons") List persons) { - this.persons.addAll(persons); + public JsonSerializableAddressBook(@JsonProperty("clients") List clients) { + this.clients.addAll(clients); } /** @@ -37,7 +37,7 @@ public JsonSerializableAddressBook(@JsonProperty("persons") List { +public class ClientCard extends UiPart { - private static final String FXML = "PersonListCard.fxml"; + private static final String FXML = "ClientListCard.fxml"; /** * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX. @@ -25,7 +25,7 @@ public class PersonCard extends UiPart { * @see
    The issue on AddressBook level 4 */ - public final Person person; + public final Client client; @FXML private HBox cardPane; @@ -43,17 +43,17 @@ public class PersonCard extends UiPart { private FlowPane tags; /** - * Creates a {@code PersonCode} with the given {@code Person} and index to display. + * Creates a {@code ClientCode} with the given {@code Client} and index to display. */ - public PersonCard(Person person, int displayedIndex) { + public ClientCard(Client client, int displayedIndex) { super(FXML); - this.person = person; + this.client = client; 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(client.getName().fullName); + phone.setText(client.getPhone().value); + address.setText(client.getAddress().value); + email.setText(client.getEmail().value); + client.getTags().stream() .sorted(Comparator.comparing(tag -> !tag.tagName.equals("Priority")) .thenComparing(tag -> tag.tagName)) .forEach(tag -> { diff --git a/src/main/java/seedu/address/ui/ClientListPanel.java b/src/main/java/seedu/address/ui/ClientListPanel.java new file mode 100644 index 00000000000..1b64ffa52c2 --- /dev/null +++ b/src/main/java/seedu/address/ui/ClientListPanel.java @@ -0,0 +1,49 @@ +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.client.Client; + +/** + * Panel containing the list of clients. + */ +public class ClientListPanel extends UiPart { + private static final String FXML = "ClientListPanel.fxml"; + private final Logger logger = LogsCenter.getLogger(ClientListPanel.class); + + @FXML + private ListView clientListView; + + /** + * Creates a {@code ClientListPanel} with the given {@code ObservableList}. + */ + public ClientListPanel(ObservableList clientList) { + super(FXML); + clientListView.setItems(clientList); + clientListView.setCellFactory(listView -> new ClientListViewCell()); + } + + /** + * Custom {@code ListCell} that displays the graphics of a {@code Client} using a {@code ClientCard}. + */ + class ClientListViewCell extends ListCell { + @Override + protected void updateItem(Client client, boolean empty) { + super.updateItem(client, empty); + + if (empty || client == null) { + setGraphic(null); + setText(null); + } else { + setGraphic(new ClientCard(client, getIndex() + 1).getRoot()); + } + } + } + +} diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index 79e74ef37c0..22a4c686e4f 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -31,7 +31,7 @@ public class MainWindow extends UiPart { private Logic logic; // Independent Ui parts residing in this Ui container - private PersonListPanel personListPanel; + private ClientListPanel clientListPanel; private ResultDisplay resultDisplay; private HelpWindow helpWindow; @@ -42,7 +42,7 @@ public class MainWindow extends UiPart { private MenuItem helpMenuItem; @FXML - private StackPane personListPanelPlaceholder; + private StackPane clientListPanelPlaceholder; @FXML private StackPane resultDisplayPlaceholder; @@ -110,8 +110,8 @@ 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()); + clientListPanel = new ClientListPanel(logic.getFilteredClientList()); + clientListPanelPlaceholder.getChildren().add(clientListPanel.getRoot()); resultDisplay = new ResultDisplay(); resultDisplayPlaceholder.getChildren().add(resultDisplay.getRoot()); @@ -163,8 +163,8 @@ private void handleExit() { primaryStage.hide(); } - public PersonListPanel getPersonListPanel() { - return personListPanel; + public ClientListPanel getClientListPanel() { + return clientListPanel; } /** 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/resources/view/PersonListCard.fxml b/src/main/resources/view/ClientListCard.fxml similarity index 100% rename from src/main/resources/view/PersonListCard.fxml rename to src/main/resources/view/ClientListCard.fxml diff --git a/src/main/resources/view/PersonListPanel.fxml b/src/main/resources/view/ClientListPanel.fxml similarity index 77% rename from src/main/resources/view/PersonListPanel.fxml rename to src/main/resources/view/ClientListPanel.fxml index a1bb6bbace8..8f6f00f1faf 100644 --- a/src/main/resources/view/PersonListPanel.fxml +++ b/src/main/resources/view/ClientListPanel.fxml @@ -4,5 +4,5 @@ - + diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml index 7778f666a0a..d2e12160757 100644 --- a/src/main/resources/view/MainWindow.fxml +++ b/src/main/resources/view/MainWindow.fxml @@ -46,11 +46,11 @@ - + - + diff --git a/src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json b/src/test/data/JsonAddressBookStorageTest/invalidAndValidClientAddressBook.json similarity index 67% rename from src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json rename to src/test/data/JsonAddressBookStorageTest/invalidAndValidClientAddressBook.json index 6a4d2b7181c..25e54003c40 100644 --- a/src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json +++ b/src/test/data/JsonAddressBookStorageTest/invalidAndValidClientAddressBook.json @@ -1,11 +1,11 @@ { - "persons": [ { - "name": "Valid Person", + "clients": [ { + "name": "Valid Client", "phone": "9482424", "email": "hans@example.com", "address": "4th street" }, { - "name": "Person With Invalid Phone Field", + "name": "Client With Invalid Phone Field", "phone": "948asdf2424", "email": "hans@example.com", "address": "4th street" diff --git a/src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json b/src/test/data/JsonAddressBookStorageTest/invalidClientAddressBook.json similarity index 54% rename from src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json rename to src/test/data/JsonAddressBookStorageTest/invalidClientAddressBook.json index ccd21f7d1a9..dbe2d487467 100644 --- a/src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json +++ b/src/test/data/JsonAddressBookStorageTest/invalidClientAddressBook.json @@ -1,6 +1,6 @@ { - "persons": [ { - "name": "Person with invalid name field: Ha!ns Mu@ster", + "clients": [ { + "name": "Client with invalid name field: Ha!ns Mu@ster", "phone": "9482424", "email": "hans@example.com", "address": "4th street" diff --git a/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/duplicateClientAddressBook.json similarity index 94% rename from src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json rename to src/test/data/JsonSerializableAddressBookTest/duplicateClientAddressBook.json index a7427fe7aa2..caa17d1ef65 100644 --- a/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json +++ b/src/test/data/JsonSerializableAddressBookTest/duplicateClientAddressBook.json @@ -1,5 +1,5 @@ { - "persons": [ { + "clients": [ { "name": "Alice Pauline", "phone": "94351253", "email": "alice@example.com", diff --git a/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/invalidClientAddressBook.json similarity index 87% rename from src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json rename to src/test/data/JsonSerializableAddressBookTest/invalidClientAddressBook.json index ad3f135ae42..04283a0b56e 100644 --- a/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json +++ b/src/test/data/JsonSerializableAddressBookTest/invalidClientAddressBook.json @@ -1,5 +1,5 @@ { - "persons": [ { + "clients": [ { "name": "Hans Muster", "phone": "9482424", "email": "invalid@email!3e", diff --git a/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/typicalClientsAddressBook.json similarity index 88% rename from src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json rename to src/test/data/JsonSerializableAddressBookTest/typicalClientsAddressBook.json index ede71906488..18fe61ebdc4 100644 --- a/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json +++ b/src/test/data/JsonSerializableAddressBookTest/typicalClientsAddressBook.json @@ -1,6 +1,6 @@ { - "_comment": "AddressBook save file which contains the same Person values as in TypicalPersons#getTypicalAddressBook()", - "persons" : [ { + "_comment": "AddressBook save file which contains the same Client values as in TypicalClients#getTypicalAddressBook()", + "clients" : [ { "name" : "Alice Pauline", "phone" : "94351253", "email" : "alice@example.com", diff --git a/src/test/java/seedu/address/commons/core/index/IndexTest.java b/src/test/java/seedu/address/commons/core/index/IndexTest.java index fc395ab964b..2c4531f9896 100644 --- a/src/test/java/seedu/address/commons/core/index/IndexTest.java +++ b/src/test/java/seedu/address/commons/core/index/IndexTest.java @@ -39,23 +39,23 @@ public void createZeroBasedIndex() { @Test public void equals() { - final Index fifthPersonIndex = Index.fromOneBased(5); + final Index fifthClientIndex = Index.fromOneBased(5); // same values -> returns true - assertTrue(fifthPersonIndex.equals(Index.fromOneBased(5))); - assertTrue(fifthPersonIndex.equals(Index.fromZeroBased(4))); + assertTrue(fifthClientIndex.equals(Index.fromOneBased(5))); + assertTrue(fifthClientIndex.equals(Index.fromZeroBased(4))); // same object -> returns true - assertTrue(fifthPersonIndex.equals(fifthPersonIndex)); + assertTrue(fifthClientIndex.equals(fifthClientIndex)); // null -> returns false - assertFalse(fifthPersonIndex.equals(null)); + assertFalse(fifthClientIndex.equals(null)); // different types -> returns false - assertFalse(fifthPersonIndex.equals(5.0f)); + assertFalse(fifthClientIndex.equals(5.0f)); // different index -> returns false - assertFalse(fifthPersonIndex.equals(Index.fromOneBased(1))); + assertFalse(fifthClientIndex.equals(Index.fromOneBased(1))); } @Test diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/address/logic/LogicManagerTest.java index ffab254cdf6..e2e6324375c 100644 --- a/src/test/java/seedu/address/logic/LogicManagerTest.java +++ b/src/test/java/seedu/address/logic/LogicManagerTest.java @@ -1,14 +1,14 @@ package seedu.address.logic; import static org.junit.jupiter.api.Assertions.assertEquals; -import static seedu.address.logic.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX; +import static seedu.address.logic.Messages.MESSAGE_INVALID_CLIENT_DISPLAYED_INDEX; import static seedu.address.logic.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.address.testutil.TypicalClients.AMY; import java.io.IOException; import java.nio.file.AccessDeniedException; @@ -27,11 +27,11 @@ import seedu.address.model.ModelManager; import seedu.address.model.ReadOnlyAddressBook; import seedu.address.model.UserPrefs; -import seedu.address.model.person.Person; +import seedu.address.model.client.Client; import seedu.address.storage.JsonAddressBookStorage; import seedu.address.storage.JsonUserPrefsStorage; import seedu.address.storage.StorageManager; -import seedu.address.testutil.PersonBuilder; +import seedu.address.testutil.ClientBuilder; public class LogicManagerTest { private static final IOException DUMMY_IO_EXCEPTION = new IOException("dummy IO exception"); @@ -61,7 +61,7 @@ public void execute_invalidCommandFormat_throwsParseException() { @Test public void execute_commandExecutionError_throwsCommandException() { String deleteClientCommand = "deleteclient 9"; - assertCommandException(deleteClientCommand, MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandException(deleteClientCommand, MESSAGE_INVALID_CLIENT_DISPLAYED_INDEX); } @Test @@ -83,8 +83,8 @@ public void execute_storageThrowsAdException_throwsCommandException() { } @Test - public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException() { - assertThrows(UnsupportedOperationException.class, () -> logic.getFilteredPersonList().remove(0)); + public void getFilteredClientList_modifyList_throwsUnsupportedOperationException() { + assertThrows(UnsupportedOperationException.class, () -> logic.getFilteredClientList().remove(0)); } /** @@ -167,9 +167,9 @@ public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) // Triggers the saveAddressBook method by executing an add command String addCommand = AddClientCommand.COMMAND_WORD + NAME_DESC_AMY + PHONE_DESC_AMY + EMAIL_DESC_AMY + ADDRESS_DESC_AMY; - Person expectedPerson = new PersonBuilder(AMY).withTags().build(); + Client expectedClient = new ClientBuilder(AMY).withTags().build(); ModelManager expectedModel = new ModelManager(); - expectedModel.addPerson(expectedPerson); + expectedModel.addClient(expectedClient); assertCommandFailure(addCommand, CommandException.class, expectedMessage, expectedModel); } } diff --git a/src/test/java/seedu/address/logic/commands/AddClientCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/AddClientCommandIntegrationTest.java index 55b574bd910..cd1c9eb6a16 100644 --- a/src/test/java/seedu/address/logic/commands/AddClientCommandIntegrationTest.java +++ b/src/test/java/seedu/address/logic/commands/AddClientCommandIntegrationTest.java @@ -2,7 +2,7 @@ import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; +import static seedu.address.testutil.TypicalClients.getTypicalAddressBook; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -11,8 +11,8 @@ 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; +import seedu.address.model.client.Client; +import seedu.address.testutil.ClientBuilder; /** * Contains integration tests (interaction with the Model) for {@code AddClientCommand}. @@ -27,22 +27,22 @@ public void setUp() { } @Test - public void execute_newPerson_success() { - Person validPerson = new PersonBuilder().build(); + public void execute_newClient_success() { + Client validClient = new ClientBuilder().build(); Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); - expectedModel.addPerson(validPerson); + expectedModel.addClient(validClient); - assertCommandSuccess(new AddClientCommand(validPerson), model, - String.format(AddClientCommand.MESSAGE_SUCCESS, Messages.format(validPerson)), + assertCommandSuccess(new AddClientCommand(validClient), model, + String.format(AddClientCommand.MESSAGE_SUCCESS, Messages.format(validClient)), expectedModel); } @Test - public void execute_duplicatePerson_throwsCommandException() { - Person personInList = model.getAddressBook().getPersonList().get(0); - assertCommandFailure(new AddClientCommand(personInList), model, - AddClientCommand.MESSAGE_DUPLICATE_PERSON); + public void execute_duplicateClient_throwsCommandException() { + Client clientInList = model.getAddressBook().getClientList().get(0); + assertCommandFailure(new AddClientCommand(clientInList), model, + AddClientCommand.MESSAGE_DUPLICATE_CLIENT); } } diff --git a/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java b/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java index 3cdf4a0c21e..d516d587657 100644 --- a/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java @@ -5,7 +5,7 @@ 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.address.testutil.TypicalPersons.ALICE; +import static seedu.address.testutil.TypicalClients.ALICE; import java.nio.file.Path; import java.util.ArrayList; @@ -22,42 +22,42 @@ 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.address.model.client.Client; +import seedu.address.testutil.ClientBuilder; public class AddClientCommandTest { @Test - public void constructor_nullPerson_throwsNullPointerException() { + public void constructor_nullClient_throwsNullPointerException() { assertThrows(NullPointerException.class, () -> new AddClientCommand(null)); } @Test - public void execute_personAcceptedByModel_addSuccessful() throws Exception { - ModelStubAcceptingPersonAdded modelStub = new ModelStubAcceptingPersonAdded(); - Person validPerson = new PersonBuilder().build(); + public void execute_clientAcceptedByModel_addSuccessful() throws Exception { + ModelStubAcceptingClientAdded modelStub = new ModelStubAcceptingClientAdded(); + Client validClient = new ClientBuilder().build(); - CommandResult commandResult = new AddClientCommand(validPerson).execute(modelStub); + CommandResult commandResult = new AddClientCommand(validClient).execute(modelStub); - assertEquals(String.format(AddClientCommand.MESSAGE_SUCCESS, Messages.format(validPerson)), + assertEquals(String.format(AddClientCommand.MESSAGE_SUCCESS, Messages.format(validClient)), commandResult.getFeedbackToUser()); - assertEquals(Arrays.asList(validPerson), modelStub.personsAdded); + assertEquals(Arrays.asList(validClient), modelStub.clientsAdded); } @Test - public void execute_duplicatePerson_throwsCommandException() { - Person validPerson = new PersonBuilder().build(); - AddClientCommand addCommand = new AddClientCommand(validPerson); - ModelStub modelStub = new ModelStubWithPerson(validPerson); + public void execute_duplicateClient_throwsCommandException() { + Client validClient = new ClientBuilder().build(); + AddClientCommand addCommand = new AddClientCommand(validClient); + ModelStub modelStub = new ModelStubWithClient(validClient); assertThrows(CommandException.class, - AddClientCommand.MESSAGE_DUPLICATE_PERSON, () -> addCommand.execute(modelStub)); + AddClientCommand.MESSAGE_DUPLICATE_CLIENT, () -> addCommand.execute(modelStub)); } @Test public void equals() { - Person alice = new PersonBuilder().withName("Alice").build(); - Person bob = new PersonBuilder().withName("Bob").build(); + Client alice = new ClientBuilder().withName("Alice").build(); + Client bob = new ClientBuilder().withName("Bob").build(); AddClientCommand addAliceCommand = new AddClientCommand(alice); AddClientCommand addBobCommand = new AddClientCommand(bob); @@ -74,7 +74,7 @@ public void equals() { // null -> returns false assertFalse(addAliceCommand.equals(null)); - // different person -> returns false + // different client -> returns false assertFalse(addAliceCommand.equals(addBobCommand)); } @@ -120,7 +120,7 @@ public void setAddressBookFilePath(Path addressBookFilePath) { } @Override - public void addPerson(Person person) { + public void addClient(Client client) { throw new AssertionError("This method should not be called."); } @@ -135,65 +135,65 @@ public ReadOnlyAddressBook getAddressBook() { } @Override - public boolean hasPerson(Person person) { + public boolean hasClient(Client client) { throw new AssertionError("This method should not be called."); } @Override - public void deletePerson(Person target) { + public void deleteClient(Client target) { throw new AssertionError("This method should not be called."); } @Override - public void setPerson(Person target, Person editedPerson) { + public void setClient(Client target, Client editedClient) { throw new AssertionError("This method should not be called."); } @Override - public ObservableList getFilteredPersonList() { + public ObservableList getFilteredClientList() { throw new AssertionError("This method should not be called."); } @Override - public void updateFilteredPersonList(Predicate predicate) { + public void updateFilteredClientList(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 client. */ - private class ModelStubWithPerson extends ModelStub { - private final Person person; + private class ModelStubWithClient extends ModelStub { + private final Client client; - ModelStubWithPerson(Person person) { - requireNonNull(person); - this.person = person; + ModelStubWithClient(Client client) { + requireNonNull(client); + this.client = client; } @Override - public boolean hasPerson(Person person) { - requireNonNull(person); - return this.person.isSamePerson(person); + public boolean hasClient(Client client) { + requireNonNull(client); + return this.client.isSameClient(client); } } /** - * A Model stub that always accept the person being added. + * A Model stub that always accept the client being added. */ - private class ModelStubAcceptingPersonAdded extends ModelStub { - final ArrayList personsAdded = new ArrayList<>(); + private class ModelStubAcceptingClientAdded extends ModelStub { + final ArrayList clientsAdded = new ArrayList<>(); @Override - public boolean hasPerson(Person person) { - requireNonNull(person); - return personsAdded.stream().anyMatch(person::isSamePerson); + public boolean hasClient(Client client) { + requireNonNull(client); + return clientsAdded.stream().anyMatch(client::isSameClient); } @Override - public void addPerson(Person person) { - requireNonNull(person); - personsAdded.add(person); + public void addClient(Client client) { + requireNonNull(client); + clientsAdded.add(client); } @Override diff --git a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java index 80d9110c03a..cc989b70c97 100644 --- a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java @@ -1,7 +1,7 @@ package seedu.address.logic.commands; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; +import static seedu.address.testutil.TypicalClients.getTypicalAddressBook; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java index 5e77cdb6f88..be7b2f834d8 100644 --- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java +++ b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java @@ -17,9 +17,9 @@ 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.address.model.client.Client; +import seedu.address.model.client.NameContainsKeywordsPredicate; +import seedu.address.testutil.EditClientDescriptorBuilder; /** * Contains helper methods for testing commands. @@ -58,14 +58,14 @@ public class CommandTestUtil { 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.EditClientDescriptor DESC_AMY; + public static final EditCommand.EditClientDescriptor DESC_BOB; static { - DESC_AMY = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY) + DESC_AMY = new EditClientDescriptorBuilder().withName(VALID_NAME_AMY) .withPhone(VALID_PHONE_AMY).withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY) .withTags(VALID_TAG_FRIEND).build(); - DESC_BOB = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB) + DESC_BOB = new EditClientDescriptorBuilder().withName(VALID_NAME_BOB) .withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB) .withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND).build(); } @@ -100,30 +100,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 client list and selected client 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.getFilteredClientList()); assertThrows(CommandException.class, expectedMessage, () -> command.execute(actualModel)); assertEquals(expectedAddressBook, actualModel.getAddressBook()); - assertEquals(expectedFilteredList, actualModel.getFilteredPersonList()); + assertEquals(expectedFilteredList, actualModel.getFilteredClientList()); } /** - * 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 client 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 showClientAtIndex(Model model, Index targetIndex) { + assertTrue(targetIndex.getZeroBased() < model.getFilteredClientList().size()); - Person person = model.getFilteredPersonList().get(targetIndex.getZeroBased()); - final String[] splitName = person.getName().fullName.split("\\s+"); - model.updateFilteredPersonList(new NameContainsKeywordsPredicate(Arrays.asList(splitName[0]))); + Client client = model.getFilteredClientList().get(targetIndex.getZeroBased()); + final String[] splitName = client.getName().fullName.split("\\s+"); + model.updateFilteredClientList(new NameContainsKeywordsPredicate(Arrays.asList(splitName[0]))); - assertEquals(1, model.getFilteredPersonList().size()); + assertEquals(1, model.getFilteredClientList().size()); } } diff --git a/src/test/java/seedu/address/logic/commands/DeleteClientCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteClientCommandTest.java index 9a2abd60958..721765d5c3a 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteClientCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteClientCommandTest.java @@ -5,10 +5,10 @@ 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.address.logic.commands.CommandTestUtil.showClientAtIndex; +import static seedu.address.testutil.TypicalClients.getTypicalAddressBook; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_CLIENT; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_CLIENT; import org.junit.jupiter.api.Test; @@ -17,7 +17,7 @@ import seedu.address.model.Model; import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; -import seedu.address.model.person.Person; +import seedu.address.model.client.Client; /** * Contains integration tests (interaction with the Model) and unit tests for @@ -29,66 +29,66 @@ public class DeleteClientCommandTest { @Test public void execute_validIndexUnfilteredList_success() { - Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); - DeleteClientCommand deleteClientCommand = new DeleteClientCommand(INDEX_FIRST_PERSON); + Client clientToDelete = model.getFilteredClientList().get(INDEX_FIRST_CLIENT.getZeroBased()); + DeleteClientCommand deleteClientCommand = new DeleteClientCommand(INDEX_FIRST_CLIENT); - String expectedMessage = String.format(DeleteClientCommand.MESSAGE_DELETE_PERSON_SUCCESS, - Messages.format(personToDelete)); + String expectedMessage = String.format(DeleteClientCommand.MESSAGE_DELETE_CLIENT_SUCCESS, + Messages.format(clientToDelete)); ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); - expectedModel.deletePerson(personToDelete); + expectedModel.deleteClient(clientToDelete); assertCommandSuccess(deleteClientCommand, model, expectedMessage, expectedModel); } @Test public void execute_invalidIndexUnfilteredList_throwsCommandException() { - Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredClientList().size() + 1); DeleteClientCommand deleteClientCommand = new DeleteClientCommand(outOfBoundIndex); - assertCommandFailure(deleteClientCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandFailure(deleteClientCommand, model, Messages.MESSAGE_INVALID_CLIENT_DISPLAYED_INDEX); } @Test public void execute_validIndexFilteredList_success() { - showPersonAtIndex(model, INDEX_FIRST_PERSON); + showClientAtIndex(model, INDEX_FIRST_CLIENT); - Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); - DeleteClientCommand deleteClientCommand = new DeleteClientCommand(INDEX_FIRST_PERSON); + Client clientToDelete = model.getFilteredClientList().get(INDEX_FIRST_CLIENT.getZeroBased()); + DeleteClientCommand deleteClientCommand = new DeleteClientCommand(INDEX_FIRST_CLIENT); - String expectedMessage = String.format(DeleteClientCommand.MESSAGE_DELETE_PERSON_SUCCESS, - Messages.format(personToDelete)); + String expectedMessage = String.format(DeleteClientCommand.MESSAGE_DELETE_CLIENT_SUCCESS, + Messages.format(clientToDelete)); Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); - expectedModel.deletePerson(personToDelete); - showNoPerson(expectedModel); + expectedModel.deleteClient(clientToDelete); + showNoClient(expectedModel); assertCommandSuccess(deleteClientCommand, model, expectedMessage, expectedModel); } @Test public void execute_invalidIndexFilteredList_throwsCommandException() { - showPersonAtIndex(model, INDEX_FIRST_PERSON); + showClientAtIndex(model, INDEX_FIRST_CLIENT); - Index outOfBoundIndex = INDEX_SECOND_PERSON; + Index outOfBoundIndex = INDEX_SECOND_CLIENT; // ensures that outOfBoundIndex is still in bounds of address book list - assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size()); + assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getClientList().size()); DeleteClientCommand deleteClientCommand = new DeleteClientCommand(outOfBoundIndex); - assertCommandFailure(deleteClientCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandFailure(deleteClientCommand, model, Messages.MESSAGE_INVALID_CLIENT_DISPLAYED_INDEX); } @Test public void equals() { - DeleteClientCommand deleteFirstCommand = new DeleteClientCommand(INDEX_FIRST_PERSON); - DeleteClientCommand deleteSecondCommand = new DeleteClientCommand(INDEX_SECOND_PERSON); + DeleteClientCommand deleteFirstCommand = new DeleteClientCommand(INDEX_FIRST_CLIENT); + DeleteClientCommand deleteSecondCommand = new DeleteClientCommand(INDEX_SECOND_CLIENT); // same object -> returns true assertTrue(deleteFirstCommand.equals(deleteFirstCommand)); // same values -> returns true - DeleteClientCommand deleteFirstCommandCopy = new DeleteClientCommand(INDEX_FIRST_PERSON); + DeleteClientCommand deleteFirstCommandCopy = new DeleteClientCommand(INDEX_FIRST_CLIENT); assertTrue(deleteFirstCommand.equals(deleteFirstCommandCopy)); // different types -> returns false @@ -97,7 +97,7 @@ public void equals() { // null -> returns false assertFalse(deleteFirstCommand.equals(null)); - // different person -> returns false + // different client -> returns false assertFalse(deleteFirstCommand.equals(deleteSecondCommand)); } @@ -112,9 +112,9 @@ public void toStringMethod() { /** * Updates {@code model}'s filtered list to show no one. */ - private void showNoPerson(Model model) { - model.updateFilteredPersonList(p -> false); + private void showNoClient(Model model) { + model.updateFilteredClientList(p -> false); - assertTrue(model.getFilteredPersonList().isEmpty()); + assertTrue(model.getFilteredClientList().isEmpty()); } } diff --git a/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java b/src/test/java/seedu/address/logic/commands/EditClientDescriptorTest.java similarity index 65% rename from src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java rename to src/test/java/seedu/address/logic/commands/EditClientDescriptorTest.java index b17c1f3d5c2..74d5fe830c1 100644 --- a/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java +++ b/src/test/java/seedu/address/logic/commands/EditClientDescriptorTest.java @@ -13,15 +13,15 @@ import org.junit.jupiter.api.Test; -import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; -import seedu.address.testutil.EditPersonDescriptorBuilder; +import seedu.address.logic.commands.EditCommand.EditClientDescriptor; +import seedu.address.testutil.EditClientDescriptorBuilder; -public class EditPersonDescriptorTest { +public class EditClientDescriptorTest { @Test public void equals() { // same values -> returns true - EditPersonDescriptor descriptorWithSameValues = new EditPersonDescriptor(DESC_AMY); + EditClientDescriptor descriptorWithSameValues = new EditClientDescriptor(DESC_AMY); assertTrue(DESC_AMY.equals(descriptorWithSameValues)); // same object -> returns true @@ -37,35 +37,35 @@ public void equals() { assertFalse(DESC_AMY.equals(DESC_BOB)); // different name -> returns false - EditPersonDescriptor editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withName(VALID_NAME_BOB).build(); + EditClientDescriptor editedAmy = new EditClientDescriptorBuilder(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(); + editedAmy = new EditClientDescriptorBuilder(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(); + editedAmy = new EditClientDescriptorBuilder(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(); + editedAmy = new EditClientDescriptorBuilder(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(); + editedAmy = new EditClientDescriptorBuilder(DESC_AMY).withTags(VALID_TAG_HUSBAND).build(); assertFalse(DESC_AMY.equals(editedAmy)); } @Test public void toStringMethod() { - EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor(); - String expected = EditPersonDescriptor.class.getCanonicalName() + "{name=" - + editPersonDescriptor.getName().orElse(null) + ", phone=" - + editPersonDescriptor.getPhone().orElse(null) + ", email=" - + editPersonDescriptor.getEmail().orElse(null) + ", address=" - + editPersonDescriptor.getAddress().orElse(null) + ", tags=" - + editPersonDescriptor.getTags().orElse(null) + "}"; - assertEquals(expected, editPersonDescriptor.toString()); + EditClientDescriptor editClientDescriptor = new EditClientDescriptor(); + String expected = EditClientDescriptor.class.getCanonicalName() + "{name=" + + editClientDescriptor.getName().orElse(null) + ", phone=" + + editClientDescriptor.getPhone().orElse(null) + ", email=" + + editClientDescriptor.getEmail().orElse(null) + ", address=" + + editClientDescriptor.getAddress().orElse(null) + ", tags=" + + editClientDescriptor.getTags().orElse(null) + "}"; + assertEquals(expected, editClientDescriptor.toString()); } } diff --git a/src/test/java/seedu/address/logic/commands/EditCommandTest.java b/src/test/java/seedu/address/logic/commands/EditCommandTest.java index 469dd97daa7..c7755fb9bb4 100644 --- a/src/test/java/seedu/address/logic/commands/EditCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/EditCommandTest.java @@ -10,23 +10,23 @@ 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.address.logic.commands.CommandTestUtil.showClientAtIndex; +import static seedu.address.testutil.TypicalClients.getTypicalAddressBook; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_CLIENT; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_CLIENT; import org.junit.jupiter.api.Test; import seedu.address.commons.core.index.Index; import seedu.address.logic.Messages; -import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; +import seedu.address.logic.commands.EditCommand.EditClientDescriptor; 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.address.model.client.Client; +import seedu.address.testutil.ClientBuilder; +import seedu.address.testutil.EditClientDescriptorBuilder; /** * Contains integration tests (interaction with the Model) and unit tests for EditCommand. @@ -37,45 +37,45 @@ public class EditCommandTest { @Test public void execute_allFieldsSpecifiedUnfilteredList_success() { - Person editedPerson = new PersonBuilder().build(); - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(editedPerson).build(); - EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, descriptor); + Client editedClient = new ClientBuilder().build(); + EditClientDescriptor descriptor = new EditClientDescriptorBuilder(editedClient).build(); + EditCommand editCommand = new EditCommand(INDEX_FIRST_CLIENT, descriptor); - String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson)); + String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_CLIENT_SUCCESS, Messages.format(editedClient)); Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs()); - expectedModel.setPerson(model.getFilteredPersonList().get(0), editedPerson); + expectedModel.setClient(model.getFilteredClientList().get(0), editedClient); 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 indexLastClient = Index.fromOneBased(model.getFilteredClientList().size()); + Client lastClient = model.getFilteredClientList().get(indexLastClient.getZeroBased()); - PersonBuilder personInList = new PersonBuilder(lastPerson); - Person editedPerson = personInList.withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB) + ClientBuilder clientInList = new ClientBuilder(lastClient); + Client editedClient = clientInList.withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB) .withTags(VALID_TAG_HUSBAND).build(); - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB) + EditClientDescriptor descriptor = new EditClientDescriptorBuilder().withName(VALID_NAME_BOB) .withPhone(VALID_PHONE_BOB).withTags(VALID_TAG_HUSBAND).build(); - EditCommand editCommand = new EditCommand(indexLastPerson, descriptor); + EditCommand editCommand = new EditCommand(indexLastClient, descriptor); - String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson)); + String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_CLIENT_SUCCESS, Messages.format(editedClient)); Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs()); - expectedModel.setPerson(lastPerson, editedPerson); + expectedModel.setClient(lastClient, editedClient); 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_CLIENT, new EditClientDescriptor()); + Client editedClient = model.getFilteredClientList().get(INDEX_FIRST_CLIENT.getZeroBased()); - String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson)); + String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_CLIENT_SUCCESS, Messages.format(editedClient)); Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs()); @@ -84,49 +84,49 @@ public void execute_noFieldSpecifiedUnfilteredList_success() { @Test public void execute_filteredList_success() { - showPersonAtIndex(model, INDEX_FIRST_PERSON); + showClientAtIndex(model, INDEX_FIRST_CLIENT); - Person personInFilteredList = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); - Person editedPerson = new PersonBuilder(personInFilteredList).withName(VALID_NAME_BOB).build(); - EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, - new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build()); + Client clientInFilteredList = model.getFilteredClientList().get(INDEX_FIRST_CLIENT.getZeroBased()); + Client editedClient = new ClientBuilder(clientInFilteredList).withName(VALID_NAME_BOB).build(); + EditCommand editCommand = new EditCommand(INDEX_FIRST_CLIENT, + new EditClientDescriptorBuilder().withName(VALID_NAME_BOB).build()); - String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson)); + String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_CLIENT_SUCCESS, Messages.format(editedClient)); Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs()); - expectedModel.setPerson(model.getFilteredPersonList().get(0), editedPerson); + expectedModel.setClient(model.getFilteredClientList().get(0), editedClient); 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(); - EditCommand editCommand = new EditCommand(INDEX_SECOND_PERSON, descriptor); + public void execute_duplicateClientUnfilteredList_failure() { + Client firstClient = model.getFilteredClientList().get(INDEX_FIRST_CLIENT.getZeroBased()); + EditClientDescriptor descriptor = new EditClientDescriptorBuilder(firstClient).build(); + EditCommand editCommand = new EditCommand(INDEX_SECOND_CLIENT, descriptor); - assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_PERSON); + assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_CLIENT); } @Test - public void execute_duplicatePersonFilteredList_failure() { - showPersonAtIndex(model, INDEX_FIRST_PERSON); + public void execute_duplicateClientFilteredList_failure() { + showClientAtIndex(model, INDEX_FIRST_CLIENT); - // edit person in filtered list into a duplicate in address book - Person personInList = model.getAddressBook().getPersonList().get(INDEX_SECOND_PERSON.getZeroBased()); - EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, - new EditPersonDescriptorBuilder(personInList).build()); + // edit client in filtered list into a duplicate in address book + Client clientInList = model.getAddressBook().getClientList().get(INDEX_SECOND_CLIENT.getZeroBased()); + EditCommand editCommand = new EditCommand(INDEX_FIRST_CLIENT, + new EditClientDescriptorBuilder(clientInList).build()); - assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_PERSON); + assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_CLIENT); } @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_invalidClientIndexUnfilteredList_failure() { + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredClientList().size() + 1); + EditClientDescriptor descriptor = new EditClientDescriptorBuilder().withName(VALID_NAME_BOB).build(); EditCommand editCommand = new EditCommand(outOfBoundIndex, descriptor); - assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_CLIENT_DISPLAYED_INDEX); } /** @@ -134,25 +134,25 @@ public void execute_invalidPersonIndexUnfilteredList_failure() { * but smaller than size of address book */ @Test - public void execute_invalidPersonIndexFilteredList_failure() { - showPersonAtIndex(model, INDEX_FIRST_PERSON); - Index outOfBoundIndex = INDEX_SECOND_PERSON; + public void execute_invalidClientIndexFilteredList_failure() { + showClientAtIndex(model, INDEX_FIRST_CLIENT); + Index outOfBoundIndex = INDEX_SECOND_CLIENT; // ensures that outOfBoundIndex is still in bounds of address book list - assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size()); + assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getClientList().size()); EditCommand editCommand = new EditCommand(outOfBoundIndex, - new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build()); + new EditClientDescriptorBuilder().withName(VALID_NAME_BOB).build()); - assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_CLIENT_DISPLAYED_INDEX); } @Test public void equals() { - final EditCommand standardCommand = new EditCommand(INDEX_FIRST_PERSON, DESC_AMY); + final EditCommand standardCommand = new EditCommand(INDEX_FIRST_CLIENT, DESC_AMY); // same values -> returns true - EditPersonDescriptor copyDescriptor = new EditPersonDescriptor(DESC_AMY); - EditCommand commandWithSameValues = new EditCommand(INDEX_FIRST_PERSON, copyDescriptor); + EditClientDescriptor copyDescriptor = new EditClientDescriptor(DESC_AMY); + EditCommand commandWithSameValues = new EditCommand(INDEX_FIRST_CLIENT, copyDescriptor); assertTrue(standardCommand.equals(commandWithSameValues)); // same object -> returns true @@ -165,19 +165,19 @@ public void equals() { assertFalse(standardCommand.equals(new ClearCommand())); // different index -> returns false - assertFalse(standardCommand.equals(new EditCommand(INDEX_SECOND_PERSON, DESC_AMY))); + assertFalse(standardCommand.equals(new EditCommand(INDEX_SECOND_CLIENT, DESC_AMY))); // different descriptor -> returns false - assertFalse(standardCommand.equals(new EditCommand(INDEX_FIRST_PERSON, DESC_BOB))); + assertFalse(standardCommand.equals(new EditCommand(INDEX_FIRST_CLIENT, DESC_BOB))); } @Test public void toStringMethod() { Index index = Index.fromOneBased(1); - EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor(); - EditCommand editCommand = new EditCommand(index, editPersonDescriptor); - String expected = EditCommand.class.getCanonicalName() + "{index=" + index + ", editPersonDescriptor=" - + editPersonDescriptor + "}"; + EditClientDescriptor editClientDescriptor = new EditClientDescriptor(); + EditCommand editCommand = new EditCommand(index, editClientDescriptor); + String expected = EditCommand.class.getCanonicalName() + "{index=" + index + ", editClientDescriptor=" + + editClientDescriptor + "}"; assertEquals(expected, editCommand.toString()); } diff --git a/src/test/java/seedu/address/logic/commands/FindCommandTest.java b/src/test/java/seedu/address/logic/commands/FindCommandTest.java index b8b7dbba91a..6610ec5d659 100644 --- a/src/test/java/seedu/address/logic/commands/FindCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/FindCommandTest.java @@ -3,12 +3,12 @@ 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.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW; +import static seedu.address.logic.Messages.MESSAGE_CLIENTS_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.address.testutil.TypicalClients.CARL; +import static seedu.address.testutil.TypicalClients.ELLE; +import static seedu.address.testutil.TypicalClients.FIONA; +import static seedu.address.testutil.TypicalClients.getTypicalAddressBook; import java.util.Arrays; import java.util.Collections; @@ -18,7 +18,7 @@ import seedu.address.model.Model; import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; -import seedu.address.model.person.NameContainsKeywordsPredicate; +import seedu.address.model.client.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 client -> returns false assertFalse(findFirstCommand.equals(findSecondCommand)); } @Test - public void execute_zeroKeywords_noPersonFound() { - String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0); + public void execute_zeroKeywords_noClientFound() { + String expectedMessage = String.format(MESSAGE_CLIENTS_LISTED_OVERVIEW, 0); NameContainsKeywordsPredicate predicate = preparePredicate(" "); FindCommand command = new FindCommand(predicate); - expectedModel.updateFilteredPersonList(predicate); + expectedModel.updateFilteredClientList(predicate); assertCommandSuccess(command, model, expectedMessage, expectedModel); - assertEquals(Collections.emptyList(), model.getFilteredPersonList()); + assertEquals(Collections.emptyList(), model.getFilteredClientList()); } @Test - public void execute_multipleKeywords_multiplePersonsFound() { - String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 3); + public void execute_multipleKeywords_multipleClientsFound() { + String expectedMessage = String.format(MESSAGE_CLIENTS_LISTED_OVERVIEW, 3); NameContainsKeywordsPredicate predicate = preparePredicate("Kurz Elle Kunz"); FindCommand command = new FindCommand(predicate); - expectedModel.updateFilteredPersonList(predicate); + expectedModel.updateFilteredClientList(predicate); assertCommandSuccess(command, model, expectedMessage, expectedModel); - assertEquals(Arrays.asList(CARL, ELLE, FIONA), model.getFilteredPersonList()); + assertEquals(Arrays.asList(CARL, ELLE, FIONA), model.getFilteredClientList()); } @Test diff --git a/src/test/java/seedu/address/logic/commands/ListCommandTest.java b/src/test/java/seedu/address/logic/commands/ListCommandTest.java index 435ff1f7275..c83e3e534fb 100644 --- a/src/test/java/seedu/address/logic/commands/ListCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ListCommandTest.java @@ -1,9 +1,9 @@ package seedu.address.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.address.logic.commands.CommandTestUtil.showClientAtIndex; +import static seedu.address.testutil.TypicalClients.getTypicalAddressBook; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_CLIENT; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -33,7 +33,7 @@ public void execute_listIsNotFiltered_showsSameList() { @Test public void execute_listIsFiltered_showsEverything() { - showPersonAtIndex(model, INDEX_FIRST_PERSON); + showClientAtIndex(model, INDEX_FIRST_CLIENT); assertCommandSuccess(new ListCommand(), model, ListCommand.MESSAGE_SUCCESS, expectedModel); } } diff --git a/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java b/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java index 75fd9622f22..a30760584c2 100644 --- a/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/PriorityCommandTest.java @@ -6,10 +6,10 @@ import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_PRIORITY; import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; -import static seedu.address.testutil.TypicalIndexes.INDEX_FOURTH_PERSON; -import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON; -import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; +import static seedu.address.testutil.TypicalClients.getTypicalAddressBook; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_CLIENT; +import static seedu.address.testutil.TypicalIndexes.INDEX_FOURTH_CLIENT; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_CLIENT; import org.junit.jupiter.api.Test; @@ -19,50 +19,50 @@ 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; +import seedu.address.model.client.Client; +import seedu.address.testutil.ClientBuilder; public class PriorityCommandTest { private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); - private void execute_togglePriorityUnfilteredList(Index personIndex, String... tags) { - Person person = model.getFilteredPersonList().get(personIndex.getZeroBased()); - Person priorityPerson = new PersonBuilder(person).withTags(tags).build(); + private void execute_togglePriorityUnfilteredList(Index clientIndex, String... tags) { + Client client = model.getFilteredClientList().get(clientIndex.getZeroBased()); + Client priorityClient = new ClientBuilder(client).withTags(tags).build(); - PriorityCommand priorityCommand = new PriorityCommand(personIndex); + PriorityCommand priorityCommand = new PriorityCommand(clientIndex); - String expectedMessage = String.format(PriorityCommand.MESSAGE_PRIORITY_PERSON_SUCCESS, - Messages.format(priorityPerson)); + String expectedMessage = String.format(PriorityCommand.MESSAGE_PRIORITY_CLIENT_SUCCESS, + Messages.format(priorityClient)); Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs()); - expectedModel.setPerson(person, priorityPerson); + expectedModel.setClient(client, priorityClient); assertCommandSuccess(priorityCommand, model, expectedMessage, expectedModel); } @Test public void execute_toggleOnPriorityUnfilteredList() { - execute_togglePriorityUnfilteredList(INDEX_FIRST_PERSON, VALID_TAG_FRIEND, VALID_TAG_PRIORITY); + execute_togglePriorityUnfilteredList(INDEX_FIRST_CLIENT, VALID_TAG_FRIEND, VALID_TAG_PRIORITY); } @Test public void execute_toggleOffPriorityUnfilteredList() { - execute_togglePriorityUnfilteredList(INDEX_FOURTH_PERSON, VALID_TAG_FRIEND); + execute_togglePriorityUnfilteredList(INDEX_FOURTH_CLIENT, VALID_TAG_FRIEND); } @Test public void execute_invalidIndex_throwsCommandException() { - Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredClientList().size() + 1); PriorityCommand priorityCommand = new PriorityCommand(outOfBoundIndex); - assertCommandFailure(priorityCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandFailure(priorityCommand, model, Messages.MESSAGE_INVALID_CLIENT_DISPLAYED_INDEX); } @Test public void equals() { - final PriorityCommand standardCommand = new PriorityCommand(INDEX_FIRST_PERSON); + final PriorityCommand standardCommand = new PriorityCommand(INDEX_FIRST_CLIENT); // same object -> returns true assertTrue(standardCommand.equals(standardCommand)); @@ -74,6 +74,6 @@ public void equals() { assertFalse(standardCommand.equals(new ClearCommand())); // different index -> returns false - assertFalse(standardCommand.equals(new PriorityCommand(INDEX_SECOND_PERSON))); + assertFalse(standardCommand.equals(new PriorityCommand(INDEX_SECOND_CLIENT))); } } diff --git a/src/test/java/seedu/address/logic/parser/AddClientCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddClientCommandParserTest.java index e3c6caa0ce2..a83c96dba5b 100644 --- a/src/test/java/seedu/address/logic/parser/AddClientCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddClientCommandParserTest.java @@ -30,111 +30,111 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; 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 static seedu.address.testutil.TypicalClients.AMY; +import static seedu.address.testutil.TypicalClients.BOB; import org.junit.jupiter.api.Test; import seedu.address.logic.Messages; import seedu.address.logic.commands.AddClientCommand; -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.client.Address; +import seedu.address.model.client.Client; +import seedu.address.model.client.Email; +import seedu.address.model.client.Name; +import seedu.address.model.client.Phone; import seedu.address.model.tag.Tag; -import seedu.address.testutil.PersonBuilder; +import seedu.address.testutil.ClientBuilder; public class AddClientCommandParserTest { private AddClientCommandParser parser = new AddClientCommandParser(); @Test public void parse_allFieldsPresent_success() { - Person expectedPerson = new PersonBuilder(BOB).withTags(VALID_TAG_FRIEND).build(); + Client expectedClient = new ClientBuilder(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 AddClientCommand(expectedPerson)); + + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, new AddClientCommand(expectedClient)); // multiple tags - all accepted - Person expectedPersonMultipleTags = new PersonBuilder(BOB).withTags(VALID_TAG_FRIEND, VALID_TAG_HUSBAND) + Client expectedClientMultipleTags = new ClientBuilder(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 AddClientCommand(expectedPersonMultipleTags)); + new AddClientCommand(expectedClientMultipleTags)); } @Test public void parse_repeatedNonTagValue_failure() { - String validExpectedPersonString = NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + String validExpectedClientString = NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB + TAG_DESC_FRIEND; // multiple names - assertParseFailure(parser, NAME_DESC_AMY + validExpectedPersonString, + assertParseFailure(parser, NAME_DESC_AMY + validExpectedClientString, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NAME)); // multiple phones - assertParseFailure(parser, PHONE_DESC_AMY + validExpectedPersonString, + assertParseFailure(parser, PHONE_DESC_AMY + validExpectedClientString, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE)); // multiple emails - assertParseFailure(parser, EMAIL_DESC_AMY + validExpectedPersonString, + assertParseFailure(parser, EMAIL_DESC_AMY + validExpectedClientString, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_EMAIL)); // multiple addresses - assertParseFailure(parser, ADDRESS_DESC_AMY + validExpectedPersonString, + assertParseFailure(parser, ADDRESS_DESC_AMY + validExpectedClientString, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_ADDRESS)); // multiple fields repeated assertParseFailure(parser, - validExpectedPersonString + PHONE_DESC_AMY + EMAIL_DESC_AMY + NAME_DESC_AMY + ADDRESS_DESC_AMY - + validExpectedPersonString, + validExpectedClientString + PHONE_DESC_AMY + EMAIL_DESC_AMY + NAME_DESC_AMY + ADDRESS_DESC_AMY + + validExpectedClientString, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NAME, PREFIX_ADDRESS, PREFIX_EMAIL, PREFIX_PHONE)); // invalid value followed by valid value // invalid name - assertParseFailure(parser, INVALID_NAME_DESC + validExpectedPersonString, + assertParseFailure(parser, INVALID_NAME_DESC + validExpectedClientString, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NAME)); // invalid email - assertParseFailure(parser, INVALID_EMAIL_DESC + validExpectedPersonString, + assertParseFailure(parser, INVALID_EMAIL_DESC + validExpectedClientString, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_EMAIL)); // invalid phone - assertParseFailure(parser, INVALID_PHONE_DESC + validExpectedPersonString, + assertParseFailure(parser, INVALID_PHONE_DESC + validExpectedClientString, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE)); // invalid address - assertParseFailure(parser, INVALID_ADDRESS_DESC + validExpectedPersonString, + assertParseFailure(parser, INVALID_ADDRESS_DESC + validExpectedClientString, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_ADDRESS)); // valid value followed by invalid value // invalid name - assertParseFailure(parser, validExpectedPersonString + INVALID_NAME_DESC, + assertParseFailure(parser, validExpectedClientString + INVALID_NAME_DESC, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NAME)); // invalid email - assertParseFailure(parser, validExpectedPersonString + INVALID_EMAIL_DESC, + assertParseFailure(parser, validExpectedClientString + INVALID_EMAIL_DESC, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_EMAIL)); // invalid phone - assertParseFailure(parser, validExpectedPersonString + INVALID_PHONE_DESC, + assertParseFailure(parser, validExpectedClientString + INVALID_PHONE_DESC, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE)); // invalid address - assertParseFailure(parser, validExpectedPersonString + INVALID_ADDRESS_DESC, + assertParseFailure(parser, validExpectedClientString + INVALID_ADDRESS_DESC, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_ADDRESS)); } @Test public void parse_optionalFieldsMissing_success() { // zero tags - Person expectedPerson = new PersonBuilder(AMY).withTags().build(); + Client expectedClient = new ClientBuilder(AMY).withTags().build(); assertParseSuccess(parser, NAME_DESC_AMY + PHONE_DESC_AMY + EMAIL_DESC_AMY + ADDRESS_DESC_AMY, - new AddClientCommand(expectedPerson)); + new AddClientCommand(expectedClient)); } @Test diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 92ffeb64431..0ddbed08b2e 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -5,7 +5,7 @@ import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; import static seedu.address.logic.Messages.MESSAGE_UNKNOWN_COMMAND; import static seedu.address.testutil.Assert.assertThrows; -import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_CLIENT; import java.util.Arrays; import java.util.List; @@ -17,18 +17,18 @@ import seedu.address.logic.commands.ClearCommand; import seedu.address.logic.commands.DeleteClientCommand; import seedu.address.logic.commands.EditCommand; -import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; +import seedu.address.logic.commands.EditCommand.EditClientDescriptor; 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.commands.PriorityCommand; 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.address.model.client.Client; +import seedu.address.model.client.NameContainsKeywordsPredicate; +import seedu.address.testutil.ClientBuilder; +import seedu.address.testutil.ClientUtil; +import seedu.address.testutil.EditClientDescriptorBuilder; public class AddressBookParserTest { @@ -36,9 +36,9 @@ public class AddressBookParserTest { @Test public void parseCommand_add() throws Exception { - Person person = new PersonBuilder().build(); - AddClientCommand command = (AddClientCommand) parser.parseCommand(PersonUtil.getAddClientCommand(person)); - assertEquals(new AddClientCommand(person), command); + Client client = new ClientBuilder().build(); + AddClientCommand command = (AddClientCommand) parser.parseCommand(ClientUtil.getAddClientCommand(client)); + assertEquals(new AddClientCommand(client), command); } @Test @@ -50,17 +50,17 @@ public void parseCommand_clear() throws Exception { @Test public void parseCommand_delete() throws Exception { DeleteClientCommand command = (DeleteClientCommand) parser.parseCommand( - DeleteClientCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased()); - assertEquals(new DeleteClientCommand(INDEX_FIRST_PERSON), command); + DeleteClientCommand.COMMAND_WORD + " " + INDEX_FIRST_CLIENT.getOneBased()); + assertEquals(new DeleteClientCommand(INDEX_FIRST_CLIENT), command); } @Test public void parseCommand_edit() throws Exception { - Person person = new PersonBuilder().build(); - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(person).build(); + Client client = new ClientBuilder().build(); + EditClientDescriptor descriptor = new EditClientDescriptorBuilder(client).build(); EditCommand command = (EditCommand) parser.parseCommand(EditCommand.COMMAND_WORD + " " - + INDEX_FIRST_PERSON.getOneBased() + " " + PersonUtil.getEditPersonDescriptorDetails(descriptor)); - assertEquals(new EditCommand(INDEX_FIRST_PERSON, descriptor), command); + + INDEX_FIRST_CLIENT.getOneBased() + " " + ClientUtil.getEditClientDescriptorDetails(descriptor)); + assertEquals(new EditCommand(INDEX_FIRST_CLIENT, descriptor), command); } @Test @@ -92,8 +92,8 @@ public void parseCommand_list() throws Exception { @Test public void parseCommand_priority() throws Exception { PriorityCommand command = (PriorityCommand) parser.parseCommand( - PriorityCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased()); - assertEquals(new PriorityCommand(INDEX_FIRST_PERSON), command); + PriorityCommand.COMMAND_WORD + " " + INDEX_FIRST_CLIENT.getOneBased()); + assertEquals(new PriorityCommand(INDEX_FIRST_CLIENT), command); } @Test diff --git a/src/test/java/seedu/address/logic/parser/DeleteClientCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteClientCommandParserTest.java index 755482a998d..c6f7c524b94 100644 --- a/src/test/java/seedu/address/logic/parser/DeleteClientCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/DeleteClientCommandParserTest.java @@ -3,7 +3,7 @@ import static seedu.address.logic.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.address.testutil.TypicalIndexes.INDEX_FIRST_CLIENT; import org.junit.jupiter.api.Test; @@ -22,7 +22,7 @@ public class DeleteClientCommandParserTest { @Test public void parse_validArgs_returnsDeleteClientCommand() { - assertParseSuccess(parser, "1", new DeleteClientCommand(INDEX_FIRST_PERSON)); + assertParseSuccess(parser, "1", new DeleteClientCommand(INDEX_FIRST_CLIENT)); } @Test diff --git a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java b/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java index 010a06e7ebd..23401ab2909 100644 --- a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java @@ -28,22 +28,22 @@ 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; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_CLIENT; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_CLIENT; +import static seedu.address.testutil.TypicalIndexes.INDEX_THIRD_CLIENT; import org.junit.jupiter.api.Test; import seedu.address.commons.core.index.Index; import seedu.address.logic.Messages; 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.logic.commands.EditCommand.EditClientDescriptor; +import seedu.address.model.client.Address; +import seedu.address.model.client.Email; +import seedu.address.model.client.Name; +import seedu.address.model.client.Phone; import seedu.address.model.tag.Tag; -import seedu.address.testutil.EditPersonDescriptorBuilder; +import seedu.address.testutil.EditClientDescriptorBuilder; public class EditCommandParserTest { @@ -92,7 +92,7 @@ public void parse_invalidValue_failure() { // invalid phone followed by valid email assertParseFailure(parser, "1" + INVALID_PHONE_DESC + EMAIL_DESC_AMY, 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 Client} 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); @@ -105,11 +105,11 @@ public void parse_invalidValue_failure() { @Test public void parse_allFieldsSpecified_success() { - Index targetIndex = INDEX_SECOND_PERSON; + Index targetIndex = INDEX_SECOND_CLIENT; String userInput = targetIndex.getOneBased() + PHONE_DESC_BOB + TAG_DESC_HUSBAND + EMAIL_DESC_AMY + ADDRESS_DESC_AMY + NAME_DESC_AMY + TAG_DESC_FRIEND; - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY) + EditClientDescriptor descriptor = new EditClientDescriptorBuilder().withName(VALID_NAME_AMY) .withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY) .withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND).build(); EditCommand expectedCommand = new EditCommand(targetIndex, descriptor); @@ -119,10 +119,10 @@ public void parse_allFieldsSpecified_success() { @Test public void parse_someFieldsSpecified_success() { - Index targetIndex = INDEX_FIRST_PERSON; + Index targetIndex = INDEX_FIRST_CLIENT; String userInput = targetIndex.getOneBased() + PHONE_DESC_BOB + EMAIL_DESC_AMY; - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_BOB) + EditClientDescriptor descriptor = new EditClientDescriptorBuilder().withPhone(VALID_PHONE_BOB) .withEmail(VALID_EMAIL_AMY).build(); EditCommand expectedCommand = new EditCommand(targetIndex, descriptor); @@ -132,33 +132,33 @@ public void parse_someFieldsSpecified_success() { @Test public void parse_oneFieldSpecified_success() { // name - Index targetIndex = INDEX_THIRD_PERSON; + Index targetIndex = INDEX_THIRD_CLIENT; String userInput = targetIndex.getOneBased() + NAME_DESC_AMY; - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY).build(); + EditClientDescriptor descriptor = new EditClientDescriptorBuilder().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 EditClientDescriptorBuilder().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 EditClientDescriptorBuilder().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(); + descriptor = new EditClientDescriptorBuilder().withAddress(VALID_ADDRESS_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 EditClientDescriptorBuilder().withTags(VALID_TAG_FRIEND).build(); expectedCommand = new EditCommand(targetIndex, descriptor); assertParseSuccess(parser, userInput, expectedCommand); } @@ -169,7 +169,7 @@ public void parse_multipleRepeatedFields_failure() { // AddClientCommandParserTest#parse_repeatedNonTagValue_failure() // valid followed by invalid - Index targetIndex = INDEX_FIRST_PERSON; + Index targetIndex = INDEX_FIRST_CLIENT; String userInput = targetIndex.getOneBased() + INVALID_PHONE_DESC + PHONE_DESC_BOB; assertParseFailure(parser, userInput, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE)); @@ -197,10 +197,10 @@ public void parse_multipleRepeatedFields_failure() { @Test public void parse_resetTags_success() { - Index targetIndex = INDEX_THIRD_PERSON; + Index targetIndex = INDEX_THIRD_CLIENT; String userInput = targetIndex.getOneBased() + TAG_EMPTY; - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withTags().build(); + EditClientDescriptor descriptor = new EditClientDescriptorBuilder().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/address/logic/parser/FindCommandParserTest.java index d92e64d12f9..db4ff590779 100644 --- a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test; import seedu.address.logic.commands.FindCommand; -import seedu.address.model.person.NameContainsKeywordsPredicate; +import seedu.address.model.client.NameContainsKeywordsPredicate; public class FindCommandParserTest { diff --git a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java b/src/test/java/seedu/address/logic/parser/ParserUtilTest.java index 4256788b1a7..3e4b4f01a34 100644 --- a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java +++ b/src/test/java/seedu/address/logic/parser/ParserUtilTest.java @@ -4,7 +4,7 @@ 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.address.testutil.TypicalIndexes.INDEX_FIRST_CLIENT; import java.util.Arrays; import java.util.Collections; @@ -14,10 +14,10 @@ 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.client.Address; +import seedu.address.model.client.Email; +import seedu.address.model.client.Name; +import seedu.address.model.client.Phone; import seedu.address.model.tag.Tag; public class ParserUtilTest { @@ -50,10 +50,10 @@ public void parseIndex_outOfRangeInput_throwsParseException() { @Test public void parseIndex_validInput_success() throws Exception { // No whitespaces - assertEquals(INDEX_FIRST_PERSON, ParserUtil.parseIndex("1")); + assertEquals(INDEX_FIRST_CLIENT, ParserUtil.parseIndex("1")); // Leading and trailing whitespaces - assertEquals(INDEX_FIRST_PERSON, ParserUtil.parseIndex(" 1 ")); + assertEquals(INDEX_FIRST_CLIENT, ParserUtil.parseIndex(" 1 ")); } @Test diff --git a/src/test/java/seedu/address/logic/parser/PriorityCommandParserTest.java b/src/test/java/seedu/address/logic/parser/PriorityCommandParserTest.java index 33802dfe80f..22de9ec08eb 100644 --- a/src/test/java/seedu/address/logic/parser/PriorityCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/PriorityCommandParserTest.java @@ -3,7 +3,7 @@ import static seedu.address.logic.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.address.testutil.TypicalIndexes.INDEX_FIRST_CLIENT; import org.junit.jupiter.api.Test; @@ -14,7 +14,7 @@ public class PriorityCommandParserTest { @Test public void parse_validArgs_returnsDeleteClientCommand() { - assertParseSuccess(parser, "1", new PriorityCommand(INDEX_FIRST_PERSON)); + assertParseSuccess(parser, "1", new PriorityCommand(INDEX_FIRST_CLIENT)); } @Test diff --git a/src/test/java/seedu/address/model/AddressBookTest.java b/src/test/java/seedu/address/model/AddressBookTest.java index c96f8b00ca8..0f8e13c1bec 100644 --- a/src/test/java/seedu/address/model/AddressBookTest.java +++ b/src/test/java/seedu/address/model/AddressBookTest.java @@ -6,8 +6,8 @@ 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 static seedu.address.testutil.TypicalClients.ALICE; +import static seedu.address.testutil.TypicalClients.getTypicalAddressBook; import java.util.Arrays; import java.util.Collection; @@ -19,9 +19,8 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import seedu.address.model.client.Client; -import seedu.address.model.person.Person; -import seedu.address.model.person.exceptions.DuplicatePersonException; -import seedu.address.testutil.PersonBuilder; +import seedu.address.model.client.exceptions.DuplicateClientException; +import seedu.address.testutil.ClientBuilder; public class AddressBookTest { @@ -29,7 +28,7 @@ public class AddressBookTest { @Test public void constructor() { - assertEquals(Collections.emptyList(), addressBook.getPersonList()); + assertEquals(Collections.emptyList(), addressBook.getClientList()); } @Test @@ -45,66 +44,59 @@ public void resetData_withValidReadOnlyAddressBook_replacesData() { } @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) + public void resetData_withDuplicateClients_throwsDuplicateClientException() { + // Two clients with the same identity fields + Client editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND) .build(); - List newPersons = Arrays.asList(ALICE, editedAlice); - AddressBookStub newData = new AddressBookStub(newPersons); + List newClients = Arrays.asList(ALICE, editedAlice); + AddressBookStub newData = new AddressBookStub(newClients); - assertThrows(DuplicatePersonException.class, () -> addressBook.resetData(newData)); + assertThrows(DuplicateClientException.class, () -> addressBook.resetData(newData)); } @Test - public void hasPerson_nullPerson_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> addressBook.hasPerson(null)); + public void hasClient_nullClient_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> addressBook.hasClient(null)); } @Test - public void hasPerson_personNotInAddressBook_returnsFalse() { - assertFalse(addressBook.hasPerson(ALICE)); + public void hasClient_clientNotInAddressBook_returnsFalse() { + assertFalse(addressBook.hasClient(ALICE)); } @Test - public void hasPerson_personInAddressBook_returnsTrue() { - addressBook.addPerson(ALICE); - assertTrue(addressBook.hasPerson(ALICE)); + public void hasClient_clientInAddressBook_returnsTrue() { + addressBook.addClient(ALICE); + assertTrue(addressBook.hasClient(ALICE)); } @Test - public void hasPerson_personWithSameIdentityFieldsInAddressBook_returnsTrue() { - addressBook.addPerson(ALICE); - Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND) + public void hasClient_clientWithSameIdentityFieldsInAddressBook_returnsTrue() { + addressBook.addClient(ALICE); + Client editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND) .build(); - assertTrue(addressBook.hasPerson(editedAlice)); + assertTrue(addressBook.hasClient(editedAlice)); } @Test - public void getPersonList_modifyList_throwsUnsupportedOperationException() { - assertThrows(UnsupportedOperationException.class, () -> addressBook.getPersonList().remove(0)); + public void getClientList_modifyList_throwsUnsupportedOperationException() { + assertThrows(UnsupportedOperationException.class, () -> addressBook.getClientList().remove(0)); } @Test public void toStringMethod() { - String expected = AddressBook.class.getCanonicalName() + "{persons=" + addressBook.getPersonList() - + ", clients=" + addressBook.getClientList() + "}"; + String expected = AddressBook.class.getCanonicalName() + "{clients=" + addressBook.getClientList() + "}"; assertEquals(expected, addressBook.toString()); } /** - * A stub ReadOnlyAddressBook whose persons list can violate interface constraints. + * A stub ReadOnlyAddressBook whose clients list can violate interface constraints. */ private static class AddressBookStub implements ReadOnlyAddressBook { - private final ObservableList persons = FXCollections.observableArrayList(); private final ObservableList clients = FXCollections.observableArrayList(); - AddressBookStub(Collection persons) { - this.persons.setAll(persons); - } - - @Override - public ObservableList getPersonList() { - return persons; + AddressBookStub(Collection clients) { + this.clients.setAll(clients); } @Override diff --git a/src/test/java/seedu/address/model/ModelManagerTest.java b/src/test/java/seedu/address/model/ModelManagerTest.java index 2cf1418d116..e202a4852a1 100644 --- a/src/test/java/seedu/address/model/ModelManagerTest.java +++ b/src/test/java/seedu/address/model/ModelManagerTest.java @@ -3,10 +3,10 @@ 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.model.Model.PREDICATE_SHOW_ALL_CLIENTS; import static seedu.address.testutil.Assert.assertThrows; -import static seedu.address.testutil.TypicalPersons.ALICE; -import static seedu.address.testutil.TypicalPersons.BENSON; +import static seedu.address.testutil.TypicalClients.ALICE; +import static seedu.address.testutil.TypicalClients.BENSON; import java.nio.file.Path; import java.nio.file.Paths; @@ -15,7 +15,7 @@ import org.junit.jupiter.api.Test; import seedu.address.commons.core.GuiSettings; -import seedu.address.model.person.NameContainsKeywordsPredicate; +import seedu.address.model.client.NameContainsKeywordsPredicate; import seedu.address.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 hasClient_nullClient_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> modelManager.hasClient(null)); } @Test - public void hasPerson_personNotInAddressBook_returnsFalse() { - assertFalse(modelManager.hasPerson(ALICE)); + public void hasClient_clientNotInAddressBook_returnsFalse() { + assertFalse(modelManager.hasClient(ALICE)); } @Test - public void hasPerson_personInAddressBook_returnsTrue() { - modelManager.addPerson(ALICE); - assertTrue(modelManager.hasPerson(ALICE)); + public void hasClient_clientInAddressBook_returnsTrue() { + modelManager.addClient(ALICE); + assertTrue(modelManager.hasClient(ALICE)); } @Test - public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException() { - assertThrows(UnsupportedOperationException.class, () -> modelManager.getFilteredPersonList().remove(0)); + public void getFilteredClientList_modifyList_throwsUnsupportedOperationException() { + assertThrows(UnsupportedOperationException.class, () -> modelManager.getFilteredClientList().remove(0)); } @Test public void equals() { - AddressBook addressBook = new AddressBookBuilder().withPerson(ALICE).withPerson(BENSON).build(); + AddressBook addressBook = new AddressBookBuilder().withClient(ALICE).withClient(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.updateFilteredClientList(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.updateFilteredClientList(PREDICATE_SHOW_ALL_CLIENTS); // different userPrefs -> returns false UserPrefs differentUserPrefs = new UserPrefs(); diff --git a/src/test/java/seedu/address/model/client/ClientTest.java b/src/test/java/seedu/address/model/client/ClientTest.java index e8175be422a..f22a9253b21 100644 --- a/src/test/java/seedu/address/model/client/ClientTest.java +++ b/src/test/java/seedu/address/model/client/ClientTest.java @@ -7,6 +7,8 @@ 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.TypicalClients.ALICE; import static seedu.address.testutil.TypicalClients.BOB; @@ -14,9 +16,14 @@ import seedu.address.testutil.ClientBuilder; - public class ClientTest { + @Test + public void asObservableList_modifyList_throwsUnsupportedOperationException() { + Client client = new ClientBuilder().build(); + assertThrows(UnsupportedOperationException.class, () -> client.getTags().remove(0)); + } + @Test public void isSameClient() { // same object -> returns true @@ -27,7 +34,7 @@ public void isSameClient() { // same name, all other attributes different -> returns true Client editedAlice = new ClientBuilder(ALICE).withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB) - .withAddress(VALID_ADDRESS_BOB).build(); + .withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND).build(); assertTrue(ALICE.isSameClient(editedAlice)); // different name, all other attributes same -> returns false @@ -59,7 +66,7 @@ public void equals() { // different type -> returns false assertFalse(ALICE.equals(5)); - // different Client -> returns false + // different client -> returns false assertFalse(ALICE.equals(BOB)); // different name -> returns false @@ -77,13 +84,16 @@ public void equals() { // different address -> returns false editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).build(); assertFalse(ALICE.equals(editedAlice)); + + // different tags -> returns false + editedAlice = new ClientBuilder(ALICE).withTags(VALID_TAG_HUSBAND).build(); + assertFalse(ALICE.equals(editedAlice)); } @Test public void toStringMethod() { String expected = Client.class.getCanonicalName() + "{name=" + ALICE.getName() + ", phone=" + ALICE.getPhone() - + ", email=" + ALICE.getEmail() + ", address=" + ALICE.getAddress() + "}"; + + ", email=" + ALICE.getEmail() + ", address=" + ALICE.getAddress() + ", tags=" + ALICE.getTags() + "}"; assertEquals(expected, ALICE.toString()); } } - diff --git a/src/test/java/seedu/address/model/client/EmailTest.java b/src/test/java/seedu/address/model/client/EmailTest.java index f5478983d43..900cc6d3f8b 100644 --- a/src/test/java/seedu/address/model/client/EmailTest.java +++ b/src/test/java/seedu/address/model/client/EmailTest.java @@ -6,7 +6,6 @@ import org.junit.jupiter.api.Test; - public class EmailTest { @Test diff --git a/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java b/src/test/java/seedu/address/model/client/NameContainsKeywordsPredicateTest.java similarity index 84% rename from src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java rename to src/test/java/seedu/address/model/client/NameContainsKeywordsPredicateTest.java index 6b3fd90ade7..7e6880b3c0c 100644 --- a/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java +++ b/src/test/java/seedu/address/model/client/NameContainsKeywordsPredicateTest.java @@ -1,4 +1,4 @@ -package seedu.address.model.person; +package seedu.address.model.client; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test; -import seedu.address.testutil.PersonBuilder; +import seedu.address.testutil.ClientBuilder; public class NameContainsKeywordsPredicateTest { @@ -35,7 +35,7 @@ public void equals() { // null -> returns false assertFalse(firstPredicate.equals(null)); - // different person -> returns false + // different client -> returns false assertFalse(firstPredicate.equals(secondPredicate)); } @@ -43,34 +43,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 ClientBuilder().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 ClientBuilder().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 ClientBuilder().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 ClientBuilder().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 ClientBuilder().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 ClientBuilder().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") + assertFalse(predicate.test(new ClientBuilder().withName("Alice").withPhone("12345") .withEmail("alice@email.com").withAddress("Main Street").build())); } diff --git a/src/test/java/seedu/address/model/client/NameTest.java b/src/test/java/seedu/address/model/client/NameTest.java index 8fc8c27c835..95603a076a3 100644 --- a/src/test/java/seedu/address/model/client/NameTest.java +++ b/src/test/java/seedu/address/model/client/NameTest.java @@ -58,4 +58,3 @@ public void equals() { assertFalse(name.equals(new Name("Other Valid Name"))); } } - diff --git a/src/test/java/seedu/address/model/client/PhoneTest.java b/src/test/java/seedu/address/model/client/PhoneTest.java index f27c4a9a6cb..d5a21a7ffa3 100644 --- a/src/test/java/seedu/address/model/client/PhoneTest.java +++ b/src/test/java/seedu/address/model/client/PhoneTest.java @@ -6,7 +6,6 @@ import org.junit.jupiter.api.Test; - public class PhoneTest { @Test @@ -32,7 +31,7 @@ public void isValidPhone() { assertFalse(Phone.isValidPhone("phone")); // non-numeric assertFalse(Phone.isValidPhone("9011p041")); // alphabets within digits assertFalse(Phone.isValidPhone("9312 1534")); // spaces within digits - assertFalse(Phone.isValidPhone("+198765432")); // with country code + // valid phone numbers assertTrue(Phone.isValidPhone("911")); // exactly 3 numbers assertTrue(Phone.isValidPhone("93121534")); diff --git a/src/test/java/seedu/address/model/client/UniqueClientListTest.java b/src/test/java/seedu/address/model/client/UniqueClientListTest.java index 997666f54ac..eb37f393dea 100644 --- a/src/test/java/seedu/address/model/client/UniqueClientListTest.java +++ b/src/test/java/seedu/address/model/client/UniqueClientListTest.java @@ -4,6 +4,7 @@ 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.TypicalClients.ALICE; import static seedu.address.testutil.TypicalClients.BOB; @@ -41,7 +42,8 @@ public void contains_clientInList_returnsTrue() { @Test public void contains_clientWithSameIdentityFieldsInList_returnsTrue() { uniqueClientList.add(ALICE); - Client editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).build(); + Client editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND) + .build(); assertTrue(uniqueClientList.contains(editedAlice)); } @@ -83,7 +85,8 @@ public void setClient_editedClientIsSameClient_success() { @Test public void setClient_editedClientHasSameIdentity_success() { uniqueClientList.add(ALICE); - Client editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).build(); + Client editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND) + .build(); uniqueClientList.setClient(ALICE, editedAlice); UniqueClientList expectedUniqueClientList = new UniqueClientList(); expectedUniqueClientList.add(editedAlice); @@ -162,7 +165,7 @@ public void setClients_listWithDuplicateClients_throwsDuplicateClientException() @Test public void asUnmodifiableObservableList_modifyList_throwsUnsupportedOperationException() { assertThrows(UnsupportedOperationException.class, () - -> uniqueClientList.asUnmodifiableObservableList().remove(0)); + -> uniqueClientList.asUnmodifiableObservableList().remove(0)); } @Test 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 314885eca26..00000000000 --- a/src/test/java/seedu/address/model/person/AddressTest.java +++ /dev/null @@ -1,56 +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 - } - - @Test - public void equals() { - Address address = new Address("Valid Address"); - - // same values -> returns true - assertTrue(address.equals(new Address("Valid Address"))); - - // same object -> returns true - assertTrue(address.equals(address)); - - // null -> returns false - assertFalse(address.equals(null)); - - // different types -> returns false - assertFalse(address.equals(5.0f)); - - // different values -> returns false - assertFalse(address.equals(new Address("Other Valid Address"))); - } -} diff --git a/src/test/java/seedu/address/model/person/EmailTest.java b/src/test/java/seedu/address/model/person/EmailTest.java deleted file mode 100644 index f08cdff0a64..00000000000 --- a/src/test/java/seedu/address/model/person/EmailTest.java +++ /dev/null @@ -1,88 +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 EmailTest { - - @Test - public void constructor_null_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> new Email(null)); - } - - @Test - public void constructor_invalidEmail_throwsIllegalArgumentException() { - String invalidEmail = ""; - assertThrows(IllegalArgumentException.class, () -> new Email(invalidEmail)); - } - - @Test - public void isValidEmail() { - // null email - assertThrows(NullPointerException.class, () -> Email.isValidEmail(null)); - - // blank email - assertFalse(Email.isValidEmail("")); // empty string - assertFalse(Email.isValidEmail(" ")); // spaces only - - // missing parts - assertFalse(Email.isValidEmail("@example.com")); // missing local part - assertFalse(Email.isValidEmail("peterjackexample.com")); // missing '@' symbol - assertFalse(Email.isValidEmail("peterjack@")); // missing domain name - - // invalid parts - assertFalse(Email.isValidEmail("peterjack@-")); // invalid domain name - assertFalse(Email.isValidEmail("peterjack@exam_ple.com")); // underscore in domain name - assertFalse(Email.isValidEmail("peter jack@example.com")); // spaces in local part - assertFalse(Email.isValidEmail("peterjack@exam ple.com")); // spaces in domain name - assertFalse(Email.isValidEmail(" peterjack@example.com")); // leading space - assertFalse(Email.isValidEmail("peterjack@example.com ")); // trailing space - assertFalse(Email.isValidEmail("peterjack@@example.com")); // double '@' symbol - assertFalse(Email.isValidEmail("peter@jack@example.com")); // '@' symbol in local part - assertFalse(Email.isValidEmail("-peterjack@example.com")); // local part starts with a hyphen - assertFalse(Email.isValidEmail("peterjack-@example.com")); // local part ends with a hyphen - assertFalse(Email.isValidEmail("peter..jack@example.com")); // local part has two consecutive periods - assertFalse(Email.isValidEmail("peterjack@example@com")); // '@' symbol in domain name - assertFalse(Email.isValidEmail("peterjack@.example.com")); // domain name starts with a period - assertFalse(Email.isValidEmail("peterjack@example.com.")); // domain name ends with a period - assertFalse(Email.isValidEmail("peterjack@-example.com")); // domain name starts with a hyphen - assertFalse(Email.isValidEmail("peterjack@example.com-")); // domain name ends with a hyphen - assertFalse(Email.isValidEmail("peterjack@example.c")); // top level domain has less than two chars - - // valid email - assertTrue(Email.isValidEmail("PeterJack_1190@example.com")); // underscore in local part - assertTrue(Email.isValidEmail("PeterJack.1190@example.com")); // period in local part - assertTrue(Email.isValidEmail("PeterJack+1190@example.com")); // '+' symbol in local part - assertTrue(Email.isValidEmail("PeterJack-1190@example.com")); // hyphen in local part - assertTrue(Email.isValidEmail("a@bc")); // minimal - assertTrue(Email.isValidEmail("test@localhost")); // alphabets only - assertTrue(Email.isValidEmail("123@145")); // numeric local part and domain name - assertTrue(Email.isValidEmail("a1+be.d@example1.com")); // mixture of alphanumeric and special characters - assertTrue(Email.isValidEmail("peter_jack@very-very-very-long-example.com")); // long domain name - assertTrue(Email.isValidEmail("if.you.dream.it_you.can.do.it@example.com")); // long local part - assertTrue(Email.isValidEmail("e1234567@u.nus.edu")); // more than one period in domain - } - - @Test - public void equals() { - Email email = new Email("valid@email"); - - // same values -> returns true - assertTrue(email.equals(new Email("valid@email"))); - - // same object -> returns true - assertTrue(email.equals(email)); - - // null -> returns false - assertFalse(email.equals(null)); - - // different types -> returns false - assertFalse(email.equals(5.0f)); - - // different values -> returns false - assertFalse(email.equals(new Email("other.valid@email"))); - } -} diff --git a/src/test/java/seedu/address/model/person/NameTest.java b/src/test/java/seedu/address/model/person/NameTest.java deleted file mode 100644 index 94e3dd726bd..00000000000 --- a/src/test/java/seedu/address/model/person/NameTest.java +++ /dev/null @@ -1,60 +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 NameTest { - - @Test - public void constructor_null_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> new Name(null)); - } - - @Test - public void constructor_invalidName_throwsIllegalArgumentException() { - String invalidName = ""; - assertThrows(IllegalArgumentException.class, () -> new Name(invalidName)); - } - - @Test - public void isValidName() { - // null name - assertThrows(NullPointerException.class, () -> Name.isValidName(null)); - - // invalid name - assertFalse(Name.isValidName("")); // empty string - assertFalse(Name.isValidName(" ")); // spaces only - assertFalse(Name.isValidName("^")); // only non-alphanumeric characters - assertFalse(Name.isValidName("peter*")); // contains non-alphanumeric characters - - // valid name - assertTrue(Name.isValidName("peter jack")); // alphabets only - assertTrue(Name.isValidName("12345")); // numbers only - assertTrue(Name.isValidName("peter the 2nd")); // alphanumeric characters - assertTrue(Name.isValidName("Capital Tan")); // with capital letters - assertTrue(Name.isValidName("David Roger Jackson Ray Jr 2nd")); // long names - } - - @Test - public void equals() { - Name name = new Name("Valid Name"); - - // same values -> returns true - assertTrue(name.equals(new Name("Valid Name"))); - - // same object -> returns true - assertTrue(name.equals(name)); - - // null -> returns false - assertFalse(name.equals(null)); - - // different types -> returns false - assertFalse(name.equals(5.0f)); - - // different values -> returns false - assertFalse(name.equals(new Name("Other Valid Name"))); - } -} 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 31a10d156c9..00000000000 --- a/src/test/java/seedu/address/model/person/PersonTest.java +++ /dev/null @@ -1,99 +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_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)); - - // same name, all other attributes different -> returns true - Person editedAlice = new PersonBuilder(ALICE).withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB) - .withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND).build(); - assertTrue(ALICE.isSamePerson(editedAlice)); - - // different name, all other attributes same -> returns false - editedAlice = new PersonBuilder(ALICE).withName(VALID_NAME_BOB).build(); - assertFalse(ALICE.isSamePerson(editedAlice)); - - // name differs in case, all other attributes same -> returns false - Person editedBob = new PersonBuilder(BOB).withName(VALID_NAME_BOB.toLowerCase()).build(); - assertFalse(BOB.isSamePerson(editedBob)); - - // name has trailing spaces, all other attributes same -> returns false - String nameWithTrailingSpaces = VALID_NAME_BOB + " "; - editedBob = new PersonBuilder(BOB).withName(nameWithTrailingSpaces).build(); - assertFalse(BOB.isSamePerson(editedBob)); - } - - @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)); - } - - @Test - public void toStringMethod() { - String expected = Person.class.getCanonicalName() + "{name=" + ALICE.getName() + ", phone=" + ALICE.getPhone() - + ", email=" + ALICE.getEmail() + ", address=" + ALICE.getAddress() + ", tags=" + ALICE.getTags() + "}"; - assertEquals(expected, ALICE.toString()); - } -} diff --git a/src/test/java/seedu/address/model/person/PhoneTest.java b/src/test/java/seedu/address/model/person/PhoneTest.java deleted file mode 100644 index deaaa5ba190..00000000000 --- a/src/test/java/seedu/address/model/person/PhoneTest.java +++ /dev/null @@ -1,60 +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 PhoneTest { - - @Test - public void constructor_null_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> new Phone(null)); - } - - @Test - public void constructor_invalidPhone_throwsIllegalArgumentException() { - String invalidPhone = ""; - assertThrows(IllegalArgumentException.class, () -> new Phone(invalidPhone)); - } - - @Test - public void isValidPhone() { - // null phone number - assertThrows(NullPointerException.class, () -> Phone.isValidPhone(null)); - - // invalid phone numbers - assertFalse(Phone.isValidPhone("")); // empty string - assertFalse(Phone.isValidPhone(" ")); // spaces only - assertFalse(Phone.isValidPhone("91")); // less than 3 numbers - assertFalse(Phone.isValidPhone("phone")); // non-numeric - assertFalse(Phone.isValidPhone("9011p041")); // alphabets within digits - assertFalse(Phone.isValidPhone("9312 1534")); // spaces within digits - - // valid phone numbers - assertTrue(Phone.isValidPhone("911")); // exactly 3 numbers - assertTrue(Phone.isValidPhone("93121534")); - assertTrue(Phone.isValidPhone("124293842033123")); // long phone numbers - } - - @Test - public void equals() { - Phone phone = new Phone("999"); - - // same values -> returns true - assertTrue(phone.equals(new Phone("999"))); - - // same object -> returns true - assertTrue(phone.equals(phone)); - - // null -> returns false - assertFalse(phone.equals(null)); - - // different types -> returns false - assertFalse(phone.equals(5.0f)); - - // different values -> returns false - assertFalse(phone.equals(new Phone("995"))); - } -} 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 17ae501df08..00000000000 --- a/src/test/java/seedu/address/model/person/UniquePersonListTest.java +++ /dev/null @@ -1,175 +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)); - } - - @Test - public void toStringMethod() { - assertEquals(uniquePersonList.asUnmodifiableObservableList().toString(), uniquePersonList.toString()); - } -} diff --git a/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java b/src/test/java/seedu/address/storage/JsonAdaptedClientTest.java similarity index 70% rename from src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java rename to src/test/java/seedu/address/storage/JsonAdaptedClientTest.java index 83b11331cdb..3acc1713304 100644 --- a/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java +++ b/src/test/java/seedu/address/storage/JsonAdaptedClientTest.java @@ -1,9 +1,9 @@ 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.storage.JsonAdaptedClient.MISSING_FIELD_MESSAGE_FORMAT; import static seedu.address.testutil.Assert.assertThrows; -import static seedu.address.testutil.TypicalPersons.BENSON; +import static seedu.address.testutil.TypicalClients.BENSON; import java.util.ArrayList; import java.util.List; @@ -12,12 +12,12 @@ 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; +import seedu.address.model.client.Address; +import seedu.address.model.client.Email; +import seedu.address.model.client.Name; +import seedu.address.model.client.Phone; -public class JsonAdaptedPersonTest { +public class JsonAdaptedClientTest { private static final String INVALID_NAME = "R@chel"; private static final String INVALID_PHONE = "+651234"; private static final String INVALID_ADDRESS = " "; @@ -33,78 +33,78 @@ public class JsonAdaptedPersonTest { .collect(Collectors.toList()); @Test - public void toModelType_validPersonDetails_returnsPerson() throws Exception { - JsonAdaptedPerson person = new JsonAdaptedPerson(BENSON); - assertEquals(BENSON, person.toModelType()); + public void toModelType_validClientDetails_returnsClient() throws Exception { + JsonAdaptedClient client = new JsonAdaptedClient(BENSON); + assertEquals(BENSON, client.toModelType()); } @Test public void toModelType_invalidName_throwsIllegalValueException() { - JsonAdaptedPerson person = - new JsonAdaptedPerson(INVALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + JsonAdaptedClient client = + new JsonAdaptedClient(INVALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); String expectedMessage = Name.MESSAGE_CONSTRAINTS; - assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); + assertThrows(IllegalValueException.class, expectedMessage, client::toModelType); } @Test public void toModelType_nullName_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(null, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + JsonAdaptedClient client = new JsonAdaptedClient(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); + assertThrows(IllegalValueException.class, expectedMessage, client::toModelType); } @Test public void toModelType_invalidPhone_throwsIllegalValueException() { - JsonAdaptedPerson person = - new JsonAdaptedPerson(VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + JsonAdaptedClient client = + new JsonAdaptedClient(VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); String expectedMessage = Phone.MESSAGE_CONSTRAINTS; - assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); + assertThrows(IllegalValueException.class, expectedMessage, client::toModelType); } @Test public void toModelType_nullPhone_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, null, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + JsonAdaptedClient client = new JsonAdaptedClient(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); + assertThrows(IllegalValueException.class, expectedMessage, client::toModelType); } @Test public void toModelType_invalidEmail_throwsIllegalValueException() { - JsonAdaptedPerson person = - new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, INVALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + JsonAdaptedClient client = + new JsonAdaptedClient(VALID_NAME, VALID_PHONE, INVALID_EMAIL, VALID_ADDRESS, VALID_TAGS); String expectedMessage = Email.MESSAGE_CONSTRAINTS; - assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); + assertThrows(IllegalValueException.class, expectedMessage, client::toModelType); } @Test public void toModelType_nullEmail_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, null, VALID_ADDRESS, VALID_TAGS); + JsonAdaptedClient client = new JsonAdaptedClient(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); + assertThrows(IllegalValueException.class, expectedMessage, client::toModelType); } @Test public void toModelType_invalidAddress_throwsIllegalValueException() { - JsonAdaptedPerson person = - new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, INVALID_ADDRESS, VALID_TAGS); + JsonAdaptedClient client = + new JsonAdaptedClient(VALID_NAME, VALID_PHONE, VALID_EMAIL, INVALID_ADDRESS, VALID_TAGS); String expectedMessage = Address.MESSAGE_CONSTRAINTS; - assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); + assertThrows(IllegalValueException.class, expectedMessage, client::toModelType); } @Test public void toModelType_nullAddress_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, null, VALID_TAGS); + JsonAdaptedClient client = new JsonAdaptedClient(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); + assertThrows(IllegalValueException.class, expectedMessage, client::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); + JsonAdaptedClient client = + new JsonAdaptedClient(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, invalidTags); + assertThrows(IllegalValueException.class, client::toModelType); } } diff --git a/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java b/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java index 4e5ce9200c8..5907335a013 100644 --- a/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java +++ b/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java @@ -3,10 +3,10 @@ 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.address.testutil.TypicalClients.ALICE; +import static seedu.address.testutil.TypicalClients.HOON; +import static seedu.address.testutil.TypicalClients.IDA; +import static seedu.address.testutil.TypicalClients.getTypicalAddressBook; import java.io.IOException; import java.nio.file.Path; @@ -51,13 +51,13 @@ public void read_notJsonFormat_exceptionThrown() { } @Test - public void readAddressBook_invalidPersonAddressBook_throwDataLoadingException() { - assertThrows(DataLoadingException.class, () -> readAddressBook("invalidPersonAddressBook.json")); + public void readAddressBook_invalidClientAddressBook_throwDataLoadingException() { + assertThrows(DataLoadingException.class, () -> readAddressBook("invalidClientAddressBook.json")); } @Test - public void readAddressBook_invalidAndValidPersonAddressBook_throwDataLoadingException() { - assertThrows(DataLoadingException.class, () -> readAddressBook("invalidAndValidPersonAddressBook.json")); + public void readAddressBook_invalidAndValidClientAddressBook_throwDataLoadingException() { + assertThrows(DataLoadingException.class, () -> readAddressBook("invalidAndValidClientAddressBook.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.addClient(HOON); + original.removeClient(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.addClient(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/address/storage/JsonSerializableAddressBookTest.java index 188c9058d20..44ce3c295d8 100644 --- a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java +++ b/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java @@ -11,36 +11,36 @@ import seedu.address.commons.exceptions.IllegalValueException; import seedu.address.commons.util.JsonUtil; import seedu.address.model.AddressBook; -import seedu.address.testutil.TypicalPersons; +import seedu.address.testutil.TypicalClients; 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_CLIENTS_FILE = TEST_DATA_FOLDER.resolve("typicalClientsAddressBook.json"); + private static final Path INVALID_CLIENT_FILE = TEST_DATA_FOLDER.resolve("invalidClientAddressBook.json"); + private static final Path DUPLICATE_CLIENT_FILE = TEST_DATA_FOLDER.resolve("duplicateClientAddressBook.json"); @Test - public void toModelType_typicalPersonsFile_success() throws Exception { - JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(TYPICAL_PERSONS_FILE, + public void toModelType_typicalClientsFile_success() throws Exception { + JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(TYPICAL_CLIENTS_FILE, JsonSerializableAddressBook.class).get(); AddressBook addressBookFromFile = dataFromFile.toModelType(); - AddressBook typicalPersonsAddressBook = TypicalPersons.getTypicalAddressBook(); - assertEquals(addressBookFromFile, typicalPersonsAddressBook); + AddressBook typicalClientsAddressBook = TypicalClients.getTypicalAddressBook(); + assertEquals(addressBookFromFile, typicalClientsAddressBook); } @Test - public void toModelType_invalidPersonFile_throwsIllegalValueException() throws Exception { - JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(INVALID_PERSON_FILE, + public void toModelType_invalidClientFile_throwsIllegalValueException() throws Exception { + JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(INVALID_CLIENT_FILE, JsonSerializableAddressBook.class).get(); assertThrows(IllegalValueException.class, dataFromFile::toModelType); } @Test - public void toModelType_duplicatePersons_throwsIllegalValueException() throws Exception { - JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(DUPLICATE_PERSON_FILE, + public void toModelType_duplicateClients_throwsIllegalValueException() throws Exception { + JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(DUPLICATE_CLIENT_FILE, JsonSerializableAddressBook.class).get(); - assertThrows(IllegalValueException.class, JsonSerializableAddressBook.MESSAGE_DUPLICATE_PERSON, + assertThrows(IllegalValueException.class, JsonSerializableAddressBook.MESSAGE_DUPLICATE_CLIENT, dataFromFile::toModelType); } diff --git a/src/test/java/seedu/address/storage/StorageManagerTest.java b/src/test/java/seedu/address/storage/StorageManagerTest.java index 99a16548970..505601d3256 100644 --- a/src/test/java/seedu/address/storage/StorageManagerTest.java +++ b/src/test/java/seedu/address/storage/StorageManagerTest.java @@ -2,7 +2,7 @@ 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.address.testutil.TypicalClients.getTypicalAddressBook; import java.nio.file.Path; diff --git a/src/test/java/seedu/address/testutil/AddressBookBuilder.java b/src/test/java/seedu/address/testutil/AddressBookBuilder.java index d53799fd110..daa51e2896c 100644 --- a/src/test/java/seedu/address/testutil/AddressBookBuilder.java +++ b/src/test/java/seedu/address/testutil/AddressBookBuilder.java @@ -1,12 +1,12 @@ package seedu.address.testutil; import seedu.address.model.AddressBook; -import seedu.address.model.person.Person; +import seedu.address.model.client.Client; /** * 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().withClient("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 Client} to the {@code AddressBook} that we are building. */ - public AddressBookBuilder withPerson(Person person) { - addressBook.addPerson(person); + public AddressBookBuilder withClient(Client client) { + addressBook.addClient(client); return this; } diff --git a/src/test/java/seedu/address/testutil/ClientBuilder.java b/src/test/java/seedu/address/testutil/ClientBuilder.java index 2f317032934..55c6c113872 100644 --- a/src/test/java/seedu/address/testutil/ClientBuilder.java +++ b/src/test/java/seedu/address/testutil/ClientBuilder.java @@ -1,10 +1,15 @@ package seedu.address.testutil; +import java.util.HashSet; +import java.util.Set; + import seedu.address.model.client.Address; import seedu.address.model.client.Client; import seedu.address.model.client.Email; import seedu.address.model.client.Name; import seedu.address.model.client.Phone; +import seedu.address.model.tag.Tag; +import seedu.address.model.util.SampleDataUtil; /** * A utility class to help with building Client objects. @@ -20,6 +25,7 @@ public class ClientBuilder { private Phone phone; private Email email; private Address address; + private Set tags; /** * Creates a {@code ClientBuilder} with the default details. @@ -29,6 +35,7 @@ public ClientBuilder() { phone = new Phone(DEFAULT_PHONE); email = new Email(DEFAULT_EMAIL); address = new Address(DEFAULT_ADDRESS); + tags = new HashSet<>(); } /** @@ -39,6 +46,7 @@ public ClientBuilder(Client clientToCopy) { phone = clientToCopy.getPhone(); email = clientToCopy.getEmail(); address = clientToCopy.getAddress(); + tags = new HashSet<>(clientToCopy.getTags()); } /** @@ -49,6 +57,14 @@ public ClientBuilder withName(String name) { return this; } + /** + * Parses the {@code tags} into a {@code Set} and set it to the {@code CLient} that we are building. + */ + public ClientBuilder withTags(String ... tags) { + this.tags = SampleDataUtil.getTagSet(tags); + return this; + } + /** * Sets the {@code Address} of the {@code Client} that we are building. */ @@ -74,7 +90,7 @@ public ClientBuilder withEmail(String email) { } public Client build() { - return new Client(name, phone, email, address); + return new Client(name, phone, email, address, tags); } } diff --git a/src/test/java/seedu/address/testutil/PersonUtil.java b/src/test/java/seedu/address/testutil/ClientUtil.java similarity index 63% rename from src/test/java/seedu/address/testutil/PersonUtil.java rename to src/test/java/seedu/address/testutil/ClientUtil.java index d47c55af5cd..1f3f3cf8660 100644 --- a/src/test/java/seedu/address/testutil/PersonUtil.java +++ b/src/test/java/seedu/address/testutil/ClientUtil.java @@ -9,41 +9,41 @@ import java.util.Set; import seedu.address.logic.commands.AddClientCommand; -import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; -import seedu.address.model.person.Person; +import seedu.address.logic.commands.EditCommand.EditClientDescriptor; +import seedu.address.model.client.Client; import seedu.address.model.tag.Tag; /** - * A utility class for Person. + * A utility class for Client. */ -public class PersonUtil { +public class ClientUtil { /** - * Returns an add command string for adding the {@code person}. + * Returns an add command string for adding the {@code client}. */ - public static String getAddClientCommand(Person person) { - return AddClientCommand.COMMAND_WORD + " " + getPersonDetails(person); + public static String getAddClientCommand(Client client) { + return AddClientCommand.COMMAND_WORD + " " + getClientDetails(client); } /** - * Returns the part of command string for the given {@code person}'s details. + * Returns the part of command string for the given {@code client}'s details. */ - public static String getPersonDetails(Person person) { + public static String getClientDetails(Client client) { 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( + sb.append(PREFIX_NAME + client.getName().fullName + " "); + sb.append(PREFIX_PHONE + client.getPhone().value + " "); + sb.append(PREFIX_EMAIL + client.getEmail().value + " "); + sb.append(PREFIX_ADDRESS + client.getAddress().value + " "); + client.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. + * Returns the part of command string for the given {@code EditClientDescriptor}'s details. */ - public static String getEditPersonDescriptorDetails(EditPersonDescriptor descriptor) { + public static String getEditClientDescriptorDetails(EditClientDescriptor 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(" ")); diff --git a/src/test/java/seedu/address/testutil/EditClientDescriptorBuilder.java b/src/test/java/seedu/address/testutil/EditClientDescriptorBuilder.java new file mode 100644 index 00000000000..0bfb092083c --- /dev/null +++ b/src/test/java/seedu/address/testutil/EditClientDescriptorBuilder.java @@ -0,0 +1,87 @@ +package seedu.address.testutil; + +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import seedu.address.logic.commands.EditCommand.EditClientDescriptor; +import seedu.address.model.client.Address; +import seedu.address.model.client.Client; +import seedu.address.model.client.Email; +import seedu.address.model.client.Name; +import seedu.address.model.client.Phone; +import seedu.address.model.tag.Tag; + +/** + * A utility class to help with building EditClientDescriptor objects. + */ +public class EditClientDescriptorBuilder { + + private EditClientDescriptor descriptor; + + public EditClientDescriptorBuilder() { + descriptor = new EditClientDescriptor(); + } + + public EditClientDescriptorBuilder(EditClientDescriptor descriptor) { + this.descriptor = new EditClientDescriptor(descriptor); + } + + /** + * Returns an {@code EditClientDescriptor} with fields containing {@code client}'s details + */ + public EditClientDescriptorBuilder(Client client) { + descriptor = new EditClientDescriptor(); + descriptor.setName(client.getName()); + descriptor.setPhone(client.getPhone()); + descriptor.setEmail(client.getEmail()); + descriptor.setAddress(client.getAddress()); + descriptor.setTags(client.getTags()); + } + + /** + * Sets the {@code Name} of the {@code EditClientDescriptor} that we are building. + */ + public EditClientDescriptorBuilder withName(String name) { + descriptor.setName(new Name(name)); + return this; + } + + /** + * Sets the {@code Phone} of the {@code EditClientDescriptor} that we are building. + */ + public EditClientDescriptorBuilder withPhone(String phone) { + descriptor.setPhone(new Phone(phone)); + return this; + } + + /** + * Sets the {@code Email} of the {@code EditClientDescriptor} that we are building. + */ + public EditClientDescriptorBuilder withEmail(String email) { + descriptor.setEmail(new Email(email)); + return this; + } + + /** + * Sets the {@code Address} of the {@code EditClientDescriptor} that we are building. + */ + public EditClientDescriptorBuilder withAddress(String address) { + descriptor.setAddress(new Address(address)); + return this; + } + + /** + * Parses the {@code tags} into a {@code Set} and set it to the {@code EditClientDescriptor} + * that we are building. + */ + public EditClientDescriptorBuilder withTags(String... tags) { + Set tagSet = Stream.of(tags).map(Tag::new).collect(Collectors.toSet()); + descriptor.setTags(tagSet); + return this; + } + + public EditClientDescriptor build() { + return descriptor; + } +} 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 6be381d39ba..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 = "Amy Bee"; - public static final String DEFAULT_PHONE = "85355255"; - public static final String DEFAULT_EMAIL = "amy@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/TestUtil.java b/src/test/java/seedu/address/testutil/TestUtil.java index 896d103eb0b..c76be011530 100644 --- a/src/test/java/seedu/address/testutil/TestUtil.java +++ b/src/test/java/seedu/address/testutil/TestUtil.java @@ -7,7 +7,7 @@ import seedu.address.commons.core.index.Index; import seedu.address.model.Model; -import seedu.address.model.person.Person; +import seedu.address.model.client.Client; /** * 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 client in the {@code model}'s client list. */ public static Index getMidIndex(Model model) { - return Index.fromOneBased(model.getFilteredPersonList().size() / 2); + return Index.fromOneBased(model.getFilteredClientList().size() / 2); } /** - * Returns the last index of the person in the {@code model}'s person list. + * Returns the last index of the client in the {@code model}'s client list. */ public static Index getLastIndex(Model model) { - return Index.fromOneBased(model.getFilteredPersonList().size()); + return Index.fromOneBased(model.getFilteredClientList().size()); } /** - * Returns the person in the {@code model}'s person list at {@code index}. + * Returns the client in the {@code model}'s client list at {@code index}. */ - public static Person getPerson(Model model, Index index) { - return model.getFilteredPersonList().get(index.getZeroBased()); + public static Client getClient(Model model, Index index) { + return model.getFilteredClientList().get(index.getZeroBased()); } } diff --git a/src/test/java/seedu/address/testutil/TypicalClients.java b/src/test/java/seedu/address/testutil/TypicalClients.java index 9c8e0a53579..96bb99e6bc7 100644 --- a/src/test/java/seedu/address/testutil/TypicalClients.java +++ b/src/test/java/seedu/address/testutil/TypicalClients.java @@ -8,6 +8,8 @@ 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; @@ -23,14 +25,16 @@ public class TypicalClients { public static final Client ALICE = new ClientBuilder().withName("Alice Pauline") .withAddress("123, Jurong West Ave 6, #08-111").withEmail("alice@example.com") - .withPhone("94351253").build(); + .withPhone("94351253") + .withTags("friends").build(); public static final Client BENSON = new ClientBuilder().withName("Benson Meier") .withAddress("311, Clementi Ave 2, #02-25") - .withEmail("johnd@example.com").withPhone("98765432").build(); + .withEmail("johnd@example.com").withPhone("98765432") + .withTags("owesMoney", "friends").build(); public static final Client CARL = new ClientBuilder().withName("Carl Kurz").withPhone("95352563") .withEmail("heinz@example.com").withAddress("wall street").build(); public static final Client DANIEL = new ClientBuilder().withName("Daniel Meier").withPhone("87652533") - .withEmail("cornelia@example.com").withAddress("10th street").build(); + .withEmail("cornelia@example.com").withAddress("10th street").withTags("friends", "Priority").build(); public static final Client ELLE = new ClientBuilder().withName("Elle Meyer").withPhone("9482224") .withEmail("werner@example.com").withAddress("michegan ave").build(); public static final Client FIONA = new ClientBuilder().withName("Fiona Kunz").withPhone("9482427") @@ -46,14 +50,14 @@ public class TypicalClients { // Manually added - Client's details found in {@code CommandTestUtil} public static final Client AMY = new ClientBuilder().withName(VALID_NAME_AMY).withPhone(VALID_PHONE_AMY) - .withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY).build(); + .withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY).withTags(VALID_TAG_FRIEND).build(); public static final Client BOB = new ClientBuilder().withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB) - .withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB).build(); + .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 TypicalClients() { - } // prevents instantiation + private TypicalClients() {} // prevents instantiation /** * Returns an {@code AddressBook} with all the typical clients. diff --git a/src/test/java/seedu/address/testutil/TypicalIndexes.java b/src/test/java/seedu/address/testutil/TypicalIndexes.java index ed886e8cf5c..b70ab8156fc 100644 --- a/src/test/java/seedu/address/testutil/TypicalIndexes.java +++ b/src/test/java/seedu/address/testutil/TypicalIndexes.java @@ -6,8 +6,8 @@ * A utility class containing a list of {@code Index} objects to be used in tests. */ public class TypicalIndexes { - public static final Index INDEX_FIRST_PERSON = Index.fromOneBased(1); - public static final Index INDEX_SECOND_PERSON = Index.fromOneBased(2); - public static final Index INDEX_THIRD_PERSON = Index.fromOneBased(3); - public static final Index INDEX_FOURTH_PERSON = Index.fromOneBased(4); + public static final Index INDEX_FIRST_CLIENT = Index.fromOneBased(1); + public static final Index INDEX_SECOND_CLIENT = Index.fromOneBased(2); + public static final Index INDEX_THIRD_CLIENT = Index.fromOneBased(3); + public static final Index INDEX_FOURTH_CLIENT = Index.fromOneBased(4); } 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 e10d6271fba..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", "Priority").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)); - } -} From 3589d5086f8ae8899b1e5357483be7f397b886a5 Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Thu, 20 Mar 2025 10:15:58 +0800 Subject: [PATCH 055/249] Make some changes to UI --- src/main/java/seedu/address/MainApp.java | 6 +++--- src/main/java/seedu/address/model/ModelManager.java | 2 +- src/main/resources/view/MainWindow.fxml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/address/MainApp.java b/src/main/java/seedu/address/MainApp.java index 678ddc8c218..4680367369f 100644 --- a/src/main/java/seedu/address/MainApp.java +++ b/src/main/java/seedu/address/MainApp.java @@ -48,7 +48,7 @@ public class MainApp extends Application { @Override public void init() throws Exception { - logger.info("=============================[ Initializing AddressBook ]==========================="); + logger.info("=============================[ Initializing WealthVault ]==========================="); super.init(); AppParameters appParameters = AppParameters.parse(getParameters()); @@ -81,12 +81,12 @@ private Model initModelManager(Storage storage, ReadOnlyUserPrefs userPrefs) { addressBookOptional = storage.readAddressBook(); if (!addressBookOptional.isPresent()) { logger.info("Creating a new data file " + storage.getAddressBookFilePath() - + " populated with a sample AddressBook."); + + " populated with a sample WealthVault."); } initialData = addressBookOptional.orElseGet(SampleDataUtil::getSampleAddressBook); } catch (DataLoadingException e) { logger.warning("Data file at " + storage.getAddressBookFilePath() + " could not be loaded." - + " Will be starting with an empty AddressBook."); + + " Will be starting with an empty WealthVault."); initialData = new AddressBook(); } diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index 2d425c8d37b..c309b3115fc 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -29,7 +29,7 @@ public class ModelManager implements Model { public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyUserPrefs userPrefs) { requireAllNonNull(addressBook, userPrefs); - logger.fine("Initializing with address book: " + addressBook + " and user prefs " + userPrefs); + logger.fine("Initializing with wealth vault: " + addressBook + " and user prefs " + userPrefs); this.addressBook = new AddressBook(addressBook); this.userPrefs = new UserPrefs(userPrefs); diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml index d2e12160757..51cc45da16c 100644 --- a/src/main/resources/view/MainWindow.fxml +++ b/src/main/resources/view/MainWindow.fxml @@ -12,7 +12,7 @@ + title="WealthVault" minWidth="450" minHeight="600" onCloseRequest="#handleExit"> From c9671a03c0a470b2d18fdb55b4c9458b361e01cd Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Thu, 20 Mar 2025 10:39:39 +0800 Subject: [PATCH 056/249] Make minor edits --- .../java/seedu/address/logic/commands/AddClientCommand.java | 4 ++-- src/main/java/seedu/address/logic/commands/ClearCommand.java | 2 +- src/main/java/seedu/address/logic/commands/EditCommand.java | 2 +- src/main/java/seedu/address/logic/commands/ExitCommand.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/AddClientCommand.java b/src/main/java/seedu/address/logic/commands/AddClientCommand.java index 3d96f9486c0..fd4d5f79b23 100644 --- a/src/main/java/seedu/address/logic/commands/AddClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddClientCommand.java @@ -20,7 +20,7 @@ public class AddClientCommand extends Command { public static final String COMMAND_WORD = "addclient"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a client to the address book. " + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a client to WealthVault. " + "Parameters: " + PREFIX_NAME + "NAME " + PREFIX_PHONE + "PHONE " @@ -36,7 +36,7 @@ public class AddClientCommand extends Command { + PREFIX_TAG + "owesMoney"; public static final String MESSAGE_SUCCESS = "New client added: %1$s"; - public static final String MESSAGE_DUPLICATE_CLIENT = "This client already exists in the address book"; + public static final String MESSAGE_DUPLICATE_CLIENT = "This client already exists in WealthVault"; private final Client toAdd; diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/address/logic/commands/ClearCommand.java index 9c86b1fa6e4..efb10950439 100644 --- a/src/main/java/seedu/address/logic/commands/ClearCommand.java +++ b/src/main/java/seedu/address/logic/commands/ClearCommand.java @@ -11,7 +11,7 @@ public class ClearCommand extends Command { public static final String COMMAND_WORD = "clear"; - public static final String MESSAGE_SUCCESS = "Address book has been cleared!"; + public static final String MESSAGE_SUCCESS = "WealthVault has been cleared!"; @Override diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index 1f010f6890a..00722ad113e 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -50,7 +50,7 @@ public class EditCommand extends Command { public static final String MESSAGE_EDIT_CLIENT_SUCCESS = "Edited Client: %1$s"; public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided."; - public static final String MESSAGE_DUPLICATE_CLIENT = "This client already exists in the address book."; + public static final String MESSAGE_DUPLICATE_CLIENT = "This client already exists in WealthVault."; private final Index index; private final EditClientDescriptor editClientDescriptor; diff --git a/src/main/java/seedu/address/logic/commands/ExitCommand.java b/src/main/java/seedu/address/logic/commands/ExitCommand.java index 3dd85a8ba90..bca249922c6 100644 --- a/src/main/java/seedu/address/logic/commands/ExitCommand.java +++ b/src/main/java/seedu/address/logic/commands/ExitCommand.java @@ -9,7 +9,7 @@ public class ExitCommand extends Command { public static final String COMMAND_WORD = "exit"; - public static final String MESSAGE_EXIT_ACKNOWLEDGEMENT = "Exiting Address Book as requested ..."; + public static final String MESSAGE_EXIT_ACKNOWLEDGEMENT = "Exiting WealthVault as requested ..."; @Override public CommandResult execute(Model model) { From a6c1f8edeb741107606ec1964f96acd4544d29fa Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Thu, 20 Mar 2025 10:54:51 +0800 Subject: [PATCH 057/249] Edit message for list command --- src/main/java/seedu/address/logic/commands/ListCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/logic/commands/ListCommand.java b/src/main/java/seedu/address/logic/commands/ListCommand.java index 0b75ea2ceda..80d1b69dd04 100644 --- a/src/main/java/seedu/address/logic/commands/ListCommand.java +++ b/src/main/java/seedu/address/logic/commands/ListCommand.java @@ -12,7 +12,7 @@ public class ListCommand extends Command { public static final String COMMAND_WORD = "list"; - public static final String MESSAGE_SUCCESS = "Listed all clients"; + public static final String MESSAGE_SUCCESS = "The list of clients has been successfully generated"; @Override From d4bbd49fb4a1eaaaeaf95d87441f90f346f13dae Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Thu, 20 Mar 2025 11:20:48 +0800 Subject: [PATCH 058/249] Make text edits --- .../seedu/address/logic/commands/AddClientCommand.java | 8 ++++---- .../java/seedu/address/logic/commands/ClearCommand.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/AddClientCommand.java b/src/main/java/seedu/address/logic/commands/AddClientCommand.java index fd4d5f79b23..8890543590b 100644 --- a/src/main/java/seedu/address/logic/commands/AddClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddClientCommand.java @@ -28,10 +28,10 @@ public class AddClientCommand extends Command { + PREFIX_ADDRESS + "ADDRESS " + "[" + PREFIX_TAG + "TAG]...\n" + "Example: " + COMMAND_WORD + " " - + PREFIX_NAME + "John Doe " - + PREFIX_PHONE + "98765432 " - + PREFIX_EMAIL + "johnd@example.com " - + PREFIX_ADDRESS + "311, Clementi Ave 2, #02-25 " + + PREFIX_NAME + "John Wilson " + + PREFIX_PHONE + "91234567 " + + PREFIX_EMAIL + "johnw@example.com " + + PREFIX_ADDRESS + "210, Clementi Ave 3, #12-01 " + PREFIX_TAG + "friends " + PREFIX_TAG + "owesMoney"; diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/address/logic/commands/ClearCommand.java index efb10950439..81326fb6adb 100644 --- a/src/main/java/seedu/address/logic/commands/ClearCommand.java +++ b/src/main/java/seedu/address/logic/commands/ClearCommand.java @@ -11,7 +11,7 @@ public class ClearCommand extends Command { public static final String COMMAND_WORD = "clear"; - public static final String MESSAGE_SUCCESS = "WealthVault has been cleared!"; + public static final String MESSAGE_SUCCESS = "WealthVault has been successfully cleared."; @Override From 8a61e1cbc4f9385b3f7ecdd4f07db0df9bdf352d Mon Sep 17 00:00:00 2001 From: joshua Date: Thu, 20 Mar 2025 14:13:55 +0800 Subject: [PATCH 059/249] add update command --- .../logic/commands/UpdateClientCommand.java | 62 ++++++++++++++ .../logic/parser/AddressBookParser.java | 4 + .../parser/UpdateClientCommandParser.java | 84 +++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 src/main/java/seedu/address/logic/commands/UpdateClientCommand.java create mode 100644 src/main/java/seedu/address/logic/parser/UpdateClientCommandParser.java diff --git a/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java b/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java new file mode 100644 index 00000000000..df30a4a8e58 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java @@ -0,0 +1,62 @@ +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 seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; + +/** + * Updates the details of an existing client in the address book. + * This is an alias for the EditCommand. + */ +public class UpdateClientCommand extends EditCommand { + + public static final String COMMAND_WORD = "update"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Updates the details of the client identified " + + "by the index number used in the displayed client 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_UPDATE_CLIENT_SUCCESS = "Updated Client: %1$s"; + + /** + * @param index of the client in the filtered client list to edit + * @param editClientDescriptor details to edit the client with + */ + public UpdateClientCommand(Index index, EditClientDescriptor editClientDescriptor) { + super(index, editClientDescriptor); + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + // Reuse the EditCommand execute logic but with a different success message + CommandResult result = super.execute(model); + + // Replace the edit success message with the update success message + String successMessage = String.format( + MESSAGE_UPDATE_CLIENT_SUCCESS, + result.getFeedbackToUser().substring( + MESSAGE_EDIT_CLIENT_SUCCESS.indexOf("%1$s") + 4 // Length of "%1$s" + ) + ); + + return new CommandResult(successMessage); + } +} \ No newline at end of file diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 94f6b42471e..d684eb57c8a 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -18,6 +18,7 @@ import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.PriorityCommand; +import seedu.address.logic.commands.UpdateClientCommand; import seedu.address.logic.parser.exceptions.ParseException; /** @@ -60,6 +61,9 @@ public Command parseCommand(String userInput) throws ParseException { case EditCommand.COMMAND_WORD: return new EditCommandParser().parse(arguments); + case UpdateClientCommand.COMMAND_WORD: + return new UpdateClientCommandParser().parse(arguments); + case DeleteClientCommand.COMMAND_WORD: return new DeleteClientCommandParser().parse(arguments); diff --git a/src/main/java/seedu/address/logic/parser/UpdateClientCommandParser.java b/src/main/java/seedu/address/logic/parser/UpdateClientCommandParser.java new file mode 100644 index 00000000000..b45a5552ecd --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/UpdateClientCommandParser.java @@ -0,0 +1,84 @@ +package seedu.address.logic.parser; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.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 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.EditClientDescriptor; +import seedu.address.logic.commands.UpdateClientCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.tag.Tag; + +/** + * Parses input arguments and creates a new UpdateClientCommand object. + */ +public class UpdateClientCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the UpdateClientCommand + * and returns an UpdateClientCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public UpdateClientCommand parse(String args) throws ParseException { + requireNonNull(args); + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG); + + Index index; + + try { + index = ParserUtil.parseIndex(argMultimap.getPreamble()); + } catch (ParseException pe) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, UpdateClientCommand.MESSAGE_USAGE), pe); + } + + argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS); + + EditClientDescriptor editClientDescriptor = new EditClientDescriptor(); + + if (argMultimap.getValue(PREFIX_NAME).isPresent()) { + editClientDescriptor.setName(ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get())); + } + if (argMultimap.getValue(PREFIX_PHONE).isPresent()) { + editClientDescriptor.setPhone(ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get())); + } + if (argMultimap.getValue(PREFIX_EMAIL).isPresent()) { + editClientDescriptor.setEmail(ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get())); + } + if (argMultimap.getValue(PREFIX_ADDRESS).isPresent()) { + editClientDescriptor.setAddress(ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get())); + } + parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editClientDescriptor::setTags); + + if (!editClientDescriptor.isAnyFieldEdited()) { + throw new ParseException(UpdateClientCommand.MESSAGE_NOT_EDITED); + } + + return new UpdateClientCommand(index, editClientDescriptor); + } + + /** + * Parses {@code Collection tags} into a {@code Set} if {@code tags} is non-empty. + * If {@code tags} contain only one element which is an empty string, it will be parsed into a + * {@code Set} containing zero tags. + */ + private Optional> parseTagsForEdit(Collection tags) throws ParseException { + assert tags != null; + + if (tags.isEmpty()) { + return Optional.empty(); + } + Collection tagSet = tags.size() == 1 && tags.contains("") ? Collections.emptySet() : tags; + return Optional.of(ParserUtil.parseTags(tagSet)); + } +} \ No newline at end of file From eaabb4b9d3c707090b20bf1ac0b89ce08958a7ca Mon Sep 17 00:00:00 2001 From: joshua Date: Thu, 20 Mar 2025 14:14:14 +0800 Subject: [PATCH 060/249] update AboutUs --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 33a3db4ef47..151143d44f3 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -31,7 +31,7 @@ You can reach us at the email `seer[at]comp.nus.edu.sg` * Role: Project Member * Responsibilities: UI -### Johnny Doe +### Joshua Tan From 063a48383108c2d2788b135c01e895b3e04504a4 Mon Sep 17 00:00:00 2001 From: joshua Date: Thu, 20 Mar 2025 14:25:11 +0800 Subject: [PATCH 061/249] fix checkstyle --- .../address/logic/commands/UpdateClientCommand.java | 12 ++++-------- .../logic/parser/UpdateClientCommandParser.java | 5 +++-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java b/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java index df30a4a8e58..d941c176905 100644 --- a/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java @@ -45,18 +45,14 @@ public UpdateClientCommand(Index index, EditClientDescriptor editClientDescripto @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); - - // Reuse the EditCommand execute logic but with a different success message CommandResult result = super.execute(model); - - // Replace the edit success message with the update success message String successMessage = String.format( - MESSAGE_UPDATE_CLIENT_SUCCESS, + MESSAGE_UPDATE_CLIENT_SUCCESS, result.getFeedbackToUser().substring( - MESSAGE_EDIT_CLIENT_SUCCESS.indexOf("%1$s") + 4 // Length of "%1$s" + MESSAGE_EDIT_CLIENT_SUCCESS.indexOf("%1$s") + 4 ) ); - + return new CommandResult(successMessage); } -} \ No newline at end of file +} diff --git a/src/main/java/seedu/address/logic/parser/UpdateClientCommandParser.java b/src/main/java/seedu/address/logic/parser/UpdateClientCommandParser.java index b45a5552ecd..df829e7d12f 100644 --- a/src/main/java/seedu/address/logic/parser/UpdateClientCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/UpdateClientCommandParser.java @@ -39,7 +39,8 @@ public UpdateClientCommand parse(String args) throws ParseException { try { index = ParserUtil.parseIndex(argMultimap.getPreamble()); } catch (ParseException pe) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, UpdateClientCommand.MESSAGE_USAGE), pe); + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + UpdateClientCommand.MESSAGE_USAGE), pe); } argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS); @@ -81,4 +82,4 @@ private Optional> parseTagsForEdit(Collection tags) throws Pars Collection tagSet = tags.size() == 1 && tags.contains("") ? Collections.emptySet() : tags; return Optional.of(ParserUtil.parseTags(tagSet)); } -} \ No newline at end of file +} From c11f50245ae4cf0d0c5933896f66802b95e159aa Mon Sep 17 00:00:00 2001 From: Nicholas Foo Date: Thu, 20 Mar 2025 14:49:29 +0800 Subject: [PATCH 062/249] Add and Refactor for FindClientCommand --- docs/diagrams/LogicClassDiagram.puml | 2 +- .../logic/commands/FindClientCommand.java | 58 +++++++++++++++++++ ...ndCommand.java => FindClientCommand.java~} | 10 ++-- .../logic/parser/AddressBookParser.java | 6 +- ...rser.java => FindClientCommandParser.java} | 16 ++--- ...ndTest.java => FindClientCommandTest.java} | 20 +++---- .../logic/parser/AddressBookParserTest.java | 8 +-- ....java => FindClientCommandParserTest.java} | 17 +++--- 8 files changed, 98 insertions(+), 39 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/FindClientCommand.java rename src/main/java/seedu/address/logic/commands/{FindCommand.java => FindClientCommand.java~} (83%) rename src/main/java/seedu/address/logic/parser/{FindCommandParser.java => FindClientCommandParser.java} (58%) rename src/test/java/seedu/address/logic/commands/{FindCommandTest.java => FindClientCommandTest.java} (82%) rename src/test/java/seedu/address/logic/parser/{FindCommandParserTest.java => FindClientCommandParserTest.java} (55%) diff --git a/docs/diagrams/LogicClassDiagram.puml b/docs/diagrams/LogicClassDiagram.puml index 58b4f602ce6..de9c34aab79 100644 --- a/docs/diagrams/LogicClassDiagram.puml +++ b/docs/diagrams/LogicClassDiagram.puml @@ -39,7 +39,7 @@ LogicManager --> Storage Storage --[hidden] Model Command .[hidden]up.> Storage Command .right.> Model -note right of XYZCommand: XYZCommand = AddCommand, \nFindCommand, etc +note right of XYZCommand: XYZCommand = AddClientCommand, \nFindClientCommand, etc Logic ..> CommandResult LogicManager .down.> CommandResult diff --git a/src/main/java/seedu/address/logic/commands/FindClientCommand.java b/src/main/java/seedu/address/logic/commands/FindClientCommand.java new file mode 100644 index 00000000000..f5ca1097f3e --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/FindClientCommand.java @@ -0,0 +1,58 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.model.Model; +import seedu.address.model.client.NameContainsKeywordsPredicate; + +/** + * Finds and lists all clients in address book whose name contains any of the argument keywords. + * Keyword matching is case insensitive. + */ +public class FindClientCommand extends Command { + + public static final String COMMAND_WORD = "findclient"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients 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"; + + private final NameContainsKeywordsPredicate predicate; + + public FindClientCommand(NameContainsKeywordsPredicate predicate) { + this.predicate = predicate; + } + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + model.updateFilteredClientList(predicate); + return new CommandResult( + String.format(Messages.MESSAGE_CLIENTS_LISTED_OVERVIEW, model.getFilteredClientList().size())); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof FindClientCommand)) { + return false; + } + + FindClientCommand otherFindClientCommand = (FindClientCommand) other; + return predicate.equals(otherFindClientCommand.predicate); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("predicate", predicate) + .toString(); + } +} diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/seedu/address/logic/commands/FindClientCommand.java~ similarity index 83% rename from src/main/java/seedu/address/logic/commands/FindCommand.java rename to src/main/java/seedu/address/logic/commands/FindClientCommand.java~ index e6000eaffe8..98855c84902 100644 --- a/src/main/java/seedu/address/logic/commands/FindCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindClientCommand.java~ @@ -11,7 +11,7 @@ * Finds and lists all clients in address book whose name contains any of the argument keywords. * Keyword matching is case insensitive. */ -public class FindCommand extends Command { +public class FindClientCommand extends Command { public static final String COMMAND_WORD = "find"; @@ -22,7 +22,7 @@ public class FindCommand extends Command { private final NameContainsKeywordsPredicate predicate; - public FindCommand(NameContainsKeywordsPredicate predicate) { + public FindClientCommand(NameContainsKeywordsPredicate predicate) { this.predicate = predicate; } @@ -41,12 +41,12 @@ public boolean equals(Object other) { } // instanceof handles nulls - if (!(other instanceof FindCommand)) { + if (!(other instanceof FindClientCommand)) { return false; } - FindCommand otherFindCommand = (FindCommand) other; - return predicate.equals(otherFindCommand.predicate); + FindClientCommand otherFindClientCommand = (FindClientCommand) other; + return predicate.equals(otherFindClientCommand.predicate); } @Override diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 94f6b42471e..053d0938275 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -14,7 +14,7 @@ import seedu.address.logic.commands.DeleteClientCommand; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.ExitCommand; -import seedu.address.logic.commands.FindCommand; +import seedu.address.logic.commands.FindClientCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.PriorityCommand; @@ -66,8 +66,8 @@ public Command parseCommand(String userInput) throws ParseException { case ClearCommand.COMMAND_WORD: return new ClearCommand(); - case FindCommand.COMMAND_WORD: - return new FindCommandParser().parse(arguments); + case FindClientCommand.COMMAND_WORD: + return new FindClientCommandParser().parse(arguments); case ListCommand.COMMAND_WORD: return new ListCommand(); diff --git a/src/main/java/seedu/address/logic/parser/FindCommandParser.java b/src/main/java/seedu/address/logic/parser/FindClientCommandParser.java similarity index 58% rename from src/main/java/seedu/address/logic/parser/FindCommandParser.java rename to src/main/java/seedu/address/logic/parser/FindClientCommandParser.java index 72e69cf2a76..f6130ee5036 100644 --- a/src/main/java/seedu/address/logic/parser/FindCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/FindClientCommandParser.java @@ -4,30 +4,30 @@ import java.util.Arrays; -import seedu.address.logic.commands.FindCommand; +import seedu.address.logic.commands.FindClientCommand; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.client.NameContainsKeywordsPredicate; /** - * Parses input arguments and creates a new FindCommand object + * Parses input arguments and creates a new FindClientCommand object */ -public class FindCommandParser implements Parser { +public class FindClientCommandParser implements Parser { /** - * Parses the given {@code String} of arguments in the context of the FindCommand - * and returns a FindCommand object for execution. + * Parses the given {@code String} of arguments in the context of the FindClientCommand + * and returns a FindClientCommand object for execution. * @throws ParseException if the user input does not conform the expected format */ - public FindCommand parse(String args) throws ParseException { + public FindClientCommand parse(String args) throws ParseException { String trimmedArgs = args.trim(); if (trimmedArgs.isEmpty()) { throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE)); + String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindClientCommand.MESSAGE_USAGE)); } String[] nameKeywords = trimmedArgs.split("\\s+"); - return new FindCommand(new NameContainsKeywordsPredicate(Arrays.asList(nameKeywords))); + return new FindClientCommand(new NameContainsKeywordsPredicate(Arrays.asList(nameKeywords))); } } diff --git a/src/test/java/seedu/address/logic/commands/FindCommandTest.java b/src/test/java/seedu/address/logic/commands/FindClientCommandTest.java similarity index 82% rename from src/test/java/seedu/address/logic/commands/FindCommandTest.java rename to src/test/java/seedu/address/logic/commands/FindClientCommandTest.java index 6610ec5d659..84c7f30595b 100644 --- a/src/test/java/seedu/address/logic/commands/FindCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/FindClientCommandTest.java @@ -21,9 +21,9 @@ import seedu.address.model.client.NameContainsKeywordsPredicate; /** - * Contains integration tests (interaction with the Model) for {@code FindCommand}. + * Contains integration tests (interaction with the Model) for {@code FindClientCommand}. */ -public class FindCommandTest { +public class FindClientCommandTest { private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs()); @@ -34,14 +34,14 @@ public void equals() { NameContainsKeywordsPredicate secondPredicate = new NameContainsKeywordsPredicate(Collections.singletonList("second")); - FindCommand findFirstCommand = new FindCommand(firstPredicate); - FindCommand findSecondCommand = new FindCommand(secondPredicate); + FindClientCommand findFirstCommand = new FindClientCommand(firstPredicate); + FindClientCommand findSecondCommand = new FindClientCommand(secondPredicate); // same object -> returns true assertTrue(findFirstCommand.equals(findFirstCommand)); // same values -> returns true - FindCommand findFirstCommandCopy = new FindCommand(firstPredicate); + FindClientCommand findFirstCommandCopy = new FindClientCommand(firstPredicate); assertTrue(findFirstCommand.equals(findFirstCommandCopy)); // different types -> returns false @@ -58,7 +58,7 @@ public void equals() { public void execute_zeroKeywords_noClientFound() { String expectedMessage = String.format(MESSAGE_CLIENTS_LISTED_OVERVIEW, 0); NameContainsKeywordsPredicate predicate = preparePredicate(" "); - FindCommand command = new FindCommand(predicate); + FindClientCommand command = new FindClientCommand(predicate); expectedModel.updateFilteredClientList(predicate); assertCommandSuccess(command, model, expectedMessage, expectedModel); assertEquals(Collections.emptyList(), model.getFilteredClientList()); @@ -68,7 +68,7 @@ public void execute_zeroKeywords_noClientFound() { public void execute_multipleKeywords_multipleClientsFound() { String expectedMessage = String.format(MESSAGE_CLIENTS_LISTED_OVERVIEW, 3); NameContainsKeywordsPredicate predicate = preparePredicate("Kurz Elle Kunz"); - FindCommand command = new FindCommand(predicate); + FindClientCommand command = new FindClientCommand(predicate); expectedModel.updateFilteredClientList(predicate); assertCommandSuccess(command, model, expectedMessage, expectedModel); assertEquals(Arrays.asList(CARL, ELLE, FIONA), model.getFilteredClientList()); @@ -77,9 +77,9 @@ public void execute_multipleKeywords_multipleClientsFound() { @Test public void toStringMethod() { NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Arrays.asList("keyword")); - FindCommand findCommand = new FindCommand(predicate); - String expected = FindCommand.class.getCanonicalName() + "{predicate=" + predicate + "}"; - assertEquals(expected, findCommand.toString()); + FindClientCommand findClientCommand = new FindClientCommand(predicate); + String expected = FindClientCommand.class.getCanonicalName() + "{predicate=" + predicate + "}"; + assertEquals(expected, findClientCommand.toString()); } /** diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 0ddbed08b2e..0d8a085a288 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -19,7 +19,7 @@ import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.EditCommand.EditClientDescriptor; import seedu.address.logic.commands.ExitCommand; -import seedu.address.logic.commands.FindCommand; +import seedu.address.logic.commands.FindClientCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.PriorityCommand; @@ -72,9 +72,9 @@ public void parseCommand_exit() throws Exception { @Test public void parseCommand_find() throws Exception { List keywords = Arrays.asList("foo", "bar", "baz"); - FindCommand command = (FindCommand) parser.parseCommand( - FindCommand.COMMAND_WORD + " " + keywords.stream().collect(Collectors.joining(" "))); - assertEquals(new FindCommand(new NameContainsKeywordsPredicate(keywords)), command); + FindClientCommand command = (FindClientCommand) parser.parseCommand( + FindClientCommand.COMMAND_WORD + " " + keywords.stream().collect(Collectors.joining(" "))); + assertEquals(new FindClientCommand(new NameContainsKeywordsPredicate(keywords)), command); } @Test diff --git a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindClientCommandParserTest.java similarity index 55% rename from src/test/java/seedu/address/logic/parser/FindCommandParserTest.java rename to src/test/java/seedu/address/logic/parser/FindClientCommandParserTest.java index db4ff590779..ce7870a15a4 100644 --- a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/FindClientCommandParserTest.java @@ -8,27 +8,28 @@ import org.junit.jupiter.api.Test; -import seedu.address.logic.commands.FindCommand; +import seedu.address.logic.commands.FindClientCommand; import seedu.address.model.client.NameContainsKeywordsPredicate; -public class FindCommandParserTest { +public class FindClientCommandParserTest { - private FindCommandParser parser = new FindCommandParser(); + private FindClientCommandParser parser = new FindClientCommandParser(); @Test public void parse_emptyArg_throwsParseException() { - assertParseFailure(parser, " ", String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE)); + assertParseFailure(parser, " ", + String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindClientCommand.MESSAGE_USAGE)); } @Test public void parse_validArgs_returnsFindCommand() { // no leading and trailing whitespaces - FindCommand expectedFindCommand = - new FindCommand(new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob"))); - assertParseSuccess(parser, "Alice Bob", expectedFindCommand); + FindClientCommand expectedFindClientCommand = + new FindClientCommand(new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob"))); + assertParseSuccess(parser, "Alice Bob", expectedFindClientCommand); // multiple whitespaces between keywords - assertParseSuccess(parser, " \n Alice \n \t Bob \t", expectedFindCommand); + assertParseSuccess(parser, " \n Alice \n \t Bob \t", expectedFindClientCommand); } } From a5f5d4dac6c09889b8d9af3cbec056d95d04387d Mon Sep 17 00:00:00 2001 From: Nicholas Foo Date: Thu, 20 Mar 2025 14:56:02 +0800 Subject: [PATCH 063/249] Edit UserGuide for Refactored Commands --- docs/UserGuide.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index bcaa1bbd470..ef707930cd2 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -31,9 +31,9 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo * `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. + * `addclient 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. + * `deleteclient 3` : Deletes the 3rd contact shown in the current list. * `clear` : Deletes all contacts. @@ -50,7 +50,7 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo **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`. + e.g. in `addclient n/NAME`, `NAME` is a parameter which can be used as `addclient 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`. @@ -76,11 +76,11 @@ Shows a message explaning how to access the help page. Format: `help` -### Adding a person: `add` +### Adding a person: `addclient` Adds a person to the address book. -Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​` +Format: `addclient n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​` @@ -88,8 +88,8 @@ Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​` 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` +* `addclient n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` +* `addclient n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal` ### Listing all persons : `list` @@ -114,11 +114,11 @@ 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. -### Locating persons by name: `find` +### Locating persons by name: `findclient` Finds persons whose names contain any of the given keywords. -Format: `find KEYWORD [MORE_KEYWORDS]` +Format: `findclient KEYWORD [MORE_KEYWORDS]` * 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` @@ -128,23 +128,23 @@ Format: `find KEYWORD [MORE_KEYWORDS]` e.g. `Hans Bo` will return `Hans Gruber`, `Bo Yang` Examples: -* `find John` returns `john` and `John Doe` -* `find alex david` returns `Alex Yeoh`, `David Li`
    +* `findclient John` returns `john` and `John Doe` +* `findclient alex david` returns `Alex Yeoh`, `David Li`
    ![result for 'find alex david'](images/findAlexDavidResult.png) -### Deleting a person : `delete` +### Deleting a person : `deleteclient` Deletes the specified person from the address book. -Format: `delete INDEX` +Format: `deleteclient INDEX` * 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, …​ 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. +* `list` followed by `deleteclient 2` deletes the 2nd person in the address book. +* `findclient Betsy` followed by `deleteclient 1` deletes the 1st person in the results of the `findclient` command. ### Clearing all entries : `clear` @@ -197,10 +197,10 @@ _Details coming soon ..._ 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` +**Add** | `addclient n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​`
    e.g., `addclient 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` +**Delete** | `deleteclient INDEX`
    e.g., `deleteclient 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` +**Find** | `findclient KEYWORD [MORE_KEYWORDS]`
    e.g., `findclient James Jake` **List** | `list` **Help** | `help` From 840b1e984d86e416320df7a684a396d80c8e3db2 Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Thu, 20 Mar 2025 15:06:49 +0800 Subject: [PATCH 064/249] Make slight edits --- .../address/logic/commands/AddClientCommandTest.java | 12 ++++++------ .../logic/commands/DeleteClientCommandTest.java | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java b/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java index d516d587657..7e33ac456db 100644 --- a/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java @@ -120,32 +120,32 @@ public void setAddressBookFilePath(Path addressBookFilePath) { } @Override - public void addClient(Client client) { + public void setAddressBook(ReadOnlyAddressBook newData) { throw new AssertionError("This method should not be called."); } @Override - public void setAddressBook(ReadOnlyAddressBook newData) { + public ReadOnlyAddressBook getAddressBook() { throw new AssertionError("This method should not be called."); } @Override - public ReadOnlyAddressBook getAddressBook() { + public boolean hasClient(Client client) { throw new AssertionError("This method should not be called."); } @Override - public boolean hasClient(Client client) { + public void setClient(Client target, Client editedClient) { throw new AssertionError("This method should not be called."); } @Override - public void deleteClient(Client target) { + public void addClient(Client client) { throw new AssertionError("This method should not be called."); } @Override - public void setClient(Client target, Client editedClient) { + public void deleteClient(Client target) { throw new AssertionError("This method should not be called."); } diff --git a/src/test/java/seedu/address/logic/commands/DeleteClientCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteClientCommandTest.java index 721765d5c3a..a05c71a12fd 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteClientCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteClientCommandTest.java @@ -94,11 +94,11 @@ public void equals() { // different types -> returns false assertFalse(deleteFirstCommand.equals(1)); - // null -> returns false - assertFalse(deleteFirstCommand.equals(null)); - // different client -> returns false assertFalse(deleteFirstCommand.equals(deleteSecondCommand)); + + // null -> returns false + assertFalse(deleteFirstCommand.equals(null)); } @Test From 696b1b64301d4e6e347e924818627be09435fae0 Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Thu, 20 Mar 2025 15:15:26 +0800 Subject: [PATCH 065/249] Make some small changes --- .../java/seedu/address/AppParameters.java | 10 ++-- .../seedu/address/logic/LogicManager.java | 10 ++-- .../logic/commands/PriorityCommand.java | 4 +- .../model/client/UniqueClientList.java | 50 +++++++++---------- .../java/seedu/address/model/tag/Tag.java | 2 +- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/main/java/seedu/address/AppParameters.java b/src/main/java/seedu/address/AppParameters.java index 3d603622d4e..44881e7e05b 100644 --- a/src/main/java/seedu/address/AppParameters.java +++ b/src/main/java/seedu/address/AppParameters.java @@ -44,6 +44,11 @@ public static AppParameters parse(Application.Parameters parameters) { return appParameters; } + @Override + public int hashCode() { + return configPath.hashCode(); + } + @Override public boolean equals(Object other) { if (other == this) { @@ -59,11 +64,6 @@ public boolean equals(Object other) { return Objects.equals(configPath, otherAppParameters.configPath); } - @Override - public int hashCode() { - return configPath.hashCode(); - } - @Override public String toString() { return new ToStringBuilder(this) diff --git a/src/main/java/seedu/address/logic/LogicManager.java b/src/main/java/seedu/address/logic/LogicManager.java index 69116c0b40b..f30323ddbd2 100644 --- a/src/main/java/seedu/address/logic/LogicManager.java +++ b/src/main/java/seedu/address/logic/LogicManager.java @@ -66,11 +66,6 @@ public ReadOnlyAddressBook getAddressBook() { return model.getAddressBook(); } - @Override - public ObservableList getFilteredClientList() { - return model.getFilteredClientList(); - } - @Override public Path getAddressBookFilePath() { return model.getAddressBookFilePath(); @@ -85,4 +80,9 @@ public GuiSettings getGuiSettings() { public void setGuiSettings(GuiSettings guiSettings) { model.setGuiSettings(guiSettings); } + + @Override + public ObservableList getFilteredClientList() { + return model.getFilteredClientList(); + } } diff --git a/src/main/java/seedu/address/logic/commands/PriorityCommand.java b/src/main/java/seedu/address/logic/commands/PriorityCommand.java index bcc892df02a..8a17d933e61 100644 --- a/src/main/java/seedu/address/logic/commands/PriorityCommand.java +++ b/src/main/java/seedu/address/logic/commands/PriorityCommand.java @@ -22,10 +22,10 @@ public class PriorityCommand extends Command { public static final String COMMAND_WORD = "priority"; - public static final String MESSAGE_PRIORITY_CLIENT_SUCCESS = "Toggle Priority of Client: %1$s"; + public static final String MESSAGE_PRIORITY_CLIENT_SUCCESS = "Priority status of client changed: %1$s"; public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Marks the client identified by the index number used in the displayed client list as a priority.\n" + + ": Marks the client identified by the index number used in the displayed client list as priority.\n" + "Parameters: INDEX (must be a positive integer)\n" + "Example: " + COMMAND_WORD + " 1"; diff --git a/src/main/java/seedu/address/model/client/UniqueClientList.java b/src/main/java/seedu/address/model/client/UniqueClientList.java index 1ff60ea30f7..7f55ba3d81c 100644 --- a/src/main/java/seedu/address/model/client/UniqueClientList.java +++ b/src/main/java/seedu/address/model/client/UniqueClientList.java @@ -68,17 +68,6 @@ public void setClient(Client target, Client editedClient) { internalList.set(index, editedClient); } - /** - * Removes the equivalent client from the list. - * The client must exist in the list. - */ - public void remove(Client toRemove) { - requireNonNull(toRemove); - if (!internalList.remove(toRemove)) { - throw new ClientNotFoundException(); - } - } - public void setClients(UniqueClientList replacement) { requireNonNull(replacement); internalList.setAll(replacement.internalList); @@ -97,6 +86,17 @@ public void setClients(List clients) { internalList.setAll(clients); } + /** + * Removes the equivalent client from the list. + * The client must exist in the list. + */ + public void remove(Client toRemove) { + requireNonNull(toRemove); + if (!internalList.remove(toRemove)) { + throw new ClientNotFoundException(); + } + } + /** * Returns the backing list as an unmodifiable {@code ObservableList}. */ @@ -109,6 +109,20 @@ public Iterator iterator() { return internalList.iterator(); } + /** + * Returns true if {@code clients} contains only unique clients. + */ + private boolean clientsAreUnique(List clients) { + for (int i = 0; i < clients.size() - 1; i++) { + for (int j = i + 1; j < clients.size(); j++) { + if (clients.get(i).isSameClient(clients.get(j))) { + return false; + } + } + } + return true; + } + @Override public boolean equals(Object other) { if (other == this) { @@ -133,18 +147,4 @@ public int hashCode() { public String toString() { return internalList.toString(); } - - /** - * Returns true if {@code clients} contains only unique clients. - */ - private boolean clientsAreUnique(List clients) { - for (int i = 0; i < clients.size() - 1; i++) { - for (int j = i + 1; j < clients.size(); j++) { - if (clients.get(i).isSameClient(clients.get(j))) { - return false; - } - } - } - return true; - } } diff --git a/src/main/java/seedu/address/model/tag/Tag.java b/src/main/java/seedu/address/model/tag/Tag.java index 840c71d0e08..5e54a9afa34 100644 --- a/src/main/java/seedu/address/model/tag/Tag.java +++ b/src/main/java/seedu/address/model/tag/Tag.java @@ -9,7 +9,7 @@ */ public class Tag { - public static final String MESSAGE_CONSTRAINTS = "Tags names should be alphanumeric"; + public static final String MESSAGE_CONSTRAINTS = "Tag names should be alphanumeric"; public static final String VALIDATION_REGEX = "\\p{Alnum}+"; public final String tagName; From af8295ce6c83e5eb456161866dbf58f8fc1f958f Mon Sep 17 00:00:00 2001 From: joshua Date: Thu, 20 Mar 2025 15:47:10 +0800 Subject: [PATCH 066/249] Add tests --- .../commands/UpdateClientCommandTest.java | 163 ++++++++++++++++++ .../seedu/address/testutil/ModelStub.java | 86 +++++++++ 2 files changed, 249 insertions(+) create mode 100644 src/test/java/seedu/address/logic/commands/UpdateClientCommandTest.java create mode 100644 src/test/java/seedu/address/testutil/ModelStub.java diff --git a/src/test/java/seedu/address/logic/commands/UpdateClientCommandTest.java b/src/test/java/seedu/address/logic/commands/UpdateClientCommandTest.java new file mode 100644 index 00000000000..4f551034422 --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/UpdateClientCommandTest.java @@ -0,0 +1,163 @@ +package seedu.address.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.address.testutil.TypicalClients.ALICE; +import static seedu.address.testutil.TypicalClients.BOB; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_CLIENT; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_CLIENT; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; + +import org.junit.jupiter.api.Test; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import seedu.address.logic.commands.EditCommand.EditClientDescriptor; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.client.Client; +import seedu.address.testutil.ClientBuilder; +import seedu.address.testutil.EditClientDescriptorBuilder; +import seedu.address.testutil.ModelStub; + +/** + * Contains unit tests for {@code UpdateClientCommand}. + */ +public class UpdateClientCommandTest { + + @Test + public void constructor_nullDescriptor_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> new UpdateClientCommand(INDEX_FIRST_CLIENT, null)); + } + + @Test + public void execute_clientAcceptedByModel_updateSuccessful() throws Exception { + Client originalClient = new ClientBuilder().withName("ted").build(); + Client updatedClient = new ClientBuilder().withName("Updated").build(); + + ModelStubForUpdate modelStub = new ModelStubForUpdate(originalClient); + EditClientDescriptor descriptor = new EditClientDescriptorBuilder(updatedClient).build(); + + UpdateClientCommand updateCommand = new UpdateClientCommand(INDEX_FIRST_CLIENT, descriptor); + CommandResult result = updateCommand.execute(modelStub); + + // Just expect exactly what's being output + String expectedMessage = "Updated Client: ted; Phone: 85355255; Email: amy@gmail.com; " + + "Address: 123, Jurong West Ave 6, #08-111; Tags: "; + assertEquals(expectedMessage, result.getFeedbackToUser()); + assertEquals(updatedClient, modelStub.clientUpdated); + } + + @Test + public void execute_duplicateClient_throwsCommandException() { + Client firstClient = new ClientBuilder().withName("First").build(); + Client secondClient = new ClientBuilder().withName("Second").build(); + + EditClientDescriptor descriptor = new EditClientDescriptorBuilder().withName("Second").build(); + UpdateClientCommand updateCommand = new UpdateClientCommand(INDEX_FIRST_CLIENT, descriptor); + + ModelStubForDuplicate modelStub = new ModelStubForDuplicate(Arrays.asList(firstClient, secondClient)); + + assertThrows(CommandException.class, + EditCommand.MESSAGE_DUPLICATE_CLIENT, () -> updateCommand.execute(modelStub)); + } + + @Test + public void equals() { + EditClientDescriptor aliceDescriptor = new EditClientDescriptorBuilder(ALICE).build(); + EditClientDescriptor bobDescriptor = new EditClientDescriptorBuilder(BOB).build(); + + UpdateClientCommand updateAliceCommand = new UpdateClientCommand(INDEX_FIRST_CLIENT, aliceDescriptor); + UpdateClientCommand updateBobCommand = new UpdateClientCommand(INDEX_FIRST_CLIENT, bobDescriptor); + + // same object -> returns true + assertTrue(updateAliceCommand.equals(updateAliceCommand)); + + // same values -> returns true + UpdateClientCommand updateAliceCommandCopy = new UpdateClientCommand(INDEX_FIRST_CLIENT, aliceDescriptor); + assertTrue(updateAliceCommand.equals(updateAliceCommandCopy)); + + // different types -> returns false + assertFalse(updateAliceCommand.equals(1)); + + // null -> returns false + assertFalse(updateAliceCommand.equals(null)); + + // different client -> returns false + assertFalse(updateAliceCommand.equals(updateBobCommand)); + + // different index -> returns false + UpdateClientCommand updateAliceCommandDiffIndex = + new UpdateClientCommand(INDEX_SECOND_CLIENT, aliceDescriptor); + assertFalse(updateAliceCommand.equals(updateAliceCommandDiffIndex)); + } + + /** + * A Model stub that correctly handles the update operation. + */ + private static class ModelStubForUpdate extends ModelStub { + private final Client originalClient; + private Client clientUpdated; + + ModelStubForUpdate(Client client) { + requireNonNull(client); + this.originalClient = client; + } + + @Override + public boolean hasClient(Client client) { + return false; // Always return false to avoid duplicate check failure + } + + @Override + public ObservableList getFilteredClientList() { + return FXCollections.observableArrayList(originalClient); + } + + @Override + public void setClient(Client target, Client editedClient) { + clientUpdated = editedClient; + } + + @Override + public void updateFilteredClientList(Predicate predicate) { + // Do nothing - this needs to be overridden to prevent the default error + } + } + + /** + * A Model stub for testing duplicate client scenarios. + */ + private static class ModelStubForDuplicate extends ModelStub { + private final List clients; + + ModelStubForDuplicate(List clients) { + this.clients = new ArrayList<>(clients); + } + + @Override + public boolean hasClient(Client client) { + // Return true for any client that isn't the first one + // This will trigger the duplicate exception + return clients.stream() + .skip(1) // Skip the first client + .anyMatch(c -> c.isSameClient(client)); + } + + @Override + public ObservableList getFilteredClientList() { + return FXCollections.observableArrayList(clients); + } + + @Override + public void updateFilteredClientList(Predicate predicate) { + // Do nothing - this needs to be overridden to prevent the default error + } + } +} diff --git a/src/test/java/seedu/address/testutil/ModelStub.java b/src/test/java/seedu/address/testutil/ModelStub.java new file mode 100644 index 00000000000..71a711a7093 --- /dev/null +++ b/src/test/java/seedu/address/testutil/ModelStub.java @@ -0,0 +1,86 @@ +package seedu.address.testutil; + +import java.nio.file.Path; +import java.util.function.Predicate; + +import javafx.collections.ObservableList; +import seedu.address.commons.core.GuiSettings; +import seedu.address.model.Model; +import seedu.address.model.ReadOnlyAddressBook; +import seedu.address.model.ReadOnlyUserPrefs; +import seedu.address.model.client.Client; + +/** + * A default model stub that has all of the methods failing. + */ +public class ModelStub implements Model { + @Override + public void setUserPrefs(ReadOnlyUserPrefs userPrefs) { + throw new AssertionError("This method should not be called."); + } + + @Override + public ReadOnlyUserPrefs getUserPrefs() { + throw new AssertionError("This method should not be called."); + } + + @Override + public GuiSettings getGuiSettings() { + throw new AssertionError("This method should not be called."); + } + + @Override + public void setGuiSettings(GuiSettings guiSettings) { + throw new AssertionError("This method should not be called."); + } + + @Override + public Path getAddressBookFilePath() { + throw new AssertionError("This method should not be called."); + } + + @Override + public void setAddressBookFilePath(Path addressBookFilePath) { + throw new AssertionError("This method should not be called."); + } + + @Override + public void addClient(Client client) { + throw new AssertionError("This method should not be called."); + } + + @Override + public void setAddressBook(ReadOnlyAddressBook newData) { + throw new AssertionError("This method should not be called."); + } + + @Override + public ReadOnlyAddressBook getAddressBook() { + throw new AssertionError("This method should not be called."); + } + + @Override + public boolean hasClient(Client client) { + throw new AssertionError("This method should not be called."); + } + + @Override + public void deleteClient(Client target) { + throw new AssertionError("This method should not be called."); + } + + @Override + public void setClient(Client target, Client editedClient) { + throw new AssertionError("This method should not be called."); + } + + @Override + public ObservableList getFilteredClientList() { + throw new AssertionError("This method should not be called."); + } + + @Override + public void updateFilteredClientList(Predicate predicate) { + throw new AssertionError("This method should not be called."); + } +} From b57f6f342170d00cfb8efa3f18541e6390d8d0bd Mon Sep 17 00:00:00 2001 From: joshua Date: Thu, 20 Mar 2025 16:03:38 +0800 Subject: [PATCH 067/249] Add tests --- .../parser/UpdateClientCommandParserTest.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/test/java/seedu/address/logic/parser/UpdateClientCommandParserTest.java diff --git a/src/test/java/seedu/address/logic/parser/UpdateClientCommandParserTest.java b/src/test/java/seedu/address/logic/parser/UpdateClientCommandParserTest.java new file mode 100644 index 00000000000..31f36ea7d15 --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/UpdateClientCommandParserTest.java @@ -0,0 +1,74 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +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.logic.commands.CommandTestUtil.VALID_ADDRESS_AMY; +import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY; +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.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_CLIENT; + +import org.junit.jupiter.api.Test; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.EditCommand.EditClientDescriptor; +import seedu.address.logic.commands.UpdateClientCommand; +import seedu.address.testutil.EditClientDescriptorBuilder; + +public class UpdateClientCommandParserTest { + + private static final String MESSAGE_INVALID_FORMAT = + String.format(MESSAGE_INVALID_COMMAND_FORMAT, UpdateClientCommand.MESSAGE_USAGE); + + private UpdateClientCommandParser parser = new UpdateClientCommandParser(); + + @Test + public void parse_missingParts_failure() { + // no index specified + assertParseFailure(parser, VALID_NAME_AMY, MESSAGE_INVALID_FORMAT); + + // no field specified + assertParseFailure(parser, "1", UpdateClientCommand.MESSAGE_NOT_EDITED); + + // no index and no field specified + assertParseFailure(parser, "", MESSAGE_INVALID_FORMAT); + } + + @Test + public void parse_invalidPreamble_failure() { + // negative index + assertParseFailure(parser, "-5" + NAME_DESC_AMY, MESSAGE_INVALID_FORMAT); + + // zero index + assertParseFailure(parser, "0" + NAME_DESC_AMY, MESSAGE_INVALID_FORMAT); + + // invalid arguments being parsed as preamble + assertParseFailure(parser, "1 some random string", MESSAGE_INVALID_FORMAT); + + // invalid prefix being parsed as preamble + assertParseFailure(parser, "1 i/ string", MESSAGE_INVALID_FORMAT); + } + + @Test + public void parse_validArgs_success() { + Index targetIndex = INDEX_FIRST_CLIENT; + String userInput = targetIndex.getOneBased() + NAME_DESC_AMY + + PHONE_DESC_AMY + EMAIL_DESC_AMY + ADDRESS_DESC_AMY; + + EditClientDescriptor descriptor = new EditClientDescriptorBuilder() + .withName(VALID_NAME_AMY) + .withPhone(VALID_PHONE_AMY) + .withEmail(VALID_EMAIL_AMY) + .withAddress(VALID_ADDRESS_AMY) + .build(); + UpdateClientCommand expectedCommand = new UpdateClientCommand(targetIndex, descriptor); + + // Only testing with a simple case to verify the parser is working + assertParseSuccess(parser, userInput, expectedCommand); + } +} From a6b7819fa4d48be0958b6a861200b8254c83b6d2 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Thu, 20 Mar 2025 19:04:31 +0800 Subject: [PATCH 068/249] Update UserGuide --- docs/DeveloperGuide.md | 2 +- docs/UserGuide.md | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index e71bdb06e04..6c76bb420f5 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -50,7 +50,7 @@ The bulk of the app's work is done by the following four components: **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 `deleteclient 1`. diff --git a/docs/UserGuide.md b/docs/UserGuide.md index ef707930cd2..9379b55e66b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -146,6 +146,20 @@ Examples: * `list` followed by `deleteclient 2` deletes the 2nd person in the address book. * `findclient Betsy` followed by `deleteclient 1` deletes the 1st person in the results of the `findclient` command. +### Prioritising a person: `priority` + +Toggles the priority of the specified person from the address book as indicated with a "Priority" tag. + +Format: `priority INDEX` + +* Adds a "Priority" tag to the specified `INDEX` if such a tag isn't attached to the person +* Removes the "Priority" tag of the specified `INDEX` if such a tag is already attached to the person +* The index **must be a positive integer** 1, 2, 3, …​ + +Examples: +* `list` followed by `priority 1` adds a priority tag to the 1st person in the list if the person is yet to be attached with a "Priority" tag. +* `list` followed by `priority 3` removes a priority tag from the 3rd person in the list if the person is attached with a "Priority" tag. + ### Clearing all entries : `clear` Clears all entries from the address book. From c9d20c52323c9c8b499ed42c6182e56741aff9c8 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Fri, 21 Mar 2025 02:14:23 +0800 Subject: [PATCH 069/249] Update findclient to include tags --- .../logic/commands/FindClientCommand.java | 12 +-- .../logic/commands/FindClientCommand.java~ | 58 ------------ .../logic/parser/FindClientCommandParser.java | 4 +- .../AbstractContainsKeywordsPredicate.java | 36 ++++++++ .../client/ContainsKeywordsPredicate.java | 23 +++++ .../client/NameContainsKeywordsPredicate.java | 27 +----- .../logic/commands/FindClientCommandTest.java | 20 ++--- .../logic/parser/AddressBookParserTest.java | 4 +- .../parser/FindClientCommandParserTest.java | 4 +- .../client/ContainsKeywordsPredicateTest.java | 88 +++++++++++++++++++ 10 files changed, 171 insertions(+), 105 deletions(-) delete mode 100644 src/main/java/seedu/address/logic/commands/FindClientCommand.java~ create mode 100644 src/main/java/seedu/address/model/client/AbstractContainsKeywordsPredicate.java create mode 100644 src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java create mode 100644 src/test/java/seedu/address/model/client/ContainsKeywordsPredicateTest.java diff --git a/src/main/java/seedu/address/logic/commands/FindClientCommand.java b/src/main/java/seedu/address/logic/commands/FindClientCommand.java index f5ca1097f3e..2a1b277123b 100644 --- a/src/main/java/seedu/address/logic/commands/FindClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindClientCommand.java @@ -5,7 +5,7 @@ import seedu.address.commons.util.ToStringBuilder; import seedu.address.logic.Messages; import seedu.address.model.Model; -import seedu.address.model.client.NameContainsKeywordsPredicate; +import seedu.address.model.client.ContainsKeywordsPredicate; /** * Finds and lists all clients in address book whose name contains any of the argument keywords. @@ -15,14 +15,14 @@ public class FindClientCommand extends Command { public static final String COMMAND_WORD = "findclient"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients whose names contain any of " - + "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n" + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients whose names/tags 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"; + + "Example: " + COMMAND_WORD + " alice bob charlie friend Priority"; - private final NameContainsKeywordsPredicate predicate; + private final ContainsKeywordsPredicate predicate; - public FindClientCommand(NameContainsKeywordsPredicate predicate) { + public FindClientCommand(ContainsKeywordsPredicate predicate) { this.predicate = predicate; } diff --git a/src/main/java/seedu/address/logic/commands/FindClientCommand.java~ b/src/main/java/seedu/address/logic/commands/FindClientCommand.java~ deleted file mode 100644 index 98855c84902..00000000000 --- a/src/main/java/seedu/address/logic/commands/FindClientCommand.java~ +++ /dev/null @@ -1,58 +0,0 @@ -package seedu.address.logic.commands; - -import static java.util.Objects.requireNonNull; - -import seedu.address.commons.util.ToStringBuilder; -import seedu.address.logic.Messages; -import seedu.address.model.Model; -import seedu.address.model.client.NameContainsKeywordsPredicate; - -/** - * Finds and lists all clients in address book whose name contains any of the argument keywords. - * Keyword matching is case insensitive. - */ -public class FindClientCommand extends Command { - - public static final String COMMAND_WORD = "find"; - - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients 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"; - - private final NameContainsKeywordsPredicate predicate; - - public FindClientCommand(NameContainsKeywordsPredicate predicate) { - this.predicate = predicate; - } - - @Override - public CommandResult execute(Model model) { - requireNonNull(model); - model.updateFilteredClientList(predicate); - return new CommandResult( - String.format(Messages.MESSAGE_CLIENTS_LISTED_OVERVIEW, model.getFilteredClientList().size())); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof FindClientCommand)) { - return false; - } - - FindClientCommand otherFindClientCommand = (FindClientCommand) other; - return predicate.equals(otherFindClientCommand.predicate); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .add("predicate", predicate) - .toString(); - } -} diff --git a/src/main/java/seedu/address/logic/parser/FindClientCommandParser.java b/src/main/java/seedu/address/logic/parser/FindClientCommandParser.java index f6130ee5036..0e471ca37d0 100644 --- a/src/main/java/seedu/address/logic/parser/FindClientCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/FindClientCommandParser.java @@ -6,7 +6,7 @@ import seedu.address.logic.commands.FindClientCommand; import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.client.NameContainsKeywordsPredicate; +import seedu.address.model.client.ContainsKeywordsPredicate; /** * Parses input arguments and creates a new FindClientCommand object @@ -27,7 +27,7 @@ public FindClientCommand parse(String args) throws ParseException { String[] nameKeywords = trimmedArgs.split("\\s+"); - return new FindClientCommand(new NameContainsKeywordsPredicate(Arrays.asList(nameKeywords))); + return new FindClientCommand(new ContainsKeywordsPredicate(Arrays.asList(nameKeywords))); } } diff --git a/src/main/java/seedu/address/model/client/AbstractContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/client/AbstractContainsKeywordsPredicate.java new file mode 100644 index 00000000000..bf2d7e29f7d --- /dev/null +++ b/src/main/java/seedu/address/model/client/AbstractContainsKeywordsPredicate.java @@ -0,0 +1,36 @@ +package seedu.address.model.client; + +import java.util.List; +import java.util.function.Predicate; + +import seedu.address.commons.util.ToStringBuilder; + +/** + * Abstract predicate class that checks whether a {@code Client} satisfies a keyword condition. + */ +public abstract class AbstractContainsKeywordsPredicate implements Predicate { + protected final List keywords; + + public AbstractContainsKeywordsPredicate(List keywords) { + this.keywords = keywords; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof AbstractContainsKeywordsPredicate)) { + return false; + } + + AbstractContainsKeywordsPredicate otherPredicate = (AbstractContainsKeywordsPredicate) other; + return keywords.equals(otherPredicate.keywords); + } + + @Override + public String toString() { + return new ToStringBuilder(this).add("keywords", keywords).toString(); + } +} diff --git a/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java new file mode 100644 index 00000000000..a9f82e6299b --- /dev/null +++ b/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java @@ -0,0 +1,23 @@ +package seedu.address.model.client; + +import java.util.List; + +import seedu.address.commons.util.StringUtil; +/** + * Tests that a {@code Client}'s {@code Name} or {@code Tag} matches any of the keywords given. + */ +public class ContainsKeywordsPredicate extends AbstractContainsKeywordsPredicate { + + public ContainsKeywordsPredicate(List keywords) { + super(keywords); + } + + @Override + public boolean test(Client client) { + return keywords.stream() + .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(client.getName().fullName, keyword)) + || keywords.stream() + .anyMatch(keyword -> client.getTags().stream() + .anyMatch(tag -> StringUtil.containsWordIgnoreCase(tag.tagName, keyword))); + } +} diff --git a/src/main/java/seedu/address/model/client/NameContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/client/NameContainsKeywordsPredicate.java index 43216a4373a..6772a0fff66 100644 --- a/src/main/java/seedu/address/model/client/NameContainsKeywordsPredicate.java +++ b/src/main/java/seedu/address/model/client/NameContainsKeywordsPredicate.java @@ -1,19 +1,16 @@ package seedu.address.model.client; import java.util.List; -import java.util.function.Predicate; import seedu.address.commons.util.StringUtil; -import seedu.address.commons.util.ToStringBuilder; /** * Tests that a {@code Client}'s {@code Name} matches any of the keywords given. */ -public class NameContainsKeywordsPredicate implements Predicate { - private final List keywords; +public class NameContainsKeywordsPredicate extends AbstractContainsKeywordsPredicate { public NameContainsKeywordsPredicate(List keywords) { - this.keywords = keywords; + super(keywords); } @Override @@ -21,24 +18,4 @@ public boolean test(Client client) { return keywords.stream() .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(client.getName().fullName, keyword)); } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof NameContainsKeywordsPredicate)) { - return false; - } - - NameContainsKeywordsPredicate otherNameContainsKeywordsPredicate = (NameContainsKeywordsPredicate) other; - return keywords.equals(otherNameContainsKeywordsPredicate.keywords); - } - - @Override - public String toString() { - return new ToStringBuilder(this).add("keywords", keywords).toString(); - } } diff --git a/src/test/java/seedu/address/logic/commands/FindClientCommandTest.java b/src/test/java/seedu/address/logic/commands/FindClientCommandTest.java index 84c7f30595b..c520dbe986f 100644 --- a/src/test/java/seedu/address/logic/commands/FindClientCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/FindClientCommandTest.java @@ -18,7 +18,7 @@ import seedu.address.model.Model; import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; -import seedu.address.model.client.NameContainsKeywordsPredicate; +import seedu.address.model.client.ContainsKeywordsPredicate; /** * Contains integration tests (interaction with the Model) for {@code FindClientCommand}. @@ -29,10 +29,10 @@ public class FindClientCommandTest { @Test public void equals() { - NameContainsKeywordsPredicate firstPredicate = - new NameContainsKeywordsPredicate(Collections.singletonList("first")); - NameContainsKeywordsPredicate secondPredicate = - new NameContainsKeywordsPredicate(Collections.singletonList("second")); + ContainsKeywordsPredicate firstPredicate = + new ContainsKeywordsPredicate(Collections.singletonList("first")); + ContainsKeywordsPredicate secondPredicate = + new ContainsKeywordsPredicate(Collections.singletonList("second")); FindClientCommand findFirstCommand = new FindClientCommand(firstPredicate); FindClientCommand findSecondCommand = new FindClientCommand(secondPredicate); @@ -57,7 +57,7 @@ public void equals() { @Test public void execute_zeroKeywords_noClientFound() { String expectedMessage = String.format(MESSAGE_CLIENTS_LISTED_OVERVIEW, 0); - NameContainsKeywordsPredicate predicate = preparePredicate(" "); + ContainsKeywordsPredicate predicate = preparePredicate(" "); FindClientCommand command = new FindClientCommand(predicate); expectedModel.updateFilteredClientList(predicate); assertCommandSuccess(command, model, expectedMessage, expectedModel); @@ -67,7 +67,7 @@ public void execute_zeroKeywords_noClientFound() { @Test public void execute_multipleKeywords_multipleClientsFound() { String expectedMessage = String.format(MESSAGE_CLIENTS_LISTED_OVERVIEW, 3); - NameContainsKeywordsPredicate predicate = preparePredicate("Kurz Elle Kunz"); + ContainsKeywordsPredicate predicate = preparePredicate("Kurz Elle Kunz"); FindClientCommand command = new FindClientCommand(predicate); expectedModel.updateFilteredClientList(predicate); assertCommandSuccess(command, model, expectedMessage, expectedModel); @@ -76,7 +76,7 @@ public void execute_multipleKeywords_multipleClientsFound() { @Test public void toStringMethod() { - NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Arrays.asList("keyword")); + ContainsKeywordsPredicate predicate = new ContainsKeywordsPredicate(Arrays.asList("keyword")); FindClientCommand findClientCommand = new FindClientCommand(predicate); String expected = FindClientCommand.class.getCanonicalName() + "{predicate=" + predicate + "}"; assertEquals(expected, findClientCommand.toString()); @@ -85,7 +85,7 @@ public void toStringMethod() { /** * Parses {@code userInput} into a {@code NameContainsKeywordsPredicate}. */ - private NameContainsKeywordsPredicate preparePredicate(String userInput) { - return new NameContainsKeywordsPredicate(Arrays.asList(userInput.split("\\s+"))); + private ContainsKeywordsPredicate preparePredicate(String userInput) { + return new ContainsKeywordsPredicate(Arrays.asList(userInput.split("\\s+"))); } } diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 0d8a085a288..c6a3026c55e 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -25,7 +25,7 @@ import seedu.address.logic.commands.PriorityCommand; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.client.Client; -import seedu.address.model.client.NameContainsKeywordsPredicate; +import seedu.address.model.client.ContainsKeywordsPredicate; import seedu.address.testutil.ClientBuilder; import seedu.address.testutil.ClientUtil; import seedu.address.testutil.EditClientDescriptorBuilder; @@ -74,7 +74,7 @@ public void parseCommand_find() throws Exception { List keywords = Arrays.asList("foo", "bar", "baz"); FindClientCommand command = (FindClientCommand) parser.parseCommand( FindClientCommand.COMMAND_WORD + " " + keywords.stream().collect(Collectors.joining(" "))); - assertEquals(new FindClientCommand(new NameContainsKeywordsPredicate(keywords)), command); + assertEquals(new FindClientCommand(new ContainsKeywordsPredicate(keywords)), command); } @Test diff --git a/src/test/java/seedu/address/logic/parser/FindClientCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindClientCommandParserTest.java index ce7870a15a4..bb4f2891cef 100644 --- a/src/test/java/seedu/address/logic/parser/FindClientCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/FindClientCommandParserTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test; import seedu.address.logic.commands.FindClientCommand; -import seedu.address.model.client.NameContainsKeywordsPredicate; +import seedu.address.model.client.ContainsKeywordsPredicate; public class FindClientCommandParserTest { @@ -25,7 +25,7 @@ public void parse_emptyArg_throwsParseException() { public void parse_validArgs_returnsFindCommand() { // no leading and trailing whitespaces FindClientCommand expectedFindClientCommand = - new FindClientCommand(new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob"))); + new FindClientCommand(new ContainsKeywordsPredicate(Arrays.asList("Alice", "Bob"))); assertParseSuccess(parser, "Alice Bob", expectedFindClientCommand); // multiple whitespaces between keywords diff --git a/src/test/java/seedu/address/model/client/ContainsKeywordsPredicateTest.java b/src/test/java/seedu/address/model/client/ContainsKeywordsPredicateTest.java new file mode 100644 index 00000000000..60fc8fa4356 --- /dev/null +++ b/src/test/java/seedu/address/model/client/ContainsKeywordsPredicateTest.java @@ -0,0 +1,88 @@ +package seedu.address.model.client; + +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 java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import seedu.address.testutil.ClientBuilder; + +public class ContainsKeywordsPredicateTest { + @Test + public void equals() { + List firstPredicateKeywordList = Collections.singletonList("first"); + List secondPredicateKeywordList = Arrays.asList("first", "second"); + + ContainsKeywordsPredicate firstPredicate = new ContainsKeywordsPredicate(firstPredicateKeywordList); + ContainsKeywordsPredicate secondPredicate = new ContainsKeywordsPredicate(secondPredicateKeywordList); + + // same object -> returns true + assertTrue(firstPredicate.equals(firstPredicate)); + + // same values -> returns true + ContainsKeywordsPredicate firstPredicateCopy = new ContainsKeywordsPredicate(firstPredicateKeywordList); + assertTrue(firstPredicate.equals(firstPredicateCopy)); + + // different types -> returns false + assertFalse(firstPredicate.equals(1)); + + // null -> returns false + assertFalse(firstPredicate.equals(null)); + + // different client -> returns false + assertFalse(firstPredicate.equals(secondPredicate)); + } + + @Test + public void test_containsKeywords_returnsTrue() { + // One keyword + ContainsKeywordsPredicate predicate = new ContainsKeywordsPredicate(Collections.singletonList("Alice")); + assertTrue(predicate.test(new ClientBuilder().withName("Alice Bob").build())); + predicate = new ContainsKeywordsPredicate(Collections.singletonList("Tag")); + assertTrue(predicate.test(new ClientBuilder().withTags("Alice", "Tag").build())); + + // Multiple keywords + predicate = new ContainsKeywordsPredicate(Arrays.asList("Alice", "Bob", "Tag")); + assertTrue(predicate.test(new ClientBuilder().withName("Alice Bob").withTags("Tag").build())); + + // Only one matching keyword + predicate = new ContainsKeywordsPredicate(Arrays.asList("Bob", "Carol")); + assertTrue(predicate.test(new ClientBuilder().withName("Alice Carol").build())); + predicate = new ContainsKeywordsPredicate(Arrays.asList("Bob", "Tag")); + assertTrue(predicate.test(new ClientBuilder().withName("Alice Carol").withTags("Tag").build())); + + // Mixed-case keywords + predicate = new ContainsKeywordsPredicate(Arrays.asList("aLIce", "bOB")); + assertTrue(predicate.test(new ClientBuilder().withName("Alice Bob").build())); + } + + @Test + public void doesNotContainKeywords_returnsFalse() { + // Zero keywords + NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Collections.emptyList()); + assertFalse(predicate.test(new ClientBuilder().withName("Alice").build())); + + // Non-matching keyword + predicate = new NameContainsKeywordsPredicate(Arrays.asList("Carol")); + assertFalse(predicate.test(new ClientBuilder().withName("Alice Bob").build())); + + // Keywords match phone, email and address, but does not match name or tag + predicate = new NameContainsKeywordsPredicate(Arrays.asList("12345", "alice@email.com", "Main", "Street")); + assertFalse(predicate.test(new ClientBuilder().withName("Alice").withPhone("12345") + .withEmail("alice@email.com").withAddress("Main Street").build())); + } + + @Test + public void toStringMethod() { + List keywords = List.of("keyword1", "keyword2"); + NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(keywords); + + String expected = NameContainsKeywordsPredicate.class.getCanonicalName() + "{keywords=" + keywords + "}"; + assertEquals(expected, predicate.toString()); + } +} From 9a70a089710460e0026fec455059bc989b014b4e Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Fri, 21 Mar 2025 02:17:27 +0800 Subject: [PATCH 070/249] Fix deleted file --- .../logic/commands/FindClientCommand.java~ | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/main/java/seedu/address/logic/commands/FindClientCommand.java~ diff --git a/src/main/java/seedu/address/logic/commands/FindClientCommand.java~ b/src/main/java/seedu/address/logic/commands/FindClientCommand.java~ new file mode 100644 index 00000000000..98855c84902 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/FindClientCommand.java~ @@ -0,0 +1,58 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.model.Model; +import seedu.address.model.client.NameContainsKeywordsPredicate; + +/** + * Finds and lists all clients in address book whose name contains any of the argument keywords. + * Keyword matching is case insensitive. + */ +public class FindClientCommand extends Command { + + public static final String COMMAND_WORD = "find"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients 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"; + + private final NameContainsKeywordsPredicate predicate; + + public FindClientCommand(NameContainsKeywordsPredicate predicate) { + this.predicate = predicate; + } + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + model.updateFilteredClientList(predicate); + return new CommandResult( + String.format(Messages.MESSAGE_CLIENTS_LISTED_OVERVIEW, model.getFilteredClientList().size())); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof FindClientCommand)) { + return false; + } + + FindClientCommand otherFindClientCommand = (FindClientCommand) other; + return predicate.equals(otherFindClientCommand.predicate); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("predicate", predicate) + .toString(); + } +} From 44d36d3479a487774792dbbccf07b0a66216cdef Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 14:38:26 +0800 Subject: [PATCH 071/249] Add new PriorityTag class --- .../logic/commands/PriorityCommand.java | 7 ++++--- .../address/logic/parser/ParserUtil.java | 3 ++- .../seedu/address/model/tag/PriorityTag.java | 14 +++++++++++++ .../seedu/address/model/tag/TagFactory.java | 20 +++++++++++++++++++ .../address/model/util/SampleDataUtil.java | 3 ++- .../seedu/address/storage/JsonAdaptedTag.java | 3 ++- .../java/seedu/address/ui/ClientCard.java | 5 +++-- 7 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 src/main/java/seedu/address/model/tag/PriorityTag.java create mode 100644 src/main/java/seedu/address/model/tag/TagFactory.java diff --git a/src/main/java/seedu/address/logic/commands/PriorityCommand.java b/src/main/java/seedu/address/logic/commands/PriorityCommand.java index 8a17d933e61..596f3c9eb62 100644 --- a/src/main/java/seedu/address/logic/commands/PriorityCommand.java +++ b/src/main/java/seedu/address/logic/commands/PriorityCommand.java @@ -13,6 +13,7 @@ import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; import seedu.address.model.client.Client; +import seedu.address.model.tag.PriorityTag; import seedu.address.model.tag.Tag; /** @@ -68,10 +69,10 @@ private static Client togglePriorityTag(Client clientToEdit) throws CommandExcep // Toggles priority if (!isPriority(tags)) { - tags.add(new Tag("Priority")); + tags.add(new PriorityTag()); } else { tags = tags.stream() - .filter(tag -> !tag.isEqualTo("Priority")) + .filter(tag -> !(tag instanceof PriorityTag)) .collect(Collectors.toSet()); } @@ -90,7 +91,7 @@ private static Client togglePriorityTag(Client clientToEdit) throws CommandExcep * @param tags the list of tags */ private static boolean isPriority(Set tags) { - return tags.stream().anyMatch(t -> t.isEqualTo("Priority")); + return tags.stream().anyMatch(t -> t instanceof PriorityTag); } @Override diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index c8d156f60f6..c61f2f834a4 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -14,6 +14,7 @@ import seedu.address.model.client.Name; import seedu.address.model.client.Phone; import seedu.address.model.tag.Tag; +import seedu.address.model.tag.TagFactory; /** * Contains utility methods used for parsing strings in the various *Parser classes. @@ -107,7 +108,7 @@ public static Tag parseTag(String tag) throws ParseException { if (!Tag.isValidTagName(trimmedTag)) { throw new ParseException(Tag.MESSAGE_CONSTRAINTS); } - return new Tag(trimmedTag); + return TagFactory.createTag(trimmedTag); } /** diff --git a/src/main/java/seedu/address/model/tag/PriorityTag.java b/src/main/java/seedu/address/model/tag/PriorityTag.java new file mode 100644 index 00000000000..aa98d2f6bc7 --- /dev/null +++ b/src/main/java/seedu/address/model/tag/PriorityTag.java @@ -0,0 +1,14 @@ +package seedu.address.model.tag; + +/** + * Represents the Priority Tag in the address book, a special Yellow Tag + */ +public class PriorityTag extends Tag { + public PriorityTag(String tagName) { + super(tagName); + } + + public PriorityTag() { + super("Priority"); + } +} diff --git a/src/main/java/seedu/address/model/tag/TagFactory.java b/src/main/java/seedu/address/model/tag/TagFactory.java new file mode 100644 index 00000000000..9c936a53cf2 --- /dev/null +++ b/src/main/java/seedu/address/model/tag/TagFactory.java @@ -0,0 +1,20 @@ +package seedu.address.model.tag; + +/** + * A factory class for creating Tag objects based on a given tag name. + * Special tag names are mapped to their respective subclasses. + */ +public class TagFactory { + /** + * Creates a Tag instance based on the given tag names + * @param tagName The name of the tag. + * @return A {@code Tag} instance, which may be a specialized subclass. + */ + public static Tag createTag(String tagName) { + // Add more for other types + if (tagName.equals("Priority")) { + return new PriorityTag(); + } + return new Tag(tagName); + } +} diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index 7d12623d7b7..c1423ed4910 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -12,6 +12,7 @@ import seedu.address.model.client.Name; import seedu.address.model.client.Phone; import seedu.address.model.tag.Tag; +import seedu.address.model.tag.TagFactory; /** * Contains utility methods for populating {@code AddressBook} with sample data. @@ -53,7 +54,7 @@ public static ReadOnlyAddressBook getSampleAddressBook() { */ public static Set getTagSet(String... strings) { return Arrays.stream(strings) - .map(Tag::new) + .map(TagFactory::createTag) .collect(Collectors.toSet()); } diff --git a/src/main/java/seedu/address/storage/JsonAdaptedTag.java b/src/main/java/seedu/address/storage/JsonAdaptedTag.java index 0df22bdb754..2ec5734e972 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedTag.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedTag.java @@ -5,6 +5,7 @@ import seedu.address.commons.exceptions.IllegalValueException; import seedu.address.model.tag.Tag; +import seedu.address.model.tag.TagFactory; /** * Jackson-friendly version of {@link Tag}. @@ -42,7 +43,7 @@ public Tag toModelType() throws IllegalValueException { if (!Tag.isValidTagName(tagName)) { throw new IllegalValueException(Tag.MESSAGE_CONSTRAINTS); } - return new Tag(tagName); + return TagFactory.createTag(tagName); } } diff --git a/src/main/java/seedu/address/ui/ClientCard.java b/src/main/java/seedu/address/ui/ClientCard.java index 236cc50b306..3fb837573dd 100644 --- a/src/main/java/seedu/address/ui/ClientCard.java +++ b/src/main/java/seedu/address/ui/ClientCard.java @@ -8,6 +8,7 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Region; import seedu.address.model.client.Client; +import seedu.address.model.tag.PriorityTag; import seedu.address.model.tag.Tag; /** @@ -54,11 +55,11 @@ public ClientCard(Client client, int displayedIndex) { address.setText(client.getAddress().value); email.setText(client.getEmail().value); client.getTags().stream() - .sorted(Comparator.comparing(tag -> !tag.tagName.equals("Priority")) + .sorted(Comparator.comparing(tag -> !(tag instanceof PriorityTag)) .thenComparing(tag -> tag.tagName)) .forEach(tag -> { Label label = new Label(tag.tagName); - if (tag.tagName.equals("Priority")) { + if (tag instanceof PriorityTag) { label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); } tags.getChildren().add(label); From a372569a52ff1bbfd5be840806b00640c7c04bb5 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 14:43:22 +0800 Subject: [PATCH 072/249] Refactor ClientCard for better readability --- .../java/seedu/address/ui/ClientCard.java | 44 ++++++++++++++++--- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/address/ui/ClientCard.java b/src/main/java/seedu/address/ui/ClientCard.java index 3fb837573dd..5bab822f90d 100644 --- a/src/main/java/seedu/address/ui/ClientCard.java +++ b/src/main/java/seedu/address/ui/ClientCard.java @@ -49,20 +49,50 @@ public class ClientCard extends UiPart { public ClientCard(Client client, int displayedIndex) { super(FXML); this.client = client; + + // Initialize UI elements + initializeClientDetails(client, displayedIndex); + populateTags(client); + } + + /** + * Initializes the client details in the UI. + * + * @param client The client whose details are being displayed. + * @param displayedIndex The index number to be displayed. + */ + private void initializeClientDetails(Client client, int displayedIndex) { id.setText(displayedIndex + ". "); name.setText(client.getName().fullName); phone.setText(client.getPhone().value); address.setText(client.getAddress().value); email.setText(client.getEmail().value); + } + + /** + * Populates the tag container with sorted tags. + * + * @param client The client whose tags need to be displayed. + */ + private void populateTags(Client client) { client.getTags().stream() .sorted(Comparator.comparing(tag -> !(tag instanceof PriorityTag)) .thenComparing(tag -> tag.tagName)) - .forEach(tag -> { - Label label = new Label(tag.tagName); - if (tag instanceof PriorityTag) { - label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); - } - tags.getChildren().add(label); - }); + .map(this::createTagLabel) + .forEach(tags.getChildren()::add); + } + + /** + * Creates a styled Label for a given tag. + * + * @param tag The tag for which a Label is created. + * @return A styled Label representing the tag. + */ + private Label createTagLabel(Tag tag) { + Label label = new Label(tag.tagName); + if (tag instanceof PriorityTag) { + label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); + } + return label; } } From c0395d4a6e294e37dd1b47ed964eacd2e9257039 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 14:51:15 +0800 Subject: [PATCH 073/249] Remove magic value "Priority" --- src/main/java/seedu/address/model/tag/PriorityTag.java | 4 +++- src/main/java/seedu/address/model/tag/TagFactory.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/address/model/tag/PriorityTag.java b/src/main/java/seedu/address/model/tag/PriorityTag.java index aa98d2f6bc7..f3396c1e056 100644 --- a/src/main/java/seedu/address/model/tag/PriorityTag.java +++ b/src/main/java/seedu/address/model/tag/PriorityTag.java @@ -4,11 +4,13 @@ * Represents the Priority Tag in the address book, a special Yellow Tag */ public class PriorityTag extends Tag { + static final String VALID_PRIORITY_TAG = "Priority"; + public PriorityTag(String tagName) { super(tagName); } public PriorityTag() { - super("Priority"); + super(VALID_PRIORITY_TAG); } } diff --git a/src/main/java/seedu/address/model/tag/TagFactory.java b/src/main/java/seedu/address/model/tag/TagFactory.java index 9c936a53cf2..31e79986519 100644 --- a/src/main/java/seedu/address/model/tag/TagFactory.java +++ b/src/main/java/seedu/address/model/tag/TagFactory.java @@ -12,7 +12,7 @@ public class TagFactory { */ public static Tag createTag(String tagName) { // Add more for other types - if (tagName.equals("Priority")) { + if (tagName.equals(PriorityTag.VALID_PRIORITY_TAG)) { return new PriorityTag(); } return new Tag(tagName); From 7c779ba41bc163eb0df9c5ea517460757bec6143 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 15:03:42 +0800 Subject: [PATCH 074/249] Add test for TagFactory --- .../address/model/tag/TagFactoryTest.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/test/java/seedu/address/model/tag/TagFactoryTest.java diff --git a/src/test/java/seedu/address/model/tag/TagFactoryTest.java b/src/test/java/seedu/address/model/tag/TagFactoryTest.java new file mode 100644 index 00000000000..e4a501a9e81 --- /dev/null +++ b/src/test/java/seedu/address/model/tag/TagFactoryTest.java @@ -0,0 +1,22 @@ +package seedu.address.model.tag; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_PRIORITY; + +import org.junit.jupiter.api.Test; + +public class TagFactoryTest { + + @Test + public void create_priority_tag() { + Tag tag = TagFactory.createTag(VALID_TAG_PRIORITY); + assertTrue(tag instanceof PriorityTag); + } + + @Test + public void create_tag() { + Tag tag = TagFactory.createTag("abcdefghijklmnop"); + assertFalse(tag instanceof PriorityTag); + } +} From 0d4e6105716ca5283f7ca51c2688f0f3742772bd Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 15:18:56 +0800 Subject: [PATCH 075/249] Add test for PriorityTag --- .../address/model/tag/PriorityTagTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test/java/seedu/address/model/tag/PriorityTagTest.java diff --git a/src/test/java/seedu/address/model/tag/PriorityTagTest.java b/src/test/java/seedu/address/model/tag/PriorityTagTest.java new file mode 100644 index 00000000000..8bf17327a61 --- /dev/null +++ b/src/test/java/seedu/address/model/tag/PriorityTagTest.java @@ -0,0 +1,26 @@ +package seedu.address.model.tag; + +import static seedu.address.testutil.Assert.assertThrows; + +import org.junit.jupiter.api.Test; + +public class PriorityTagTest { + + @Test + public void constructor_null_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> new PriorityTag(null)); + } + + @Test + public void constructor_invalidTagName_throwsIllegalArgumentException() { + String invalidTagName = ""; + assertThrows(IllegalArgumentException.class, () -> new PriorityTag(invalidTagName)); + } + + @Test + public void isValidTagName() { + // null tag name + assertThrows(NullPointerException.class, () -> PriorityTag.isValidTagName(null)); + } + +} From 30b81cda4324018d453591ccd0bc37b69012c326 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 15:19:16 +0800 Subject: [PATCH 076/249] Revert ClientCard --- .../java/seedu/address/ui/ClientCard.java | 53 +++++++------------ 1 file changed, 18 insertions(+), 35 deletions(-) diff --git a/src/main/java/seedu/address/ui/ClientCard.java b/src/main/java/seedu/address/ui/ClientCard.java index 5bab822f90d..d08124fe6e2 100644 --- a/src/main/java/seedu/address/ui/ClientCard.java +++ b/src/main/java/seedu/address/ui/ClientCard.java @@ -49,50 +49,33 @@ public class ClientCard extends UiPart { public ClientCard(Client client, int displayedIndex) { super(FXML); this.client = client; - - // Initialize UI elements - initializeClientDetails(client, displayedIndex); - populateTags(client); - } - - /** - * Initializes the client details in the UI. - * - * @param client The client whose details are being displayed. - * @param displayedIndex The index number to be displayed. - */ - private void initializeClientDetails(Client client, int displayedIndex) { id.setText(displayedIndex + ". "); name.setText(client.getName().fullName); phone.setText(client.getPhone().value); address.setText(client.getAddress().value); email.setText(client.getEmail().value); - } - - /** - * Populates the tag container with sorted tags. - * - * @param client The client whose tags need to be displayed. - */ - private void populateTags(Client client) { client.getTags().stream() .sorted(Comparator.comparing(tag -> !(tag instanceof PriorityTag)) .thenComparing(tag -> tag.tagName)) - .map(this::createTagLabel) - .forEach(tags.getChildren()::add); + .forEach(tag -> { + Label label = new Label(tag.tagName); + if (tag instanceof PriorityTag) { + label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); + } + tags.getChildren().add(label); + }); } - /** - * Creates a styled Label for a given tag. - * - * @param tag The tag for which a Label is created. - * @return A styled Label representing the tag. - */ - private Label createTagLabel(Tag tag) { - Label label = new Label(tag.tagName); - if (tag instanceof PriorityTag) { - label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); - } - return label; + private void sortClientTags(Client client) { + client.getTags().stream() + .sorted(Comparator.comparing(tag -> !(tag instanceof PriorityTag)) + .thenComparing(tag -> tag.tagName)) + .forEach(tag -> { + Label label = new Label(tag.tagName); + if (tag instanceof PriorityTag) { + label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); + } + tags.getChildren().add(label); + }); } } From b13c879c91eab38d3823bfb90354ad48758e5acf Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 15:25:12 +0800 Subject: [PATCH 077/249] Refactor ClientCard --- .../java/seedu/address/ui/ClientCard.java | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/main/java/seedu/address/ui/ClientCard.java b/src/main/java/seedu/address/ui/ClientCard.java index d08124fe6e2..5932bcff0f6 100644 --- a/src/main/java/seedu/address/ui/ClientCard.java +++ b/src/main/java/seedu/address/ui/ClientCard.java @@ -1,6 +1,8 @@ package seedu.address.ui; import java.util.Comparator; +import java.util.Set; +import java.util.stream.Stream; import javafx.fxml.FXML; import javafx.scene.control.Label; @@ -54,28 +56,21 @@ public ClientCard(Client client, int displayedIndex) { phone.setText(client.getPhone().value); address.setText(client.getAddress().value); email.setText(client.getEmail().value); - client.getTags().stream() - .sorted(Comparator.comparing(tag -> !(tag instanceof PriorityTag)) - .thenComparing(tag -> tag.tagName)) - .forEach(tag -> { - Label label = new Label(tag.tagName); - if (tag instanceof PriorityTag) { - label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); - } - tags.getChildren().add(label); - }); + sortClientTags(client.getTags()) + .forEach(this::createLabel); } - private void sortClientTags(Client client) { - client.getTags().stream() + private Stream sortClientTags(Set set) { + return set.stream() .sorted(Comparator.comparing(tag -> !(tag instanceof PriorityTag)) - .thenComparing(tag -> tag.tagName)) - .forEach(tag -> { - Label label = new Label(tag.tagName); - if (tag instanceof PriorityTag) { - label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); - } - tags.getChildren().add(label); - }); + .thenComparing(tag -> tag.tagName)); + } + + private void createLabel(Tag tag) { + Label label = new Label(tag.tagName); + if (tag instanceof PriorityTag) { + label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); + } + tags.getChildren().add(label); } } From fd0607c822615ee65ab231c011b115f779f86565 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 16:06:51 +0800 Subject: [PATCH 078/249] Revert ClientCard --- .../java/seedu/address/ui/ClientCard.java | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/src/main/java/seedu/address/ui/ClientCard.java b/src/main/java/seedu/address/ui/ClientCard.java index 5932bcff0f6..449f8531d98 100644 --- a/src/main/java/seedu/address/ui/ClientCard.java +++ b/src/main/java/seedu/address/ui/ClientCard.java @@ -1,8 +1,6 @@ package seedu.address.ui; import java.util.Comparator; -import java.util.Set; -import java.util.stream.Stream; import javafx.fxml.FXML; import javafx.scene.control.Label; @@ -56,21 +54,15 @@ public ClientCard(Client client, int displayedIndex) { phone.setText(client.getPhone().value); address.setText(client.getAddress().value); email.setText(client.getEmail().value); - sortClientTags(client.getTags()) - .forEach(this::createLabel); - } - - private Stream sortClientTags(Set set) { - return set.stream() - .sorted(Comparator.comparing(tag -> !(tag instanceof PriorityTag)) - .thenComparing(tag -> tag.tagName)); - } - - private void createLabel(Tag tag) { - Label label = new Label(tag.tagName); - if (tag instanceof PriorityTag) { - label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); - } - tags.getChildren().add(label); + client.getTags().stream() + .sorted(Comparator.comparing(tag -> tag instanceof PriorityTag) + .thenComparing(tag -> tag.tagName)) + .forEach(tag -> { + Label label = new Label(tag.tagName); + if (tag instanceof PriorityTag) { + label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); + } + tags.getChildren().add(label); + }); } } From 99ef3a7b4262e57b7dd9c0b0a7c89868a3d121b8 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 16:19:10 +0800 Subject: [PATCH 079/249] Add more tests --- .../java/seedu/address/model/tag/PriorityTagTest.java | 8 ++++++++ src/test/java/seedu/address/model/tag/TagFactoryTest.java | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/test/java/seedu/address/model/tag/PriorityTagTest.java b/src/test/java/seedu/address/model/tag/PriorityTagTest.java index 8bf17327a61..dcc01e077ac 100644 --- a/src/test/java/seedu/address/model/tag/PriorityTagTest.java +++ b/src/test/java/seedu/address/model/tag/PriorityTagTest.java @@ -1,11 +1,19 @@ package seedu.address.model.tag; +import static org.junit.jupiter.api.Assertions.assertEquals; import static seedu.address.testutil.Assert.assertThrows; import org.junit.jupiter.api.Test; public class PriorityTagTest { + @Test + void testDefaultConstructor() { + // Test the default constructor + PriorityTag priorityTag = new PriorityTag(); + assertEquals("Priority", priorityTag.tagName); + } + @Test public void constructor_null_throwsNullPointerException() { assertThrows(NullPointerException.class, () -> new PriorityTag(null)); diff --git a/src/test/java/seedu/address/model/tag/TagFactoryTest.java b/src/test/java/seedu/address/model/tag/TagFactoryTest.java index e4a501a9e81..db05d78a58a 100644 --- a/src/test/java/seedu/address/model/tag/TagFactoryTest.java +++ b/src/test/java/seedu/address/model/tag/TagFactoryTest.java @@ -1,5 +1,6 @@ package seedu.address.model.tag; +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_TAG_PRIORITY; @@ -12,11 +13,14 @@ public class TagFactoryTest { public void create_priority_tag() { Tag tag = TagFactory.createTag(VALID_TAG_PRIORITY); assertTrue(tag instanceof PriorityTag); + assertEquals("Priority", tag.tagName); } @Test public void create_tag() { Tag tag = TagFactory.createTag("abcdefghijklmnop"); assertFalse(tag instanceof PriorityTag); + assertTrue(tag instanceof Tag); + assertEquals("abcdefghijklmnop", tag.tagName); } } From 47c88443160d3f74cd7300ab4e537a95aff5daa7 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 16:22:57 +0800 Subject: [PATCH 080/249] Update edit command such that CLI command is now editclient --- src/main/java/seedu/address/logic/commands/EditCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index 00722ad113e..f4cb81e7d67 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -33,7 +33,7 @@ */ public class EditCommand extends Command { - public static final String COMMAND_WORD = "edit"; + public static final String COMMAND_WORD = "editclient"; public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the details of the client identified " + "by the index number used in the displayed client list. " From a46220fa3db7ca58b7ea09b7f38fcc6145e2798b Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 16:32:57 +0800 Subject: [PATCH 081/249] Update test function --- .../java/seedu/address/model/tag/TagFactoryTest.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/test/java/seedu/address/model/tag/TagFactoryTest.java b/src/test/java/seedu/address/model/tag/TagFactoryTest.java index db05d78a58a..f960dfd4d91 100644 --- a/src/test/java/seedu/address/model/tag/TagFactoryTest.java +++ b/src/test/java/seedu/address/model/tag/TagFactoryTest.java @@ -3,15 +3,14 @@ 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_TAG_PRIORITY; import org.junit.jupiter.api.Test; public class TagFactoryTest { @Test - public void create_priority_tag() { - Tag tag = TagFactory.createTag(VALID_TAG_PRIORITY); + public void create_priorityTag() { + Tag tag = TagFactory.createTag("Priority"); assertTrue(tag instanceof PriorityTag); assertEquals("Priority", tag.tagName); } @@ -23,4 +22,11 @@ public void create_tag() { assertTrue(tag instanceof Tag); assertEquals("abcdefghijklmnop", tag.tagName); } + + @Test + public void create_nonPriorityTag() { + Tag tag = TagFactory.createTag("NonPriority"); + assertFalse(tag instanceof PriorityTag); + assertEquals("NonPriority", tag.tagName); + } } From 7fde46b91a1f4fd240ee12c352eab859b49bf7e4 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 16:41:32 +0800 Subject: [PATCH 082/249] Update strings in edit command --- src/main/java/seedu/address/logic/commands/EditCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index f4cb81e7d67..c72c617e98a 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -35,8 +35,8 @@ public class EditCommand extends Command { public static final String COMMAND_WORD = "editclient"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the details of the client identified " - + "by the index number used in the displayed client list. " + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Edits the client identified by the index number used in the displayed client list. " + "Existing values will be overwritten by the input values.\n" + "Parameters: INDEX (must be a positive integer) " + "[" + PREFIX_NAME + "NAME] " From b501f6502467bb1225d98dd0f06119665794ebc0 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 16:46:42 +0800 Subject: [PATCH 083/249] Update text --- src/main/java/seedu/address/logic/commands/PriorityCommand.java | 2 +- src/main/java/seedu/address/model/tag/TagFactory.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/PriorityCommand.java b/src/main/java/seedu/address/logic/commands/PriorityCommand.java index 596f3c9eb62..a27d2f4f273 100644 --- a/src/main/java/seedu/address/logic/commands/PriorityCommand.java +++ b/src/main/java/seedu/address/logic/commands/PriorityCommand.java @@ -23,7 +23,7 @@ public class PriorityCommand extends Command { public static final String COMMAND_WORD = "priority"; - public static final String MESSAGE_PRIORITY_CLIENT_SUCCESS = "Priority status of client changed: %1$s"; + public static final String MESSAGE_PRIORITY_CLIENT_SUCCESS = "Toggle Priority of the Client: %1$s"; public static final String MESSAGE_USAGE = COMMAND_WORD + ": Marks the client identified by the index number used in the displayed client list as priority.\n" diff --git a/src/main/java/seedu/address/model/tag/TagFactory.java b/src/main/java/seedu/address/model/tag/TagFactory.java index 31e79986519..9c936a53cf2 100644 --- a/src/main/java/seedu/address/model/tag/TagFactory.java +++ b/src/main/java/seedu/address/model/tag/TagFactory.java @@ -12,7 +12,7 @@ public class TagFactory { */ public static Tag createTag(String tagName) { // Add more for other types - if (tagName.equals(PriorityTag.VALID_PRIORITY_TAG)) { + if (tagName.equals("Priority")) { return new PriorityTag(); } return new Tag(tagName); From 6ea807970b85184111b90682d8acd3846cf9b3ee Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 16:49:47 +0800 Subject: [PATCH 084/249] Revert ClientCard even more --- src/main/java/seedu/address/ui/ClientCard.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/address/ui/ClientCard.java b/src/main/java/seedu/address/ui/ClientCard.java index 449f8531d98..236cc50b306 100644 --- a/src/main/java/seedu/address/ui/ClientCard.java +++ b/src/main/java/seedu/address/ui/ClientCard.java @@ -8,7 +8,6 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Region; import seedu.address.model.client.Client; -import seedu.address.model.tag.PriorityTag; import seedu.address.model.tag.Tag; /** @@ -55,11 +54,11 @@ public ClientCard(Client client, int displayedIndex) { address.setText(client.getAddress().value); email.setText(client.getEmail().value); client.getTags().stream() - .sorted(Comparator.comparing(tag -> tag instanceof PriorityTag) + .sorted(Comparator.comparing(tag -> !tag.tagName.equals("Priority")) .thenComparing(tag -> tag.tagName)) .forEach(tag -> { Label label = new Label(tag.tagName); - if (tag instanceof PriorityTag) { + if (tag.tagName.equals("Priority")) { label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); } tags.getChildren().add(label); From c71943db11de1b2039584a802938a707f732edb8 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 19:57:47 +0800 Subject: [PATCH 085/249] Revert changes made to FindCommand --- .../logic/commands/FindClientCommand.java | 12 ++-- .../logic/commands/FindClientCommand.java~ | 58 ------------------- .../logic/parser/FindClientCommandParser.java | 4 +- .../logic/commands/FindClientCommandTest.java | 20 +++---- .../logic/parser/AddressBookParserTest.java | 4 +- .../parser/FindClientCommandParserTest.java | 4 +- 6 files changed, 22 insertions(+), 80 deletions(-) delete mode 100644 src/main/java/seedu/address/logic/commands/FindClientCommand.java~ diff --git a/src/main/java/seedu/address/logic/commands/FindClientCommand.java b/src/main/java/seedu/address/logic/commands/FindClientCommand.java index 2a1b277123b..f5ca1097f3e 100644 --- a/src/main/java/seedu/address/logic/commands/FindClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindClientCommand.java @@ -5,7 +5,7 @@ import seedu.address.commons.util.ToStringBuilder; import seedu.address.logic.Messages; import seedu.address.model.Model; -import seedu.address.model.client.ContainsKeywordsPredicate; +import seedu.address.model.client.NameContainsKeywordsPredicate; /** * Finds and lists all clients in address book whose name contains any of the argument keywords. @@ -15,14 +15,14 @@ public class FindClientCommand extends Command { public static final String COMMAND_WORD = "findclient"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients whose names/tags contain any " - + "of the specified keywords (case-insensitive) and displays them as a list with index numbers.\n" + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients 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 friend Priority"; + + "Example: " + COMMAND_WORD + " alice bob charlie"; - private final ContainsKeywordsPredicate predicate; + private final NameContainsKeywordsPredicate predicate; - public FindClientCommand(ContainsKeywordsPredicate predicate) { + public FindClientCommand(NameContainsKeywordsPredicate predicate) { this.predicate = predicate; } diff --git a/src/main/java/seedu/address/logic/commands/FindClientCommand.java~ b/src/main/java/seedu/address/logic/commands/FindClientCommand.java~ deleted file mode 100644 index 98855c84902..00000000000 --- a/src/main/java/seedu/address/logic/commands/FindClientCommand.java~ +++ /dev/null @@ -1,58 +0,0 @@ -package seedu.address.logic.commands; - -import static java.util.Objects.requireNonNull; - -import seedu.address.commons.util.ToStringBuilder; -import seedu.address.logic.Messages; -import seedu.address.model.Model; -import seedu.address.model.client.NameContainsKeywordsPredicate; - -/** - * Finds and lists all clients in address book whose name contains any of the argument keywords. - * Keyword matching is case insensitive. - */ -public class FindClientCommand extends Command { - - public static final String COMMAND_WORD = "find"; - - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients 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"; - - private final NameContainsKeywordsPredicate predicate; - - public FindClientCommand(NameContainsKeywordsPredicate predicate) { - this.predicate = predicate; - } - - @Override - public CommandResult execute(Model model) { - requireNonNull(model); - model.updateFilteredClientList(predicate); - return new CommandResult( - String.format(Messages.MESSAGE_CLIENTS_LISTED_OVERVIEW, model.getFilteredClientList().size())); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof FindClientCommand)) { - return false; - } - - FindClientCommand otherFindClientCommand = (FindClientCommand) other; - return predicate.equals(otherFindClientCommand.predicate); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .add("predicate", predicate) - .toString(); - } -} diff --git a/src/main/java/seedu/address/logic/parser/FindClientCommandParser.java b/src/main/java/seedu/address/logic/parser/FindClientCommandParser.java index 0e471ca37d0..f6130ee5036 100644 --- a/src/main/java/seedu/address/logic/parser/FindClientCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/FindClientCommandParser.java @@ -6,7 +6,7 @@ import seedu.address.logic.commands.FindClientCommand; import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.client.ContainsKeywordsPredicate; +import seedu.address.model.client.NameContainsKeywordsPredicate; /** * Parses input arguments and creates a new FindClientCommand object @@ -27,7 +27,7 @@ public FindClientCommand parse(String args) throws ParseException { String[] nameKeywords = trimmedArgs.split("\\s+"); - return new FindClientCommand(new ContainsKeywordsPredicate(Arrays.asList(nameKeywords))); + return new FindClientCommand(new NameContainsKeywordsPredicate(Arrays.asList(nameKeywords))); } } diff --git a/src/test/java/seedu/address/logic/commands/FindClientCommandTest.java b/src/test/java/seedu/address/logic/commands/FindClientCommandTest.java index c520dbe986f..84c7f30595b 100644 --- a/src/test/java/seedu/address/logic/commands/FindClientCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/FindClientCommandTest.java @@ -18,7 +18,7 @@ import seedu.address.model.Model; import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; -import seedu.address.model.client.ContainsKeywordsPredicate; +import seedu.address.model.client.NameContainsKeywordsPredicate; /** * Contains integration tests (interaction with the Model) for {@code FindClientCommand}. @@ -29,10 +29,10 @@ public class FindClientCommandTest { @Test public void equals() { - ContainsKeywordsPredicate firstPredicate = - new ContainsKeywordsPredicate(Collections.singletonList("first")); - ContainsKeywordsPredicate secondPredicate = - new ContainsKeywordsPredicate(Collections.singletonList("second")); + NameContainsKeywordsPredicate firstPredicate = + new NameContainsKeywordsPredicate(Collections.singletonList("first")); + NameContainsKeywordsPredicate secondPredicate = + new NameContainsKeywordsPredicate(Collections.singletonList("second")); FindClientCommand findFirstCommand = new FindClientCommand(firstPredicate); FindClientCommand findSecondCommand = new FindClientCommand(secondPredicate); @@ -57,7 +57,7 @@ public void equals() { @Test public void execute_zeroKeywords_noClientFound() { String expectedMessage = String.format(MESSAGE_CLIENTS_LISTED_OVERVIEW, 0); - ContainsKeywordsPredicate predicate = preparePredicate(" "); + NameContainsKeywordsPredicate predicate = preparePredicate(" "); FindClientCommand command = new FindClientCommand(predicate); expectedModel.updateFilteredClientList(predicate); assertCommandSuccess(command, model, expectedMessage, expectedModel); @@ -67,7 +67,7 @@ public void execute_zeroKeywords_noClientFound() { @Test public void execute_multipleKeywords_multipleClientsFound() { String expectedMessage = String.format(MESSAGE_CLIENTS_LISTED_OVERVIEW, 3); - ContainsKeywordsPredicate predicate = preparePredicate("Kurz Elle Kunz"); + NameContainsKeywordsPredicate predicate = preparePredicate("Kurz Elle Kunz"); FindClientCommand command = new FindClientCommand(predicate); expectedModel.updateFilteredClientList(predicate); assertCommandSuccess(command, model, expectedMessage, expectedModel); @@ -76,7 +76,7 @@ public void execute_multipleKeywords_multipleClientsFound() { @Test public void toStringMethod() { - ContainsKeywordsPredicate predicate = new ContainsKeywordsPredicate(Arrays.asList("keyword")); + NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Arrays.asList("keyword")); FindClientCommand findClientCommand = new FindClientCommand(predicate); String expected = FindClientCommand.class.getCanonicalName() + "{predicate=" + predicate + "}"; assertEquals(expected, findClientCommand.toString()); @@ -85,7 +85,7 @@ public void toStringMethod() { /** * Parses {@code userInput} into a {@code NameContainsKeywordsPredicate}. */ - private ContainsKeywordsPredicate preparePredicate(String userInput) { - return new ContainsKeywordsPredicate(Arrays.asList(userInput.split("\\s+"))); + private NameContainsKeywordsPredicate preparePredicate(String userInput) { + return new NameContainsKeywordsPredicate(Arrays.asList(userInput.split("\\s+"))); } } diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index c6a3026c55e..0d8a085a288 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -25,7 +25,7 @@ import seedu.address.logic.commands.PriorityCommand; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.client.Client; -import seedu.address.model.client.ContainsKeywordsPredicate; +import seedu.address.model.client.NameContainsKeywordsPredicate; import seedu.address.testutil.ClientBuilder; import seedu.address.testutil.ClientUtil; import seedu.address.testutil.EditClientDescriptorBuilder; @@ -74,7 +74,7 @@ public void parseCommand_find() throws Exception { List keywords = Arrays.asList("foo", "bar", "baz"); FindClientCommand command = (FindClientCommand) parser.parseCommand( FindClientCommand.COMMAND_WORD + " " + keywords.stream().collect(Collectors.joining(" "))); - assertEquals(new FindClientCommand(new ContainsKeywordsPredicate(keywords)), command); + assertEquals(new FindClientCommand(new NameContainsKeywordsPredicate(keywords)), command); } @Test diff --git a/src/test/java/seedu/address/logic/parser/FindClientCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindClientCommandParserTest.java index bb4f2891cef..ce7870a15a4 100644 --- a/src/test/java/seedu/address/logic/parser/FindClientCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/FindClientCommandParserTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test; import seedu.address.logic.commands.FindClientCommand; -import seedu.address.model.client.ContainsKeywordsPredicate; +import seedu.address.model.client.NameContainsKeywordsPredicate; public class FindClientCommandParserTest { @@ -25,7 +25,7 @@ public void parse_emptyArg_throwsParseException() { public void parse_validArgs_returnsFindCommand() { // no leading and trailing whitespaces FindClientCommand expectedFindClientCommand = - new FindClientCommand(new ContainsKeywordsPredicate(Arrays.asList("Alice", "Bob"))); + new FindClientCommand(new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob"))); assertParseSuccess(parser, "Alice Bob", expectedFindClientCommand); // multiple whitespaces between keywords From 77c873f95c0e7f6eccbcfd4865cd3d7a8054c0bf Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 20:15:09 +0800 Subject: [PATCH 086/249] Add ContainsAllKeywordPredicate to function as the AND operator --- .../client/ContainsAllKeywordsPredicate.java | 25 +++++++++++++++++++ .../client/ContainsKeywordsPredicate.java | 12 +++++---- 2 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 src/main/java/seedu/address/model/client/ContainsAllKeywordsPredicate.java diff --git a/src/main/java/seedu/address/model/client/ContainsAllKeywordsPredicate.java b/src/main/java/seedu/address/model/client/ContainsAllKeywordsPredicate.java new file mode 100644 index 00000000000..08ca130206c --- /dev/null +++ b/src/main/java/seedu/address/model/client/ContainsAllKeywordsPredicate.java @@ -0,0 +1,25 @@ +package seedu.address.model.client; + +import java.util.List; + +import seedu.address.commons.util.StringUtil; +/** + * Tests that a {@code Client}'s {@code Name} or {@code Tag} contains all the keywords given. + * This predicate is equilivant to the AND operations when using find, i.e. strict matching + */ +public class ContainsAllKeywordsPredicate extends AbstractContainsKeywordsPredicate { + + public ContainsAllKeywordsPredicate(List keywords) { + super(keywords); + } + + @Override + public boolean test(Client client) { + return keywords.stream().allMatch(keyword -> + StringUtil.containsWordIgnoreCase(client.getName().fullName, keyword) || + client.getTags().stream().anyMatch(tag -> + StringUtil.containsWordIgnoreCase(tag.tagName, keyword) + ) + ); + } +} diff --git a/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java index a9f82e6299b..d731ca5ca45 100644 --- a/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java +++ b/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java @@ -5,6 +5,7 @@ import seedu.address.commons.util.StringUtil; /** * Tests that a {@code Client}'s {@code Name} or {@code Tag} matches any of the keywords given. + * This predicate is equilivant to the OR operations when using find, i.e. loose matching */ public class ContainsKeywordsPredicate extends AbstractContainsKeywordsPredicate { @@ -14,10 +15,11 @@ public ContainsKeywordsPredicate(List keywords) { @Override public boolean test(Client client) { - return keywords.stream() - .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(client.getName().fullName, keyword)) - || keywords.stream() - .anyMatch(keyword -> client.getTags().stream() - .anyMatch(tag -> StringUtil.containsWordIgnoreCase(tag.tagName, keyword))); + return keywords.stream().anyMatch(keyword -> + StringUtil.containsWordIgnoreCase(client.getName().fullName, keyword) || + client.getTags().stream().anyMatch(tag -> + StringUtil.containsWordIgnoreCase(tag.tagName, keyword) + ) + ); } } From 0105fcb0c850c37cb1c9597777dce9d13cde2e2b Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 20:31:59 +0800 Subject: [PATCH 087/249] Update Testcases --- .../client/ContainsAllKeywordsPredicate.java | 8 +- .../client/ContainsKeywordsPredicate.java | 4 +- .../ContainsAllKeywordsPredicateTest.java | 88 +++++++++++++++++++ .../client/ContainsKeywordsPredicateTest.java | 10 +-- 4 files changed, 101 insertions(+), 9 deletions(-) create mode 100644 src/test/java/seedu/address/model/client/ContainsAllKeywordsPredicateTest.java diff --git a/src/main/java/seedu/address/model/client/ContainsAllKeywordsPredicate.java b/src/main/java/seedu/address/model/client/ContainsAllKeywordsPredicate.java index 08ca130206c..7ffa9b256b1 100644 --- a/src/main/java/seedu/address/model/client/ContainsAllKeywordsPredicate.java +++ b/src/main/java/seedu/address/model/client/ContainsAllKeywordsPredicate.java @@ -15,9 +15,13 @@ public ContainsAllKeywordsPredicate(List keywords) { @Override public boolean test(Client client) { + if (keywords.isEmpty()) { + return false; // Ensures empty keyword list returns false like to ContainsKeywordsPredicate + } + return keywords.stream().allMatch(keyword -> - StringUtil.containsWordIgnoreCase(client.getName().fullName, keyword) || - client.getTags().stream().anyMatch(tag -> + StringUtil.containsWordIgnoreCase(client.getName().fullName, keyword) + || client.getTags().stream().anyMatch(tag -> StringUtil.containsWordIgnoreCase(tag.tagName, keyword) ) ); diff --git a/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java index d731ca5ca45..0c2ba5e2b29 100644 --- a/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java +++ b/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java @@ -16,8 +16,8 @@ public ContainsKeywordsPredicate(List keywords) { @Override public boolean test(Client client) { return keywords.stream().anyMatch(keyword -> - StringUtil.containsWordIgnoreCase(client.getName().fullName, keyword) || - client.getTags().stream().anyMatch(tag -> + StringUtil.containsWordIgnoreCase(client.getName().fullName, keyword) + || client.getTags().stream().anyMatch(tag -> StringUtil.containsWordIgnoreCase(tag.tagName, keyword) ) ); diff --git a/src/test/java/seedu/address/model/client/ContainsAllKeywordsPredicateTest.java b/src/test/java/seedu/address/model/client/ContainsAllKeywordsPredicateTest.java new file mode 100644 index 00000000000..1d61c712fa1 --- /dev/null +++ b/src/test/java/seedu/address/model/client/ContainsAllKeywordsPredicateTest.java @@ -0,0 +1,88 @@ +package seedu.address.model.client; + +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 java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import seedu.address.testutil.ClientBuilder; + +public class ContainsAllKeywordsPredicateTest { + @Test + public void equals() { + List firstPredicateKeywordList = Collections.singletonList("first"); + List secondPredicateKeywordList = Arrays.asList("first", "second"); + + ContainsAllKeywordsPredicate firstPredicate = new ContainsAllKeywordsPredicate(firstPredicateKeywordList); + ContainsAllKeywordsPredicate secondPredicate = new ContainsAllKeywordsPredicate(secondPredicateKeywordList); + + // same object -> returns true + assertTrue(firstPredicate.equals(firstPredicate)); + + // same values -> returns true + ContainsAllKeywordsPredicate firstPredicateCopy = new ContainsAllKeywordsPredicate(firstPredicateKeywordList); + assertTrue(firstPredicate.equals(firstPredicateCopy)); + + // different types -> returns false + assertFalse(firstPredicate.equals(1)); + + // null -> returns false + assertFalse(firstPredicate.equals(null)); + + // different client -> returns false + assertFalse(firstPredicate.equals(secondPredicate)); + } + + @Test + public void test_containsKeywords_returnsTrue() { + // One keyword + ContainsAllKeywordsPredicate predicate = new ContainsAllKeywordsPredicate(Collections.singletonList("Alice")); + assertTrue(predicate.test(new ClientBuilder().withName("Alice Bob").build())); + predicate = new ContainsAllKeywordsPredicate(Collections.singletonList("Tag")); + assertTrue(predicate.test(new ClientBuilder().withTags("Alice", "Tag").build())); + + // Multiple keywords + predicate = new ContainsAllKeywordsPredicate(Arrays.asList("Alice", "Bob", "Tag")); + assertTrue(predicate.test(new ClientBuilder().withName("Alice Bob").withTags("Tag").build())); + + // Mixed-case keywords + predicate = new ContainsAllKeywordsPredicate(Arrays.asList("aLIce", "bOB")); + assertTrue(predicate.test(new ClientBuilder().withName("Alice Bob").build())); + } + + @Test + public void doesNotContainKeywords_returnsFalse() { + // Zero keywords + ContainsAllKeywordsPredicate predicate = new ContainsAllKeywordsPredicate(Collections.emptyList()); + assertFalse(predicate.test(new ClientBuilder().withName("Alice").build())); + + // Non-matching keyword + predicate = new ContainsAllKeywordsPredicate(Arrays.asList("Carol")); + assertFalse(predicate.test(new ClientBuilder().withName("Alice Bob").build())); + + // Only one matching keyword + predicate = new ContainsAllKeywordsPredicate(Arrays.asList("Bob", "Carol")); + assertFalse(predicate.test(new ClientBuilder().withName("Alice Carol").build())); + predicate = new ContainsAllKeywordsPredicate(Arrays.asList("Bob", "Tag")); + assertFalse(predicate.test(new ClientBuilder().withName("Alice Carol").withTags("Tag").build())); + + // Keywords match phone, email and address, but does not match name or tag + predicate = new ContainsAllKeywordsPredicate(Arrays.asList("12345", "alice@email.com", "Main", "Street")); + assertFalse(predicate.test(new ClientBuilder().withName("Alice").withPhone("12345") + .withEmail("alice@email.com").withAddress("Main Street").build())); + } + + @Test + public void toStringMethod() { + List keywords = List.of("keyword1", "keyword2"); + ContainsAllKeywordsPredicate predicate = new ContainsAllKeywordsPredicate(keywords); + + String expected = ContainsAllKeywordsPredicate.class.getCanonicalName() + "{keywords=" + keywords + "}"; + assertEquals(expected, predicate.toString()); + } +} diff --git a/src/test/java/seedu/address/model/client/ContainsKeywordsPredicateTest.java b/src/test/java/seedu/address/model/client/ContainsKeywordsPredicateTest.java index 60fc8fa4356..c837beae1dd 100644 --- a/src/test/java/seedu/address/model/client/ContainsKeywordsPredicateTest.java +++ b/src/test/java/seedu/address/model/client/ContainsKeywordsPredicateTest.java @@ -64,15 +64,15 @@ public void test_containsKeywords_returnsTrue() { @Test public void doesNotContainKeywords_returnsFalse() { // Zero keywords - NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Collections.emptyList()); + ContainsKeywordsPredicate predicate = new ContainsKeywordsPredicate(Collections.emptyList()); assertFalse(predicate.test(new ClientBuilder().withName("Alice").build())); // Non-matching keyword - predicate = new NameContainsKeywordsPredicate(Arrays.asList("Carol")); + predicate = new ContainsKeywordsPredicate(Arrays.asList("Carol")); assertFalse(predicate.test(new ClientBuilder().withName("Alice Bob").build())); // Keywords match phone, email and address, but does not match name or tag - predicate = new NameContainsKeywordsPredicate(Arrays.asList("12345", "alice@email.com", "Main", "Street")); + predicate = new ContainsKeywordsPredicate(Arrays.asList("12345", "alice@email.com", "Main", "Street")); assertFalse(predicate.test(new ClientBuilder().withName("Alice").withPhone("12345") .withEmail("alice@email.com").withAddress("Main Street").build())); } @@ -80,9 +80,9 @@ public void doesNotContainKeywords_returnsFalse() { @Test public void toStringMethod() { List keywords = List.of("keyword1", "keyword2"); - NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(keywords); + ContainsKeywordsPredicate predicate = new ContainsKeywordsPredicate(keywords); - String expected = NameContainsKeywordsPredicate.class.getCanonicalName() + "{keywords=" + keywords + "}"; + String expected = ContainsKeywordsPredicate.class.getCanonicalName() + "{keywords=" + keywords + "}"; assertEquals(expected, predicate.toString()); } } From eeae7230b3d2f216d6639fed13f577cc014a2759 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 23 Mar 2025 20:36:22 +0800 Subject: [PATCH 088/249] Fix deleted file --- .../logic/commands/FindClientCommand.java~ | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/main/java/seedu/address/logic/commands/FindClientCommand.java~ diff --git a/src/main/java/seedu/address/logic/commands/FindClientCommand.java~ b/src/main/java/seedu/address/logic/commands/FindClientCommand.java~ new file mode 100644 index 00000000000..98855c84902 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/FindClientCommand.java~ @@ -0,0 +1,58 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.model.Model; +import seedu.address.model.client.NameContainsKeywordsPredicate; + +/** + * Finds and lists all clients in address book whose name contains any of the argument keywords. + * Keyword matching is case insensitive. + */ +public class FindClientCommand extends Command { + + public static final String COMMAND_WORD = "find"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients 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"; + + private final NameContainsKeywordsPredicate predicate; + + public FindClientCommand(NameContainsKeywordsPredicate predicate) { + this.predicate = predicate; + } + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + model.updateFilteredClientList(predicate); + return new CommandResult( + String.format(Messages.MESSAGE_CLIENTS_LISTED_OVERVIEW, model.getFilteredClientList().size())); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof FindClientCommand)) { + return false; + } + + FindClientCommand otherFindClientCommand = (FindClientCommand) other; + return predicate.equals(otherFindClientCommand.predicate); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("predicate", predicate) + .toString(); + } +} From 1e3b2dcfd50688681608d48912065eadeccbff8e Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Mon, 24 Mar 2025 10:32:02 +0800 Subject: [PATCH 089/249] Revert changes made to editcommand --- src/main/java/seedu/address/logic/commands/EditCommand.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index c72c617e98a..00722ad113e 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -33,10 +33,10 @@ */ public class EditCommand extends Command { - public static final String COMMAND_WORD = "editclient"; + public static final String COMMAND_WORD = "edit"; - public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Edits the client identified by the index number used in the displayed client list. " + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the details of the client identified " + + "by the index number used in the displayed client list. " + "Existing values will be overwritten by the input values.\n" + "Parameters: INDEX (must be a positive integer) " + "[" + PREFIX_NAME + "NAME] " From 46fdd4cca0e809df9e8ed99b193c4c221c528e85 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Mon, 24 Mar 2025 11:22:31 +0800 Subject: [PATCH 090/249] Add improved findcommands based on new predicates --- .../commands/AbstractFindClientCommand.java | 50 +++++++++++++++++++ .../logic/commands/FindClientAndCommand.java | 16 ++++++ .../logic/commands/FindClientOrCommand.java | 16 ++++++ .../logic/parser/AddressBookParser.java | 8 +++ .../parser/FindClientAndCommandParser.java | 33 ++++++++++++ .../parser/FindClientOrCommandParser.java | 33 ++++++++++++ 6 files changed, 156 insertions(+) create mode 100644 src/main/java/seedu/address/logic/commands/AbstractFindClientCommand.java create mode 100644 src/main/java/seedu/address/logic/commands/FindClientAndCommand.java create mode 100644 src/main/java/seedu/address/logic/commands/FindClientOrCommand.java create mode 100644 src/main/java/seedu/address/logic/parser/FindClientAndCommandParser.java create mode 100644 src/main/java/seedu/address/logic/parser/FindClientOrCommandParser.java diff --git a/src/main/java/seedu/address/logic/commands/AbstractFindClientCommand.java b/src/main/java/seedu/address/logic/commands/AbstractFindClientCommand.java new file mode 100644 index 00000000000..c2358388542 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/AbstractFindClientCommand.java @@ -0,0 +1,50 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.model.Model; +import seedu.address.model.client.AbstractContainsKeywordsPredicate; +/** + * Finds and lists all clients in address book whose name contains any of the argument keywords. + * Keyword matching is case insensitive. + */ +public class AbstractFindClientCommand extends Command { + + private final AbstractContainsKeywordsPredicate predicate; + + public AbstractFindClientCommand(AbstractContainsKeywordsPredicate predicate) { + this.predicate = predicate; + } + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + model.updateFilteredClientList(predicate); + return new CommandResult( + String.format(Messages.MESSAGE_CLIENTS_LISTED_OVERVIEW, model.getFilteredClientList().size())); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof AbstractFindClientCommand)) { + return false; + } + + AbstractFindClientCommand otherFindClientCommand = (AbstractFindClientCommand) other; + return predicate.equals(otherFindClientCommand.predicate); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("predicate", predicate) + .toString(); + } +} diff --git a/src/main/java/seedu/address/logic/commands/FindClientAndCommand.java b/src/main/java/seedu/address/logic/commands/FindClientAndCommand.java new file mode 100644 index 00000000000..cbb6ee6d108 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/FindClientAndCommand.java @@ -0,0 +1,16 @@ +package seedu.address.logic.commands; + +import seedu.address.model.client.ContainsAllKeywordsPredicate; + +public class FindClientAndCommand extends AbstractFindClientCommand { + public static final String COMMAND_WORD = "findclientand"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients whose names/tags contain all 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 Priority"; + + public FindClientAndCommand(ContainsAllKeywordsPredicate predicate) { + super(predicate); + } +} diff --git a/src/main/java/seedu/address/logic/commands/FindClientOrCommand.java b/src/main/java/seedu/address/logic/commands/FindClientOrCommand.java new file mode 100644 index 00000000000..fe6e3567995 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/FindClientOrCommand.java @@ -0,0 +1,16 @@ +package seedu.address.logic.commands; + +import seedu.address.model.client.ContainsKeywordsPredicate; + +public class FindClientOrCommand extends AbstractFindClientCommand { + public static final String COMMAND_WORD = "findclientor"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients whose names/tags 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 Priority"; + + public FindClientOrCommand(ContainsKeywordsPredicate predicate) { + super(predicate); + } +} diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 020b56739c3..ecb55c330c4 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -14,7 +14,9 @@ import seedu.address.logic.commands.DeleteClientCommand; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.ExitCommand; +import seedu.address.logic.commands.FindClientAndCommand; import seedu.address.logic.commands.FindClientCommand; +import seedu.address.logic.commands.FindClientOrCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.PriorityCommand; @@ -85,6 +87,12 @@ public Command parseCommand(String userInput) throws ParseException { case PriorityCommand.COMMAND_WORD: return new PriorityCommandParser().parse(arguments); + case FindClientOrCommand.COMMAND_WORD: + return new FindClientOrCommandParser().parse(arguments); + + case FindClientAndCommand.COMMAND_WORD: + return new FindClientAndCommandParser().parse(arguments); + default: logger.finer("This user input caused a ParseException: " + userInput); throw new ParseException(MESSAGE_UNKNOWN_COMMAND); diff --git a/src/main/java/seedu/address/logic/parser/FindClientAndCommandParser.java b/src/main/java/seedu/address/logic/parser/FindClientAndCommandParser.java new file mode 100644 index 00000000000..8a0fdfa1a39 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/FindClientAndCommandParser.java @@ -0,0 +1,33 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import java.util.Arrays; + +import seedu.address.logic.commands.FindClientAndCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.client.ContainsAllKeywordsPredicate; + +/** + * Parses input arguments and creates a new FindClientOrCommand object + */ +public class FindClientAndCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the FindClientCommand + * and returns a FindClientCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public FindClientAndCommand parse(String args) throws ParseException { + String trimmedArgs = args.trim(); + if (trimmedArgs.isEmpty()) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindClientAndCommand.MESSAGE_USAGE)); + } + + String[] nameKeywords = trimmedArgs.split("\\s+"); + + return new FindClientAndCommand(new ContainsAllKeywordsPredicate(Arrays.asList(nameKeywords))); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/FindClientOrCommandParser.java b/src/main/java/seedu/address/logic/parser/FindClientOrCommandParser.java new file mode 100644 index 00000000000..c2fcb9d507e --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/FindClientOrCommandParser.java @@ -0,0 +1,33 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import java.util.Arrays; + +import seedu.address.logic.commands.FindClientOrCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.client.ContainsKeywordsPredicate; + +/** + * Parses input arguments and creates a new FindClientOrCommand object + */ +public class FindClientOrCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the FindClientCommand + * and returns a FindClientCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public FindClientOrCommand parse(String args) throws ParseException { + String trimmedArgs = args.trim(); + if (trimmedArgs.isEmpty()) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindClientOrCommand.MESSAGE_USAGE)); + } + + String[] nameKeywords = trimmedArgs.split("\\s+"); + + return new FindClientOrCommand(new ContainsKeywordsPredicate(Arrays.asList(nameKeywords))); + } + +} From f142b40eaa5ea3868e92e1b2707097e4add2074b Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Mon, 24 Mar 2025 11:36:57 +0800 Subject: [PATCH 091/249] Add testcases --- .../logic/commands/FindClientAndCommand.java | 4 + .../logic/commands/FindClientOrCommand.java | 4 + .../commands/FindClientAndCommandTest.java | 87 ++++++++++++++++++ .../commands/FindClientOrCommandTest.java | 91 +++++++++++++++++++ .../FindClientAndCommandParserTest.java | 35 +++++++ .../parser/FindClientOrCommandParserTest.java | 35 +++++++ 6 files changed, 256 insertions(+) create mode 100644 src/test/java/seedu/address/logic/commands/FindClientAndCommandTest.java create mode 100644 src/test/java/seedu/address/logic/commands/FindClientOrCommandTest.java create mode 100644 src/test/java/seedu/address/logic/parser/FindClientAndCommandParserTest.java create mode 100644 src/test/java/seedu/address/logic/parser/FindClientOrCommandParserTest.java diff --git a/src/main/java/seedu/address/logic/commands/FindClientAndCommand.java b/src/main/java/seedu/address/logic/commands/FindClientAndCommand.java index cbb6ee6d108..a41a1601066 100644 --- a/src/main/java/seedu/address/logic/commands/FindClientAndCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindClientAndCommand.java @@ -2,6 +2,10 @@ import seedu.address.model.client.ContainsAllKeywordsPredicate; +/** + * Finds and lists all clients in address book whose name or tag contains all of the argument keywords. + * Keyword matching is case insensitive. + */ public class FindClientAndCommand extends AbstractFindClientCommand { public static final String COMMAND_WORD = "findclientand"; diff --git a/src/main/java/seedu/address/logic/commands/FindClientOrCommand.java b/src/main/java/seedu/address/logic/commands/FindClientOrCommand.java index fe6e3567995..04c699daed3 100644 --- a/src/main/java/seedu/address/logic/commands/FindClientOrCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindClientOrCommand.java @@ -2,6 +2,10 @@ import seedu.address.model.client.ContainsKeywordsPredicate; +/** + * Finds and lists all clients in address book whose name or tag contains any of the argument keywords. + * Keyword matching is case insensitive. + */ public class FindClientOrCommand extends AbstractFindClientCommand { public static final String COMMAND_WORD = "findclientor"; diff --git a/src/test/java/seedu/address/logic/commands/FindClientAndCommandTest.java b/src/test/java/seedu/address/logic/commands/FindClientAndCommandTest.java new file mode 100644 index 00000000000..8878530830b --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/FindClientAndCommandTest.java @@ -0,0 +1,87 @@ +package seedu.address.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.logic.Messages.MESSAGE_CLIENTS_LISTED_OVERVIEW; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.address.testutil.TypicalClients.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.client.ContainsAllKeywordsPredicate; + +/** + * Contains integration tests (interaction with the Model) for {@code FindClientAndCommand}. + */ +public class FindClientAndCommandTest { + private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + + @Test + public void equals() { + ContainsAllKeywordsPredicate firstPredicate = + new ContainsAllKeywordsPredicate(Collections.singletonList("first")); + ContainsAllKeywordsPredicate secondPredicate = + new ContainsAllKeywordsPredicate(Collections.singletonList("second")); + + FindClientAndCommand findFirstCommand = new FindClientAndCommand(firstPredicate); + FindClientAndCommand findSecondCommand = new FindClientAndCommand(secondPredicate); + + // same object -> returns true + assertTrue(findFirstCommand.equals(findFirstCommand)); + + // same values -> returns true + FindClientAndCommand findFirstCommandCopy = new FindClientAndCommand(firstPredicate); + assertTrue(findFirstCommand.equals(findFirstCommandCopy)); + + // different types -> returns false + assertFalse(findFirstCommand.equals(1)); + + // null -> returns false + assertFalse(findFirstCommand.equals(null)); + + // different client -> returns false + assertFalse(findFirstCommand.equals(findSecondCommand)); + } + + @Test + public void execute_zeroKeywords_noClientFound() { + String expectedMessage = String.format(MESSAGE_CLIENTS_LISTED_OVERVIEW, 0); + ContainsAllKeywordsPredicate predicate = preparePredicate(" "); + FindClientAndCommand command = new FindClientAndCommand(predicate); + expectedModel.updateFilteredClientList(predicate); + assertCommandSuccess(command, model, expectedMessage, expectedModel); + assertEquals(Collections.emptyList(), model.getFilteredClientList()); + } + + @Test + public void execute_multipleKeywords_multipleClientsFound() { + String expectedMessage = String.format(MESSAGE_CLIENTS_LISTED_OVERVIEW, 0); + ContainsAllKeywordsPredicate predicate = preparePredicate("Kurz Elle Kunz"); + FindClientAndCommand command = new FindClientAndCommand(predicate); + expectedModel.updateFilteredClientList(predicate); + assertCommandSuccess(command, model, expectedMessage, expectedModel); + } + + @Test + public void toStringMethod() { + ContainsAllKeywordsPredicate predicate = new ContainsAllKeywordsPredicate(Arrays.asList("keyword")); + FindClientAndCommand findClientCommand = new FindClientAndCommand(predicate); + String expected = FindClientAndCommand.class.getCanonicalName() + "{predicate=" + predicate + "}"; + assertEquals(expected, findClientCommand.toString()); + } + + /** + * Parses {@code userInput} into a {@code NameContainsAllKeywordsPredicate}. + */ + private ContainsAllKeywordsPredicate preparePredicate(String userInput) { + return new ContainsAllKeywordsPredicate(Arrays.asList(userInput.split("\\s+"))); + } +} diff --git a/src/test/java/seedu/address/logic/commands/FindClientOrCommandTest.java b/src/test/java/seedu/address/logic/commands/FindClientOrCommandTest.java new file mode 100644 index 00000000000..81ed79c1b74 --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/FindClientOrCommandTest.java @@ -0,0 +1,91 @@ +package seedu.address.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.logic.Messages.MESSAGE_CLIENTS_LISTED_OVERVIEW; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.address.testutil.TypicalClients.CARL; +import static seedu.address.testutil.TypicalClients.ELLE; +import static seedu.address.testutil.TypicalClients.FIONA; +import static seedu.address.testutil.TypicalClients.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.client.ContainsKeywordsPredicate; + +/** + * Contains integration tests (interaction with the Model) for {@code FindClientOrCommand}. + */ +public class FindClientOrCommandTest { + private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + + @Test + public void equals() { + ContainsKeywordsPredicate firstPredicate = + new ContainsKeywordsPredicate(Collections.singletonList("first")); + ContainsKeywordsPredicate secondPredicate = + new ContainsKeywordsPredicate(Collections.singletonList("second")); + + FindClientOrCommand findFirstCommand = new FindClientOrCommand(firstPredicate); + FindClientOrCommand findSecondCommand = new FindClientOrCommand(secondPredicate); + + // same object -> returns true + assertTrue(findFirstCommand.equals(findFirstCommand)); + + // same values -> returns true + FindClientOrCommand findFirstCommandCopy = new FindClientOrCommand(firstPredicate); + assertTrue(findFirstCommand.equals(findFirstCommandCopy)); + + // different types -> returns false + assertFalse(findFirstCommand.equals(1)); + + // null -> returns false + assertFalse(findFirstCommand.equals(null)); + + // different client -> returns false + assertFalse(findFirstCommand.equals(findSecondCommand)); + } + + @Test + public void execute_zeroKeywords_noClientFound() { + String expectedMessage = String.format(MESSAGE_CLIENTS_LISTED_OVERVIEW, 0); + ContainsKeywordsPredicate predicate = preparePredicate(" "); + FindClientOrCommand command = new FindClientOrCommand(predicate); + expectedModel.updateFilteredClientList(predicate); + assertCommandSuccess(command, model, expectedMessage, expectedModel); + assertEquals(Collections.emptyList(), model.getFilteredClientList()); + } + + @Test + public void execute_multipleKeywords_multipleClientsFound() { + String expectedMessage = String.format(MESSAGE_CLIENTS_LISTED_OVERVIEW, 3); + ContainsKeywordsPredicate predicate = preparePredicate("Kurz Elle Kunz"); + FindClientOrCommand command = new FindClientOrCommand(predicate); + expectedModel.updateFilteredClientList(predicate); + assertCommandSuccess(command, model, expectedMessage, expectedModel); + assertEquals(Arrays.asList(CARL, ELLE, FIONA), model.getFilteredClientList()); + } + + @Test + public void toStringMethod() { + ContainsKeywordsPredicate predicate = new ContainsKeywordsPredicate(Arrays.asList("keyword")); + FindClientOrCommand findClientCommand = new FindClientOrCommand(predicate); + String expected = FindClientOrCommand.class.getCanonicalName() + "{predicate=" + predicate + "}"; + assertEquals(expected, findClientCommand.toString()); + } + + /** + * Parses {@code userInput} into a {@code NameContainsKeywordsPredicate}. + */ + private ContainsKeywordsPredicate preparePredicate(String userInput) { + return new ContainsKeywordsPredicate(Arrays.asList(userInput.split("\\s+"))); + } +} diff --git a/src/test/java/seedu/address/logic/parser/FindClientAndCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindClientAndCommandParserTest.java new file mode 100644 index 00000000000..87102fbce91 --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/FindClientAndCommandParserTest.java @@ -0,0 +1,35 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +import seedu.address.logic.commands.FindClientAndCommand; +import seedu.address.model.client.ContainsAllKeywordsPredicate; + +public class FindClientAndCommandParserTest { + + private FindClientAndCommandParser parser = new FindClientAndCommandParser(); + + @Test + public void parse_emptyArg_throwsParseException() { + assertParseFailure(parser, " ", + String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindClientAndCommand.MESSAGE_USAGE)); + } + + @Test + public void parse_validArgs_returnsFindCommand() { + // no leading and trailing whitespaces + FindClientAndCommand expectedFindClientAndCommand = + new FindClientAndCommand(new ContainsAllKeywordsPredicate(Arrays.asList("Alice", "Bob"))); + assertParseSuccess(parser, "Alice Bob", expectedFindClientAndCommand); + + // multiple whitespaces between keywords + assertParseSuccess(parser, " \n Alice \n \t Bob \t", expectedFindClientAndCommand); + } + +} diff --git a/src/test/java/seedu/address/logic/parser/FindClientOrCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindClientOrCommandParserTest.java new file mode 100644 index 00000000000..e91f1deecf9 --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/FindClientOrCommandParserTest.java @@ -0,0 +1,35 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +import seedu.address.logic.commands.FindClientOrCommand; +import seedu.address.model.client.ContainsKeywordsPredicate; + +public class FindClientOrCommandParserTest { + + private FindClientOrCommandParser parser = new FindClientOrCommandParser(); + + @Test + public void parse_emptyArg_throwsParseException() { + assertParseFailure(parser, " ", + String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindClientOrCommand.MESSAGE_USAGE)); + } + + @Test + public void parse_validArgs_returnsFindCommand() { + // no leading and trailing whitespaces + FindClientOrCommand expectedFindClientOrCommand = + new FindClientOrCommand(new ContainsKeywordsPredicate(Arrays.asList("Alice", "Bob"))); + assertParseSuccess(parser, "Alice Bob", expectedFindClientOrCommand); + + // multiple whitespaces between keywords + assertParseSuccess(parser, " \n Alice \n \t Bob \t", expectedFindClientOrCommand); + } + +} From 01514426e55835aa15b6101813cc41af1dd1b358 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Mon, 24 Mar 2025 11:42:04 +0800 Subject: [PATCH 092/249] Add missing testcases for addressbook parser --- .../logic/parser/AddressBookParserTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 0d8a085a288..b7e1e7a761b 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -19,12 +19,16 @@ import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.EditCommand.EditClientDescriptor; import seedu.address.logic.commands.ExitCommand; +import seedu.address.logic.commands.FindClientAndCommand; import seedu.address.logic.commands.FindClientCommand; +import seedu.address.logic.commands.FindClientOrCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.PriorityCommand; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.client.Client; +import seedu.address.model.client.ContainsAllKeywordsPredicate; +import seedu.address.model.client.ContainsKeywordsPredicate; import seedu.address.model.client.NameContainsKeywordsPredicate; import seedu.address.testutil.ClientBuilder; import seedu.address.testutil.ClientUtil; @@ -77,6 +81,22 @@ public void parseCommand_find() throws Exception { assertEquals(new FindClientCommand(new NameContainsKeywordsPredicate(keywords)), command); } + @Test + public void parseCommand_findor() throws Exception { + List keywords = Arrays.asList("foo", "bar", "baz"); + FindClientOrCommand command = (FindClientOrCommand) parser.parseCommand( + FindClientOrCommand.COMMAND_WORD + " " + keywords.stream().collect(Collectors.joining(" "))); + assertEquals(new FindClientOrCommand(new ContainsKeywordsPredicate(keywords)), command); + } + + @Test + public void parseCommand_findand() throws Exception { + List keywords = Arrays.asList("foo", "bar", "baz"); + FindClientAndCommand command = (FindClientAndCommand) parser.parseCommand( + FindClientAndCommand.COMMAND_WORD + " " + keywords.stream().collect(Collectors.joining(" "))); + assertEquals(new FindClientAndCommand(new ContainsAllKeywordsPredicate(keywords)), command); + } + @Test public void parseCommand_help() throws Exception { assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD) instanceof HelpCommand); From f194ec2d961074713cfb4788ece729277a4b6238 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Mon, 24 Mar 2025 18:23:33 +0800 Subject: [PATCH 093/249] Update UG to include improved find commands --- docs/UserGuide.md | 77 +++++++++++++----- docs/images/findclientandFriendsPriority.png | Bin 0 -> 9832 bytes docs/images/findclientorAlexDavidPriority.png | Bin 0 -> 33993 bytes 3 files changed, 58 insertions(+), 19 deletions(-) create mode 100644 docs/images/findclientandFriendsPriority.png create mode 100644 docs/images/findclientorAlexDavidPriority.png diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 9379b55e66b..9ae23f525f9 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -6,7 +6,7 @@ # WealthVault User Guide -AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized for use via a 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. +WealthVault is a **desktop app for managing contacts, optimized for use via a Line Interface** (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, WealthVault can get your contact management tasks done faster than traditional GUI apps. @@ -18,11 +18,11 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo 1. Ensure you have Java `17` or above installed in your Computer.
    **Mac users:** Ensure you have the precise JDK version prescribed [here](https://se-education.org/guides/tutorials/javaInstallationMac.html). -1. Download the latest `.jar` file from [here](https://github.com/se-edu/addressbook-level3/releases). +1. Download the latest `.jar` file from [here](https://github.com/AY2425S2-CS2103T-W12-2/tp/releases/tag/v1.3). -1. Copy the file to the folder you want to use as the _home folder_ for your AddressBook. +1. Copy the file to the folder you want to use as the _home folder_ for your application. -1. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar addressbook.jar` command to run the application.
    +1. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar wealthvault.jar` command to run the application.
    A GUI similar to the below should appear in a few seconds. Note how the app contains some sample data.
    ![Ui](images/Ui.png) @@ -31,7 +31,7 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo * `list` : Lists all contacts. - * `addclient 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. + * `addclient n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` : Adds a contact named `John Doe` to the application. * `deleteclient 3` : Deletes the 3rd contact shown in the current list. @@ -132,6 +132,42 @@ Examples: * `findclient alex david` returns `Alex Yeoh`, `David Li`
    ![result for 'find alex david'](images/findAlexDavidResult.png) +### Locating persons by name and tag: `findclientor` + +Finds persons whose name or tag contain any of the given keywords. + +Format: `findclientor KEYWORD [MORE_KEYWORDS]` + +* 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` +* Both the name and the tag 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` + +Examples: +* `findclientor John` returns `john` and `John Doe` +* `findclientor alex david priority` returns `Alex Yeoh`, `David Li` and anyone with the `Priority` tag attached
    + ![result for 'find alex david'](images/findclientorAlexDavidPriority.png) + +### Locating specific persons by name and tag: `findclientand` + +Finds persons whose name or tag contain all of the given keywords. + +Format: `findclientand KEYWORD [MORE_KEYWORDS]` + +* 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` +* Both the name and the tag 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` + +Examples: +* `findclientand John` returns `john` and `John Doe` +* `findclientand friends priority` returns only people with the `Priority` and `friends` tags attached
    + ![result for 'find alex david'](images/findclientandFriendsPriority.png) + ### Deleting a person : `deleteclient` Deletes the specified person from the address book. @@ -174,17 +210,17 @@ 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. +WealthVault data are saved in the hard disk automatically after any command that changes the data. There is no need to save manually. ### Editing the data file -AddressBook data are saved automatically as a JSON file `[JAR file location]/data/addressbook.json`. Advanced users are welcome to update data directly by editing that data file. +WealthVault data are saved automatically as a JSON file `[JAR file location]/data/addressbook.json`. Advanced users are welcome to update data directly by editing that data file. **Caution:** -If your changes to the data file makes its format invalid, AddressBook will discard all data and start with an empty data file at the next run. Hence, it is recommended to take a backup of the file before editing it.
    -Furthermore, certain edits can cause the AddressBook to behave in unexpected ways (e.g., if a value entered is outside the acceptable range). Therefore, edit the data file only if you are confident that you can update it correctly. +If your changes to the data file makes its format invalid, WealthVault will discard all data and start with an empty data file at the next run. Hence, it is recommended to take a backup of the file before editing it.
    +Furthermore, certain edits can cause the WealthVault to behave in unexpected ways (e.g., if a value entered is outside the acceptable range). Therefore, edit the data file only if you are confident that you can update it correctly.
    ### Archiving data files `[coming in v2.0]` @@ -196,7 +232,7 @@ _Details coming soon ..._ ## 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. +**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 WealthVault home folder. -------------------------------------------------------------------------------------------------------------------- @@ -209,12 +245,15 @@ _Details coming soon ..._ ## Command summary -Action | Format, Examples ------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------- -**Add** | `addclient n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​`
    e.g., `addclient n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague` -**Clear** | `clear` -**Delete** | `deleteclient INDEX`
    e.g., `deleteclient 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** | `findclient KEYWORD [MORE_KEYWORDS]`
    e.g., `findclient James Jake` -**List** | `list` -**Help** | `help` +Action | Format, Examples +-------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------- +**Add** | `addclient n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​`
    e.g., `addclient n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague` +**Clear** | `clear` +**Delete** | `deleteclient INDEX`
    e.g., `deleteclient 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** | `findclient KEYWORD [MORE_KEYWORDS]`
    e.g., `findclient James Jake` +**Find(Or)** | `findclientor KEYWORD [MORE_KEYWORDS]`
    e.g., `findclientor James Jake` +**Find(And)**| `findclientand KEYWORD [MORE_KEYWORDS]`
    e.g., `findclientand James Jake` +**Priority** | `priority INDEX`
    e.g.,`priority 1` +**List** | `list` +**Help** | `help` diff --git a/docs/images/findclientandFriendsPriority.png b/docs/images/findclientandFriendsPriority.png new file mode 100644 index 0000000000000000000000000000000000000000..ea2c3ca5355aa868112e3e1e7416153d1817667a GIT binary patch literal 9832 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 C2-uha literal 0 HcmV?d00001 diff --git a/docs/images/findclientorAlexDavidPriority.png b/docs/images/findclientorAlexDavidPriority.png new file mode 100644 index 0000000000000000000000000000000000000000..4c60cad8f2714c0b9494c44263fd23e38700b915 GIT binary patch literal 33993 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 literal 0 HcmV?d00001 From 093177a9f0231a58cdf94ab6d0f51a761fee7bd9 Mon Sep 17 00:00:00 2001 From: joshua Date: Mon, 24 Mar 2025 22:52:26 +0800 Subject: [PATCH 094/249] fix update --- .../seedu/address/logic/commands/EditCommand.java | 2 +- .../address/logic/commands/UpdateClientCommand.java | 11 +++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index 1f010f6890a..e023e540144 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -48,7 +48,7 @@ public class EditCommand extends Command { + PREFIX_PHONE + "91234567 " + PREFIX_EMAIL + "johndoe@example.com"; - public static final String MESSAGE_EDIT_CLIENT_SUCCESS = "Edited Client: %1$s"; + public static final String MESSAGE_EDIT_CLIENT_SUCCESS = "%1$s"; public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided."; public static final String MESSAGE_DUPLICATE_CLIENT = "This client already exists in the address book."; diff --git a/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java b/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java index d941c176905..6543b88841d 100644 --- a/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java @@ -32,7 +32,7 @@ public class UpdateClientCommand extends EditCommand { + PREFIX_PHONE + "91234567 " + PREFIX_EMAIL + "johndoe@example.com"; - public static final String MESSAGE_UPDATE_CLIENT_SUCCESS = "Updated Client: %1$s"; + public static final String MESSAGE_UPDATE_CLIENT_SUCCESS = "Updated Client:%1$s"; /** * @param index of the client in the filtered client list to edit @@ -46,13 +46,8 @@ public UpdateClientCommand(Index index, EditClientDescriptor editClientDescripto public CommandResult execute(Model model) throws CommandException { requireNonNull(model); CommandResult result = super.execute(model); - String successMessage = String.format( - MESSAGE_UPDATE_CLIENT_SUCCESS, - result.getFeedbackToUser().substring( - MESSAGE_EDIT_CLIENT_SUCCESS.indexOf("%1$s") + 4 - ) - ); - + String clientName = result.getFeedbackToUser().replace("Updated Client: ", ""); + String successMessage = String.format(MESSAGE_UPDATE_CLIENT_SUCCESS, clientName); return new CommandResult(successMessage); } } From 371af9010d65b23c410cbf5607a3d0369321f9b0 Mon Sep 17 00:00:00 2001 From: joshua Date: Mon, 24 Mar 2025 23:03:00 +0800 Subject: [PATCH 095/249] fix update --- .../seedu/address/logic/commands/UpdateClientCommand.java | 8 ++++---- .../address/logic/commands/UpdateClientCommandTest.java | 5 +---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java b/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java index 6543b88841d..dd90c691d96 100644 --- a/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/UpdateClientCommand.java @@ -32,7 +32,7 @@ public class UpdateClientCommand extends EditCommand { + PREFIX_PHONE + "91234567 " + PREFIX_EMAIL + "johndoe@example.com"; - public static final String MESSAGE_UPDATE_CLIENT_SUCCESS = "Updated Client:%1$s"; + public static final String MESSAGE_UPDATE_CLIENT_SUCCESS = "Updated Client: %1$s"; /** * @param index of the client in the filtered client list to edit @@ -46,8 +46,8 @@ public UpdateClientCommand(Index index, EditClientDescriptor editClientDescripto public CommandResult execute(Model model) throws CommandException { requireNonNull(model); CommandResult result = super.execute(model); - String clientName = result.getFeedbackToUser().replace("Updated Client: ", ""); - String successMessage = String.format(MESSAGE_UPDATE_CLIENT_SUCCESS, clientName); - return new CommandResult(successMessage); + String fullMessage = result.getFeedbackToUser(); + String clientName = fullMessage.substring(0, fullMessage.indexOf(";")).trim(); + return new CommandResult(String.format(MESSAGE_UPDATE_CLIENT_SUCCESS, clientName)); } } diff --git a/src/test/java/seedu/address/logic/commands/UpdateClientCommandTest.java b/src/test/java/seedu/address/logic/commands/UpdateClientCommandTest.java index 4f551034422..8f30719c972 100644 --- a/src/test/java/seedu/address/logic/commands/UpdateClientCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/UpdateClientCommandTest.java @@ -46,10 +46,7 @@ public void execute_clientAcceptedByModel_updateSuccessful() throws Exception { UpdateClientCommand updateCommand = new UpdateClientCommand(INDEX_FIRST_CLIENT, descriptor); CommandResult result = updateCommand.execute(modelStub); - - // Just expect exactly what's being output - String expectedMessage = "Updated Client: ted; Phone: 85355255; Email: amy@gmail.com; " - + "Address: 123, Jurong West Ave 6, #08-111; Tags: "; + String expectedMessage = "Updated Client: Updated"; assertEquals(expectedMessage, result.getFeedbackToUser()); assertEquals(updatedClient, modelStub.clientUpdated); } From 1228fe1e27d0be834db6deef70162aa9a2b184ee Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Wed, 26 Mar 2025 07:06:57 +0800 Subject: [PATCH 096/249] Fix missing abstract keyword --- .../seedu/address/logic/commands/AbstractFindClientCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/logic/commands/AbstractFindClientCommand.java b/src/main/java/seedu/address/logic/commands/AbstractFindClientCommand.java index c2358388542..c07bab695a8 100644 --- a/src/main/java/seedu/address/logic/commands/AbstractFindClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/AbstractFindClientCommand.java @@ -10,7 +10,7 @@ * Finds and lists all clients in address book whose name contains any of the argument keywords. * Keyword matching is case insensitive. */ -public class AbstractFindClientCommand extends Command { +public abstract class AbstractFindClientCommand extends Command { private final AbstractContainsKeywordsPredicate predicate; From e4feb27c656231731f464298ba194f8cb1442611 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Wed, 26 Mar 2025 07:27:56 +0800 Subject: [PATCH 097/249] Refactor ClientCard --- .../java/seedu/address/ui/ClientCard.java | 47 +++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/main/java/seedu/address/ui/ClientCard.java b/src/main/java/seedu/address/ui/ClientCard.java index 236cc50b306..5bab822f90d 100644 --- a/src/main/java/seedu/address/ui/ClientCard.java +++ b/src/main/java/seedu/address/ui/ClientCard.java @@ -8,6 +8,7 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Region; import seedu.address.model.client.Client; +import seedu.address.model.tag.PriorityTag; import seedu.address.model.tag.Tag; /** @@ -48,20 +49,50 @@ public class ClientCard extends UiPart { public ClientCard(Client client, int displayedIndex) { super(FXML); this.client = client; + + // Initialize UI elements + initializeClientDetails(client, displayedIndex); + populateTags(client); + } + + /** + * Initializes the client details in the UI. + * + * @param client The client whose details are being displayed. + * @param displayedIndex The index number to be displayed. + */ + private void initializeClientDetails(Client client, int displayedIndex) { id.setText(displayedIndex + ". "); name.setText(client.getName().fullName); phone.setText(client.getPhone().value); address.setText(client.getAddress().value); email.setText(client.getEmail().value); + } + + /** + * Populates the tag container with sorted tags. + * + * @param client The client whose tags need to be displayed. + */ + private void populateTags(Client client) { client.getTags().stream() - .sorted(Comparator.comparing(tag -> !tag.tagName.equals("Priority")) + .sorted(Comparator.comparing(tag -> !(tag instanceof PriorityTag)) .thenComparing(tag -> tag.tagName)) - .forEach(tag -> { - Label label = new Label(tag.tagName); - if (tag.tagName.equals("Priority")) { - label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); - } - tags.getChildren().add(label); - }); + .map(this::createTagLabel) + .forEach(tags.getChildren()::add); + } + + /** + * Creates a styled Label for a given tag. + * + * @param tag The tag for which a Label is created. + * @return A styled Label representing the tag. + */ + private Label createTagLabel(Tag tag) { + Label label = new Label(tag.tagName); + if (tag instanceof PriorityTag) { + label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); + } + return label; } } From 8ab0d77c218d37372f1692488cadf2858bf86b26 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Wed, 26 Mar 2025 07:28:22 +0800 Subject: [PATCH 098/249] Removed useless constructor in PriorityTag --- .../java/seedu/address/model/tag/PriorityTag.java | 4 ---- .../java/seedu/address/model/tag/PriorityTagTest.java | 11 ----------- 2 files changed, 15 deletions(-) diff --git a/src/main/java/seedu/address/model/tag/PriorityTag.java b/src/main/java/seedu/address/model/tag/PriorityTag.java index f3396c1e056..01b2a84af51 100644 --- a/src/main/java/seedu/address/model/tag/PriorityTag.java +++ b/src/main/java/seedu/address/model/tag/PriorityTag.java @@ -6,10 +6,6 @@ public class PriorityTag extends Tag { static final String VALID_PRIORITY_TAG = "Priority"; - public PriorityTag(String tagName) { - super(tagName); - } - public PriorityTag() { super(VALID_PRIORITY_TAG); } diff --git a/src/test/java/seedu/address/model/tag/PriorityTagTest.java b/src/test/java/seedu/address/model/tag/PriorityTagTest.java index dcc01e077ac..a8c4f525171 100644 --- a/src/test/java/seedu/address/model/tag/PriorityTagTest.java +++ b/src/test/java/seedu/address/model/tag/PriorityTagTest.java @@ -14,17 +14,6 @@ void testDefaultConstructor() { assertEquals("Priority", priorityTag.tagName); } - @Test - public void constructor_null_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> new PriorityTag(null)); - } - - @Test - public void constructor_invalidTagName_throwsIllegalArgumentException() { - String invalidTagName = ""; - assertThrows(IllegalArgumentException.class, () -> new PriorityTag(invalidTagName)); - } - @Test public void isValidTagName() { // null tag name From b7f1bf43f9c063e46bd656234575a9dfd5f39cd4 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Wed, 26 Mar 2025 07:34:50 +0800 Subject: [PATCH 099/249] Revert "Refactor ClientCard" This reverts commit e4feb27c656231731f464298ba194f8cb1442611. --- .../java/seedu/address/ui/ClientCard.java | 47 ++++--------------- 1 file changed, 8 insertions(+), 39 deletions(-) diff --git a/src/main/java/seedu/address/ui/ClientCard.java b/src/main/java/seedu/address/ui/ClientCard.java index 5bab822f90d..236cc50b306 100644 --- a/src/main/java/seedu/address/ui/ClientCard.java +++ b/src/main/java/seedu/address/ui/ClientCard.java @@ -8,7 +8,6 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Region; import seedu.address.model.client.Client; -import seedu.address.model.tag.PriorityTag; import seedu.address.model.tag.Tag; /** @@ -49,50 +48,20 @@ public class ClientCard extends UiPart { public ClientCard(Client client, int displayedIndex) { super(FXML); this.client = client; - - // Initialize UI elements - initializeClientDetails(client, displayedIndex); - populateTags(client); - } - - /** - * Initializes the client details in the UI. - * - * @param client The client whose details are being displayed. - * @param displayedIndex The index number to be displayed. - */ - private void initializeClientDetails(Client client, int displayedIndex) { id.setText(displayedIndex + ". "); name.setText(client.getName().fullName); phone.setText(client.getPhone().value); address.setText(client.getAddress().value); email.setText(client.getEmail().value); - } - - /** - * Populates the tag container with sorted tags. - * - * @param client The client whose tags need to be displayed. - */ - private void populateTags(Client client) { client.getTags().stream() - .sorted(Comparator.comparing(tag -> !(tag instanceof PriorityTag)) + .sorted(Comparator.comparing(tag -> !tag.tagName.equals("Priority")) .thenComparing(tag -> tag.tagName)) - .map(this::createTagLabel) - .forEach(tags.getChildren()::add); - } - - /** - * Creates a styled Label for a given tag. - * - * @param tag The tag for which a Label is created. - * @return A styled Label representing the tag. - */ - private Label createTagLabel(Tag tag) { - Label label = new Label(tag.tagName); - if (tag instanceof PriorityTag) { - label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); - } - return label; + .forEach(tag -> { + Label label = new Label(tag.tagName); + if (tag.tagName.equals("Priority")) { + label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); + } + tags.getChildren().add(label); + }); } } From a1c40666869e9d6861c22a370ac6c306c8bb58b0 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Wed, 26 Mar 2025 10:28:37 +0800 Subject: [PATCH 100/249] Reapply "Refactor ClientCard" This reverts commit b7f1bf43f9c063e46bd656234575a9dfd5f39cd4. --- .../java/seedu/address/ui/ClientCard.java | 47 +++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/main/java/seedu/address/ui/ClientCard.java b/src/main/java/seedu/address/ui/ClientCard.java index 236cc50b306..5bab822f90d 100644 --- a/src/main/java/seedu/address/ui/ClientCard.java +++ b/src/main/java/seedu/address/ui/ClientCard.java @@ -8,6 +8,7 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Region; import seedu.address.model.client.Client; +import seedu.address.model.tag.PriorityTag; import seedu.address.model.tag.Tag; /** @@ -48,20 +49,50 @@ public class ClientCard extends UiPart { public ClientCard(Client client, int displayedIndex) { super(FXML); this.client = client; + + // Initialize UI elements + initializeClientDetails(client, displayedIndex); + populateTags(client); + } + + /** + * Initializes the client details in the UI. + * + * @param client The client whose details are being displayed. + * @param displayedIndex The index number to be displayed. + */ + private void initializeClientDetails(Client client, int displayedIndex) { id.setText(displayedIndex + ". "); name.setText(client.getName().fullName); phone.setText(client.getPhone().value); address.setText(client.getAddress().value); email.setText(client.getEmail().value); + } + + /** + * Populates the tag container with sorted tags. + * + * @param client The client whose tags need to be displayed. + */ + private void populateTags(Client client) { client.getTags().stream() - .sorted(Comparator.comparing(tag -> !tag.tagName.equals("Priority")) + .sorted(Comparator.comparing(tag -> !(tag instanceof PriorityTag)) .thenComparing(tag -> tag.tagName)) - .forEach(tag -> { - Label label = new Label(tag.tagName); - if (tag.tagName.equals("Priority")) { - label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); - } - tags.getChildren().add(label); - }); + .map(this::createTagLabel) + .forEach(tags.getChildren()::add); + } + + /** + * Creates a styled Label for a given tag. + * + * @param tag The tag for which a Label is created. + * @return A styled Label representing the tag. + */ + private Label createTagLabel(Tag tag) { + Label label = new Label(tag.tagName); + if (tag instanceof PriorityTag) { + label.setStyle("-fx-background-color: orange; -fx-font-weight: bold;"); + } + return label; } } From 3e14272aa3cadba014754b188fe3b5be61739ccc Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Wed, 26 Mar 2025 15:49:45 +0800 Subject: [PATCH 101/249] Add tutorial edits --- .../seedu/address/storage/StorageManagerTest.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/test/java/seedu/address/storage/StorageManagerTest.java b/src/test/java/seedu/address/storage/StorageManagerTest.java index 505601d3256..61352e9a552 100644 --- a/src/test/java/seedu/address/storage/StorageManagerTest.java +++ b/src/test/java/seedu/address/storage/StorageManagerTest.java @@ -64,5 +64,16 @@ public void addressBookReadSave() throws Exception { public void getAddressBookFilePath() { assertNotNull(storageManager.getAddressBookFilePath()); } - } + + + + + + + + + + + + From 20c0d011facffaa605fff7eb7b2a60530c7745c2 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Wed, 26 Mar 2025 19:24:12 +0800 Subject: [PATCH 102/249] Fix typo and grammar error --- .../address/logic/commands/AbstractFindClientCommand.java | 2 +- .../seedu/address/logic/commands/FindClientAndCommand.java | 4 ++-- .../seedu/address/logic/commands/FindClientOrCommand.java | 4 ++-- .../address/logic/parser/FindClientAndCommandParser.java | 2 +- .../seedu/address/logic/parser/FindClientOrCommandParser.java | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/AbstractFindClientCommand.java b/src/main/java/seedu/address/logic/commands/AbstractFindClientCommand.java index c07bab695a8..a99b666ff11 100644 --- a/src/main/java/seedu/address/logic/commands/AbstractFindClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/AbstractFindClientCommand.java @@ -7,7 +7,7 @@ import seedu.address.model.Model; import seedu.address.model.client.AbstractContainsKeywordsPredicate; /** - * Finds and lists all clients in address book whose name contains any of the argument keywords. + * Finds and lists clients in address book whose name/tag contains any or all of the argument keywords. * Keyword matching is case insensitive. */ public abstract class AbstractFindClientCommand extends Command { diff --git a/src/main/java/seedu/address/logic/commands/FindClientAndCommand.java b/src/main/java/seedu/address/logic/commands/FindClientAndCommand.java index a41a1601066..7edd505ed27 100644 --- a/src/main/java/seedu/address/logic/commands/FindClientAndCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindClientAndCommand.java @@ -7,9 +7,9 @@ * Keyword matching is case insensitive. */ public class FindClientAndCommand extends AbstractFindClientCommand { - public static final String COMMAND_WORD = "findclientand"; + public static final String COMMAND_WORD = "findall"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients whose names/tags contain all of " + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients whose names or tags contain all 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 Priority"; diff --git a/src/main/java/seedu/address/logic/commands/FindClientOrCommand.java b/src/main/java/seedu/address/logic/commands/FindClientOrCommand.java index 04c699daed3..f667b015a5c 100644 --- a/src/main/java/seedu/address/logic/commands/FindClientOrCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindClientOrCommand.java @@ -7,9 +7,9 @@ * Keyword matching is case insensitive. */ public class FindClientOrCommand extends AbstractFindClientCommand { - public static final String COMMAND_WORD = "findclientor"; + public static final String COMMAND_WORD = "findany"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients whose names/tags contain any of " + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all clients whose names or tags 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 Priority"; diff --git a/src/main/java/seedu/address/logic/parser/FindClientAndCommandParser.java b/src/main/java/seedu/address/logic/parser/FindClientAndCommandParser.java index 8a0fdfa1a39..a185ccac586 100644 --- a/src/main/java/seedu/address/logic/parser/FindClientAndCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/FindClientAndCommandParser.java @@ -15,7 +15,7 @@ public class FindClientAndCommandParser implements Parser /** * Parses the given {@code String} of arguments in the context of the FindClientCommand - * and returns a FindClientCommand object for execution. + * and returns a FindClientAndCommand object for execution. * @throws ParseException if the user input does not conform the expected format */ public FindClientAndCommand parse(String args) throws ParseException { diff --git a/src/main/java/seedu/address/logic/parser/FindClientOrCommandParser.java b/src/main/java/seedu/address/logic/parser/FindClientOrCommandParser.java index c2fcb9d507e..ce362090e11 100644 --- a/src/main/java/seedu/address/logic/parser/FindClientOrCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/FindClientOrCommandParser.java @@ -15,7 +15,7 @@ public class FindClientOrCommandParser implements Parser { /** * Parses the given {@code String} of arguments in the context of the FindClientCommand - * and returns a FindClientCommand object for execution. + * and returns a FindClientOrCommand object for execution. * @throws ParseException if the user input does not conform the expected format */ public FindClientOrCommand parse(String args) throws ParseException { From 32a3f09c9e1aba03375a8ad94403e4329c82273b Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Wed, 26 Mar 2025 19:24:50 +0800 Subject: [PATCH 103/249] Update predicates to readability --- .../client/ContainsAllKeywordsPredicate.java | 17 ++++++++++------- .../model/client/ContainsKeywordsPredicate.java | 15 +++++++++------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/main/java/seedu/address/model/client/ContainsAllKeywordsPredicate.java b/src/main/java/seedu/address/model/client/ContainsAllKeywordsPredicate.java index 7ffa9b256b1..0cee1da8a7d 100644 --- a/src/main/java/seedu/address/model/client/ContainsAllKeywordsPredicate.java +++ b/src/main/java/seedu/address/model/client/ContainsAllKeywordsPredicate.java @@ -5,7 +5,7 @@ import seedu.address.commons.util.StringUtil; /** * Tests that a {@code Client}'s {@code Name} or {@code Tag} contains all the keywords given. - * This predicate is equilivant to the AND operations when using find, i.e. strict matching + * This predicate is equivalent to the AND operations when using find, i.e. strict matching */ public class ContainsAllKeywordsPredicate extends AbstractContainsKeywordsPredicate { @@ -19,11 +19,14 @@ public boolean test(Client client) { return false; // Ensures empty keyword list returns false like to ContainsKeywordsPredicate } - return keywords.stream().allMatch(keyword -> - StringUtil.containsWordIgnoreCase(client.getName().fullName, keyword) - || client.getTags().stream().anyMatch(tag -> - StringUtil.containsWordIgnoreCase(tag.tagName, keyword) - ) - ); + return keywords.stream() + .allMatch(keyword -> isKeywordMatch(client, keyword)); + } + + private boolean isKeywordMatch(Client client, String keyword) { + boolean nameMatch = StringUtil.containsWordIgnoreCase(client.getName().fullName, keyword); + boolean tagMatch = client.getTags().stream() + .anyMatch(tag -> StringUtil.containsWordIgnoreCase(tag.tagName, keyword)); + return nameMatch || tagMatch; } } diff --git a/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java index 0c2ba5e2b29..b4d91e17b6e 100644 --- a/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java +++ b/src/main/java/seedu/address/model/client/ContainsKeywordsPredicate.java @@ -15,11 +15,14 @@ public ContainsKeywordsPredicate(List keywords) { @Override public boolean test(Client client) { - return keywords.stream().anyMatch(keyword -> - StringUtil.containsWordIgnoreCase(client.getName().fullName, keyword) - || client.getTags().stream().anyMatch(tag -> - StringUtil.containsWordIgnoreCase(tag.tagName, keyword) - ) - ); + return keywords.stream() + .anyMatch(keyword -> isKeywordMatch(client, keyword)); + } + + private boolean isKeywordMatch(Client client, String keyword) { + boolean nameMatch = StringUtil.containsWordIgnoreCase(client.getName().fullName, keyword); + boolean tagMatch = client.getTags().stream() + .anyMatch(tag -> StringUtil.containsWordIgnoreCase(tag.tagName, keyword)); + return nameMatch || tagMatch; } } From 5b25abcd6da548710bd0323d33df0929bf549f15 Mon Sep 17 00:00:00 2001 From: Nicholas Foo Date: Thu, 27 Mar 2025 01:54:23 +0800 Subject: [PATCH 104/249] Add Sort Client Feature --- .../logic/commands/PriorityCommand.java | 1 + .../address/logic/commands/SortCommand.java | 22 ++ .../logic/parser/AddressBookParser.java | 4 + .../java/seedu/address/model/AddressBook.java | 5 + src/main/java/seedu/address/model/Model.java | 6 + .../seedu/address/model/ModelManager.java | 5 + .../address/model/ReadOnlyAddressBook.java | 2 + .../address/model/ReadOnlyAddressBook.java~ | 16 ++ .../model/client/UniqueClientList.java | 5 + .../logic/commands/AddClientCommandTest.java | 5 + .../logic/commands/AddClientCommandTest.java~ | 205 ++++++++++++++++++ .../logic/commands/SortCommandTest.java | 39 ++++ .../logic/commands/SortCommandTest.java~ | 40 ++++ .../logic/parser/AddressBookParserTest.java | 7 + .../seedu/address/model/AddressBookTest.java | 6 + .../seedu/address/testutil/ModelStub.java | 5 + 16 files changed, 373 insertions(+) create mode 100644 src/main/java/seedu/address/logic/commands/SortCommand.java create mode 100644 src/main/java/seedu/address/model/ReadOnlyAddressBook.java~ create mode 100644 src/test/java/seedu/address/logic/commands/AddClientCommandTest.java~ create mode 100644 src/test/java/seedu/address/logic/commands/SortCommandTest.java create mode 100644 src/test/java/seedu/address/logic/commands/SortCommandTest.java~ diff --git a/src/main/java/seedu/address/logic/commands/PriorityCommand.java b/src/main/java/seedu/address/logic/commands/PriorityCommand.java index a27d2f4f273..a35e7959a9c 100644 --- a/src/main/java/seedu/address/logic/commands/PriorityCommand.java +++ b/src/main/java/seedu/address/logic/commands/PriorityCommand.java @@ -109,3 +109,4 @@ public boolean equals(Object other) { return index.equals(e.index); } } + diff --git a/src/main/java/seedu/address/logic/commands/SortCommand.java b/src/main/java/seedu/address/logic/commands/SortCommand.java new file mode 100644 index 00000000000..8453fbe752c --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/SortCommand.java @@ -0,0 +1,22 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import seedu.address.model.Model; + +/** + * Sorts all clients in the address book to the user. + */ +public class SortCommand extends Command { + public static final String COMMAND_WORD = "sort"; + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Sorts all clients in the address book by alphabetical order."; + public static final String MESSAGE_SORTED_SUCCESS = "Clients sorted in alphabetical order."; + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + model.sortClients(); + return new CommandResult(MESSAGE_SORTED_SUCCESS); + } +} diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index ecb55c330c4..f4abc3aeaaf 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -20,6 +20,7 @@ import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.PriorityCommand; +import seedu.address.logic.commands.SortCommand; import seedu.address.logic.commands.UpdateClientCommand; import seedu.address.logic.parser.exceptions.ParseException; @@ -93,6 +94,9 @@ public Command parseCommand(String userInput) throws ParseException { case FindClientAndCommand.COMMAND_WORD: return new FindClientAndCommandParser().parse(arguments); + case SortCommand.COMMAND_WORD: + return new SortCommand(); + default: logger.finer("This user input caused a ParseException: " + userInput); throw new ParseException(MESSAGE_UNKNOWN_COMMAND); diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index 75b4611f35d..749d1328e3e 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -99,6 +99,11 @@ public void removeClient(Client key) { clients.remove(key); } + @Override + public void sortClients() { + clients.sort(); + } + /** * Returns a string representation of the address book. * diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index 70a893c5fc9..08392ee4157 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -69,6 +69,12 @@ public interface Model { */ void addClient(Client client); + /** + * Sorts all clients in the address book in alphabetical order. + * The sorted list of clients will be displayed to the user. + */ + void sortClients(); + /** * Replaces the given client {@code target} with {@code editedClient}. * {@code target} must exist in the address book. diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index c309b3115fc..b1411f4f9cd 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -104,6 +104,11 @@ public void addClient(Client client) { updateFilteredClientList(PREDICATE_SHOW_ALL_CLIENTS); } + @Override + public void sortClients() { + addressBook.sortClients(); + } + @Override public void setClient(Client target, Client editedClient) { requireAllNonNull(target, editedClient); diff --git a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java index 305685bf782..7fa44832287 100644 --- a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java +++ b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java @@ -8,6 +8,8 @@ */ public interface ReadOnlyAddressBook { + void sortClients(); + /** * Returns an unmodifiable view of the clients list. * This list will not contain any duplicate clients. diff --git a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java~ b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java~ new file mode 100644 index 00000000000..305685bf782 --- /dev/null +++ b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java~ @@ -0,0 +1,16 @@ +package seedu.address.model; + +import javafx.collections.ObservableList; +import seedu.address.model.client.Client; + +/** + * Unmodifiable view of an address book + */ +public interface ReadOnlyAddressBook { + + /** + * Returns an unmodifiable view of the clients list. + * This list will not contain any duplicate clients. + */ + ObservableList getClientList(); +} diff --git a/src/main/java/seedu/address/model/client/UniqueClientList.java b/src/main/java/seedu/address/model/client/UniqueClientList.java index 7f55ba3d81c..302c8c2055e 100644 --- a/src/main/java/seedu/address/model/client/UniqueClientList.java +++ b/src/main/java/seedu/address/model/client/UniqueClientList.java @@ -3,6 +3,7 @@ import static java.util.Objects.requireNonNull; import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; +import java.util.Comparator; import java.util.Iterator; import java.util.List; @@ -97,6 +98,10 @@ public void remove(Client toRemove) { } } + public void sort() { + internalList.sort(Comparator.comparing(client -> client.getName().fullName, String.CASE_INSENSITIVE_ORDER)); + } + /** * Returns the backing list as an unmodifiable {@code ObservableList}. */ diff --git a/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java b/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java index 7e33ac456db..58520fbbad5 100644 --- a/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java @@ -149,6 +149,11 @@ public void deleteClient(Client target) { throw new AssertionError("This method should not be called."); } + @Override + public void sortClients() { + throw new AssertionError("This method should not be called."); + } + @Override public ObservableList getFilteredClientList() { throw new AssertionError("This method should not be called."); diff --git a/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java~ b/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java~ new file mode 100644 index 00000000000..7e33ac456db --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java~ @@ -0,0 +1,205 @@ +package seedu.address.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.address.testutil.TypicalClients.ALICE; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.function.Predicate; + +import org.junit.jupiter.api.Test; + +import javafx.collections.ObservableList; +import seedu.address.commons.core.GuiSettings; +import seedu.address.logic.Messages; +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.client.Client; +import seedu.address.testutil.ClientBuilder; + +public class AddClientCommandTest { + + @Test + public void constructor_nullClient_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> new AddClientCommand(null)); + } + + @Test + public void execute_clientAcceptedByModel_addSuccessful() throws Exception { + ModelStubAcceptingClientAdded modelStub = new ModelStubAcceptingClientAdded(); + Client validClient = new ClientBuilder().build(); + + CommandResult commandResult = new AddClientCommand(validClient).execute(modelStub); + + assertEquals(String.format(AddClientCommand.MESSAGE_SUCCESS, Messages.format(validClient)), + commandResult.getFeedbackToUser()); + assertEquals(Arrays.asList(validClient), modelStub.clientsAdded); + } + + @Test + public void execute_duplicateClient_throwsCommandException() { + Client validClient = new ClientBuilder().build(); + AddClientCommand addCommand = new AddClientCommand(validClient); + ModelStub modelStub = new ModelStubWithClient(validClient); + + assertThrows(CommandException.class, + AddClientCommand.MESSAGE_DUPLICATE_CLIENT, () -> addCommand.execute(modelStub)); + } + + @Test + public void equals() { + Client alice = new ClientBuilder().withName("Alice").build(); + Client bob = new ClientBuilder().withName("Bob").build(); + AddClientCommand addAliceCommand = new AddClientCommand(alice); + AddClientCommand addBobCommand = new AddClientCommand(bob); + + // same object -> returns true + assertTrue(addAliceCommand.equals(addAliceCommand)); + + // same values -> returns true + AddClientCommand addAliceCommandCopy = new AddClientCommand(alice); + assertTrue(addAliceCommand.equals(addAliceCommandCopy)); + + // different types -> returns false + assertFalse(addAliceCommand.equals(1)); + + // null -> returns false + assertFalse(addAliceCommand.equals(null)); + + // different client -> returns false + assertFalse(addAliceCommand.equals(addBobCommand)); + } + + @Test + public void toStringMethod() { + AddClientCommand addCommand = new AddClientCommand(ALICE); + String expected = AddClientCommand.class.getCanonicalName() + "{toAdd=" + ALICE + "}"; + assertEquals(expected, addCommand.toString()); + } + + /** + * A default model stub that have all of the methods failing. + */ + private class ModelStub implements Model { + @Override + public void setUserPrefs(ReadOnlyUserPrefs userPrefs) { + throw new AssertionError("This method should not be called."); + } + + @Override + public ReadOnlyUserPrefs getUserPrefs() { + throw new AssertionError("This method should not be called."); + } + + @Override + public GuiSettings getGuiSettings() { + throw new AssertionError("This method should not be called."); + } + + @Override + public void setGuiSettings(GuiSettings guiSettings) { + throw new AssertionError("This method should not be called."); + } + + @Override + public Path getAddressBookFilePath() { + throw new AssertionError("This method should not be called."); + } + + @Override + public void setAddressBookFilePath(Path addressBookFilePath) { + throw new AssertionError("This method should not be called."); + } + + @Override + public void setAddressBook(ReadOnlyAddressBook newData) { + throw new AssertionError("This method should not be called."); + } + + @Override + public ReadOnlyAddressBook getAddressBook() { + throw new AssertionError("This method should not be called."); + } + + @Override + public boolean hasClient(Client client) { + throw new AssertionError("This method should not be called."); + } + + @Override + public void setClient(Client target, Client editedClient) { + throw new AssertionError("This method should not be called."); + } + + @Override + public void addClient(Client client) { + throw new AssertionError("This method should not be called."); + } + + @Override + public void deleteClient(Client target) { + throw new AssertionError("This method should not be called."); + } + + @Override + public ObservableList getFilteredClientList() { + throw new AssertionError("This method should not be called."); + } + + @Override + public void updateFilteredClientList(Predicate predicate) { + throw new AssertionError("This method should not be called."); + } + } + + /** + * A Model stub that contains a single client. + */ + private class ModelStubWithClient extends ModelStub { + private final Client client; + + ModelStubWithClient(Client client) { + requireNonNull(client); + this.client = client; + } + + @Override + public boolean hasClient(Client client) { + requireNonNull(client); + return this.client.isSameClient(client); + } + } + + /** + * A Model stub that always accept the client being added. + */ + private class ModelStubAcceptingClientAdded extends ModelStub { + final ArrayList clientsAdded = new ArrayList<>(); + + @Override + public boolean hasClient(Client client) { + requireNonNull(client); + return clientsAdded.stream().anyMatch(client::isSameClient); + } + + @Override + public void addClient(Client client) { + requireNonNull(client); + clientsAdded.add(client); + } + + @Override + public ReadOnlyAddressBook getAddressBook() { + return new AddressBook(); + } + } + +} diff --git a/src/test/java/seedu/address/logic/commands/SortCommandTest.java b/src/test/java/seedu/address/logic/commands/SortCommandTest.java new file mode 100644 index 00000000000..90e5c120905 --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/SortCommandTest.java @@ -0,0 +1,39 @@ +package seedu.address.logic.commands; + +import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.address.testutil.TypicalClients.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; + +/** + * Contains integration tests (interaction with the Model) and unit tests for SortCommand. + */ + +public class SortCommandTest { + + private Model model; + private Model expectedModel; + private SortCommand sortCommand; + + @BeforeEach + public void setUp() { + model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + sortCommand = new SortCommand(); + } + + /** + * Tests the execution of the SortCommand with all clients. + */ + @Test + public void execute_sort_allClients() { + expectedModel.sortClients(); + assertCommandSuccess(sortCommand, model, SortCommand.MESSAGE_SORTED_SUCCESS, expectedModel); + } + +} diff --git a/src/test/java/seedu/address/logic/commands/SortCommandTest.java~ b/src/test/java/seedu/address/logic/commands/SortCommandTest.java~ new file mode 100644 index 00000000000..df96e063706 --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/SortCommandTest.java~ @@ -0,0 +1,40 @@ +package seedu.address.logic.commands; + +import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.address.testutil.TypicalClients.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; + +/** + * Contains integration tests (interaction with the Model) and unit tests for SortCommand. + */ + +public class SortCommandTest { + + private Model model; + private Model expectedModel; + private SortCommand sortCommand; + + @BeforeEach + public void setUp() { + model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + sortCommand = new SortCommand(); + } + + /** + * Tests the execution of the SortCommand with all clients. + */ + @Test + public void execute_sort_allClients() { + expectedModel.sortClients(); + CommandResult result = sortCommand.execute(model); + assertCommandSuccess(sortCommand, model, SortCommand.MESSAGE_SORTED_SUCCESS, expectedModel); + } + +} diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index b7e1e7a761b..31c1eea7771 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -25,6 +25,7 @@ import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.PriorityCommand; +import seedu.address.logic.commands.SortCommand; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.client.Client; import seedu.address.model.client.ContainsAllKeywordsPredicate; @@ -116,6 +117,12 @@ public void parseCommand_priority() throws Exception { assertEquals(new PriorityCommand(INDEX_FIRST_CLIENT), command); } + @Test + public void parseCommand_sort() throws Exception { + assertTrue(parser.parseCommand(SortCommand.COMMAND_WORD) instanceof SortCommand); + assertTrue(parser.parseCommand(SortCommand.COMMAND_WORD + " 3") instanceof SortCommand); + } + @Test public void parseCommand_unrecognisedInput_throwsParseException() { assertThrows(ParseException.class, String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE), () diff --git a/src/test/java/seedu/address/model/AddressBookTest.java b/src/test/java/seedu/address/model/AddressBookTest.java index 0f8e13c1bec..270836d7704 100644 --- a/src/test/java/seedu/address/model/AddressBookTest.java +++ b/src/test/java/seedu/address/model/AddressBookTest.java @@ -12,6 +12,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.List; import org.junit.jupiter.api.Test; @@ -103,6 +104,11 @@ private static class AddressBookStub implements ReadOnlyAddressBook { public ObservableList getClientList() { return clients; } + + @Override + public void sortClients() { + clients.sort(Comparator.comparing(client -> client.getName().fullName)); + } } } diff --git a/src/test/java/seedu/address/testutil/ModelStub.java b/src/test/java/seedu/address/testutil/ModelStub.java index 71a711a7093..76f74ac8de3 100644 --- a/src/test/java/seedu/address/testutil/ModelStub.java +++ b/src/test/java/seedu/address/testutil/ModelStub.java @@ -69,6 +69,11 @@ public void deleteClient(Client target) { throw new AssertionError("This method should not be called."); } + @Override + public void sortClients() { + throw new AssertionError("This method should not be called."); + } + @Override public void setClient(Client target, Client editedClient) { throw new AssertionError("This method should not be called."); From 201502231d0c03cd698ad5514ba2d00160a6ab5e Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Thu, 27 Mar 2025 01:55:26 +0800 Subject: [PATCH 105/249] Add policy command --- .../logic/commands/AddClientCommand.java | 7 +- .../logic/commands/AddPolicyCommand.java | 92 ++++++++++++ .../logic/parser/AddPolicyCommandParser.java | 60 ++++++++ .../logic/parser/AddressBookParser.java | 5 + .../java/seedu/address/model/tag/Tag.java | 3 +- .../address/model/util/SampleDataUtil.java | 25 ++-- .../logic/commands/AddPolicyCommandTest.java | 138 ++++++++++++++++++ .../parser/AddPolicyCommandParserTest.java | 76 ++++++++++ 8 files changed, 390 insertions(+), 16 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/AddPolicyCommand.java create mode 100644 src/main/java/seedu/address/logic/parser/AddPolicyCommandParser.java create mode 100644 src/test/java/seedu/address/logic/commands/AddPolicyCommandTest.java create mode 100644 src/test/java/seedu/address/logic/parser/AddPolicyCommandParserTest.java diff --git a/src/main/java/seedu/address/logic/commands/AddClientCommand.java b/src/main/java/seedu/address/logic/commands/AddClientCommand.java index 8890543590b..1f079a6a4ba 100644 --- a/src/main/java/seedu/address/logic/commands/AddClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddClientCommand.java @@ -26,14 +26,14 @@ public class AddClientCommand extends Command { + PREFIX_PHONE + "PHONE " + PREFIX_EMAIL + "EMAIL " + PREFIX_ADDRESS + "ADDRESS " - + "[" + PREFIX_TAG + "TAG]...\n" + + "[" + PREFIX_TAG + "POLICY_TAG]...\n" + "Example: " + COMMAND_WORD + " " + PREFIX_NAME + "John Wilson " + PREFIX_PHONE + "91234567 " + PREFIX_EMAIL + "johnw@example.com " + PREFIX_ADDRESS + "210, Clementi Ave 3, #12-01 " - + PREFIX_TAG + "friends " - + PREFIX_TAG + "owesMoney"; + + PREFIX_TAG + "Travel Policy 21 " + + PREFIX_TAG + "Health Policy 03"; public static final String MESSAGE_SUCCESS = "New client added: %1$s"; public static final String MESSAGE_DUPLICATE_CLIENT = "This client already exists in WealthVault"; @@ -82,3 +82,4 @@ public String toString() { .toString(); } } + diff --git a/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java b/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java new file mode 100644 index 00000000000..f6b02a7b535 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java @@ -0,0 +1,92 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import java.util.HashSet; +import java.util.Set; + +import seedu.address.commons.core.index.Index; +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.client.Client; +import seedu.address.model.tag.Tag; + +/** + * Adds policies to an existing client by their index. + */ +public class AddPolicyCommand extends Command { + + public static final String COMMAND_WORD = "addpolicy"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Adds policies to an existing client identified by index. " + + "Parameters: INDEX POLICY [MORE_POLICIES]...\n" + + "Example: " + COMMAND_WORD + " 1 t/Life Insurance t/Health Insurance"; + + public static final String MESSAGE_SUCCESS = "Policies added to client: %1$s"; + public static final String MESSAGE_CLIENT_NOT_FOUND = "Client with the given index does not exist."; + + private final Index clientIndex; + private final Set policiesToAdd; + + /** + * Creates an AddPolicyCommand to add the specified policies to a client by index. + */ + public AddPolicyCommand(Index clientIndex, Set policies) { + requireNonNull(clientIndex); + requireNonNull(policies); + this.clientIndex = clientIndex; + this.policiesToAdd = new HashSet<>(policies); + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + // Check if the index is valid + if (clientIndex.getZeroBased() >= model.getFilteredClientList().size()) { + throw new CommandException(MESSAGE_CLIENT_NOT_FOUND); + } + + Client clientToEdit = model.getFilteredClientList().get(clientIndex.getZeroBased()); + + Set updatedPolicies = new HashSet<>(clientToEdit.getTags()); + updatedPolicies.addAll(policiesToAdd); + + Client updatedClient = new Client( + clientToEdit.getName(), + clientToEdit.getPhone(), + clientToEdit.getEmail(), + clientToEdit.getAddress(), + updatedPolicies + ); + + model.setClient(clientToEdit, updatedClient); + return new CommandResult(String.format(MESSAGE_SUCCESS, Messages.format(updatedClient))); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof AddPolicyCommand)) { + return false; + } + + AddPolicyCommand otherCommand = (AddPolicyCommand) other; + return clientIndex.equals(otherCommand.clientIndex) && policiesToAdd.equals(otherCommand.policiesToAdd); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("clientIndex", clientIndex) + .add("policiesToAdd", policiesToAdd) + .toString(); + } +} + diff --git a/src/main/java/seedu/address/logic/parser/AddPolicyCommandParser.java b/src/main/java/seedu/address/logic/parser/AddPolicyCommandParser.java new file mode 100644 index 00000000000..0263e57fb28 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/AddPolicyCommandParser.java @@ -0,0 +1,60 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; + +import java.util.Set; +import java.util.stream.Stream; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.AddPolicyCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.tag.Tag; + +/** + * Parses input arguments and creates a new AddPolicyCommand object. + */ +public class AddPolicyCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the AddPolicyCommand + * and returns an AddPolicyCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public AddPolicyCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_TAG); + + if (!arePrefixesPresent(argMultimap, PREFIX_TAG) || argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddPolicyCommand.MESSAGE_USAGE)); + } + + try { + // Parse the index of the client + Index index = ParserUtil.parseIndex(argMultimap.getPreamble()); + + // Parse policies + Set policies = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); + + // Check if policies are provided + if (policies.isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddPolicyCommand.MESSAGE_USAGE)); + } + + // Return the AddPolicyCommand object + return new AddPolicyCommand(index, policies); + + } catch (ParseException pe) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddPolicyCommand.MESSAGE_USAGE), pe); + } + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } +} + diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index ecb55c330c4..36be25e07e3 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -9,6 +9,7 @@ import seedu.address.commons.core.LogsCenter; import seedu.address.logic.commands.AddClientCommand; +import seedu.address.logic.commands.AddPolicyCommand; import seedu.address.logic.commands.ClearCommand; import seedu.address.logic.commands.Command; import seedu.address.logic.commands.DeleteClientCommand; @@ -60,6 +61,9 @@ public Command parseCommand(String userInput) throws ParseException { case AddClientCommand.COMMAND_WORD: return new AddClientCommandParser().parse(arguments); + case AddPolicyCommand.COMMAND_WORD: + return new AddPolicyCommandParser().parse(arguments); + case EditCommand.COMMAND_WORD: return new EditCommandParser().parse(arguments); @@ -100,3 +104,4 @@ public Command parseCommand(String userInput) throws ParseException { } } + diff --git a/src/main/java/seedu/address/model/tag/Tag.java b/src/main/java/seedu/address/model/tag/Tag.java index 5e54a9afa34..1bab95e1d60 100644 --- a/src/main/java/seedu/address/model/tag/Tag.java +++ b/src/main/java/seedu/address/model/tag/Tag.java @@ -10,7 +10,7 @@ public class Tag { public static final String MESSAGE_CONSTRAINTS = "Tag names should be alphanumeric"; - public static final String VALIDATION_REGEX = "\\p{Alnum}+"; + public static final String VALIDATION_REGEX = "^[\\p{Alnum} ]+$"; public final String tagName; @@ -63,3 +63,4 @@ public boolean isEqualTo(String string) { return tagName.equals(string); } } + diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index c1423ed4910..ce812090334 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -21,23 +21,23 @@ public class SampleDataUtil { public static Client[] getSampleClients() { return new Client[] { new Client(new Name("Alex Yeoh"), new Phone("87438807"), new Email("alexyeoh@example.com"), - new Address("Blk 30 Geylang Street 29, #06-40"), - getTagSet("friends")), + new Address("Blk 30 Geylang Street 29, #06-40"), + getTagSet("Policy A")), new Client(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 Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"), + getTagSet("Policy B", "Policy C")), new Client(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 Address("Blk 11 Ang Mo Kio Street 74, #11-04"), + getTagSet("Policy A")), new Client(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 Address("Blk 436 Serangoon Gardens Street 26, #16-43"), + getTagSet("Policy A")), new Client(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"), - new Address("Blk 47 Tampines Street 20, #17-35"), - getTagSet("classmates")), + new Address("Blk 47 Tampines Street 20, #17-35"), + getTagSet("Policy B")), new Client(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"), - new Address("Blk 45 Aljunied Street 85, #11-31"), - getTagSet("colleagues")) + new Address("Blk 45 Aljunied Street 85, #11-31"), + getTagSet("Policy C")) }; } @@ -59,3 +59,4 @@ public static Set getTagSet(String... strings) { } } + diff --git a/src/test/java/seedu/address/logic/commands/AddPolicyCommandTest.java b/src/test/java/seedu/address/logic/commands/AddPolicyCommandTest.java new file mode 100644 index 00000000000..e8d9d1f4648 --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/AddPolicyCommandTest.java @@ -0,0 +1,138 @@ +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.assertCommandFailure; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.address.testutil.TypicalClients.getTypicalAddressBook; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_CLIENT; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_CLIENT; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.Messages; +import seedu.address.model.Model; +import seedu.address.model.ModelManager; +import seedu.address.model.UserPrefs; +import seedu.address.model.client.Client; +import seedu.address.model.tag.Tag; + +/** + * Contains integration tests (interaction with the Model) and unit tests for {@code AddPolicyCommand}. + */ +public class AddPolicyCommandTest { + + private Model model; + + @BeforeEach + public void setUp() { + model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + } + + @Test + public void execute_addPolicyToExistingClient_success() { + Client clientToEdit = model.getFilteredClientList().get(INDEX_FIRST_CLIENT.getZeroBased()); + + // Creating new policies to add + Set policiesToAdd = new HashSet<>(); + policiesToAdd.add(new Tag("Life Insurance")); + policiesToAdd.add(new Tag("Health Insurance")); + + AddPolicyCommand addPolicyCommand = new AddPolicyCommand(INDEX_FIRST_CLIENT, policiesToAdd); + + Set updatedPolicies = new HashSet<>(clientToEdit.getTags()); + updatedPolicies.addAll(policiesToAdd); + + Client expectedClient = new Client( + clientToEdit.getName(), + clientToEdit.getPhone(), + clientToEdit.getEmail(), + clientToEdit.getAddress(), + updatedPolicies + ); + + Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + expectedModel.setClient(clientToEdit, expectedClient); + + String expectedMessage = String.format(AddPolicyCommand.MESSAGE_SUCCESS, Messages.format(expectedClient)); + + assertCommandSuccess(addPolicyCommand, model, expectedMessage, expectedModel); + } + + @Test + public void execute_invalidClientIndex_throwsCommandException() { + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredClientList().size() + 1); + Set policiesToAdd = new HashSet<>(); + policiesToAdd.add(new Tag("Life Insurance")); + + AddPolicyCommand addPolicyCommand = new AddPolicyCommand(outOfBoundIndex, policiesToAdd); + + assertCommandFailure(addPolicyCommand, model, AddPolicyCommand.MESSAGE_CLIENT_NOT_FOUND); + } + + @Test + public void execute_addExistingPolicyToClient_success() { + Client clientToEdit = model.getFilteredClientList().get(INDEX_SECOND_CLIENT.getZeroBased()); + + // Get an existing policy from the client + Set existingPolicies = new HashSet<>(clientToEdit.getTags()); + Tag existingPolicy = existingPolicies.iterator().next(); // Assume the client has at least one policy + + Set policiesToAdd = new HashSet<>(); + policiesToAdd.add(existingPolicy); // Trying to re-add the same policy + + AddPolicyCommand addPolicyCommand = new AddPolicyCommand(INDEX_SECOND_CLIENT, policiesToAdd); + + Client expectedClient = new Client( + clientToEdit.getName(), + clientToEdit.getPhone(), + clientToEdit.getEmail(), + clientToEdit.getAddress(), + existingPolicies // No change since we're adding the same policy + ); + + Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + expectedModel.setClient(clientToEdit, expectedClient); + + String expectedMessage = String.format(AddPolicyCommand.MESSAGE_SUCCESS, Messages.format(expectedClient)); + + assertCommandSuccess(addPolicyCommand, model, expectedMessage, expectedModel); + } + + @Test + public void equals() { + Set policiesA = new HashSet<>(); + policiesA.add(new Tag("Policy A")); + Set policiesB = new HashSet<>(); + policiesB.add(new Tag("Policy B")); + + AddPolicyCommand addPolicyFirstCommand = new AddPolicyCommand(INDEX_FIRST_CLIENT, policiesA); + AddPolicyCommand addPolicySecondCommand = new AddPolicyCommand(INDEX_SECOND_CLIENT, policiesB); + + // Same object -> returns true + assertTrue(addPolicyFirstCommand.equals(addPolicyFirstCommand)); + + // Same values -> returns true + AddPolicyCommand addPolicyFirstCommandCopy = new AddPolicyCommand(INDEX_FIRST_CLIENT, policiesA); + assertTrue(addPolicyFirstCommand.equals(addPolicyFirstCommandCopy)); + + // Different types -> returns false + assertFalse(addPolicyFirstCommand.equals(1)); + + // Different index -> returns false + assertFalse(addPolicyFirstCommand.equals(addPolicySecondCommand)); + + // Different policies -> returns false + AddPolicyCommand addPolicyDifferentPolicyCommand = new AddPolicyCommand(INDEX_FIRST_CLIENT, policiesB); + assertFalse(addPolicyFirstCommand.equals(addPolicyDifferentPolicyCommand)); + + // Null -> returns false + assertFalse(addPolicyFirstCommand.equals(null)); + } +} + diff --git a/src/test/java/seedu/address/logic/parser/AddPolicyCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddPolicyCommandParserTest.java new file mode 100644 index 00000000000..96c8925197d --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/AddPolicyCommandParserTest.java @@ -0,0 +1,76 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +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_CLIENT; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_CLIENT; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import seedu.address.logic.commands.AddPolicyCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.tag.Tag; + +public class AddPolicyCommandParserTest { + + private AddPolicyCommandParser parser = new AddPolicyCommandParser(); + + @Test + public void parse_allFieldsPresent_success() throws ParseException { + // Prepare the expected tags and client index + Set policiesToAdd = new HashSet<>(); + policiesToAdd.add(new Tag("Health")); + policiesToAdd.add(new Tag("Life")); + + assertParseSuccess(parser, "1 " + PREFIX_TAG + "Health " + PREFIX_TAG + "Life", + new AddPolicyCommand(INDEX_FIRST_CLIENT, policiesToAdd)); + } + + @Test + public void parse_multipleTags_success() throws ParseException { + Set policiesToAdd = new HashSet<>(); + policiesToAdd.add(new Tag("Health")); + policiesToAdd.add(new Tag("Life")); + policiesToAdd.add(new Tag("Travel")); + + assertParseSuccess(parser, "1 " + PREFIX_TAG + "Health " + PREFIX_TAG + "Life " + PREFIX_TAG + "Travel", + new AddPolicyCommand(INDEX_FIRST_CLIENT, policiesToAdd)); + } + + @Test + public void parse_missingPolicy_throwsParseException() { + assertParseFailure(parser, "1", String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddPolicyCommand.MESSAGE_USAGE)); + } + + @Test + public void parse_invalidClientIndex_throwsParseException() { + assertParseFailure(parser, "abc " + PREFIX_TAG + "Health", + String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddPolicyCommand.MESSAGE_USAGE)); + } + + @Test + public void parse_nonEmptyPreamble_throwsParseException() { + assertParseFailure(parser, "ExtraText 1 " + PREFIX_TAG + "Health", + String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddPolicyCommand.MESSAGE_USAGE)); + } + + @Test + public void parse_emptyCommand_throwsParseException() { + assertParseFailure(parser, "", String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddPolicyCommand.MESSAGE_USAGE)); + } + + @Test + public void parse_validClientWithSinglePolicy_success() throws ParseException { + Set policiesToAdd = new HashSet<>(); + policiesToAdd.add(new Tag("Health")); + + assertParseSuccess(parser, "2 " + PREFIX_TAG + "Health", + new AddPolicyCommand(INDEX_SECOND_CLIENT, policiesToAdd)); + } +} + From a3dc34aabc520c88a5876091a137146bf342361d Mon Sep 17 00:00:00 2001 From: Nicholas Foo Date: Thu, 27 Mar 2025 02:12:10 +0800 Subject: [PATCH 106/249] Remove editor backup files and update .gitignore --- .gitignore | 3 + .../address/model/ReadOnlyAddressBook.java~ | 16 -- .../logic/commands/AddClientCommandTest.java~ | 205 ------------------ .../logic/commands/SortCommandTest.java~ | 40 ---- 4 files changed, 3 insertions(+), 261 deletions(-) delete mode 100644 src/main/java/seedu/address/model/ReadOnlyAddressBook.java~ delete mode 100644 src/test/java/seedu/address/logic/commands/AddClientCommandTest.java~ delete mode 100644 src/test/java/seedu/address/logic/commands/SortCommandTest.java~ diff --git a/.gitignore b/.gitignore index d69d8b814ec..a7e7e8aa5b8 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,6 @@ src/test/data/sandbox/ docs/_site/ docs/_markbind/logs/ node_modules + +# Ignore editor backup files +*~ \ No newline at end of file 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 305685bf782..00000000000 --- a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java~ +++ /dev/null @@ -1,16 +0,0 @@ -package seedu.address.model; - -import javafx.collections.ObservableList; -import seedu.address.model.client.Client; - -/** - * Unmodifiable view of an address book - */ -public interface ReadOnlyAddressBook { - - /** - * Returns an unmodifiable view of the clients list. - * This list will not contain any duplicate clients. - */ - ObservableList getClientList(); -} diff --git a/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java~ b/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java~ deleted file mode 100644 index 7e33ac456db..00000000000 --- a/src/test/java/seedu/address/logic/commands/AddClientCommandTest.java~ +++ /dev/null @@ -1,205 +0,0 @@ -package seedu.address.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.address.testutil.TypicalClients.ALICE; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.function.Predicate; - -import org.junit.jupiter.api.Test; - -import javafx.collections.ObservableList; -import seedu.address.commons.core.GuiSettings; -import seedu.address.logic.Messages; -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.client.Client; -import seedu.address.testutil.ClientBuilder; - -public class AddClientCommandTest { - - @Test - public void constructor_nullClient_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> new AddClientCommand(null)); - } - - @Test - public void execute_clientAcceptedByModel_addSuccessful() throws Exception { - ModelStubAcceptingClientAdded modelStub = new ModelStubAcceptingClientAdded(); - Client validClient = new ClientBuilder().build(); - - CommandResult commandResult = new AddClientCommand(validClient).execute(modelStub); - - assertEquals(String.format(AddClientCommand.MESSAGE_SUCCESS, Messages.format(validClient)), - commandResult.getFeedbackToUser()); - assertEquals(Arrays.asList(validClient), modelStub.clientsAdded); - } - - @Test - public void execute_duplicateClient_throwsCommandException() { - Client validClient = new ClientBuilder().build(); - AddClientCommand addCommand = new AddClientCommand(validClient); - ModelStub modelStub = new ModelStubWithClient(validClient); - - assertThrows(CommandException.class, - AddClientCommand.MESSAGE_DUPLICATE_CLIENT, () -> addCommand.execute(modelStub)); - } - - @Test - public void equals() { - Client alice = new ClientBuilder().withName("Alice").build(); - Client bob = new ClientBuilder().withName("Bob").build(); - AddClientCommand addAliceCommand = new AddClientCommand(alice); - AddClientCommand addBobCommand = new AddClientCommand(bob); - - // same object -> returns true - assertTrue(addAliceCommand.equals(addAliceCommand)); - - // same values -> returns true - AddClientCommand addAliceCommandCopy = new AddClientCommand(alice); - assertTrue(addAliceCommand.equals(addAliceCommandCopy)); - - // different types -> returns false - assertFalse(addAliceCommand.equals(1)); - - // null -> returns false - assertFalse(addAliceCommand.equals(null)); - - // different client -> returns false - assertFalse(addAliceCommand.equals(addBobCommand)); - } - - @Test - public void toStringMethod() { - AddClientCommand addCommand = new AddClientCommand(ALICE); - String expected = AddClientCommand.class.getCanonicalName() + "{toAdd=" + ALICE + "}"; - assertEquals(expected, addCommand.toString()); - } - - /** - * A default model stub that have all of the methods failing. - */ - private class ModelStub implements Model { - @Override - public void setUserPrefs(ReadOnlyUserPrefs userPrefs) { - throw new AssertionError("This method should not be called."); - } - - @Override - public ReadOnlyUserPrefs getUserPrefs() { - throw new AssertionError("This method should not be called."); - } - - @Override - public GuiSettings getGuiSettings() { - throw new AssertionError("This method should not be called."); - } - - @Override - public void setGuiSettings(GuiSettings guiSettings) { - throw new AssertionError("This method should not be called."); - } - - @Override - public Path getAddressBookFilePath() { - throw new AssertionError("This method should not be called."); - } - - @Override - public void setAddressBookFilePath(Path addressBookFilePath) { - throw new AssertionError("This method should not be called."); - } - - @Override - public void setAddressBook(ReadOnlyAddressBook newData) { - throw new AssertionError("This method should not be called."); - } - - @Override - public ReadOnlyAddressBook getAddressBook() { - throw new AssertionError("This method should not be called."); - } - - @Override - public boolean hasClient(Client client) { - throw new AssertionError("This method should not be called."); - } - - @Override - public void setClient(Client target, Client editedClient) { - throw new AssertionError("This method should not be called."); - } - - @Override - public void addClient(Client client) { - throw new AssertionError("This method should not be called."); - } - - @Override - public void deleteClient(Client target) { - throw new AssertionError("This method should not be called."); - } - - @Override - public ObservableList getFilteredClientList() { - throw new AssertionError("This method should not be called."); - } - - @Override - public void updateFilteredClientList(Predicate predicate) { - throw new AssertionError("This method should not be called."); - } - } - - /** - * A Model stub that contains a single client. - */ - private class ModelStubWithClient extends ModelStub { - private final Client client; - - ModelStubWithClient(Client client) { - requireNonNull(client); - this.client = client; - } - - @Override - public boolean hasClient(Client client) { - requireNonNull(client); - return this.client.isSameClient(client); - } - } - - /** - * A Model stub that always accept the client being added. - */ - private class ModelStubAcceptingClientAdded extends ModelStub { - final ArrayList clientsAdded = new ArrayList<>(); - - @Override - public boolean hasClient(Client client) { - requireNonNull(client); - return clientsAdded.stream().anyMatch(client::isSameClient); - } - - @Override - public void addClient(Client client) { - requireNonNull(client); - clientsAdded.add(client); - } - - @Override - public ReadOnlyAddressBook getAddressBook() { - return new AddressBook(); - } - } - -} diff --git a/src/test/java/seedu/address/logic/commands/SortCommandTest.java~ b/src/test/java/seedu/address/logic/commands/SortCommandTest.java~ deleted file mode 100644 index df96e063706..00000000000 --- a/src/test/java/seedu/address/logic/commands/SortCommandTest.java~ +++ /dev/null @@ -1,40 +0,0 @@ -package seedu.address.logic.commands; - -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.testutil.TypicalClients.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; - -/** - * Contains integration tests (interaction with the Model) and unit tests for SortCommand. - */ - -public class SortCommandTest { - - private Model model; - private Model expectedModel; - private SortCommand sortCommand; - - @BeforeEach - public void setUp() { - model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); - expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); - sortCommand = new SortCommand(); - } - - /** - * Tests the execution of the SortCommand with all clients. - */ - @Test - public void execute_sort_allClients() { - expectedModel.sortClients(); - CommandResult result = sortCommand.execute(model); - assertCommandSuccess(sortCommand, model, SortCommand.MESSAGE_SORTED_SUCCESS, expectedModel); - } - -} From 23a1f074dd90bced16230dc5452723ab7fb34152 Mon Sep 17 00:00:00 2001 From: Nicholas Foo Date: Thu, 27 Mar 2025 02:15:58 +0800 Subject: [PATCH 107/249] Add newline for .gitignore file --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a7e7e8aa5b8..2878bdb26ec 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,4 @@ docs/_markbind/logs/ node_modules # Ignore editor backup files -*~ \ No newline at end of file +*~ From 944d07913089aabb9291bd863f514bf4ea63175c Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Thu, 27 Mar 2025 08:47:35 +0800 Subject: [PATCH 108/249] Make small edit --- .../logic/commands/AddPolicyCommandTest.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/test/java/seedu/address/logic/commands/AddPolicyCommandTest.java b/src/test/java/seedu/address/logic/commands/AddPolicyCommandTest.java index e8d9d1f4648..6222febc640 100644 --- a/src/test/java/seedu/address/logic/commands/AddPolicyCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddPolicyCommandTest.java @@ -1,5 +1,6 @@ package seedu.address.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.logic.commands.CommandTestUtil.assertCommandFailure; @@ -15,6 +16,7 @@ import org.junit.jupiter.api.Test; import seedu.address.commons.core.index.Index; +import seedu.address.commons.util.ToStringBuilder; import seedu.address.logic.Messages; import seedu.address.model.Model; import seedu.address.model.ModelManager; @@ -134,5 +136,20 @@ public void equals() { // Null -> returns false assertFalse(addPolicyFirstCommand.equals(null)); } -} + @Test + public void toStringMethod() { + Set policies = new HashSet<>(); + policies.add(new Tag("Life Insurance")); + policies.add(new Tag("Health Insurance")); + + AddPolicyCommand addPolicyCommand = new AddPolicyCommand(INDEX_FIRST_CLIENT, policies); + + String expectedString = new ToStringBuilder(addPolicyCommand) + .add("clientIndex", INDEX_FIRST_CLIENT) + .add("policiesToAdd", policies) + .toString(); + + assertEquals(expectedString, addPolicyCommand.toString()); + } +} From a17719d83251e9a27878d6c8a62dd0a8396bc741 Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Thu, 27 Mar 2025 09:05:38 +0800 Subject: [PATCH 109/249] Add test case for AddPolicyCommand --- .../address/logic/commands/AddPolicyCommand.java | 5 +++-- .../address/logic/parser/AddressBookParserTest.java | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java b/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java index f6b02a7b535..83e150f1cc7 100644 --- a/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java @@ -21,8 +21,9 @@ public class AddPolicyCommand extends Command { public static final String COMMAND_WORD = "addpolicy"; public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Adds policies to an existing client identified by index. " - + "Parameters: INDEX POLICY [MORE_POLICIES]...\n" + + ": Adds policies to an existing client identified by " + + "the index number used in the displayed client list." + + "Parameters: INDEX (MUST BE A POSITIVE INTEGER) POLICY [MORE_POLICIES]...\n" + "Example: " + COMMAND_WORD + " 1 t/Life Insurance t/Health Insurance"; public static final String MESSAGE_SUCCESS = "Policies added to client: %1$s"; diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index b7e1e7a761b..b6110096b6c 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -9,11 +9,13 @@ import java.util.Arrays; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import org.junit.jupiter.api.Test; import seedu.address.logic.commands.AddClientCommand; +import seedu.address.logic.commands.AddPolicyCommand; import seedu.address.logic.commands.ClearCommand; import seedu.address.logic.commands.DeleteClientCommand; import seedu.address.logic.commands.EditCommand; @@ -30,6 +32,7 @@ import seedu.address.model.client.ContainsAllKeywordsPredicate; import seedu.address.model.client.ContainsKeywordsPredicate; import seedu.address.model.client.NameContainsKeywordsPredicate; +import seedu.address.model.tag.Tag; import seedu.address.testutil.ClientBuilder; import seedu.address.testutil.ClientUtil; import seedu.address.testutil.EditClientDescriptorBuilder; @@ -116,6 +119,15 @@ public void parseCommand_priority() throws Exception { assertEquals(new PriorityCommand(INDEX_FIRST_CLIENT), command); } + @Test + public void parseCommand_addPolicy() throws Exception { + Set policies = Set.of(new Tag("Life Insurance"), new Tag("Health Insurance")); + AddPolicyCommand command = (AddPolicyCommand) parser.parseCommand( + AddPolicyCommand.COMMAND_WORD + " " + INDEX_FIRST_CLIENT.getOneBased() + + " t/Life Insurance t/Health Insurance"); + assertEquals(new AddPolicyCommand(INDEX_FIRST_CLIENT, policies), command); + } + @Test public void parseCommand_unrecognisedInput_throwsParseException() { assertThrows(ParseException.class, String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE), () From 14c4a9da2aa0b88b8ddf2b150392be02014182c2 Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Thu, 27 Mar 2025 09:23:34 +0800 Subject: [PATCH 110/249] Make minor edits --- .../java/seedu/address/logic/commands/AddPolicyCommand.java | 4 ++-- .../seedu/address/logic/commands/DeleteClientCommand.java | 3 ++- src/main/java/seedu/address/logic/commands/DeleteCommand.java | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java b/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java index 83e150f1cc7..0189c804d1e 100644 --- a/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java @@ -21,8 +21,8 @@ public class AddPolicyCommand extends Command { public static final String COMMAND_WORD = "addpolicy"; public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Adds policies to an existing client identified by " - + "the index number used in the displayed client list." + + ": Adds policies to an existing client identified by the user-inputted index number. " + + "The index number must be based on the displayed client list." + "Parameters: INDEX (MUST BE A POSITIVE INTEGER) POLICY [MORE_POLICIES]...\n" + "Example: " + COMMAND_WORD + " 1 t/Life Insurance t/Health Insurance"; diff --git a/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java b/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java index a9139c83513..31dec2ac294 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteClientCommand.java @@ -19,7 +19,8 @@ public class DeleteClientCommand extends DeleteCommand { public static final String COMMAND_WORD = "deleteclient"; public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Deletes the client identified by the index number used in the displayed client list.\n" + + ": Deletes an existing client identified by the user-inputted index number. " + + "The index number must be based on the displayed client list.\n" + "Parameters: INDEX (must be a positive integer)\n" + "Example: " + COMMAND_WORD + " 1"; diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java index 5e973e0aac1..8fcbeee7d6c 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteCommand.java @@ -11,7 +11,8 @@ public abstract class DeleteCommand extends Command { public static final String COMMAND_WORD = "delete"; public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Deletes the client identified by the index number used in the displayed client list.\n" + + ": Deletes based on the user-inputted index number. " + + "The index must be based on the displayed list.\n" + "Parameters: INDEX (must be a positive integer)\n" + "Example: " + COMMAND_WORD + " 1"; From 8a4346c9ee240958eddfb75b6822fd7fe1010d57 Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Thu, 27 Mar 2025 09:33:56 +0800 Subject: [PATCH 111/249] Make slight edit to sample --- src/main/java/seedu/address/model/util/SampleDataUtil.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index ce812090334..2d7f12735b7 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -35,9 +35,6 @@ public static Client[] getSampleClients() { new Client(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"), new Address("Blk 47 Tampines Street 20, #17-35"), getTagSet("Policy B")), - new Client(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"), - new Address("Blk 45 Aljunied Street 85, #11-31"), - getTagSet("Policy C")) }; } From 206eb091374b2b70f5694363ec3800de2dd30a1c Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Thu, 27 Mar 2025 09:36:59 +0800 Subject: [PATCH 112/249] Make minor edit to sample --- .../java/seedu/address/model/util/SampleDataUtil.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index 2d7f12735b7..01287fb7525 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -28,13 +28,7 @@ public static Client[] getSampleClients() { getTagSet("Policy B", "Policy C")), new Client(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Email("charlotte@example.com"), new Address("Blk 11 Ang Mo Kio Street 74, #11-04"), - getTagSet("Policy A")), - new Client(new Name("David Li"), new Phone("91031282"), new Email("lidavid@example.com"), - new Address("Blk 436 Serangoon Gardens Street 26, #16-43"), - getTagSet("Policy A")), - new Client(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"), - new Address("Blk 47 Tampines Street 20, #17-35"), - getTagSet("Policy B")), + getTagSet("Policy A")) }; } From 5cf992f0a64aa367b4ce82425e07d07cd3f7c20f Mon Sep 17 00:00:00 2001 From: Nicholas Foo <132979537+FooNicholas@users.noreply.github.com> Date: Thu, 27 Mar 2025 10:46:42 +0800 Subject: [PATCH 113/249] Update SortCommand.java --- src/main/java/seedu/address/logic/commands/SortCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/SortCommand.java b/src/main/java/seedu/address/logic/commands/SortCommand.java index 8453fbe752c..25574bd4fa2 100644 --- a/src/main/java/seedu/address/logic/commands/SortCommand.java +++ b/src/main/java/seedu/address/logic/commands/SortCommand.java @@ -5,12 +5,12 @@ import seedu.address.model.Model; /** - * Sorts all clients in the address book to the user. + * Sorts all clients on the GUI in case-insensitive alphabetical order for the user. */ public class SortCommand extends Command { public static final String COMMAND_WORD = "sort"; public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Sorts all clients in the address book by alphabetical order."; + + ": Sorts all clients in WealthVault by case-insensitive alphabetical order."; public static final String MESSAGE_SORTED_SUCCESS = "Clients sorted in alphabetical order."; @Override From 19f0bb7a3acb527fec3d64a51e93fd7119ad03a3 Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Thu, 27 Mar 2025 17:00:46 +0800 Subject: [PATCH 114/249] add delete policy command edits --- .../logic/commands/DeletePolicyCommand.java | 98 ++++++++++++ .../logic/parser/AddressBookParser.java | 4 + .../parser/DeletePolicyCommandParser.java | 60 ++++++++ .../commands/DeletePolicyCommandTest.java | 141 ++++++++++++++++++ .../logic/parser/AddressBookParserTest.java | 10 ++ .../parser/DeletePolicyCommandParserTest.java | 78 ++++++++++ 6 files changed, 391 insertions(+) create mode 100644 src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java create mode 100644 src/main/java/seedu/address/logic/parser/DeletePolicyCommandParser.java create mode 100644 src/test/java/seedu/address/logic/commands/DeletePolicyCommandTest.java create mode 100644 src/test/java/seedu/address/logic/parser/DeletePolicyCommandParserTest.java diff --git a/src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java b/src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java new file mode 100644 index 00000000000..7d66f881ca6 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java @@ -0,0 +1,98 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import java.util.HashSet; +import java.util.Set; + +import seedu.address.commons.core.index.Index; +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.client.Client; +import seedu.address.model.tag.Tag; + +/** + * Deletes policies from an existing client by their index. + */ +public class DeletePolicyCommand extends Command { + + public static final String COMMAND_WORD = "deletepolicy"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Deletes policies from an existing client identified by the user-inputted index number. " + + "The index number must be based on the displayed client list. " + + "Parameters: INDEX (MUST BE A POSITIVE INTEGER) POLICY [MORE_POLICIES]...\n" + + "Example: " + COMMAND_WORD + " 1 t/Life Insurance t/Health Insurance"; + + public static final String MESSAGE_SUCCESS = "Policies deleted from client: %1$s"; + public static final String MESSAGE_CLIENT_NOT_FOUND = "Client with the given index does not exist."; + public static final String MESSAGE_POLICY_NOT_FOUND = "One or more specified policies do not exist for the client."; + + private final Index clientIndex; + private final Set policiesToDelete; + + /** + * Creates a DeletePolicyCommand to remove the specified policies from a client by index. + */ + public DeletePolicyCommand(Index clientIndex, Set policies) { + requireNonNull(clientIndex); + requireNonNull(policies); + this.clientIndex = clientIndex; + this.policiesToDelete = new HashSet<>(policies); + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + // Check if the index is valid + if (clientIndex.getZeroBased() >= model.getFilteredClientList().size()) { + throw new CommandException(MESSAGE_CLIENT_NOT_FOUND); + } + + Client clientToEdit = model.getFilteredClientList().get(clientIndex.getZeroBased()); + Set updatedPolicies = new HashSet<>(clientToEdit.getTags()); + + // Check if all policies to delete exist + if (!updatedPolicies.containsAll(policiesToDelete)) { + throw new CommandException(MESSAGE_POLICY_NOT_FOUND); + } + + updatedPolicies.removeAll(policiesToDelete); + + Client updatedClient = new Client( + clientToEdit.getName(), + clientToEdit.getPhone(), + clientToEdit.getEmail(), + clientToEdit.getAddress(), + updatedPolicies + ); + + model.setClient(clientToEdit, updatedClient); + return new CommandResult(String.format(MESSAGE_SUCCESS, Messages.format(updatedClient))); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof DeletePolicyCommand)) { + return false; + } + + DeletePolicyCommand otherCommand = (DeletePolicyCommand) other; + return clientIndex.equals(otherCommand.clientIndex) && policiesToDelete.equals(otherCommand.policiesToDelete); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("clientIndex", clientIndex) + .add("policiesToDelete", policiesToDelete) + .toString(); + } +} diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 36be25e07e3..0aed42edb5b 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -13,6 +13,7 @@ import seedu.address.logic.commands.ClearCommand; import seedu.address.logic.commands.Command; import seedu.address.logic.commands.DeleteClientCommand; +import seedu.address.logic.commands.DeletePolicyCommand; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.ExitCommand; import seedu.address.logic.commands.FindClientAndCommand; @@ -73,6 +74,9 @@ public Command parseCommand(String userInput) throws ParseException { case DeleteClientCommand.COMMAND_WORD: return new DeleteClientCommandParser().parse(arguments); + case DeletePolicyCommand.COMMAND_WORD: + return new DeletePolicyCommandParser().parse(arguments); + case ClearCommand.COMMAND_WORD: return new ClearCommand(); diff --git a/src/main/java/seedu/address/logic/parser/DeletePolicyCommandParser.java b/src/main/java/seedu/address/logic/parser/DeletePolicyCommandParser.java new file mode 100644 index 00000000000..78a9794fa28 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/DeletePolicyCommandParser.java @@ -0,0 +1,60 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; + +import java.util.Set; +import java.util.stream.Stream; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.DeletePolicyCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.tag.Tag; + +/** + * Parses input arguments and creates a new DeletePolicyCommand object. + */ +public class DeletePolicyCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the DeletePolicyCommand + * and returns a DeletePolicyCommand object for execution. + * @throws ParseException if the user input does not conform to the expected format + */ + public DeletePolicyCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_TAG); + + if (!arePrefixesPresent(argMultimap, PREFIX_TAG) || argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeletePolicyCommand.MESSAGE_USAGE)); + } + + try { + // Parse the index of the client + Index index = ParserUtil.parseIndex(argMultimap.getPreamble()); + + // Parse policies + Set policies = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); + + // Check if policies are provided + if (policies.isEmpty()) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeletePolicyCommand.MESSAGE_USAGE)); + } + + // Return the DeletePolicyCommand object + return new DeletePolicyCommand(index, policies); + + } catch (ParseException pe) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeletePolicyCommand.MESSAGE_USAGE), pe); + } + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } +} diff --git a/src/test/java/seedu/address/logic/commands/DeletePolicyCommandTest.java b/src/test/java/seedu/address/logic/commands/DeletePolicyCommandTest.java new file mode 100644 index 00000000000..a090f5c1373 --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/DeletePolicyCommandTest.java @@ -0,0 +1,141 @@ +package seedu.address.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.logic.commands.CommandTestUtil.assertCommandFailure; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.address.testutil.TypicalClients.getTypicalAddressBook; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_CLIENT; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_CLIENT; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import seedu.address.commons.core.index.Index; +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.model.Model; +import seedu.address.model.ModelManager; +import seedu.address.model.UserPrefs; +import seedu.address.model.client.Client; +import seedu.address.model.tag.Tag; + +/** + * Contains integration tests (interaction with the Model) and unit tests for {@code DeletePolicyCommand}. + */ +public class DeletePolicyCommandTest { + + private Model model; + + @BeforeEach + public void setUp() { + model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + } + + @Test + public void execute_deleteExistingPolicyFromClient_success() { + Client clientToEdit = model.getFilteredClientList().get(INDEX_FIRST_CLIENT.getZeroBased()); + + // Get an existing policy from the client + Set existingPolicies = new HashSet<>(clientToEdit.getTags()); + Tag policyToDelete = existingPolicies.iterator().next(); // Assume the client has at least one policy + + Set policiesToDelete = new HashSet<>(); + policiesToDelete.add(policyToDelete); + + DeletePolicyCommand deletePolicyCommand = new DeletePolicyCommand(INDEX_FIRST_CLIENT, policiesToDelete); + + Set updatedPolicies = new HashSet<>(existingPolicies); + updatedPolicies.remove(policyToDelete); + + Client expectedClient = new Client( + clientToEdit.getName(), + clientToEdit.getPhone(), + clientToEdit.getEmail(), + clientToEdit.getAddress(), + updatedPolicies + ); + + Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + expectedModel.setClient(clientToEdit, expectedClient); + + String expectedMessage = String.format(DeletePolicyCommand.MESSAGE_SUCCESS, Messages.format(expectedClient)); + + assertCommandSuccess(deletePolicyCommand, model, expectedMessage, expectedModel); + } + + @Test + public void execute_invalidClientIndex_throwsCommandException() { + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredClientList().size() + 1); + Set policiesToDelete = new HashSet<>(); + policiesToDelete.add(new Tag("Life Insurance")); + + DeletePolicyCommand deletePolicyCommand = new DeletePolicyCommand(outOfBoundIndex, policiesToDelete); + + assertCommandFailure(deletePolicyCommand, model, DeletePolicyCommand.MESSAGE_CLIENT_NOT_FOUND); + } + + @Test + public void execute_deleteNonExistingPolicyFromClient_throwsCommandException() { + Client clientToEdit = model.getFilteredClientList().get(INDEX_SECOND_CLIENT.getZeroBased()); + + Set policiesToDelete = new HashSet<>(); + policiesToDelete.add(new Tag("NonExistentPolicy")); + + DeletePolicyCommand deletePolicyCommand = new DeletePolicyCommand(INDEX_SECOND_CLIENT, policiesToDelete); + + assertCommandFailure(deletePolicyCommand, model, DeletePolicyCommand.MESSAGE_POLICY_NOT_FOUND); + } + + @Test + public void equals() { + Set policiesA = new HashSet<>(); + policiesA.add(new Tag("Policy A")); + Set policiesB = new HashSet<>(); + policiesB.add(new Tag("Policy B")); + + DeletePolicyCommand deletePolicyFirstCommand = new DeletePolicyCommand(INDEX_FIRST_CLIENT, policiesA); + DeletePolicyCommand deletePolicySecondCommand = new DeletePolicyCommand(INDEX_SECOND_CLIENT, policiesB); + + // Same object -> returns true + assertTrue(deletePolicyFirstCommand.equals(deletePolicyFirstCommand)); + + // Same values -> returns true + DeletePolicyCommand deletePolicyFirstCommandCopy = new DeletePolicyCommand(INDEX_FIRST_CLIENT, policiesA); + assertTrue(deletePolicyFirstCommand.equals(deletePolicyFirstCommandCopy)); + + // Different types -> returns false + assertFalse(deletePolicyFirstCommand.equals(1)); + + // Different index -> returns false + assertFalse(deletePolicyFirstCommand.equals(deletePolicySecondCommand)); + + // Different policies -> returns false + DeletePolicyCommand deletePolicyDifferentPolicyCommand = new DeletePolicyCommand(INDEX_FIRST_CLIENT, policiesB); + assertFalse(deletePolicyFirstCommand.equals(deletePolicyDifferentPolicyCommand)); + + // Null -> returns false + assertFalse(deletePolicyFirstCommand.equals(null)); + } + + @Test + public void toStringMethod() { + Set policies = new HashSet<>(); + policies.add(new Tag("Life Insurance")); + policies.add(new Tag("Health Insurance")); + + DeletePolicyCommand deletePolicyCommand = new DeletePolicyCommand(INDEX_FIRST_CLIENT, policies); + + String expectedString = new ToStringBuilder(deletePolicyCommand) + .add("clientIndex", INDEX_FIRST_CLIENT) + .add("policiesToDelete", policies) + .toString(); + + assertEquals(expectedString, deletePolicyCommand.toString()); + } +} + diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index b6110096b6c..27287f1f8b1 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -18,6 +18,7 @@ import seedu.address.logic.commands.AddPolicyCommand; import seedu.address.logic.commands.ClearCommand; import seedu.address.logic.commands.DeleteClientCommand; +import seedu.address.logic.commands.DeletePolicyCommand; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.EditCommand.EditClientDescriptor; import seedu.address.logic.commands.ExitCommand; @@ -128,6 +129,15 @@ public void parseCommand_addPolicy() throws Exception { assertEquals(new AddPolicyCommand(INDEX_FIRST_CLIENT, policies), command); } + @Test + public void parseCommand_deletePolicy() throws Exception { + Set policies = Set.of(new Tag("Life Insurance"), new Tag("Health Insurance")); + DeletePolicyCommand command = (DeletePolicyCommand) parser.parseCommand( + DeletePolicyCommand.COMMAND_WORD + " " + INDEX_FIRST_CLIENT.getOneBased() + + " t/Life Insurance t/Health Insurance"); + assertEquals(new DeletePolicyCommand(INDEX_FIRST_CLIENT, policies), command); + } + @Test public void parseCommand_unrecognisedInput_throwsParseException() { assertThrows(ParseException.class, String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE), () diff --git a/src/test/java/seedu/address/logic/parser/DeletePolicyCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeletePolicyCommandParserTest.java new file mode 100644 index 00000000000..211f40006c1 --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/DeletePolicyCommandParserTest.java @@ -0,0 +1,78 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +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_CLIENT; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_CLIENT; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import seedu.address.logic.commands.DeletePolicyCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.tag.Tag; + +public class DeletePolicyCommandParserTest { + + private DeletePolicyCommandParser parser = new DeletePolicyCommandParser(); + + @Test + public void parse_allFieldsPresent_success() throws ParseException { + // Prepare the expected tags and client index + Set policiesToDelete = new HashSet<>(); + policiesToDelete.add(new Tag("Health")); + policiesToDelete.add(new Tag("Life")); + + assertParseSuccess(parser, "1 " + PREFIX_TAG + "Health " + PREFIX_TAG + "Life", + new DeletePolicyCommand(INDEX_FIRST_CLIENT, policiesToDelete)); + } + + @Test + public void parse_multipleTags_success() throws ParseException { + Set policiesToDelete = new HashSet<>(); + policiesToDelete.add(new Tag("Health")); + policiesToDelete.add(new Tag("Life")); + policiesToDelete.add(new Tag("Travel")); + + assertParseSuccess(parser, "1 " + PREFIX_TAG + "Health " + PREFIX_TAG + "Life " + PREFIX_TAG + "Travel", + new DeletePolicyCommand(INDEX_FIRST_CLIENT, policiesToDelete)); + } + + @Test + public void parse_missingPolicy_throwsParseException() { + assertParseFailure(parser, "1", + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeletePolicyCommand.MESSAGE_USAGE)); + } + + @Test + public void parse_invalidClientIndex_throwsParseException() { + assertParseFailure(parser, "abc " + PREFIX_TAG + "Health", + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeletePolicyCommand.MESSAGE_USAGE)); + } + + @Test + public void parse_nonEmptyPreamble_throwsParseException() { + assertParseFailure(parser, "ExtraText 1 " + PREFIX_TAG + "Health", + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeletePolicyCommand.MESSAGE_USAGE)); + } + + @Test + public void parse_emptyCommand_throwsParseException() { + assertParseFailure(parser, "", + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeletePolicyCommand.MESSAGE_USAGE)); + } + + @Test + public void parse_validClientWithSinglePolicy_success() throws ParseException { + Set policiesToDelete = new HashSet<>(); + policiesToDelete.add(new Tag("Health")); + + assertParseSuccess(parser, "2 " + PREFIX_TAG + "Health", + new DeletePolicyCommand(INDEX_SECOND_CLIENT, policiesToDelete)); + } +} + From 13191a0de878bbbb766dd71d732ad49c4e4567ed Mon Sep 17 00:00:00 2001 From: Nicholas Foo Date: Thu, 27 Mar 2025 17:10:31 +0800 Subject: [PATCH 115/249] Add minor documentation and message fix --- src/main/java/seedu/address/logic/commands/SortCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/SortCommand.java b/src/main/java/seedu/address/logic/commands/SortCommand.java index 8453fbe752c..25574bd4fa2 100644 --- a/src/main/java/seedu/address/logic/commands/SortCommand.java +++ b/src/main/java/seedu/address/logic/commands/SortCommand.java @@ -5,12 +5,12 @@ import seedu.address.model.Model; /** - * Sorts all clients in the address book to the user. + * Sorts all clients on the GUI in case-insensitive alphabetical order for the user. */ public class SortCommand extends Command { public static final String COMMAND_WORD = "sort"; public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Sorts all clients in the address book by alphabetical order."; + + ": Sorts all clients in WealthVault by case-insensitive alphabetical order."; public static final String MESSAGE_SORTED_SUCCESS = "Clients sorted in alphabetical order."; @Override From 3234f3322446085fc25e9bbaa7db78d5bc42e9f5 Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Thu, 27 Mar 2025 17:26:46 +0800 Subject: [PATCH 116/249] delete newspaces edits --- .../seedu/address/storage/StorageManagerTest.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/test/java/seedu/address/storage/StorageManagerTest.java b/src/test/java/seedu/address/storage/StorageManagerTest.java index 61352e9a552..7a6fe475280 100644 --- a/src/test/java/seedu/address/storage/StorageManagerTest.java +++ b/src/test/java/seedu/address/storage/StorageManagerTest.java @@ -65,15 +65,3 @@ public void getAddressBookFilePath() { assertNotNull(storageManager.getAddressBookFilePath()); } } - - - - - - - - - - - - From bed76df5a6d5bb6e4412bd5322c801ee9b9a5532 Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Thu, 27 Mar 2025 20:21:46 +0800 Subject: [PATCH 117/249] add debug edits --- .../seedu/address/logic/parser/AddressBookParserTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 27287f1f8b1..66003332941 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -138,6 +138,12 @@ public void parseCommand_deletePolicy() throws Exception { assertEquals(new DeletePolicyCommand(INDEX_FIRST_CLIENT, policies), command); } + @Test + public void parseCommand_sort() throws Exception { + assertTrue(parser.parseCommand(SortCommand.COMMAND_WORD) instanceof SortCommand); + assertTrue(parser.parseCommand(SortCommand.COMMAND_WORD + " 3") instanceof SortCommand); + } + @Test public void parseCommand_unrecognisedInput_throwsParseException() { assertThrows(ParseException.class, String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE), () From b3a3b3e4450cfd83a87cd5f5b4763f8c41f8fb9d Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Thu, 27 Mar 2025 21:04:51 +0800 Subject: [PATCH 118/249] add enable assertions edit --- build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build.gradle b/build.gradle index 6b182d845af..8808e4baa49 100644 --- a/build.gradle +++ b/build.gradle @@ -70,3 +70,8 @@ shadowJar { } defaultTasks 'clean', 'test' + +run { + enableAssertions = true +} + From 66d3b25e59c0564aa1b3f7c04df362d98d949eb8 Mon Sep 17 00:00:00 2001 From: joshua Date: Thu, 27 Mar 2025 22:35:04 +0800 Subject: [PATCH 119/249] fix phonelength --- src/main/java/seedu/address/model/client/Phone.java | 2 +- src/test/java/seedu/address/model/client/PhoneTest.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/address/model/client/Phone.java b/src/main/java/seedu/address/model/client/Phone.java index d6ede5e9299..ba55a53a1df 100644 --- a/src/main/java/seedu/address/model/client/Phone.java +++ b/src/main/java/seedu/address/model/client/Phone.java @@ -12,7 +12,7 @@ public class Phone { public static final String MESSAGE_CONSTRAINTS = "Phone numbers should only contain numbers, and it should be at least 3 digits long"; - public static final String VALIDATION_REGEX = "\\d{3,}"; + public static final String VALIDATION_REGEX = "\\d{3,13}"; public final String value; /** diff --git a/src/test/java/seedu/address/model/client/PhoneTest.java b/src/test/java/seedu/address/model/client/PhoneTest.java index d5a21a7ffa3..0435033f192 100644 --- a/src/test/java/seedu/address/model/client/PhoneTest.java +++ b/src/test/java/seedu/address/model/client/PhoneTest.java @@ -31,11 +31,12 @@ public void isValidPhone() { assertFalse(Phone.isValidPhone("phone")); // non-numeric assertFalse(Phone.isValidPhone("9011p041")); // alphabets within digits assertFalse(Phone.isValidPhone("9312 1534")); // spaces within digits + assertFalse(Phone.isValidPhone("42938420331212")); // more than 13 digits // valid phone numbers assertTrue(Phone.isValidPhone("911")); // exactly 3 numbers assertTrue(Phone.isValidPhone("93121534")); - assertTrue(Phone.isValidPhone("124293842033123")); // long phone numbers + assertTrue(Phone.isValidPhone("429384203312")); // exactly 13 numbers } @Test From ca17e0af496473e20a09283ceaf31fee085a0c7f Mon Sep 17 00:00:00 2001 From: joshua Date: Thu, 27 Mar 2025 22:41:41 +0800 Subject: [PATCH 120/249] fix --- src/main/java/seedu/address/model/client/Phone.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/model/client/Phone.java b/src/main/java/seedu/address/model/client/Phone.java index ba55a53a1df..39166e1657a 100644 --- a/src/main/java/seedu/address/model/client/Phone.java +++ b/src/main/java/seedu/address/model/client/Phone.java @@ -11,7 +11,7 @@ public class Phone { public static final String MESSAGE_CONSTRAINTS = - "Phone numbers should only contain numbers, and it should be at least 3 digits long"; + "Phone numbers should only contain numbers, and it should be between 3 and 13 digits long"; public static final String VALIDATION_REGEX = "\\d{3,13}"; public final String value; From caff2bb6ae4f8fea0f1b804e0eea78893c47254a Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 30 Mar 2025 17:56:01 +0800 Subject: [PATCH 121/249] Add priority command UMLs into DG --- docs/DeveloperGuide.md | 31 +++++++++ .../PrioritySequenceDiagram-Client.puml | 62 ++++++++++++++++++ .../PrioritySequenceDiagram-Logic.puml | 65 +++++++++++++++++++ .../TogglePrioritySequenceDiagram1.puml | 31 +++++++++ .../TogglePrioritySequenceDiagram2.puml | 53 +++++++++++++++ 5 files changed, 242 insertions(+) create mode 100644 docs/diagrams/PrioritySequenceDiagram-Client.puml create mode 100644 docs/diagrams/PrioritySequenceDiagram-Logic.puml create mode 100644 docs/diagrams/TogglePrioritySequenceDiagram1.puml create mode 100644 docs/diagrams/TogglePrioritySequenceDiagram2.puml diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 6c76bb420f5..63d4243930c 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -158,6 +158,37 @@ Classes used by multiple components are in the `seedu.address.commons` package. This section describes some noteworthy details on how certain features are implemented. +### Priority feature + +#### Priority Tag +The priority command is built around the `PriorityTag` class, which extends `Tag`. +The PriorityTag constructor does not accept arguments, ensuring that its tagName +is always set to "Priority." + +The Class Diagram of a Client can be [seen in the diagram above](#model-component). + +#### Implementation + +The priority command toggles a client’s priority status. The following sequence diagrams +illustrate how this process flows through the logic component: + + + +The following sequence diagrams illustrate how the `PriorityCommand` class interacts with +model components to toggle the priority of the user + + + +As seen above, the `togglePriority` method creates a new `Client` object +with updated priority. If the `Client` does not have a `PriorityTag`, +`togglePriority` will create a new `Client` with a `PriorityTag` object. +Else, it will filter the `PriorityTag` out of `tags`. +Its operation is modeled below: + + + + + ### \[Proposed\] Undo/redo feature #### Proposed Implementation diff --git a/docs/diagrams/PrioritySequenceDiagram-Client.puml b/docs/diagrams/PrioritySequenceDiagram-Client.puml new file mode 100644 index 00000000000..fdd50e2d0dc --- /dev/null +++ b/docs/diagrams/PrioritySequenceDiagram-Client.puml @@ -0,0 +1,62 @@ +@startuml +!include style.puml +skinparam ArrowFontStyle plain + +box Logic LOGIC_COLOR_T1 +participant "p:PriorityCommand" as PriorityCommand LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant ":Model" as Model MODEL_COLOR +participant "oldClient:Client" as oClient MODEL_COLOR +participant "newClient:Client" as nClient MODEL_COLOR +end box + +[-> PriorityCommand : execute(index) +activate PriorityCommand + +PriorityCommand -> Model +activate Model +Model -> Model : getFilteredClientList +activate Model +Model --> Model +deactivate Model +Model --> PriorityCommand +deactivate Model + +PriorityCommand -> oClient : getClientFromIndex(index) +activate oClient +oClient --> PriorityCommand +deactivate oClient + +PriorityCommand -> PriorityCommand +activate Pr +create nClient +PriorityCommand -> nClient : togglePriority(oldClient) +activate nClient +nClient --> PriorityCommand +deactivate + +PriorityCommand -> Model +activate Model +Model -> Model : setClient(oldClient, newClient) +activate Model +Model --> Model +deactivate Model +Model --> PriorityCommand +deactivate Model + +destroy oClient + +PriorityCommand -> Model +activate Model +Model -> Model : updateFilteredClientList +activate Model +Model --> Model +deactivate Model +Model --> PriorityCommand +deactivate Model + +[<--PriorityCommand +deactivate PriorityCommand +@enduml \ No newline at end of file diff --git a/docs/diagrams/PrioritySequenceDiagram-Logic.puml b/docs/diagrams/PrioritySequenceDiagram-Logic.puml new file mode 100644 index 00000000000..b3d2a1a0fc4 --- /dev/null +++ b/docs/diagrams/PrioritySequenceDiagram-Logic.puml @@ -0,0 +1,65 @@ +@startuml +!include style.puml +skinparam ArrowFontStyle plain + +box Logic LOGIC_COLOR_T1 +participant ":LogicManager" as LogicManager LOGIC_COLOR +participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR +participant "p:PriorityCommandParser" as PriorityCommandParser LOGIC_COLOR +participant "p:PriorityCommand" as PriorityCommand LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant ":Model" as Model MODEL_COLOR +end box +[-> LogicManager : execute() +activate LogicManager + +LogicManager -> AddressBookParser : parseCommand() +activate AddressBookParser + +create PriorityCommandParser +AddressBookParser -> PriorityCommandParser +activate PriorityCommandParser + +create PriorityCommand +PriorityCommandParser -> PriorityCommand : parse(index) +activate PriorityCommand +PriorityCommandParser <-- PriorityCommand +deactivate PriorityCommand + +PriorityCommandParser --> AddressBookParser : p +deactivate PriorityCommandParser + +AddressBookParser --> LogicManager : p +deactivate AddressBookParser + +LogicManager -> PriorityCommand : execute() +activate PriorityCommand + +PriorityCommand -> Model +activate Model +Model -> Model : getFilteredClientList() +Model --> PriorityCommand +deactivate Model + +PriorityCommand -> Model +activate Model +Model -> Model : setClient() +Model --> PriorityCommand +deactivate Model + +PriorityCommand -> Model +activate Model +Model -> Model : updateFilteredClientList() +Model --> PriorityCommand +deactivate Model + +PriorityCommand --> LogicManager : result +deactivate PriorityCommand +PriorityCommand -[hidden]-> LogicManager : result +destroy PriorityCommand + +[<--LogicManager +deactivate LogicManager +@enduml \ No newline at end of file diff --git a/docs/diagrams/TogglePrioritySequenceDiagram1.puml b/docs/diagrams/TogglePrioritySequenceDiagram1.puml new file mode 100644 index 00000000000..812a1087b48 --- /dev/null +++ b/docs/diagrams/TogglePrioritySequenceDiagram1.puml @@ -0,0 +1,31 @@ +@startuml +!include style.puml +skinparam ArrowFontStyle plain + +box Logic LOGIC_COLOR_T1 +participant "p:PriorityCommand" as PriorityCommand LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant "newClient:Client" as nClient MODEL_COLOR +participant "oldClient:Client" as oClient MODEL_COLOR +participant "oldTags:Set" as oTags MODEL_COLOR +end box + +[-> PriorityCommand : togglePriority(oldClient) +activate PriorityCommand + +PriorityCommand -> oClient +activate oClient +oClient -> oTags : getTags() +activate oTags +oTags --> oClient +deactivate oTags +oClient --> PriorityCommand +deactivate oClient + +ref over PriorityCommand, nClient: Create New Client + +[<--PriorityCommand : newClient +deactivate PriorityCommand +@enduml \ No newline at end of file diff --git a/docs/diagrams/TogglePrioritySequenceDiagram2.puml b/docs/diagrams/TogglePrioritySequenceDiagram2.puml new file mode 100644 index 00000000000..6f21682388a --- /dev/null +++ b/docs/diagrams/TogglePrioritySequenceDiagram2.puml @@ -0,0 +1,53 @@ +@startuml +mainframe sd [Create New Client] +!include style.puml +skinparam ArrowFontStyle plain + +box Logic LOGIC_COLOR_T1 +participant "p:PriorityCommand" as PriorityCommand LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant "newTags:Set" as nTags MODEL_COLOR +participant "p:PriortyTag" as p MODEL_COLOR +participant "newClient:Client" as nClient MODEL_COLOR +end box + +create nTags +PriorityCommand -> nTags : HashSet() +activate nTags +nTags --> PriorityCommand +deactivate nTags + +alt oldTags does not contain a :PriorityTag + create p + PriorityCommand -> p : PriorityTag() + activate p + p --> PriorityCommand: p + deactivate p + PriorityCommand -> nTags + activate nTags + nTags -> nTags : add(p) + activate nTags + nTags --> nTags + deactivate nTags + nTags --> PriorityCommand + deactivate nTags +else oldTags does not contain a :PriorityTag + PriorityCommand -> nTags + activate nTags + nTags -> nTags : filter + activate nTags + nTags --> nTags + deactivate nTags + nTags --> PriorityCommand + deactivate nTags +end + +create nClient +PriorityCommand -> nClient : Client() +activate nClient +nClient --> PriorityCommand +deactivate nClient + +@enduml \ No newline at end of file From 9ce65112f50ca9b219e4baab5e7e2ca00275ea36 Mon Sep 17 00:00:00 2001 From: Sean-G-Han <156769273+Sean-G-Han@users.noreply.github.com> Date: Sun, 30 Mar 2025 17:59:25 +0800 Subject: [PATCH 122/249] Add extra line below new puml files --- docs/diagrams/PrioritySequenceDiagram-Client.puml | 2 +- docs/diagrams/PrioritySequenceDiagram-Logic.puml | 2 +- docs/diagrams/TogglePrioritySequenceDiagram1.puml | 2 +- docs/diagrams/TogglePrioritySequenceDiagram2.puml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/diagrams/PrioritySequenceDiagram-Client.puml b/docs/diagrams/PrioritySequenceDiagram-Client.puml index fdd50e2d0dc..3ae1b2f37a5 100644 --- a/docs/diagrams/PrioritySequenceDiagram-Client.puml +++ b/docs/diagrams/PrioritySequenceDiagram-Client.puml @@ -59,4 +59,4 @@ deactivate Model [<--PriorityCommand deactivate PriorityCommand -@enduml \ No newline at end of file +@enduml diff --git a/docs/diagrams/PrioritySequenceDiagram-Logic.puml b/docs/diagrams/PrioritySequenceDiagram-Logic.puml index b3d2a1a0fc4..7683366b6eb 100644 --- a/docs/diagrams/PrioritySequenceDiagram-Logic.puml +++ b/docs/diagrams/PrioritySequenceDiagram-Logic.puml @@ -62,4 +62,4 @@ destroy PriorityCommand [<--LogicManager deactivate LogicManager -@enduml \ No newline at end of file +@enduml diff --git a/docs/diagrams/TogglePrioritySequenceDiagram1.puml b/docs/diagrams/TogglePrioritySequenceDiagram1.puml index 812a1087b48..4bdce85e057 100644 --- a/docs/diagrams/TogglePrioritySequenceDiagram1.puml +++ b/docs/diagrams/TogglePrioritySequenceDiagram1.puml @@ -28,4 +28,4 @@ ref over PriorityCommand, nClient: Create New Client [<--PriorityCommand : newClient deactivate PriorityCommand -@enduml \ No newline at end of file +@enduml diff --git a/docs/diagrams/TogglePrioritySequenceDiagram2.puml b/docs/diagrams/TogglePrioritySequenceDiagram2.puml index 6f21682388a..df70a7e560a 100644 --- a/docs/diagrams/TogglePrioritySequenceDiagram2.puml +++ b/docs/diagrams/TogglePrioritySequenceDiagram2.puml @@ -50,4 +50,4 @@ activate nClient nClient --> PriorityCommand deactivate nClient -@enduml \ No newline at end of file +@enduml From 5a5038a18acffeaae9ca77711b4c2566493eb0fb Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Mon, 31 Mar 2025 12:27:36 +0800 Subject: [PATCH 123/249] add dg minor uml edits --- docs/diagrams/ModelClassDiagram.puml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/diagrams/ModelClassDiagram.puml b/docs/diagrams/ModelClassDiagram.puml index 0de5673070d..8bdeda47df7 100644 --- a/docs/diagrams/ModelClassDiagram.puml +++ b/docs/diagrams/ModelClassDiagram.puml @@ -12,8 +12,8 @@ Class AddressBook Class ModelManager Class UserPrefs -Class UniquePersonList -Class Person +Class UniqueClientList +Class Client Class Address Class Email Class Name @@ -35,20 +35,20 @@ ModelManager -left-> "1" AddressBook ModelManager -right-> "1" UserPrefs UserPrefs .up.|> ReadOnlyUserPrefs -AddressBook *--> "1" UniquePersonList -UniquePersonList --> "~* all" Person -Person *--> Name -Person *--> Phone -Person *--> Email -Person *--> Address -Person *--> "*" Tag +AddressBook *--> "1" UniqueClientList +UniqueClientList --> "~* all" Client +Client *--> Name +Client *--> Phone +Client *--> Email +Client *--> Address +Client *--> "*" Tag -Person -[hidden]up--> I -UniquePersonList -[hidden]right-> I +Client -[hidden]up--> I +UniqueClientList -[hidden]right-> I Name -[hidden]right-> Phone Phone -[hidden]right-> Address Address -[hidden]right-> Email -ModelManager --> "~* filtered" Person +ModelManager --> "~* filtered" Client @enduml From 432678def029ebafb27057a7001ae3e7796aaa92 Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Mon, 31 Mar 2025 12:31:02 +0800 Subject: [PATCH 124/249] Make some UML edits --- docs/diagrams/DeleteSequenceDiagram.puml | 56 ++++++++++++------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/diagrams/DeleteSequenceDiagram.puml b/docs/diagrams/DeleteSequenceDiagram.puml index 5241e79d7da..84bcc2e6456 100644 --- a/docs/diagrams/DeleteSequenceDiagram.puml +++ b/docs/diagrams/DeleteSequenceDiagram.puml @@ -5,8 +5,8 @@ skinparam ArrowFontStyle plain box Logic LOGIC_COLOR_T1 participant ":LogicManager" as LogicManager LOGIC_COLOR participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR -participant ":DeleteCommandParser" as DeleteCommandParser LOGIC_COLOR -participant "d:DeleteCommand" as DeleteCommand LOGIC_COLOR +participant ":DeleteClientCommandParser" as DeleteClientCommandParser LOGIC_COLOR +participant "d:DeleteClientCommand" as DeleteClientCommand LOGIC_COLOR participant "r:CommandResult" as CommandResult LOGIC_COLOR end box @@ -14,56 +14,56 @@ box Model MODEL_COLOR_T1 participant "m:Model" as Model MODEL_COLOR end box -[-> LogicManager : execute("delete 1") +[-> LogicManager : execute("deleteclient 1") activate LogicManager -LogicManager -> AddressBookParser : parseCommand("delete 1") +LogicManager -> AddressBookParser : parseCommand("deleteclient 1") activate AddressBookParser -create DeleteCommandParser -AddressBookParser -> DeleteCommandParser -activate DeleteCommandParser +create DeleteClientCommandParser +AddressBookParser -> DeleteClientCommandParser +activate DeleteClientCommandParser -DeleteCommandParser --> AddressBookParser -deactivate DeleteCommandParser +DeleteClientCommandParser --> AddressBookParser +deactivate DeleteClientCommandParser -AddressBookParser -> DeleteCommandParser : parse("1") -activate DeleteCommandParser +AddressBookParser -> DeleteClientCommandParser : parse("1") +activate DeleteClientCommandParser -create DeleteCommand -DeleteCommandParser -> DeleteCommand -activate DeleteCommand +create DeleteClientCommand +DeleteClientCommandParser -> DeleteClientCommand +activate DeleteClientCommand -DeleteCommand --> DeleteCommandParser : -deactivate DeleteCommand +DeleteClientCommand --> DeleteClientCommandParser : +deactivate DeleteClientCommand -DeleteCommandParser --> AddressBookParser : d -deactivate DeleteCommandParser +DeleteClientCommandParser --> AddressBookParser : d +deactivate DeleteClientCommandParser 'Hidden arrow to position the destroy marker below the end of the activation bar. -DeleteCommandParser -[hidden]-> AddressBookParser -destroy DeleteCommandParser +DeleteClientCommandParser -[hidden]-> AddressBookParser +destroy DeleteClientCommandParser AddressBookParser --> LogicManager : d deactivate AddressBookParser -LogicManager -> DeleteCommand : execute(m) -activate DeleteCommand +LogicManager -> DeleteClientCommand : execute(m) +activate DeleteClientCommand -DeleteCommand -> Model : deletePerson(1) +DeleteClientCommand -> Model : deleteClient(1) activate Model -Model --> DeleteCommand +Model --> DeleteClientCommand deactivate Model create CommandResult -DeleteCommand -> CommandResult +DeleteClientCommand -> CommandResult activate CommandResult -CommandResult --> DeleteCommand +CommandResult --> DeleteClientCommand deactivate CommandResult -DeleteCommand --> LogicManager : r -deactivate DeleteCommand +DeleteClientCommand --> LogicManager : r +deactivate DeleteClientCommand [<--LogicManager deactivate LogicManager From 2b466fc73776d8a77b4174671e096b15922e8e96 Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Mon, 31 Mar 2025 15:29:05 +0800 Subject: [PATCH 125/249] add UI minor edits --- docs/stylesheets/main.css | 1 + src/main/java/seedu/address/logic/Messages.java | 2 +- src/main/java/seedu/address/ui/UiManager.java | 2 +- src/main/resources/view/MainWindow.fxml | 2 +- src/test/java/seedu/address/commons/util/AppUtilTest.java | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/stylesheets/main.css b/docs/stylesheets/main.css index ba6f8385d2d..c32c2c95945 100644 --- a/docs/stylesheets/main.css +++ b/docs/stylesheets/main.css @@ -168,3 +168,4 @@ h5, h6 { color: #e46c0a; } + diff --git a/src/main/java/seedu/address/logic/Messages.java b/src/main/java/seedu/address/logic/Messages.java index 278eca98c21..d3e3928fc12 100644 --- a/src/main/java/seedu/address/logic/Messages.java +++ b/src/main/java/seedu/address/logic/Messages.java @@ -14,7 +14,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_CLIENT_DISPLAYED_INDEX = "The client index provided is invalid"; + public static final String MESSAGE_INVALID_CLIENT_DISPLAYED_INDEX = "The client index provided is invalid. Client index must be an existing index."; public static final String MESSAGE_CLIENTS_LISTED_OVERVIEW = "%1$d clients listed!"; public static final String MESSAGE_DUPLICATE_FIELDS = "Multiple values specified for the following single-valued field(s): "; diff --git a/src/main/java/seedu/address/ui/UiManager.java b/src/main/java/seedu/address/ui/UiManager.java index fdf024138bc..7f35f37eb09 100644 --- a/src/main/java/seedu/address/ui/UiManager.java +++ b/src/main/java/seedu/address/ui/UiManager.java @@ -20,7 +20,7 @@ public class UiManager implements Ui { public static final String ALERT_DIALOG_PANE_FIELD_ID = "alertDialogPane"; private static final Logger logger = LogsCenter.getLogger(UiManager.class); - private static final String ICON_APPLICATION = "/images/address_book_32.png"; + private static final String ICON_APPLICATION = "/images/WealthVaultLogo.png"; private Logic logic; private MainWindow mainWindow; diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml index 51cc45da16c..475a6bf3ca6 100644 --- a/src/main/resources/view/MainWindow.fxml +++ b/src/main/resources/view/MainWindow.fxml @@ -14,7 +14,7 @@ - + diff --git a/src/test/java/seedu/address/commons/util/AppUtilTest.java b/src/test/java/seedu/address/commons/util/AppUtilTest.java index 594de1e6365..7573281ba62 100644 --- a/src/test/java/seedu/address/commons/util/AppUtilTest.java +++ b/src/test/java/seedu/address/commons/util/AppUtilTest.java @@ -9,7 +9,7 @@ public class AppUtilTest { @Test public void getImage_exitingImage() { - assertNotNull(AppUtil.getImage("/images/address_book_32.png")); + assertNotNull(AppUtil.getImage("/images/WealthVaultLogo.png")); } @Test From 78520bdd5e2de778895b04d7a1f90c97780a691a Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Tue, 1 Apr 2025 01:03:21 +0800 Subject: [PATCH 126/249] Edit Name class and other minor changes --- .../java/seedu/address/logic/Messages.java | 2 +- .../logic/commands/AddClientCommand.java | 14 ++-- .../logic/commands/AddPolicyCommand.java | 4 +- .../seedu/address/model/client/Client.java | 5 +- .../java/seedu/address/model/client/Name.java | 77 ++++++++++++++++--- .../duplicateClientAddressBook.json | 5 +- .../address/logic/parser/ParserUtilTest.java | 2 +- .../seedu/address/model/AddressBookTest.java | 17 ++-- .../address/model/client/ClientTest.java | 26 ++++--- .../seedu/address/model/client/NameTest.java | 30 +++++--- .../model/client/UniqueClientListTest.java | 24 ++---- .../storage/JsonAdaptedClientTest.java | 2 +- .../JsonSerializableAddressBookTest.java | 4 +- 13 files changed, 134 insertions(+), 78 deletions(-) diff --git a/src/main/java/seedu/address/logic/Messages.java b/src/main/java/seedu/address/logic/Messages.java index 278eca98c21..5d142daf71f 100644 --- a/src/main/java/seedu/address/logic/Messages.java +++ b/src/main/java/seedu/address/logic/Messages.java @@ -13,7 +13,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_COMMAND_FORMAT = "Invalid command format!\n%1$s"; public static final String MESSAGE_INVALID_CLIENT_DISPLAYED_INDEX = "The client index provided is invalid"; public static final String MESSAGE_CLIENTS_LISTED_OVERVIEW = "%1$d clients listed!"; public static final String MESSAGE_DUPLICATE_FIELDS = diff --git a/src/main/java/seedu/address/logic/commands/AddClientCommand.java b/src/main/java/seedu/address/logic/commands/AddClientCommand.java index 1f079a6a4ba..42488c92ed7 100644 --- a/src/main/java/seedu/address/logic/commands/AddClientCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddClientCommand.java @@ -20,20 +20,20 @@ public class AddClientCommand extends Command { public static final String COMMAND_WORD = "addclient"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a client to WealthVault. " - + "Parameters: " + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a client to WealthVault.\n" + + "\nParameters: " + PREFIX_NAME + "NAME " + PREFIX_PHONE + "PHONE " + PREFIX_EMAIL + "EMAIL " + PREFIX_ADDRESS + "ADDRESS " + "[" + PREFIX_TAG + "POLICY_TAG]...\n" + "Example: " + COMMAND_WORD + " " - + PREFIX_NAME + "John Wilson " + + PREFIX_NAME + "Jo Ng " + PREFIX_PHONE + "91234567 " - + PREFIX_EMAIL + "johnw@example.com " - + PREFIX_ADDRESS + "210, Clementi Ave 3, #12-01 " - + PREFIX_TAG + "Travel Policy 21 " - + PREFIX_TAG + "Health Policy 03"; + + PREFIX_EMAIL + "j@mail.com " + + PREFIX_ADDRESS + "21 View " + + PREFIX_TAG + "Policy A " + + PREFIX_TAG + "Policy B"; public static final String MESSAGE_SUCCESS = "New client added: %1$s"; public static final String MESSAGE_DUPLICATE_CLIENT = "This client already exists in WealthVault"; diff --git a/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java b/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java index 0189c804d1e..4cc9ab3d27c 100644 --- a/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddPolicyCommand.java @@ -21,8 +21,8 @@ public class AddPolicyCommand extends Command { public static final String COMMAND_WORD = "addpolicy"; public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Adds policies to an existing client identified by the user-inputted index number. " - + "The index number must be based on the displayed client list." + + ": Adds policies to an existing client identified by the user-inputted index number.\n" + + " The index number must be based on the displayed client list.\n\n" + "Parameters: INDEX (MUST BE A POSITIVE INTEGER) POLICY [MORE_POLICIES]...\n" + "Example: " + COMMAND_WORD + " 1 t/Life Insurance t/Health Insurance"; diff --git a/src/main/java/seedu/address/model/client/Client.java b/src/main/java/seedu/address/model/client/Client.java index 38a812f2062..dea99fe3cfe 100644 --- a/src/main/java/seedu/address/model/client/Client.java +++ b/src/main/java/seedu/address/model/client/Client.java @@ -71,7 +71,10 @@ public boolean isSameClient(Client otherClient) { } return otherClient != null - && otherClient.getName().equals(getName()); + && otherClient.getName().equals(getName()) + && otherClient.getAddress().equals(getAddress()) + && otherClient.getEmail().equals(getEmail()) + && otherClient.getPhone().equals(getPhone()); } /** diff --git a/src/main/java/seedu/address/model/client/Name.java b/src/main/java/seedu/address/model/client/Name.java index 09e11a470d0..a77acbb950c 100644 --- a/src/main/java/seedu/address/model/client/Name.java +++ b/src/main/java/seedu/address/model/client/Name.java @@ -10,13 +10,10 @@ public class Name { public static final String MESSAGE_CONSTRAINTS = - "Names should only contain alphanumeric characters and spaces, and it should not be blank"; + "Names should only contain alphanumeric characters, spaces, periods (.), commas (,)" + + "'at' symbol (@), s/o or d/o!"; - /* - * 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 = "[\\p{Alnum}][\\p{Alnum} ]*"; + public static final String VALIDATION_REGEX = "^(?:(s/o|d/o)|[\\p{Alnum},.@])[\\p{Alnum},.@ ]*$"; public final String fullName; @@ -27,8 +24,8 @@ public class Name { */ public Name(String name) { requireNonNull(name); - checkArgument(isValidName(name), MESSAGE_CONSTRAINTS); - fullName = name; + checkArgument(isValidName(normalizeName(name)), MESSAGE_CONSTRAINTS); + fullName = formatName(normalizeName(name)); } /** @@ -38,6 +35,68 @@ public static boolean isValidName(String test) { return test.matches(VALIDATION_REGEX); } + private String normalizeName(String name) { + name = name.replaceAll("\\s+", " ").trim(); + name = name.replaceAll("([,.@])(?!\\s)", "$1 "); + name = name.replaceAll("(? maxLineLength) { + // If adding this word exceeds maxLineLength, go to a new line + while (lineLength < maxLineLength) { + formattedName.append(" "); // Pad with spaces + lineLength++; + } + formattedName.append("\n"); + lineLength = 0; + } + + if (lineLength > 0) { + formattedName.append(" "); + lineLength++; + } + + if (word.length() > maxLineLength) { + // Break the long word with a hyphen + for (int i = 0; i < word.length(); i++) { + if (lineLength >= maxLineLength) { + formattedName.append("-\n"); + lineLength = 0; + } + formattedName.append(word.charAt(i)); + lineLength++; + } + } else { + formattedName.append(word); + lineLength += word.length(); + } + } + // Ensure the last line also reaches exactly maxLineLength + while (lineLength < maxLineLength) { + formattedName.append(" "); + lineLength++; + } + return formattedName.toString().trim(); + } @Override public String toString() { @@ -64,4 +123,4 @@ public int hashCode() { return fullName.hashCode(); } -} +} \ No newline at end of file diff --git a/src/test/data/JsonSerializableAddressBookTest/duplicateClientAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/duplicateClientAddressBook.json index caa17d1ef65..66e0a05be7f 100644 --- a/src/test/data/JsonSerializableAddressBookTest/duplicateClientAddressBook.json +++ b/src/test/data/JsonSerializableAddressBookTest/duplicateClientAddressBook.json @@ -8,7 +8,8 @@ }, { "name": "Alice Pauline", "phone": "94351253", - "email": "pauline@example.com", - "address": "4th street" + "email": "alice@example.com", + "address": "123, Jurong West Ave 6, #08-111", + "tags": [ "friends" ] } ] } diff --git a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java b/src/test/java/seedu/address/logic/parser/ParserUtilTest.java index 3e4b4f01a34..a1f2cbacff1 100644 --- a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java +++ b/src/test/java/seedu/address/logic/parser/ParserUtilTest.java @@ -21,7 +21,7 @@ import seedu.address.model.tag.Tag; public class ParserUtilTest { - private static final String INVALID_NAME = "R@chel"; + 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"; diff --git a/src/test/java/seedu/address/model/AddressBookTest.java b/src/test/java/seedu/address/model/AddressBookTest.java index 270836d7704..f950c0b963b 100644 --- a/src/test/java/seedu/address/model/AddressBookTest.java +++ b/src/test/java/seedu/address/model/AddressBookTest.java @@ -3,8 +3,6 @@ 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.TypicalClients.ALICE; import static seedu.address.testutil.TypicalClients.getTypicalAddressBook; @@ -46,10 +44,9 @@ public void resetData_withValidReadOnlyAddressBook_replacesData() { @Test public void resetData_withDuplicateClients_throwsDuplicateClientException() { - // Two clients with the same identity fields - Client editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND) - .build(); - List newClients = Arrays.asList(ALICE, editedAlice); + // Two clients with the same attributes + Client duplicateAlice = new ClientBuilder(ALICE).build(); + List newClients = Arrays.asList(ALICE, duplicateAlice); AddressBookStub newData = new AddressBookStub(newClients); assertThrows(DuplicateClientException.class, () -> addressBook.resetData(newData)); @@ -72,11 +69,10 @@ public void hasClient_clientInAddressBook_returnsTrue() { } @Test - public void hasClient_clientWithSameIdentityFieldsInAddressBook_returnsTrue() { + public void hasClient_clientWithSameAttributesInAddressBook_returnsTrue() { addressBook.addClient(ALICE); - Client editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND) - .build(); - assertTrue(addressBook.hasClient(editedAlice)); + Client duplicateAlice = new ClientBuilder(ALICE).build(); + assertTrue(addressBook.hasClient(duplicateAlice)); } @Test @@ -110,5 +106,4 @@ public void sortClients() { clients.sort(Comparator.comparing(client -> client.getName().fullName)); } } - } diff --git a/src/test/java/seedu/address/model/client/ClientTest.java b/src/test/java/seedu/address/model/client/ClientTest.java index f22a9253b21..e9aa4729755 100644 --- a/src/test/java/seedu/address/model/client/ClientTest.java +++ b/src/test/java/seedu/address/model/client/ClientTest.java @@ -32,23 +32,25 @@ public void isSameClient() { // null -> returns false assertFalse(ALICE.isSameClient(null)); - // same name, all other attributes different -> returns true - Client editedAlice = new ClientBuilder(ALICE).withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB) - .withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND).build(); - assertTrue(ALICE.isSameClient(editedAlice)); + // same attributes -> returns true + Client identicalAlice = new ClientBuilder(ALICE).build(); + assertTrue(ALICE.isSameClient(identicalAlice)); // different name, all other attributes same -> returns false - editedAlice = new ClientBuilder(ALICE).withName(VALID_NAME_BOB).build(); + Client editedAlice = new ClientBuilder(ALICE).withName(VALID_NAME_BOB).build(); + assertFalse(ALICE.isSameClient(editedAlice)); + + // different address, same name, email, and phone -> returns false + editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).build(); assertFalse(ALICE.isSameClient(editedAlice)); - // name differs in case, all other attributes same -> returns false - Client editedBob = new ClientBuilder(BOB).withName(VALID_NAME_BOB.toLowerCase()).build(); - assertFalse(BOB.isSameClient(editedBob)); + // different email, same name, address, and phone -> returns false + editedAlice = new ClientBuilder(ALICE).withEmail(VALID_EMAIL_BOB).build(); + assertFalse(ALICE.isSameClient(editedAlice)); - // name has trailing spaces, all other attributes same -> returns false - String nameWithTrailingSpaces = VALID_NAME_BOB + " "; - editedBob = new ClientBuilder(BOB).withName(nameWithTrailingSpaces).build(); - assertFalse(BOB.isSameClient(editedBob)); + // different phone, same name, address, and email -> returns false + editedAlice = new ClientBuilder(ALICE).withPhone(VALID_PHONE_BOB).build(); + assertFalse(ALICE.isSameClient(editedAlice)); } @Test diff --git a/src/test/java/seedu/address/model/client/NameTest.java b/src/test/java/seedu/address/model/client/NameTest.java index 95603a076a3..146b3e4a82b 100644 --- a/src/test/java/seedu/address/model/client/NameTest.java +++ b/src/test/java/seedu/address/model/client/NameTest.java @@ -13,29 +13,30 @@ public void constructor_null_throwsNullPointerException() { assertThrows(NullPointerException.class, () -> new Name(null)); } - @Test - public void constructor_invalidName_throwsIllegalArgumentException() { - String invalidName = ""; - assertThrows(IllegalArgumentException.class, () -> new Name(invalidName)); - } - @Test public void isValidName() { // null name assertThrows(NullPointerException.class, () -> Name.isValidName(null)); - // invalid name + // invalid names assertFalse(Name.isValidName("")); // empty string - assertFalse(Name.isValidName(" ")); // spaces only + assertFalse(Name.isValidName(" ")); // spaces only assertFalse(Name.isValidName("^")); // only non-alphanumeric characters assertFalse(Name.isValidName("peter*")); // contains non-alphanumeric characters + assertFalse(Name.isValidName("John,, Doe")); // consecutive commas + assertFalse(Name.isValidName("John.. Doe")); // consecutive periods + assertFalse(Name.isValidName("John@@Doe")); // consecutive @ symbols + assertFalse(Name.isValidName("John#Doe")); // contains non-alphanumeric characters - // valid name + // valid names assertTrue(Name.isValidName("peter jack")); // alphabets only assertTrue(Name.isValidName("12345")); // numbers only assertTrue(Name.isValidName("peter the 2nd")); // alphanumeric characters assertTrue(Name.isValidName("Capital Tan")); // with capital letters assertTrue(Name.isValidName("David Roger Jackson Ray Jr 2nd")); // long names + assertTrue(Name.isValidName("John, Jane")); // valid with comma + assertTrue(Name.isValidName("John. Jane")); // valid with period + assertTrue(Name.isValidName("John @ Doe")); // valid with @ symbol } @Test @@ -57,4 +58,15 @@ public void equals() { // different values -> returns false assertFalse(name.equals(new Name("Other Valid Name"))); } + + @Test + public void formatName_breaksLongNamesIntoLines() { + String longName = "John Doe " + "x".repeat(130); // 130 characters long, should break into new lines + Name name = new Name(longName); + String formattedName = name.toString(); + + // Check that the formatted name is split correctly + String[] lines = formattedName.split("\n"); + assertTrue(lines.length > 1); // Ensures that line breaks occur + } } diff --git a/src/test/java/seedu/address/model/client/UniqueClientListTest.java b/src/test/java/seedu/address/model/client/UniqueClientListTest.java index eb37f393dea..ea36018cdef 100644 --- a/src/test/java/seedu/address/model/client/UniqueClientListTest.java +++ b/src/test/java/seedu/address/model/client/UniqueClientListTest.java @@ -3,8 +3,6 @@ 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.TypicalClients.ALICE; import static seedu.address.testutil.TypicalClients.BOB; @@ -40,11 +38,10 @@ public void contains_clientInList_returnsTrue() { } @Test - public void contains_clientWithSameIdentityFieldsInList_returnsTrue() { + public void contains_clientWithSameAttributesInList_returnsTrue() { uniqueClientList.add(ALICE); - Client editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND) - .build(); - assertTrue(uniqueClientList.contains(editedAlice)); + Client duplicateAlice = new ClientBuilder(ALICE).build(); + assertTrue(uniqueClientList.contains(duplicateAlice)); } @Test @@ -82,17 +79,6 @@ public void setClient_editedClientIsSameClient_success() { assertEquals(expectedUniqueClientList, uniqueClientList); } - @Test - public void setClient_editedClientHasSameIdentity_success() { - uniqueClientList.add(ALICE); - Client editedAlice = new ClientBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND) - .build(); - uniqueClientList.setClient(ALICE, editedAlice); - UniqueClientList expectedUniqueClientList = new UniqueClientList(); - expectedUniqueClientList.add(editedAlice); - assertEquals(expectedUniqueClientList, uniqueClientList); - } - @Test public void setClient_editedClientHasDifferentIdentity_success() { uniqueClientList.add(ALICE); @@ -164,8 +150,8 @@ public void setClients_listWithDuplicateClients_throwsDuplicateClientException() @Test public void asUnmodifiableObservableList_modifyList_throwsUnsupportedOperationException() { - assertThrows(UnsupportedOperationException.class, () - -> uniqueClientList.asUnmodifiableObservableList().remove(0)); + assertThrows( + UnsupportedOperationException.class, () -> uniqueClientList.asUnmodifiableObservableList().remove(0)); } @Test diff --git a/src/test/java/seedu/address/storage/JsonAdaptedClientTest.java b/src/test/java/seedu/address/storage/JsonAdaptedClientTest.java index 3acc1713304..6998a95b275 100644 --- a/src/test/java/seedu/address/storage/JsonAdaptedClientTest.java +++ b/src/test/java/seedu/address/storage/JsonAdaptedClientTest.java @@ -18,7 +18,7 @@ import seedu.address.model.client.Phone; public class JsonAdaptedClientTest { - private static final String INVALID_NAME = "R@chel"; + 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"; diff --git a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java b/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java index 44ce3c295d8..4dba62a7f4d 100644 --- a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java +++ b/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java @@ -40,8 +40,6 @@ public void toModelType_invalidClientFile_throwsIllegalValueException() throws E public void toModelType_duplicateClients_throwsIllegalValueException() throws Exception { JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(DUPLICATE_CLIENT_FILE, JsonSerializableAddressBook.class).get(); - assertThrows(IllegalValueException.class, JsonSerializableAddressBook.MESSAGE_DUPLICATE_CLIENT, - dataFromFile::toModelType); + assertThrows(IllegalValueException.class, () -> dataFromFile.toModelType()); } - } From 96561b487721ce2d21631336e4a27ceb2384b819 Mon Sep 17 00:00:00 2001 From: Nicholas Foo Date: Tue, 1 Apr 2025 02:31:26 +0800 Subject: [PATCH 127/249] Add SortSequenceDiagram UML --- docs/diagrams/SortSequenceDiagram.puml | 53 ++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 docs/diagrams/SortSequenceDiagram.puml diff --git a/docs/diagrams/SortSequenceDiagram.puml b/docs/diagrams/SortSequenceDiagram.puml new file mode 100644 index 00000000000..00d8b888b88 --- /dev/null +++ b/docs/diagrams/SortSequenceDiagram.puml @@ -0,0 +1,53 @@ +@startuml +!include style.puml +skinparam ArrowFontStyle plain + +box Logic LOGIC_COLOR_T1 +participant ":LogicManager" as LogicManager LOGIC_COLOR +participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR +participant "s:SortCommand" as SortCommand LOGIC_COLOR +participant "r:CommandResult" as CommandResult LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant "m:Model" as Model MODEL_COLOR +end box + +[-> LogicManager : execute("sort") +activate LogicManager + +LogicManager -> AddressBookParser : parseCommand("sort") +activate AddressBookParser + +create SortCommand +AddressBookParser -> SortCommand +activate SortCommand + +AddressBookParser <-- SortCommand : s +deactivate SortCommand + +LogicManager <-- AddressBookParser : s +deactivate AddressBookParser + +LogicManager -> SortCommand : execute() +activate SortCommand + +SortCommand -> Model : sortClients() +activate Model + +Model --> SortCommand +deactivate Model + +create CommandResult +SortCommand -> CommandResult +activate CommandResult + +CommandResult --> SortCommand +deactivate CommandResult + +SortCommand --> LogicManager : r +deactivate SortCommand + +[<--LogicManager +deactivate LogicManager +@enduml From 92f0ea7d66c673a4e51cce053110674520923762 Mon Sep 17 00:00:00 2001 From: sciphi-123 Date: Tue, 1 Apr 2025 10:43:14 +0800 Subject: [PATCH 128/249] Add further edits to Name class --- .../java/seedu/address/model/client/Name.java | 5 +- .../seedu/address/model/client/NameTest.java | 48 +++++++++++++++++-- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/address/model/client/Name.java b/src/main/java/seedu/address/model/client/Name.java index a77acbb950c..f9bc3ac6dc3 100644 --- a/src/main/java/seedu/address/model/client/Name.java +++ b/src/main/java/seedu/address/model/client/Name.java @@ -10,10 +10,9 @@ public class Name { public static final String MESSAGE_CONSTRAINTS = - "Names should only contain alphanumeric characters, spaces, periods (.), commas (,)" + - "'at' symbol (@), s/o or d/o!"; + "The name given is invalid."; - public static final String VALIDATION_REGEX = "^(?:(s/o|d/o)|[\\p{Alnum},.@])[\\p{Alnum},.@ ]*$"; + public static final String VALIDATION_REGEX = "[\\p{L}\\p{N}]+([ '-/@]+[\\p{L}\\p{N}]+)*"; public final String fullName; diff --git a/src/test/java/seedu/address/model/client/NameTest.java b/src/test/java/seedu/address/model/client/NameTest.java index 146b3e4a82b..b3994d297f1 100644 --- a/src/test/java/seedu/address/model/client/NameTest.java +++ b/src/test/java/seedu/address/model/client/NameTest.java @@ -1,7 +1,6 @@ package seedu.address.model.client; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import static seedu.address.testutil.Assert.assertThrows; import org.junit.jupiter.api.Test; @@ -26,7 +25,6 @@ public void isValidName() { assertFalse(Name.isValidName("John,, Doe")); // consecutive commas assertFalse(Name.isValidName("John.. Doe")); // consecutive periods assertFalse(Name.isValidName("John@@Doe")); // consecutive @ symbols - assertFalse(Name.isValidName("John#Doe")); // contains non-alphanumeric characters // valid names assertTrue(Name.isValidName("peter jack")); // alphabets only @@ -39,6 +37,23 @@ public void isValidName() { assertTrue(Name.isValidName("John @ Doe")); // valid with @ symbol } + @Test + public void isValidName_invalidPunctuation() { + assertFalse(Name.isValidName("John--Doe")); // consecutive hyphens + assertFalse(Name.isValidName("Anne//Marie")); // consecutive slashes + assertFalse(Name.isValidName("O''Brien")); // consecutive apostrophes + assertFalse(Name.isValidName("John ,Doe")); // space before comma + assertFalse(Name.isValidName("John. Doe")); // multiple spaces after period + } + + @Test + public void isValidName_validSlashUsage() { + assertTrue(Name.isValidName("s/o John")); + assertTrue(Name.isValidName("d/o Jane")); + assertFalse(Name.isValidName("ss/oo")); // not allowed + assertFalse(Name.isValidName("x/y")); // not allowed + } + @Test public void equals() { Name name = new Name("Valid Name"); @@ -69,4 +84,31 @@ public void formatName_breaksLongNamesIntoLines() { String[] lines = formattedName.split("\n"); assertTrue(lines.length > 1); // Ensures that line breaks occur } + + @Test + public void formatName_handlesExact120Characters() { + String exact120 = "x".repeat(120); + Name name = new Name(exact120); + assertEquals(exact120, name.toString()); // No new line needed + } + + @Test + public void formatName_handlesLongWords() { + String longWord = "x".repeat(130); + Name name = new Name(longWord); + String formattedName = name.toString(); + assertTrue(formattedName.contains("-\n")); // Ensure hyphen is added for long words + } + + @Test + public void normalizeName_handlesSpacingAndSpecialCharacters() { + Name name1 = new Name("John Doe"); + assertEquals("John Doe", name1.toString()); // Normalize spaces + + Name name2 = new Name("John,Jane"); + assertEquals("John, Jane", name2.toString()); // Ensure comma spacing + + Name name3 = new Name("John@Doe"); + assertEquals("John @ Doe", name3.toString()); // Ensure @ spacing + } } From 7cf690fa85df57952b2378baa5faf4c3ca121fb5 Mon Sep 17 00:00:00 2001 From: curiousfun88 Date: Tue, 1 Apr 2025 11:41:47 +0800 Subject: [PATCH 129/249] revamp ui and css edits --- .../java/seedu/address/logic/Messages.java | 3 +- .../logic/commands/DeletePolicyCommand.java | 2 +- .../java/seedu/address/ui/ResultDisplay.java | 1 - src/main/java/seedu/address/ui/UiManager.java | 2 +- src/main/resources/images/WealthVaultLogo.png | Bin 0 -> 85733 bytes src/main/resources/view/ClientListPanel.fxml | 2 +- src/main/resources/view/MainWindow.fxml | 2 +- src/main/resources/view/ResultDisplay.fxml | 5 +- .../view/{DarkTheme.css => WealthTheme.css} | 73 ++++++++++-------- 9 files changed, 48 insertions(+), 42 deletions(-) create mode 100644 src/main/resources/images/WealthVaultLogo.png rename src/main/resources/view/{DarkTheme.css => WealthTheme.css} (82%) diff --git a/src/main/java/seedu/address/logic/Messages.java b/src/main/java/seedu/address/logic/Messages.java index d3e3928fc12..7198f8b8976 100644 --- a/src/main/java/seedu/address/logic/Messages.java +++ b/src/main/java/seedu/address/logic/Messages.java @@ -14,7 +14,8 @@ 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_CLIENT_DISPLAYED_INDEX = "The client index provided is invalid. Client index must be an existing index."; + public static final String MESSAGE_INVALID_CLIENT_DISPLAYED_INDEX = "The client index provided is invalid. " + + "Client index must be an existing index."; public static final String MESSAGE_CLIENTS_LISTED_OVERVIEW = "%1$d clients listed!"; public static final String MESSAGE_DUPLICATE_FIELDS = "Multiple values specified for the following single-valued field(s): "; diff --git a/src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java b/src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java index 7d66f881ca6..f53746018cd 100644 --- a/src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeletePolicyCommand.java @@ -22,7 +22,7 @@ public class DeletePolicyCommand extends Command { public static final String MESSAGE_USAGE = COMMAND_WORD + ": Deletes policies from an existing client identified by the user-inputted index number. " - + "The index number must be based on the displayed client list. " + + "The index number must be based on the displayed client list.\n" + "Parameters: INDEX (MUST BE A POSITIVE INTEGER) POLICY [MORE_POLICIES]...\n" + "Example: " + COMMAND_WORD + " 1 t/Life Insurance t/Health Insurance"; diff --git a/src/main/java/seedu/address/ui/ResultDisplay.java b/src/main/java/seedu/address/ui/ResultDisplay.java index 7d98e84eedf..00905884f46 100644 --- a/src/main/java/seedu/address/ui/ResultDisplay.java +++ b/src/main/java/seedu/address/ui/ResultDisplay.java @@ -24,5 +24,4 @@ public void setFeedbackToUser(String feedbackToUser) { requireNonNull(feedbackToUser); resultDisplay.setText(feedbackToUser); } - } diff --git a/src/main/java/seedu/address/ui/UiManager.java b/src/main/java/seedu/address/ui/UiManager.java index 7f35f37eb09..56f0db76851 100644 --- a/src/main/java/seedu/address/ui/UiManager.java +++ b/src/main/java/seedu/address/ui/UiManager.java @@ -65,7 +65,7 @@ void showAlertDialogAndWait(Alert.AlertType type, String title, String headerTex private static void showAlertDialogAndWait(Stage owner, AlertType type, String title, String headerText, String contentText) { final Alert alert = new Alert(type); - alert.getDialogPane().getStylesheets().add("view/DarkTheme.css"); + alert.getDialogPane().getStylesheets().add("view/WealthTheme.css"); alert.initOwner(owner); alert.setTitle(title); alert.setHeaderText(headerText); diff --git a/src/main/resources/images/WealthVaultLogo.png b/src/main/resources/images/WealthVaultLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..2fbb190b8e8d7c26724c9ca0fdc5153d3546d176 GIT binary patch literal 85733 zcmcG#cT^K!-!B?Kq^O`GNQ%3>J^G7B#dwWI7C$BCK0#(Od`D;N=ye9F|R(cA8BU#sp7gX*qjJ!ag zD|8nh5>R?3BawhcQ%zSv&B5a?m%%+Q{d?So?Dw_V?`z%THXdwk)?KjKv7{DH$Z)9)pBc^8EZfeteCYLy>_|3D*ma8C#*f zF3-tlKy_K{=g!~J{d1N(>gdz+@2h`uaewQ2kuXHx!v5di=jU4Hq1n^8-ScxP1*g>C zyB)KedaqMF%Uhr6`r4$G#TK+BPvIKI7au-(mDbqpl-Xe69KCsdj@&wl>w-DF$v8bf zFZlkmVi=|A5g+k=Dj=?e@$U1Q#a&Tpo1iA7ev)H&YqCwT_xW*wZG0sS4Wy#Gdw(X9 zj!`-g@WAeEmFK)2?~co@?4oCt`_PmgT9L>6q4JREt}EW!8ag0wZnY=QL-4JafJOdC;Jl02$W*5Xh$eNGCJ(=zgP_NJV@_GY`( zLLCGuSWhAtn`~xQ>zizCL@JPgl9GLp5SJO4ha#l%1q38#VMO5D2qedvVi1x!eNtf8hHIbYYbn6D7DEV)`sChH*jATP7}a;~k>`AoG)A(W1K>nRkE7tiq}TXC+>VNLJJ(2GEul zxnHi*{w1L_`u*mXezGP;of4rq+p{Fj6{6=om1w7Ir=L!yq^I~EOpKB9F{gL&hFmNs z-v07At8GoTL3!Eac8iOv@BA zcVojN$VquuSor*q(9>S>O6F0TKFQ6mR&6QR`)c`^HKuPD{u0u5`U){C$={H?<$TM#=BNJ&GDTHT?x=-%n2+T*V6i8e#%qo@JS|+ef2KOsITkMm? z#I;7WH72QUFDu}565edwvUDtj9`P8G*&J$@E&M4}NM7^nQr4up8X`wLpP-F;9B-F{ zP)_JI^5t7*;sPxd6{Nh`WugbCn*B9KF>&hw@Y(*rE?oEqt!x2}w*e`-gw<^?Eem+E zjlw5aIdNDN9aJX-LW{y_9i$0Ql%6HKQRm~m>2r@dvCJ{WhWE?Sm8 z)vo75%_@+r#jgom^)vQ%4Z(jUzPbyZb*+R^e=@O1`ST*O6L-}94Rgk4G1+&;;R)Ld zuMAt;yo`yzYz7AR!22ow0ZHXJmQW!1oA` zd^VeQ=&3bTVD=_H;JwRS0Q<0d?g&j^3SmcZOJ<{US@Q6p;M~jPZTpBFojT$y+e2Bs z{ouH2y2hsZcoJ*JRSasr4PX*m@ZJZ3zXH4F@A&>aK(oGpm2?xnXWe$22)GW**mZhC{Sq7U6<=XOSGn2OLgBEw;9wxiE*dXReGL4y z%Fx69sVzqk+p2J}91kM(myhKXlLYQSv|5%-Z>fAyvCMC0@#vcMZQzL~%^t*v z8*82QrA`!?-BhJ5(OjdG5vH76716wJqy@@9a~_PtBHxzNjpDPt%Gp=ep7QcXz-AZ3 zxr``o8KXW5M%`(ved%neVnN`4!IIXq{X+oC{~p8DE1Zq&`r90(JVAmEhn82JWR%m5 z;ZKatH2z4{snVwnwsbsLTip}tmt-HSDhp+JY3we^*^})HnH1)zXsXVcl#MmwIsZG( z@P6VZdwV$|943B(j`xWl#k+a1c~L^{<5?67Ju1KekCzVK2ONU^uvPRZHb3=e)rrSV zRm+jq;N8>D;-T7=frFX_Hegv3_Fm|a%HRkV^*y=>CXoh?Z5dGiQuYSZfSbOvQcDOn z+>m4+soJ!(P?}KaLJnH2GIt92INkMZ3m%>gP4Z7AWRZa+-otz>Umks|3fTSO`jUdm zOHcLod`l}uvI;DNl)bmgDTWc?mK@0blbqd6qri)>j!B`dhc`x!1oU4M?F4n=%V@Oj zVhf$V2mYatvjQUhQ{{FnxG^JH_B?DDeLPccf~k%|m#b1h>JTMa4GrXoR?I@o;ytxR zirS3vkFE!6k3YwklNDoy?qL~YkEmOHwn+AbNO&PtG0k--kDsX7zT);OewSUPQ|IjO(at$HS3|~~DB5K7f!XI`DK>5JE zrru#H1#~sBOco#uC6pF=Sl6=O!a%SgQh8*vkBEjW8DrYa@l_7>5T%R!m$+i=#JH3I zj^T}-#D8E+%=Z4_BP5B^(y?QS5L|us^GA`A?V1+7|3R={+1XY%Mtj?%L|Sddf|O{t z5~?By+%OxMuH`VJy~Sg9hf5B1g9z;j^H#;F7p)F|;*n|u1oA40N|tTt-!1*mLLu{Hf1|KO2k*8e*hEFNZ#*e zRrZZakGGf%j!cv3IQ30T0K%ZJjQ(Zxbzm|;Zm2%I$p>|f?e}Nmj8SR?F`|i`u5CF8 z?%}@0)JX~1o`BI_cC2UV=09_Eo%r3ICuKh^2*O?~ZBXtou%H_TIw1{4OgWKNHKX6=gSQIB~mbIkK0TxBlw_n(w-m$uMmFxcX%6!4gi3~GtXXmoZY4NZ}n2C?CT#RJw z9MG=5Mw84VJC8*P(to-x$pJBJhk{Ke2fcbjEj9#)x)bve4R!=We34sZjuIoN=A;Un zgSR#in8Ix=#y&(yQ0O8%eI$+xDUS<5>x3saL$n?)o7ojX7e%woJ*({xw>qh67#yVZ=oC%Ih!^b_AVaq5Zym zgO}mC2v{2v*}E0<*k2xMgN0qm3b83KoLT)oVhZq5cG24mlWbbrS~TX&$UD zFP}8F(#3;WdpdnUKP=HU4TIi{Rbd%2K0MydmevD?4=p_9k#vx3RC$`8ZguW|QXgvD+!h zMa1|MF(q;UxE3RTq2dWUGr0)WCveRs>nS!@Jod~2qRkT(LH6&l{I?=6_7WMd`ac5^ zX`TVFU$DnjF27M^SH@wkZ6xA16aiB7V{hi#KRW%k;i9RG$PE)%p%`=QYq$1yR$p;; z;`%vdS8GpSTN|`v6Sv=Y>m%~*bB(}NkOpOq(^Fuyne8 zxHNG5F=!WhMv{56pCtJ*O|iYCtmmI4dOWuN`1ohFNVeJRqL3xAG+~YYf z^-Lz$ukm|TcL%A4#a&{DSo?Zd&+Wx*8xCXF7@(DIt$~**y@(#ie5a5>$R0;Qzq+R3 z2a9D7x5HRKM6chrk*uvNNUAz+6+DEq6rPN-7>nqRdW6kCyU^4z3v@a!@z`w9R%j-> zHxzhR#tZ0nt}s#)6;ZVFjCeSgJhk|Z5EX-QKDC+tKtl{4oG$%a~}A9+g^s z`)BN3;1TTRK%SL%fSw(x_=S<0OkmdX8^#XH`ry-VAR-)V18y?!$rf!g)dwwaNr)7E za3rUC$z}91rSp7!VJVVT#lrqVSRY(*lInM#&=@$`7pDp1DYbe-_Rp{@>xrK4;Yv4r zb3a)hELQz5;*Wl-D3x3ULoxD6g*IdSKbh`CX|m}$sdyEa=}4|qrjaWt2M|5`xD291 zl@D?DWuCl7p^^qSSHJ2)?yf=;=V)#43Rt)&gF2CQ94p`{Yegb zS#oZScHGgLio~zS+nSj-tq^=%zz%P%V z?wTR0@APE6sP*XDKX#SL*2o5Fbna2CUqUCp1UwGE$W9idZMGXryZ%wl9GToyTDKEL zD^71sises5uZyeD*xv}WK1M^#PB$an>z70Zk2cr$98VU1+kQ2Cn4m!FF2XR&fPTyl zSstl$EfaPS_*!#x{h*#LsoEen$kxdLs|7km!@Kv31U<5A(2Cp(LnvC~kb zSHEALg)OsZNXhgR-1AZTAU1ym~mMZDQz+-wORX_8H_2~=lheBT( zG+yDCB)upjgUsODuvGDb&cP=;c`r`jrc6)m$FvIiV|fafy>`Y2HSJmutGI{zqvUxP z^(F8K)p|SY0J8)cd{g+ZJr!#0mq(3}&WyTl{!h>leQRKz4rUg2Gzc#xsS zP}1nvlzptl{!H(1*U1Iq6)(|J*4_a3D;I@r|9$YLtyNiMOgQSI1~@}8E`-QLpecSkwzY{59Pp#WhJd zEh=j~cyQ6>^x~lrp%@k}7UxNMKp0LcQv| zZ(n00$%;ZYo{DX+PXDrMyF?6xV24C|m7~F~izka=c#ZHn}VaA1h6icem5+ zO}lj=tjF3{Ie+AlL9>5Q^k2=7q(vh9Qzg1i=?U#k8V~55R|r>hFWfWEi-@8I(zb58 z75dzcI3j#vg$q?KNb$H ztQbe2`UGImZ-?!es7KqX z??Y^UsxJE*7Q3h&wQeN#vI4<(@B#~%4bUm!c{DMfQCd2gjZ^9Q78-eG2 zjj1J<`do$dHs zn+AWkWU8iStVbJOMD+Baw^9!feWDT+J9xj9Hs92v`w2SMi#M6D8Fr`c%rQRipMdsT z6Ba-JJPb0AZADAn%+?qsonAKT^4|R#-*NnwQ|%&!ep@S5os9Hleu>hXFEd5Q@&(Iy zVOE=wF@=eL&ap6@>f#V{kIR&ILhM6)yhF|>Z=Qt3cma}lnJ7%E;JY6b>9pkM#3ul2 zE|&_p#w$s$qLxX8pU_E1z;~!}@-*@~*Cmt>HKJ~pEPEE+LF_IAL-|!2y|Abt$mvYd zhBr97f^C)3;%Nw!y9)Amz#$#pz#Eiy(>!j9NPX%ro?^7?HQ?ku*kZ;wTU@=Acpgg&69mmzS$15v+zC{kd|Wb39i}Fc{XyxHAchp28FoQb#ou{<{lvq!l#@ehI$K4m0tR5Nqt8 zx{SF9Q7t{2-=4yf)au{80`i0AJdRI)+yC05{j_?L{mK87xh*#0rE*A$F;NZ`f`22a zWK6t;0Dg6SDA80wbZle|>)u$B13eHg!3+9^i(4i|K8FUg=e?jjdVh_2?OKFe8lgG8 zzsw+^(oL{KlCp{;99pWGV$HeE%)^(RpghA=HgrD>+7?n>CSEu=@2W4&XdI)xV^Ry> zQtZT(9Lh%LeW>k_V`?4g{b~VYo>(6i^Ga4Py5t0=9CfB1R>oyz1LS?Vd1V&Iq`kM;BbYJ=WgJoaij(_Mt z@(uFMJKu=*7NEiKauG73l3=yHl#;QP!Y3M%Ry zQi_{@7|+tnZPb^oY#aKZMiPJQ-QNp)q>=UL^{K_ypLeOr88l0u$*O2bv6L1mrOwbA zAKQ-jslpT8hkJc|`Jv!wDAcB3)WxH+gOQ z!Ze2zQasPN_r_>M$8ET>h`z8lSTiU+$y1T)x?5V zj>5_lkCgQLC8H_-QJ1Wcda{-;fwDo=4E_0KL18ud2~g(5MF#kf-AmT0xNcj)Zs#Cn z6H;saYO4wew>>s&r`cTbiyu2jDF#auidjvzk?n$ij^dYbl(?@9Z$2`VfOp3DFBrV`}h;SiwJ-`uUBf2TqPN z++V7C?*NG~`B4@`j=wgrZY7P-QXdyu(;ucJ+a!kSIw0~sjY8khfT8q~{F_U-59SdV znPG?9Bc%?LZryafnv8px3E4_k*+Ru?A>Wjd+V_y=4Y|!tL%+Ri7Y-IdDNlSic|hJ^ zpHf!@ro!$r22$|b6Qs(f-u`eW=?pQUpN_NS>5UV%vyTCu;q^@im)4p8#fY}W{H)7= zOAKg~DB>!hWfH`@E})@|csrugSc(s)+Z<4@#uWQGJQX z{jH+rBG#O$X8CU(?fTV_Xdh0Tagw!h1UMQ~P3`(r|7Wmf`{ggI8~Vv6309-1Yy0wQ z!dJFPS(%BQ@2XYlLQ?cqfPV})u!y*gR&s29LtS4V5o0_UK-K|WFkC@lZ$b=MM6a=} zpf<=zfH0(hx>!;VybeHrACSVHNna+~GtSfNm{nz@FaiGiB+% z>Lz^3M2dZ3(Wqi?)TlmPq46-9%F0d-?KSQR`RP>k$J=mT;AUo7|L`4>KZYZz)htw) zOd&2Vt#=EzE;C{wwj^(XP(prZe|DsUbx50ANH>&c`PrsL_XBmc9P{QU1JZ zDO&>CPvhg($=UC%`+vTS==AYH4h@gqS6i*Xg+ePRPG6XOl(=%6@%$>$*;Rbe(3_Wx zl&Yp5wHTIF4O(E;!1K$0gP7OT#zgej+JmwzXQz9-dKj%-jO^egrtRNjtG92+t6i85 zbH*ZDwtc2^fA}YsRgfXh>)vBHqhZx@E8~eWF5Ik%CLMvxdtu%_Z=Ck6{c6K|Ma2b% zem0`QWmg%^K_tMJDifD?NOSIK+N%-7UkYh@kZU)Bverg{tm_r@kwVYc z!(ZfS_My`K(~mjS%_fy>(Sxqx!XWerL~E`u;RArZ)nm zmvFj z9obRTXSCMHSDN3MYg|)aYxR;dy&GL2#c015zDUI@eD}jGz$Okl0c8}`X$6X|6AM~2 zFw*TQ)HB+PZvwB5=;T{bUTdasS&vxkW%N?7as5*9?qgw`7poX$-Y~jC@-Z+v<)U%d zj>5{$bWb(cWNAYY$@Fnn#LZAdP|`eWlb-f&=Fc<#V zm1lVk@PFq?vNzz$-QsxtcV_%1{q6yW*p+KaXK4}#G);v#_VighLrbDVk?_UcBq*!b zxc^1nD6)&D4LwTyB(33qs~hY6d)nt9N|)0dR6Ro4L-X#1#bn^E+B%?qF}0yoc#k|9 zM(;$}-f@I*RX~->ArGhD)I&Rxs_9y8@NX(TJb25#A++N7Q+P9}UR4qR)~ai5aBahn za1=xIUA2`(ov4`lah{jO8gJQmg=`60Ly8`1CdB$9QsKP=Odk?S~+k15G z!0t^)n$U(t;;Q4JqeO73VhcIw?6wuuEk_t|_Vg0j>`$3<$LF?R0%~NIFGa&@fM#Vo zG1p6o%Cu@oTKkw!Lu&N-9jBsbOs{jcPkW7CRRQgza$eHMBSrd zj6kts&&I#ud5-o^D}p%9RwG(}oY55G?YQF`#*86cZ48@#-@41%o-DPQSQSwkuqN;A z4Gs?S?T6&h`0UH(O@!*b;YA84>rmSf>JInk8js;Y+wBu1Q*E-c2HQG6OaOb_p_)#7 ze}ow|@kU-97wp%y>F=95ErRz9mPGopiAUtPKEI53BteB5H{0`aM#4id**$ndilkJ^ z>bc#PX#kzgvCu0Mld12{En-YBUdWN?D1{0OE5>L#(B0ho6CPNt+W8f zxXKxwR?Au&g!)Ae&Ww)S1_-J}nG>bFgCM6Tt{GQ6(!tPKl-i;y@LU-@@@ME=Kj z35dY^@Kda`eV*L1FG@WxWx;GnA?NSzr@8yv8itU2z7OnD#(m}9N971B5$L?#J+GS+ z4vIZU5jp%QpIMa6^-76(Ef?T^rt?GD%C;(_qVyi*UV626D4Q)!W+({p5=GA1fp2yo z8saL|(tRR#bYt?5gXjbvI&8TA>=^bImeP^bNfT8c-D zX>teTNyRfZj1aFwj|m?Np7mQH#5MRl_ACTyi4|zotl$Y=z2m*&y%aE-tdEchhzI{% z%@<{Y9FLz+j}n(d=Djpl8Vnr2N>6(rTh0>#zw}BrIeBTBR>oQ1uTJ3>3)C-vctu>D zbfyM}Lani{l-A^q!+jS!m^@aMheW|f2-j}mEmVDK_vcBwkCv|;b~s;9kO0L!))B%M z*q~Jm)0nUBboIy|>2+Cej>!I{W{DY?jo(0fAv{1bfwFd z3)ga^_su8K&k#m7yAPIyU>`Z6<*?_y%Nm+#>{h+V*=vfcYck?%YBy)np&zVft+B!) zEBgfS54J*@2%<;>2}^et$Ms5KTVLPs0zGOJ)a*Zhd@-Xv_Sm*;YA?`suAk zjTE|sf^JNNnpT}yU~}3@w^*CJTBBo@6CMV!*7jz7Q1q@{*}WB6opRmW;2YYdolm1@E`mApinJ#&^QLHzK|l`cHKNBKG-F^-9DzbrSYT`X zQb3jZGtE)C4}HaB(RQ@Yb@nAQuxp@VV!k}B3V0Jh%>L#eClp$thh{yNwW&-vb-jfJ zF<3@RIoPQ3d@kCF?`7_pp}ZFLB@}%ahC>i3VD{2q54E0M6%~zP=n=3Jua%i;{#{+` zF%(gTh=yVnU9^UpNa-#VEL1J#5!hc}**co_QYS7bR~LKw6cEfFs{*JigIoRkp{Oc^ zZ4p*CK#vx?MtQ*@QlA}**6`ew$*e3hWDtBmRpDV!aNz)%wG{wCLc zX%|veE5e!>oMe0H`8-z9K4`QN8?j?X{)T6%(2KFA^NPm$b05U+M&JGMnqO<^#)dZg zH+XriDz7f7z=qBpmN4koX^I{JS=@#S=BK%bb&s%HfBg@wAr_u|1~0wVe!Qqr#3CgL zP|y>uP&G#Cv7zJ0N6Z0cUDOOuKJ!AVDh%94`Ilp{IFB;2(Nf5jj_p;fhlJIj?FF!RK=3{lgw( ziJ~Rt_X~EaVfLy4pZKW>&<~bN3XORYu&>pWZ#M1EPgyGpyX5KB`t*&Ob;emY zm4q{f&@R0wU(LIpC5p}Q_Ek^P0+$b)v?9V;LBjy-lv#XuD*`*KI}_XLqWhZv?)&XOp59*uxVJLKs_2Zai9h z*8{(dYMu9Q9@pd=mq}HIc<||_?(>uyaS;P5LQaZB{>EB5O;Y2utq3#4wI*GtdKJiq zz!S-MLurTB*zuy`l`6j!3?=dL8R7L!Ad6{2!^&T?{8sH{l*>eu!bSmfryB+lQ{%$o zCH1rKCFX98F04x?Y08ISn9K>RgsJ*@+&k~N4zI*27Aps*m^!}rrhMJ$YgArSeKABJ zB3FRt*<X2YNb~;uIvQW~Ma@w#Dg7 zD?}22Kw*pC@|VIfuvH&BdzF?W%gh%{hxzgJt=qKcD(AJg1X%#?KQF7Jp$n;5Q#_hR zw}Q*gGmj6AsxkuF*kwoJWnT!=BMs8N8+he*gRf<&*%ran!pdJ-Fj%RqxGyuq7K^=#I^9aLv?CbK)AQgSx=o=1Uk)3;HCV!Gth4D^b|G(c zqhkJ!uzaund&_@j_HAfK6D6)#Y^utF`%3fjYPt{%vt81+pg*uqU~R7m^Fsde>e-y^ zccjM?5KNc!CNi%m`XD8v)O*oY)KfZM$G+-9p&$*c}U$F2zXZn5ZC9n6cWn7oW@87eVL2)Y# z6vIZ0Op9cLCeC5@tKTMKC<8Vun$21bXMd?|I*EV1zIWS3o8MZm__^84{&=Wgm6eik zjM15e1uGt|+L;ph*ymN}vb-eCH4}}XdJjp3_v{~>lo!70Jq~jHD0o{>md3}c%_OFE z{X^GZXfDGg<~JxnQKHbVYVbi1>wD5#0iM>n!m-KIj$d&t>I+5gnl$fnYIzj1Zuv|3 z)L!k)>N30bEItPQ3wj;4&;GP8*^iS~3~OQ0759|~f;3D4Mvo@EtLOS!EL4S8?^Cra zP`*RD?k40Ex(GBPe=)mH#B16IHxEASP5SVml|qaOiC4~-FzNRnnB*+pY!0-%JRl&qdM> zH!+d}M5s?ba4U>V_3VyUKZLudWCOYx)plGjd>1%zsW6J2H!Y^$Q{PkzD8d$_pN)S| zjzDo!lH_IxRP70O=J*d&`FocTh)P17l)qQ7rGT z{gA)@OLF_qZ`)1CL~2>yd-*$4KiQom3+<}{nl_ZnKYQ*qoor~u8>akWHbmb06~`O@ zR+94F6s_IOQ$_?NcIHR?o}rVTG=(e;iX;CcI`)FJCRo}$o)Do z*zX=qdC=GwTt2-|oLFb2Z&d!o3*_&a`?N47vQ2O{AglHFa$QJ$u3y@r8@#_%yfvv4 zJfsd&Y5NLu5@p8SLty|4AinlQoC*?an1X8AM+#BO*U-FUhr8RAc6CK^d!^WUGLEZ3 zExR)*NR+*KTT`oB zQ^p4!BZ=pq`02BLBUFe46tx4k^CeIFl?o@xohr6zZ1T4_-+46F`O5{6fHeu!55Bz{ zP6aYl6VTbM40A4Wm9zJRGsZfc688FH!?h}tz?_pdo0Q2spb!PL23A|LLFaaf?o&<# zxgwD6VBv^Hdz&^I(caZ2?zXT&yRM~}BQ)OR_2K9G1PVvJg<9~BTJUo-PM;~hoji4v zIQ?~79p^-tYa{j7{!|TH`I;@qfsnoW2^{}1bulo()(wEk%4q(kOiUo#j(y?OR{LVU zn$OK`U2r>3IdJo3b`C*tIi`Wd3L+vQV!{d8&w@5RLa)cx>SS&|v+ELIf)YNHSU4NU z^oW((heZ^PF^3Qqh2{*Oe~RD}oGS7f4mF+U@RuCAGVtxx$j>bX*N4*3`f~F{zKzn# zrt-`_i>a860Kd%ht`a<(K}HNquLNjI>FeF+Pi8T5Z9Y(f`uD$OQpg9;eNwi5zvD}6 zKrilaf_*9Jm$h3J2F_la+1BQA+c29ursOkB?5hAGbtom#HDXgm2N}GyXOB846L%|h zG`++NnoWtl`7-6!gY~{we@NR8Nq0tQ33$NKQWj%cHW z@mdqQn=F713Ys(-Lz!_FrYzuhIzJ?4wUl?t$^b6N1rECu|0Xm z0}arsC;GtsC)gec2Os`nP_wv=jBI2!pa=R%0&-nKu$S?7wDNHsh`1GxrK+@GC)Wx^ z^#O_ag`|hW8Vl5u{_0Hox@989w zkIVBG4#cW(+HSzVhu`P2%AIcwy~+ie@A5VvFZ1y(p|X%{d1GMx+&SeLfb>5T{pcH4 z7bnn+tm(EG*V6=p=AVTktnLd=#YSX=DL&Y##SJBa;{ne}^{u1uexAj$(W)3om=7p~ zmImLVB#0N+N?5YcPqL^Xy6EynsU)G3SH8!J&u0mnbX7K&nJj! zAT?{|2Z+obo?8tWv$9~uf;NZ0fe}SlKynd6p{fO|)rNal z;E8<1cS+@b0_pXGt7Z!sv? z`OkPgs536?h5U*v_jDQ;Q5qY~Lkd z-GHk;Ce4Y0=(HdA{h}Y`!nQuv6x^JWo-AhMLSznTsTyg~WWmM5agYl;5(^=UQ(6&S zfhze@3)w%ALg=4VSp2j7=i?4vP1(NrfIy|XN6NJ>y;54-{1rct4=?7^cj{k=iN9f) zcOV7*D44ziZ3NS~S|&0x+kVCx^S*`F{QO+x&Scd^lrI@y0*Oxa?-Jk~bs*fDV&X(( zb_=WS#bPw<6(dgal*}nWIcl@Z+_}?H5(UB~P)NS@WXp5rf$1;0?R3IX*+QpGAh{W! zBY&ldt>^tocY(+UaWOTZS=Ck>75HG>1W?0zl+uDiny~4GtWSqs)u5V8Oiv;J;_Jf& zW4=F>a$BSnk|>Eg>i#@KBqwc5kvV8doXoRMG2MsozJ+b};18cJmGus|TqkbZTN@kS zDD@m%4ZhKDmGuk~YJFSBzrQasU_BuHEQ$IpF>FEhlNAru+l2(9h6?E}WK0)$&dXQp z*a`DH$q`L4RJ^AnMipsNqHaHlWJRNOH{Q)ORfO|KNem}Bu|q)L?mb0Nn3ZPGE`ift zt4;fmT3M$w>%I~h9hQeitt*s?UHkrKz;6Wv+CJZYlZP?^w06z;euXdpeZd(g0Y7UN zt|=?N9|sj{C2EvzLsqh8C9Ep5Ha-D?zH+#*_9mXBmsvM1ZWu#?ctu3wVNTK5^dYV> zty!hghg?_kp}yfO3lrqTJ{Kx|E+(;M=~zOgx0jRlz3U;+kDbyh?1Qs&Ai4#bdAAAo zr`Kvz{hiyJct}9=tp+7qb=5)g)Q(8q{nXL(bX#j{1IBv@aGLv+x~M8W;lx5$OdZYu z%aHd1g=C<9Gyh&5k5nBlgg&!B?_)*BAN3J7_z^-=CCKW*X}j+oL@E}ZEr}mG$M7r7 zyfu5>ExEN02IZXAzS9}pTE1w1kvIDxyKkb`*(E{WdZ`2hFuq=QbRORgWt(BB5!D5B z0#zzX$M?H(y@Q4=k!aOa8qjupXU40hM6*BxX?HXFDPo0lCiaG5UHK8>Mtqw(oyF%8 zQE99Emc&LuHP?D`_HoSXF=R?uDJMI^BzQrYFK~G2*XA?vt2u{7?r)CNyL$FJCY$7nwJfK^L|!DbX9g?~GL z6)nx)5X>d&5?*fo1+Bk1@QSxu1KNi)MB^^+f5z+tFwhaZ_m8Vvg*&{m*oLbEI}r;> zoS$ITHIPz@qR6d%p4C@m#Y7m|zPLT(aqlc${1EGb?tt)JBHDQuV_sjcg7fYB2rom5 zi)GjpGLQye%5MPB1emcyyljddLYe2@Wo_sz>^;zz(gA@I8cu|p%6_3sn+c#AQ9Xd7 z1nHI?N030!(B1-t)ZwvcAi0I+?M{|TKG@nf0L?RveOe8R6!z-&28ECxB4vt1%92}P zDu1rsgFLgjUDRnnb7lJS(UK%~f&}#091>6iEx?0m@~uMqkh2l>uT~iy^rQ%{G%eUz-UeEkLJn^ zgW5{cf)7izaxBZSPeOz2c} z6u$}rHF;`91)A|AZq{t@(-v22iZoaU)UzDhuBmOTy z|F2s2ZI3Q{rZS?X_~SrJ+hA4< zwB;C4t`t)X-hM}4V50rmrm^^MxfIL(@QGC`F-uPzD4s;7+n6Z%ZaN%0V@u!oNLNnR zc(jlmM1M@zLO0kv${rESP94dpZK)Wv59qmI;np^og$X`UV7@f+mov0#AhK-VWo#AM z3Yka$daRC~*hB1%Tc`Ir96ac+WDwhoOVKhBJpUnb53nT6P51;JlRoG1N3$(7C&D&qd%6aoBH!4!#Xqd@7V&#Nz(w*qL<`_wHqOAXRq zHFOABFB^gBy%Tljc5xrtxY8wMhVlVP=4LMnDc3B-;}al#zvRlRDkqH^YrRROAYL78 zH~d^Sc4L=oIN^}KT5&GH(1%;$y9GBDbG|4SM> z@b1y3Qd&HVZ;nsk=0Jbp>wS@gEVg>UQfwO~jqRK;s)s4JRRHpuHc>V>Vfr5}E_w_K z+XLhUCo640{^Ga>_B|L8F;VfvO?pE5Kp^9ZBZZ}ye z{#{5pH`(HX!>`s)rgY6mq}l}Pbh{ZVEIex7G`K+wV?H#k17gy6I-ku~AKKCAiq3Ld zXvAfOiX$9j^@+eev3Y0cB)uDK>^>N_cnsT?B>5SeZpoH9dtNY!FgThGHSmZ2}6PNefljdC(n5@GHU*KLKt0fpZ8n( z=GyZ9gbodIxTJk|ZK~d!YsDXc=_2O73V7GLw$9MJhkSpy>aYvfyDzA}@8NnHg)z69 ze95XvSkKjNtbit;l|AkY`+Wzik47|%VD4#Sz;^Vv5V<{Y+5f@YTmLovz2W03FGWQ` z8l(iIyM+;=0wN_XF&aiAv5iJVx}oCkL^C^>0cekeV0fdv2SZcW6}1O2r_s|2q98HxOhbT3c*L7aeNH$JVIQOhsIfj=@vySZkvhQ(Vs zm2?l(#(4>UcNiGbT1Ig|UecK-j+#|ML#RJF)9cuzTI!|h^wvPV{M1DGq_S?kl$>F~ z4*|wfuCJ<3NtRy~p!}I;e^hfc<8XjmT$k?A_~!lvXQ`-O!cLm^9aD*dBwPG|aG-~Q zcJQ;AoH!Q_h#55h^2n-ueKQ`bm1IA*`SWzWl)GbpgtCioq>wF$D z=pvwm&H2yv5n;?z)MSI3req(4huL|Q))W_CJ1s6grv5lscY|=6cSa;A4@T5j|;~@u}zj#Uxw6|_X`APA_N75^q$RSvc zZDo92=05w7&Xs}V_2RVm>kouxyi>utYkUQBQ}BLN=bzFi51|j%izepszmM4J8g*S- z?KpbQy;{Bz!63dw%k*EE{GEXh=pg@;H>&wjx|K8>wd|km(D3USFTO;8W0vRDaFAatHn0k;pHt(psR| z2+q(pJGA4=f!gB&`|gC&Wy;pwL*zdKYAIILbeEsv&gnOAqFMlD1|R5H>V$2$QA;c11v5Q3e7ZKun-!xc&*1XVQuFW`L$NBTSX5T`ls!`$@S4 zUED^+lt3#XT9pVf1ntgbWx@Kr1703jK=(E^dAbgJs|@|pDk2m+Ebwt=UZGQ;k*4=g3bVxefx#oeRE=qv_z7{%kP{P15#M|i!$7JTG z(WtxV?}X^6AYj#|!f;JNtE2Qe#ss7zxPyhFPqu2)tC$<^4wQyRb0`M6}ud?{Hs=y<`TaGCV*TfC&=* zdt0-kJLw_Bif(UlboH&S{oY-42yX80*w;vLRsHB46VT$Kijz@3Di2`i<_aJ#t}jX7 z__&--hlI^rB)t*$|72aHp4^w=Ho{6RT?P;ds9z`fG?xOZWKhu@BXWV~uscievNZ!sZ@k57O^| zWg`0Ph(Av8kai9!lah&hfJ+kgs$E{_!?9wGn4ZVdecmK$UnzsWf(D9Q*v3E?sTNeb zkD`13BK3hQ=}lTnbD>3|(|*{hj{mp#%77>QedjUGE%bll-M8XAt%gVqR6xyqK z^(84pa24hX;v1yE-Mc`|l77b&MG@%n@PNl5<8GD57S}tgzRC*Aqq5!=?Z-sS^fHuJ zTE+v+?u_M-<`fCfY&Z`Qv>UmrjnB7^|1996aL*z-e{TG}!e&hStSYxxZDY^~*HMnk z@p_Y6!I$u&3X!~ZdKh3rSWGp8e%HRhN>ZKc_f%Zoy=ZckD|rFRvRe`yDN1!bW+ldRP9-0&)>n~kiuD7w!#ja)gU_Mp zAZ-<;!kwOya7Vh*v7R6B|Ni>yiID{T8i7(4&vAclu3ysNGxR*P5jLzh+uRw@S<<$7 zEE2saVwW21WqHk8*x++90UELG(~Vtt*}jhP7zB8_UopVrk+I+>H`QR+$aSv|)q?(F=dve?+*{*+;@QjypQtj=v% zC}Wl5m$%F|=R#)>vm?{(jb&_hC+1}b^mJ;S6`n2C7i7M2Y=8BIewHU#H(}jdM3p4&HY-|cTEg1fDdKh_C3ZLps;;LZ`0b}Y6HDDA+nW!S*G26Ns2rg z^JMJ0v7ClpHbAh6V0?I4koS^1TE?`a96+z1u&CjAXA>vhzX0M-x_QwBJ;Fx!V52rjXM>#;JR!eSuQrxAyd$ zL!xD;S-D|NgQ}%(r6Dh++}DNLlIu9#OsACPsN5#M(=Giix+p!3BuTQb zPCG|iN`vX@sGaGCQfN~zGsYmb z%b9HOaVL6+^~AKiyldy>W5DFeS2UTI-jhfVBa^9DN1MQ0HKtzsz&P%i)1c%dGa@{Gm(apRVoVv_RUpZr4eyX)RZ#$qw1d=6xuwo_a+ zI{A5WUYX0(*l!E(I{p7r6|whu=xuG^T*=p=IRdv?aiu?|)?90S210!Wvb-+MH;?c` zs7{(+I#rJa7|m46VYV5EMVBxuVJiI(E!ZjFAL*kVuS#N+Dx@&2B(~ z+vHfVR&PH8blP2$ImDLKs#}EO{b43r3clbSf4aj#wBK82booKczu{wWB1}-&zGg6-Ak-U92 zSzlS3hE6;vb{Fl@WEu%~X&TVyZBm1pl+Vj`pt?eybWlIP@&I504WFo2VXP-n>6-!N zZy#2^Jtdyn)vN5a+5XlOu=mNeg<$tZZEW7BN1obz1yOtp#`B;@wL3-csMNoPQsErH zSwZE36C1`fC{HsZHqEAYEvD?rZ|eeuR=1nV`<#p1>Z1%_CJuY9D|Y3%-o{>g{T+L# zksQ?!4CIm-MW;+{uaufWk zh;io{-M)0x^hl51imL&h=-f=97@ViljbD!~B0nfw81)DLW}6M4@gj4b`t-*7 z{q;B;Qt_=?w(7NLD?_I`;7u zzD#x3u-rtHgZT02QVR{Oc6;cPC+Jz$W?W|Ni`}#g`LVq+^Ik{hMsN_fxwHp#0C0pm zJb5s6cVFw~UuOIc2KPyl@hD}R>ukT4$h54m7G2hEFnDwU^41-8?;2Z4uWf}TF#G!6p8e|bJJpM>bImY&@?q* z{hRMdaK-STRhK&%ogB<5@SRhYU|XtlT)z$s>MuC?Q5754O_nxCL%e5AM-`up2e^U} z#h!QkCKNodvZ5c*DLI$07Y1Qo*ri>p=I>9qUsIh)Hx3N!jRkqP>)&$9cp0zv&p#*>qinV9MmU-+EGEm$=AX$@ijGfkf2&DuY8r2J08X);^9TK(uCoI0zEB{U;t3O_N8V4VF@7_YSe?5! z-@I0Gugx$;`$y#urId_yfhjG{@ACiXO7qf?GPy9u+Zt_FU|y0g^0lCikEXfq0ANY6 z&9Y)7@yF)Lkd;AT6z4xN9xMeuHgyc=jtWu$>k0ED^tM25Ru{=Xk{1(N=-OPuza{bD zruNoyww>G~GLS>~T!h#Nb2loBF(aX9-<|+Tx+iznun#ih}$bQ`Q!|Yxxgj1+7Jj!2{ALk>O4b*K-@`ixlR6C zlk2k9Ugvg4=z(_g+5kfhOxiJ9gNuBAorDY}3ghYr_TK>$?`0+PF(`v~{!yPQ30Bo! zCKyhablxrzee%&+FZj)WM|0#IQY?2_DB#tzH!x`QfNcX9T5_!v!j-lu4sF4y7SR1B zWx@KI32kW0{wrYCq*Zs&dj(AUAA9&NLVEqWJ_bA2tA$m=HGWhjEPN=CsF+ZxuGhgI zc<*;O#J8fK6vw5>%L8qCX&$XA8`clkTWfN;t~c#kL4t?fMH^2f(oozo+)5ejt zEiG|=9<3e>RQXUyUoyi%RFstQuKv7h}5#{{3&ZmsxvckH}KqE2p9#fN*8Qc zzC6Goe_4of_n=YRxi}j;=krlfFh0m#I1T{7(mJ(VBrdzRX_#vZeC$U;{#FF4^}*&8 z3>?#>zwV))o&&b#^pTft6U(I4ldW6FY;JBId&Ej!_$spw9|o#QGtW zR*JoMzUBKRb~>{d+QR1am~|ND>9uFn3!oYEpJL^MrbOI{pRXRTuOGhUilb&%5Kwx( zrIU9v8pVKLzUPn1(M+Bos9Y;{;xZprvlKPp$T>*iwN{G(7i7I1dU5c$i=}tbFP`u` z#OG}LqMu`mdGDjx@1ZR4^hIt<6>NJ4-Q6~O3082aMpXlv~l zl?haFyY1~JN0L-6(O8jw%S3#uB#j%d12u{3sr{4(knI7|-#!qvmNYW{E$?{l)}ZA013r&tX2*vaT>Mzxe6Csuz0Wlw86AmR9G^ ztEk#BFB3N%dbGbwk`7wAe;eAiF+1tHk7$aqCn#xK8oFA%9KDg9yGyCSla?Kymx!Oo zr`RR2*zedZ4rSSX@Og2zBSXaWq~e^9H#>~LI3xXqVr+UweZVq{P9r~5+k=g#+f`ie zt0+R}(5~3Qm~;=7NP)$2Cf&oW0~=+eN*>RioEGh50b?a)7!1$CE%v{BKy?;tn)O+> z0F&K56D{(@7q)2{`KNJ6Y{YgGHvBZ~Imh!D8B%w~)Y|hUc5qJGzRhIbh|f7qH@oYejB4 z$!}Yf=>hA!9rO6Vjat1tM^UTkf|)k;Lg9MD8z~tQR8EHI2UnUv&_nDX?hZajf6mL- z=XW!ge;xe*z=A(-oMk?k{^LOMIDqdV}Ea*cVeG5eJ30_U1)fOT<;oFMLjR1KfHo zv=-_=S*@dNu%hHB5%uk(2iUCQck}9ER|}YYFt9F^h^Ed7Ioph1m$QeRsHvJOaJoMHdC5o&T>Z50g^Z34By8JQ_lf`3p^l+-avgs!; ziTeJg#(_iW&8?ySr0j)Gw3#c%8aSroBdwLgeIp@P1_5YE5rGy* zhoTgsuMuFsbgpAR`xFOI2yo7cXCj9yu16X=__H~*49kSKFkbXC0>p2}vkQnz(S}?L8(G_Dk z;Yk>|-OG{o9*p7GX2&NlxAP$;eM2ZLzTG2?JaI;`D0}7(A?B#$vSAsTN510Ye`ppa ziLi!ZOd6%spUEs(;pa3}FVT+>7pAqZkJhG(_}>ys-|IHsZ~2fMZE)lUK8V0n+%30D zX^2VF6C^ThV}8^{2)1h;ihE!Nkamn)Atp+v2Uq4N zpG7s*uJ&hwshn2V(pK_+!GokaH#6y!<-b*p@0siq+`l#(jVw@tuvBTfS>J7{A340| zDHyrl71lBlTUzd#&Mt?Zt>!&sW{pd`Rl>jLV^~UR6%$8-2X<=j^jo^QNMkm}%##Y5 zG8~817Y?~mW5|3SzfCf;2u3nO7Nby1D!W`W7H8CbNIUjAFR|Zw-}xRGLw?D7t+GN@ z=Wd%#SAgw;d-b~017wP-?R6iRMRLSXfJYB2e%wio>xEHfW+No>SSWZD`}eduzRa(l zFPUExfCXZAz6Icj9vYY=c&{soirCXMBMpjU8?X2E!`&Xk1aZ(`pSifXR;2ijEs(cH^f#>uJk`mr&O?(y!2qI&rY~aYV{FW zO+VeMyw6Bs&O}_ct`6Lrw$u833oLon`eo6^p4s6L;$pXWJXk?HP6=TG5k0i4OqVXwJ;sz2~wp zMU+ze6yX(c^%2xLqfxzst79@}T9D*mH-BWc6%fsqtL&V#R@PA>om2f~h~^o%%NT1t zNyxUI0%y}Kd|)v$%ZPK9FG;|ZQONn}d8|x`)t!PcWOYplM{!)p_N&_S6kYK`ntNMa z0l8QyXt~OEBjul?*7zP9v3Z|sE^t5yMB?mI`~tvX*(Gu&!N_Xo)jBY~PV?k_B5f|P zL#alUhHz`uCf^sVF$%Tz&gZ|+$<-EY z!XbIy5#?IjL(*;Y2#{rM^*K~dxdYC!O%->Sf!38AkwBj(*RuXh`l82ixVj<48T$of z)!77q!x+SsRS~DAhrO?G6{*<_fA+Sr)0jj}MA+5%+uQPO5}`R3t~*1V`fT}oqB6B} zt~}VN>^j>3>po*S!JUIf8l?u~Wp6Hrw|8F+im$bw3``X`2WZ z-)hsZOt*z{yQ4f!9?KOuXETG2GbN~7oOLm`9Mo7x`%2#u^2`TyUmFsu(4@4nC=aR% zusC{2Q9w0QZHa0#B~jC$a(P?OS?=C7xBo1|txQ|@l}?s7FaoxHOY&va!2TC=tH5gI z{5sbiU6T3=L&W!thfZ_X{GgpF`1~y^Ca75H3H&8`wtPs1{N6UVX2BF=1cfOKDz?d* zyV5L6I>kT#>1_QGg+_}^2~NzU}(VLu~=jE_s3KMsC(CJ%Sh zy~p>X*Ftqx&7OV~OJk{jWuK>f~26Ox5l(Y;Ix6KxPXoY z7u}Nb&2%|lJevG$M~$I%mEylf0gCM0DG!K`wf89;e-^<$Ansii<;QL|J+HEL$7;r& z<=tze$UjG(}KP)l89cbT8BczXu>jamiD+Q4@P1+#UM- zO06%^`t3te6gzq!T>v7FnxbBlZ+>CxIPsfuMq?d1;3;)OhetU(OeR47G?YDzYJzSq zOB{I=48AdQrVZjJNj9|A_@1~@7Ov;X@DbpNfP}kX{*a;`Pu>0RYO_HDaXVa)_=;j0 zB%w_1QqZK=C-Wfn18Gq8gt(dQ0I4^OjYPO4~&zSnSRHsZoR?Xex3&`cYLZ zm!D9Z>PlJB&Jo2ts@YZHT#IAc@m=TY)t*fTU9oWsB3T!nm<~{J5r|tX{8Wze4+dwJ z1suz^r_UUqraZ7xZj`)yF8d(z#JT*t+YOI@np6EC81H}nWX)C@o6jX;k3x;QYpqV4 z6tH9imuKrDLUFSEtyPckAqB6R<33wOnG;ALF$$Hl{l3V2AtY4QYM=iilIa%roJykKTx0tdU_n$HJM!8_YM2#pS;ax!nF z89e1o*2WFA`={jY4+w@#r-6Ej-2h58_b-Xd{V&c}9bv`7q_IEmdMMB{I<;60x%j;n zI^f!RCCIv#H&GMSuw4-`(?SAO%U@tUzo zL_8(`yJw!El!w(T)oyxT9!{w&(5?H0_JiZ^Z8e{e4X73PC787H@}!v@O-pzdfiKIU z&?XyZ;EfM_KBlhz+y+sdRMFi%g2bP{JZCQrGzoa&XlrwMndt%Q`lg8BXP`=?-f^C@ zPf*FeBewS^J;im%M>AQnY}+!dnpgJRt$PGs!0&hDc3SWr6Q-;$N-_ej*?PfBT84*y z(1G30MNLnk3R?^&iHI1Rd@l(qjwH{TaM##$9uK$HqHiD)X&~q)R#_%=qxS8sB?!Cw zmEvK?nmpmXFA(i>ZtvBSy+)Ttr&TN~h;+Ad+E|~s*ht&=8?Q19t0Dr*eJ%r_`{`h&F(p4Ax}{SpfI2uVnz`ofTnxbX4d6q=qM zI_gjGo=!OUg#7@)nFKwCxRvaE(h?}Cd4PzxJcIm(etH1-!C(aw;0i&{>IL^UP-L!} zuk#Z%XMh_|$>-qVSn4SOX^H^l`aoGh@5geZP1WJ4QzNOvUW8ST2O{ZI9p3<>R^I#q6fZM+8 z=Ij4i)AL{>gq$8?Y^I+48H{|8Bewf_&hPbY9IgZ5=rc~^f>#iQd1=2_* zHIdk4fS!VKcVry(=t9X}Dlz_1^PTLxXIhcykLZJ_9LS<5mSPs8WvX7{l-4c4-s zCd8SGXpdSguUQ^}w_-!)*8SR@ydY+r1PnuFHC4Q7X3pzmw!pfl8E_ny(setd@j+3o z*6?P_^`M#VjfJ#`!Fa?O2}bm#>5Ey@hl__f7@n_JF+WE)y5)XE2~-gV4gdAS>uuhn8FHVy zXnlQ!L|JaBmOOEq+=8dk56Xx1(b9Pr)|Rw0EBzV`_-PNszJ2VuLK;pxdtAU@1)!Uu z^Lwpkt~0__JQxHFTz_4|Kb6|9PqTd|_Z^52(%m(3GV35@!}hj{>Cwzh$Olxl?u6SE zrJL*zWT5d^n5RWI?$=_tHi@R_)(3sDf~r)R%7l8)7C$f$zYGA;936|Q?KS+WJp0Qt z2$u`OGK8FU9@&h~B0NqWLN-!@?+=`Nhj;eo- zsDE7RSay7HrHiMKSbc;HGXnph$1x$V%zWCm9s8kU>b7$ki@txL^ORmBU8eCu{1a=R z_82fvia5iBmzk43uAcy{+!3XF$sNA8w{a1HZob6b7O}4jcx_hmhHnK-cbDsPz%#E= zj^5p-TpFw4kkkNPlkRGo#ys3pweY)QmleAQmrI)B46mr9h4yYVI2ev}ZsM-Uo;q+% zo}FFJbze0y^c$e)@Y&pax1I)qts?0Nu());zTgB{(y$d&t6WR(HQL>XWhZkSTY+Ps zFHDxCauDxzeg7vKNbz?^Lmkhl-@6h4F3EJ?qbTP$ZMs>9`Gk5Q#Y#JHP{DOsV1=Bm z4G*yh@`a%{K>9piGa9vRXEL*&mzB4(Ax(?H!h!nJLW2^g<)^tY`S%Js><^wgBdRMg zH~#va(Zda|0d*J8d6Msca3r>iJLmtrT5t7E48HyFK{lKKDKeigi}0twwu<6XT{n|lFz`E;3G-fpB2y;o>uEYN zrRP8N4S;Joz}WA-tVQ>FoOu~M5R8nYGclnP5V0eSsDhIsfmuM+UA#A+z5=Os`e||b zxq+~=OUj&3m8n<>*8JWeDi%O)rpSrjsvi1=mnbGQ-r#65T}3!P0iUmTe!|P+4Arr{ z64092baBu*>8yWwoX;4!L;OB@!YJI{1 z{uPh-A>L{r$O{0fhp^brkGYVu_bCkot6^?f)H?;f4e-GrV+KTAp3Xr|1&{u6)=~1u z3TcY+AZ`GnEs}jY*1yE@Tw`mUf3UIPBPt29ReO8oUaZ?ELI-7wTaXX1nHV~m((WoQ z-e`2HnM)ZQNaD&ukKFq2C5#x-QXGB*k!E)UuZ~HLOK~@1Ok2{LNxFtDyZkhV4xp@O zNHRm-xOSu14gu9~>WXr|nXcP6`BPfPtBQZBfzUJ$r4$%_`jtqujotUpizgLV_-)(i zYAYE5jW!e@w`ttU23s2vYd^3E+}>uOfz&Y9mpZGZ`6hqv5>^2$+|*95fPCaOAYov- z7UYS>c24C-XI*P~2s)aq2$m;SM-3+(KG9>X;(fK1O*l{s#~tzgLf3`w%p~-Dg$(bC zjnIJA#2i80R4>SFqHXv4q~Gigs{F_A-G7BIfbs--N;tznRbW&b_8Fcm2u+f5k2Gcf z@_}wgg%cO922|bvG6mB9fq^W)j*IFX-i1IQe+}SzBqG&(W4Nex?8xpzhgyd zpz#Q|nmLW0p;r*1nU_6f1_w|fc{=n|wVGLM${*^*LD~a~x%q~kUr(*@%kA_F*rQ#4 zwiAeDxi94WKICvN938zY2~` zwxA3Tj>~r5w0XDAhhsoElCB>!5ze^hvK_L{(6Kj`HJHUYeYLOcp~X~Kv+cpB2jCeO39&xeQJmAI7K_U=QRh7(Pv z(HSe2sEDpyN;ck~Evw;z-Gn5`x?@qrL2Y?n!P=BX21&M*$WfM)qwU2Ig24_f1E1Wt zQw_o_Lm+~7#e;`iT$a>OZ?EJI&f1h|_a*QxT9v%1;z$7fp@2(DcZu`S(Y=>;S#{1U zVsiNU1pCg4#v^tTu(8@R;Qq895#YjdycFTV!Ry5nb^C6!CzGadP5NZ|FYf!-i?moL zJajwNeaN}Rmk0@T4v)9Db-rAGqH9kx`L3JLOkRK6E4mcZ6dk=DU2B!HgUSHxm90#O z3_X<2*t8Q^Ee*7CqqL#z{l<`xM5BJ`3)tA#FmJGN00DK@kabhU}`pKjw|DiK}53xRk1SVzdy zxC2s?07F>ikqi}FDddV=xTN^B4>7x{A9=AAOj8vxbXcG=584_w_c0*BS1lC&{PG7s zx=kdS${|6f-7T}D%b3#QC>dh{ws1RPKdcI+e#(y!n>=5pIQw>GvRO-0(|&4loK-yZ zl0-M@OqQ}_N0enbnGE&L1?^_Xlkm+sO+%35FP^%)^Y+PS5%QNgJyH4!K9^L}?2>mT z2GhQW2FI-j=ANB>4)Z*3y%U&~($p@Xig}iO3zx4CbcP@Z+FOvgHlpw-%%=_a=o34- zxJ*^Qr`4oqz9gX+(mh+f-PQtsN=>?r!quxni4zu%nIow>4*ocND*&oxJG~1u?!3G+ z63+7VYBPQl@*d_@=ocz9s_7#IpLm0I_XpA!>`ebAvvP`9{`rb<(3v#eA$Od{N>HUO z%HT+}pnXY8THyWm&y>#k82O&Fe0_tVtkW05)#(WgKOw@Oa1WlvK?)ZlI^gihr=;t2 z)xtmhHN^24*j5J)P{d@29}Tf)M>`e3WO0I*CL#NeZRd6*cKOe`mJ-7HS4QE{P4@2B z!u|Zz&5yYBpWV1Bo%qxBnAB%vtYxA(W-$q+2;7ZCfGG*BG zEO}q>O3OttajEtwa=jyFXUf6<)F&I5wsv`$KCJpB7}Z4w$o*FI8=Pc8m&~@~zD5V- z*Lpm?b(%A*2kH&laGoWn%mzA{OqcO~jcqFX4`bw#vz$53u8XWxqKv6}DmF{NK>mrY zjnFi>>@=phpPnIkf=WP-{iy)%+Bx@8jl)3ZypU$J%PgF)tjK`yXR+M`dDAdnwK<~o z#v6pGWYUoPZY%>M<`LvB;1eBuI5v5cH9qLso$5wisWMW(;6vH5;5VN%0+5 zZyhd+%`Vc_HgwzIqUVlPsN2@lxXn>9o=J=ElYRN$NZil8bD@U;Hp#D}ofyWncMwGX zqEWkLc=9MPmR;$kY5Gm6vb}`YkI25?9k$UO>{oghd~g%8?59oJsrtO;V_Cgs;cLLC z1AcXnn*u?>z)|5G)p+t1ByCu>`v~LEj+?0j2)X-KFpcS(l#rXRkxkkKWEU;@Xfij{ zrq}R}tPR`8b;fu|IRNyv<5Buh>-ZM&HKc8DnJSttq8Q;il@G0hVDh-+HdeGX+xHv8 zCo_(h(8aA<+>_Loq>?zjFzrL#lUF?|W9_`g(+f3hNr*?l_uEx5i^kyiRz zls+Mwg@l&9L^7fuL8M3^3B_ZQvw1HmSFZ%J6hw)+T zZF-cu9e?=Ysp;E4VY(kBUie`MhSuI1y#FVR?eMZVYRy>dm>28q#Tj_o|J^=* zx7vfvc15<_0OTtm*#z8m^Rdrwl=S>G4*wy`gt=So#rr=xNB8k&=v3Ii+-{LU%uMW- z*hxant&BL@u#@5g$!crlrg_5+{IeWf0Jc9;Zj8YWFJ>_X-_Ad1t@tWk(FZ5YZM-a< z%>eZKpjS}lB{Ib17cC0NLo~O6+FS|=bQ*UYfoN|>-Vcl{h^WDVN2qm3Lgr}VSnxM< zrqcwbNdjtPh=Dan@A{{?IJg`@1LA1gvLZd`x5vff>X1QeK(az^zPjGXtErP;BX%~y z*T}zbBC>I8u)=7TJ0O;gZ+(6=qG&b+f^69g=;~T)Rv{?R3zBWZCJLN%NRd!wB-Gr^ z+UbbWJjn5s`+uEBE&@ZFXS(xX{p?X{h@Ul&(XMl9d zv_GtnVJ))+AO9h8au71|YRyF0rbV0=Ls%=t+w_2)_VZ8oN3{Yazs=UySTLOB| z17TxsyGM*I`*Ya?&|?cDJcxvEGK1j2sM1&F9J$Chcj6#ePFR&wI6n4`?Dh0_5nKd- z3+==R+9&oIZM2W%z+t8RDdOW~VqM;Xr8fXPG6T^>>&bSQdZLV#K5)ytVVsg){gakeH9mq zyg2izPnZQ%-9ba^U)|X$>mPe)a~@c97m=|2-)tlCxB>2w+n`KkWA2AYu+8uBqq|;3 zom%OrlOqejh=Fors?c(EYMs`$d&ocK`cOimi3CZlB>e9IbhYv}!f9LfrEpuuow&^w zcm?}z00}w@*Tp3Be5DVj2a2;!w9{P+G0^!8i7gH3%;mUVlwKka&N_HAcn$F2$?{Df zo>_!YAc_OZR$|05H~tK*%1}C8Z>d@ZUZ}f{7vEBiZtAvoXf)Y1lv>(&kAE5|tw{w1D*jSg`j7|6UA>N3GeY(oiv7x97CH((s8e}Tg5Vx6v`xfMh zX&xx-xco_FT^{}B7q{=yDIY^bHq%l4={hP3O*tOw7xJIWZ0nou^)@=(yGTb3Wq@;}YGe%$&h6{aUT7Z3=9ip5kU3zWV*!#Ib3H-t^{oEbW5Q=g9lPT^L!7H!IrXRM#qI zM4uok+(=n5fe?D2|3|9JxJ4jdDW7#MCJQrU#Cf5ctrU0%;4&sR!P-$H@fBNb6zI-P za>6?dyV23$*bo)eEy=(1c<%vs4{eF%?G!hd*<;dc!v}gu#WBrvI=dbsL-#yMn%}Q@ zotqPL-h#Nl=%4~5s`YDai8!I)~K zY$xtIj=#MC7jtZtj(6F2lLER)%q0DeYa1&$2)YrCXO+aQ9~9nYZ+kC_Rj#xVJ+{b> zjiiWWB@c%yNS)ngy2jG5di}=>jSLd`FF`K6=sQu2$dnw|vmhk5(K^46V@+KHdxeSHc$&nMH0YEKP=_uXWx$VCTbYFBaOMUHjP@F}B10 zJsuUROXnEI#J?JB}W0!4xd65CTpPZ2Hx1Ppx+$;{_c_tBdWpdA1RNY45S=-^z(ZiF$s#D;RKV zK#4mZomCe6ALFa$OI^LWpMzGyHi#Q@sC#~ycLtT?lSgE9!P+7`RWz!TDEuE*w)4V& z4;Jt`J(KYIvD?V)06K7Z1xOk1E;+i&6IKGZ!$yX_MyMBfKR1i@5h{6g`?_C! zyW;g!&bP+d&eFT+d7WwiNHurx#oXO(LN+F()j+$}C&)KY8att-oXWUuGE>F%DTI`S zPG!f0&O37B6Ovyo1S+dGn**%af;WrW&X&B&hX+hWMTqv=N3a~sk?M+xA2|@(9l|2T zlh?h^_!!O_WBVHFhrRwVJ2=F6#nzL4ts6SW9N8c0G=bq9NFoYa6}UcqK*@l#EH7?Qe}=xNSU} zZqmVv+FQ5qW!#=^8k7sYFNgRkpC2t<_9t7<<8MoKMKYrSBXPd|Ao?Hc2cqRL{$yy@y69vPzC`GS1s;O@+_6EDiZ%C zM#ju{=kH+vb0);T@6-4K+3>}fKFtcZDQSqxK<_I<1)9%_;v3ycj`j!Cb<&w^*M0IP zAZ3d2(CI?of-H(X0oL0PHM)1xJ?R6(;XvqAy_A^iT_-OJltbH=7FHmb;;9U6c`4YfOCIDNCqZUe|hHovNJ2y@WOo9{< zVcSE7m-9c+YxX?Vc(Yg=mc;0lW<3@Pb{K9yGj|ex&G8jTv3Q{Ep`3QWfa_kx5o{=# zdoBCqr9(geSLG<&P1yO{ZZ7ZcQJW|Jd=cVn{C<&;GMvAKtCNe-y;-!Ja79Awu0&(M z+9$GaNrXw$Sui3oL_(uD5ECe zF@v%35d!s$ySH*-1xeU|!TFW_$}*9-;ioNq0!6v(ORa0Sl4y}03-7-b3zVTBGKO!u z2}cKa0EGb{^h=L-}@FdIt^2mJ~0Gvme}*!Uw+5T@$#6!ap`w)rje? zI^Cm+`5R&gx0NJAQQmPMf9PEkE1O_{Ai`C!pYPrC?(w1Rv` zB9-{Cl`NsB$cbBRM>j1@a*Y!riR-1s`6Xm>o9aT#x6Ph4@m^~KVZWw+Mx354i)-x^ zV%m1iSB&p6=`;pL%0aWP8V8muM7j9+KNGo^A`?wSRM&5J`JPLF=vAjN9we#Jl2V*` z^+AMpNuODt=Q`LCNZ=~SlP17x!GW4o)WxEFAG`brj&z=0l^lrPO{QmzuE$Zv;kU_< z`?Z)*EclS#>;|sn-|B|OCZGNO6R{9T%ZN+S1i2DN9S-Md9Ic@sV$$!A>Q@>BqZMtc zi>SX>D*xljC+@Y9lln#~$Jf1PR`8%6_^5bFqV_BBsyu2kMYr5XEa9Ou$fgp@FUZZb zpP(@Gj(soLMW7?&ZwfvLTU8Y2(^87XpTuWT2#sU|h2q+|`w3mQ4(Ij?y!IShR@%%m z=OjGo_Z+jaRirkbdahNGhiZ5Ra{*JhZpGA~Gd%UDmUF8r?O8js1hxq0o7U#bg#rMB zQ=_}dsuGO}eUiDugW|_GuH*!**G-i?>D!7gYhhCM+HLHa`~(zo72LbzES4|uT5){( zNALe4>N*^u{{Mfa2q8OkRI*p3#2HaiwusPWoRM9)w-6E{Gn;gTY|hzn_Bwlya~x&H z4MoWQUHE)|f55%ouh(-tp0C&Io{z_C3MNlRPJN=FXU}VdVfr0<#v_m>{BfCha(R&H z@#5bEV@;>--`lY*p-dM`96r_DYuUz|Jk1%m29y}q`6c{V5VJ3`8Bt}6Rwiw!F;i9dap{Z}!t=Jt!Fe6fF|t^lS-sb=_B6lHaa=9e zMRYzhbev$crwtXg`2tf_^wG|K!a}QERiw9Nn6&J6INZ~+#~ZaBHyU}N`%sal8d73s z+mUm$Sn~UXJwF1xy8GA|0zD?fQl%w21^PP63lmyu%&L1Nm(=Kc%GaVk`Qp2@z)?3k zWb4vgVW!)bAt%lmuMvHoS4H^y_dU~u>bL?916s6F$Nxk+?_qDl_&mUePl=Az0~2n) zoI7=R)z_OscN0px7Wq%`w+Pdw-If436z^Lpa+5dO4Si;Y0RW8I=u%p(R9K!;1jn}k_E%>G zs$tDD9`_*0U7xu}Y01hUBrPvW`3G^HJ=mEu0wrXr!|e=`Nlqeqr0y=@Q47FBS!m_;q zBSDEr9JaUc_D1or)%&9f@OyUh0}WTGoNv5lJkT2>B5EoSm~XUEL)zgH53M#4@EtEr z3E%myU5OT|oBx4ADCDx3Ra*k+>h8R%jsgWhuumKZfiaX0VPAv(NT=tmDKvXO|mHia0ql0xAbF;w;vIW&O}|NPpoW z6UjFevo6KSU(%nX7wt~K z7K&6bD=NfRZ%dw6Y|Dl(wavu2DF2>fNx6tUGL|?CN|fUjS!WUSs=M#)^~JF3G#L{$ zDyUmIm5HX|QMeDM!5Lp^SZy;23Lgo@XO9!Q9M>X9o#o}b8d_t`{-V-(5pk|0NUTcx zXF2H$NS4MrC9zZU@WxN+O!+%`4sgd3saXm#)rHI)(Iw30&f0y}l^}U0=b*a9&wB-| zj+91a+_ugcC4cl>&afkjnTVrW=%m`f;NZ!8C$!*7(vJXLhD*jdzXdR*w9{kPGhhh- zKJ=63gK=$90mSA_B7&M+C}x~Tb{jIue_R|2WQ_xqJTj&B z&ppcrx=EH0S^n63c=@w^997^S|I~)E&q8xVlf*%e+?c zM1S41**ji%{m@3zs_(-oByImBa?-i#(93V3xPP)TlP&L85UGWs%Xpvy%O|t)fUWDx zljE}QK#huCbGK9X37xafTTECpXDWP@m83e}#PO(SCV5w@cDRBo*5t?ffOh>0#kN~l zK;JoYx@cGzcNr)}FaMhbDy(*BH;4(md|2qmw3Shw`$6uOd1T4@A6kyS8lE>&H0}IBbNJzyB-jxA z2V}xYO}%l)kHMY&jOs=-gsu1hJze)lI@0mgDKjs0sfrT+}C;ctwKCxqp%3^N7ID{}iv(!{5OfsuB=}((0jyOR6$#a-aHFHS4W>y0Q`L zZ*{|sVceMTTVxUAs}zEjaMSVm?~#B#`t>WeUA79|IH-m`RqRstwuB z)Vv$;G_Sf;)@2#sYd^t z+V!!Sb)=6X#kfacnduCeV-b#qMMx!Y)AE(iSuRiZKzGP)*_f}%R#^Z}^cmQOk{;0k zcvwG}L0;+kMU#=sW9AX?NBE!E1ytbUkIUx^)+Ot%+Q}{6(^_rP!ABf#Oe8{ZUUg3_ z1=^mam2qB>Dv+3QSN#z3?3ER|h7zm5tQf-lz{qYU2ihl07~vwmv^hFn;P*D;w{-Te zcaJ{XeHwq*WH0o_>w#P;^L$=Xb`h^bV#DKhW4DqHsT4ct-c0~hE%ln z;>tIw5`Pp8$MK@{yPj#XecYuFH&qjV-0AQ@{a{tl8Wjx82u0&$(tV9xPWJT8ZhoC3 zlLW->wCDHj-!U<5aRr%E2{0?-8hhxZe2tEnO$0TD*q|)LMSR!hb;PEm03b?R>+7FJ zix}d_mIO1@_ROqw%U#wM*O{pB2i=OU=JiRK6{_G+_v5*UL}6%PM%5b|MMp4L90K=( ziO}}t?33hkBMEVmt%p7_@U}+81){4xckI^wKwtlZor&+UJRgL4yB7e;e?^%5!I}Dr z-UkYCl7GjxZiAJ4uSs*ijJ{ZwBp?O>TXM(V_#58&#OC)vWcil)v*9Ns*JISiA5=F~ zi^mP#zq=yjXOsfBU0j<}O&42vsbbIOHqHi&++PeW9Yg%m=apH7X!JkA(An2?8UKRP z9Dfw92GEW=bXv3(vJz@%Mw0K8a`F4uGpFb~NSc;Ka*}(6a8&dXeVUiC`{$;;If>;@ zG}a^X3qA)i9_JP;3irl1_qj%4QaCl{mbV#+g2pc?iytA1n7$`R_%<~}-;1Rsgrq|b z3VD1MU%ukZu|f2#r?h*-@hLrVm4AF;$Gznz+i{JrsrSjW%TRTf#^Ha&~)JHyskQT~k%L~kQ`nT+(r%W9v# zx#?Z6^swEst6l2*c|Ly7(H9|4O`qAle00>JBFNSIlzkdZ`f#AkO~+a2yphi;S>ji5 z;o4QtOKS|zuPOo5WwDS%z-l}n);d5+9xx*Pf(HBjrMbr+ASmynIY-$9Dk*s5i`ctt z;jVZhpb^Ql`=Mq(@z0eg&OdQR7Ld;he9`7tZNsG&3ixYZU0yucQ9V!i_VA$^K%@l9 z2N3p(0}>TbbVFnTxKZ(S{P)g>(+cgQf-d9>Uq3TuB&yKUROtwN-a?k5_MLhIYHx%> zSQT5Nx>a8GDek2L`F;!FnZbkHl@0`zKS;9NJ3i*ugrA7Zck#6WvF4oerm-uByXIfe zBnCt(du8%5BsC)D&<8nQq3Peoco5+o3JczNM02y`UEF~Jq+N!E(4hv@HHt4aU$yWc za8^ewFi@)^|2&T3o>*4PHSja+^0a6=0b|%9rtDMkcgm82&?~bM7pF$RHE-r(uc6kW zHYym5H7&VsrkgJr@YHoJa8}1pQCDsWZD1m$BnrhX8r#T?HUChx#+R^^h%l(MR7z?g z_14_wEG3B{y}>m@QRCMv#%o|-2O=M*uW^CZo#<~Ra}@5yy>?u(-C-1lsWm+l6@Z@P z%_WrE0<jScKk4F)0c+$bt*Y`EG?kHywz`^)e;IJ`NzY^#ZVRm!RraH79vA(JE;KPhN+{ul_@kaOw; zXKGBu%`-r1q9SF__YET}HKF!67D7#jeTk%N$bR-ALHwY3+-4IB~)z ziRe)xShB0!r0v%SRYW?x1+h<#2ZRztEsPYzyDvM}oh zO?|xPiCG>GC{PV0(6fXXh)yKoVKA^A#z(l!-;5rS3B+mj=C7TEj9e5UPJ&M+oYDqa zP?|L5#8(Q<#uB^&A?6~b&{^rt;36oR_he2CfVEXs>Q4sScEziu8a%W%)TkRz7pa19 zBIm$4bcC+eb0tf#cewM%!MO7dMBesUEZKn>h9XKA%X|o_-fmWEa^;iDC2l6o+Jz)) zK4B}u)Ry0eGsi{qxrGd;?lqJ}4NGA^W zA`@%?;mb8t?KnnuR%mQru1*2KJ{ma86M4gVe5!_^F}?VLMNJEVDF8W4f5nYnJi^#A zCyjlK9;m&;_Wybkd)z7kY|0BaH>hn&C0ym`mE#sKL|CE1R6vusae-b=Fejn5zSQW zU2Npso;vVUD_GqQfM zglX)9nb8ZEYB;I_mhmz5-##K!#6xwrX;046v>2gblSAv(X)k7@Qo&P7J55&t!^Ls} zL4q&RFGiR5_F9RawaZ?ndZ)`GO=cX06WzDwzoLG*zI^tutk7+`FY6Vup)kMB15)gD z3aEO>`7i_Wb7BD+T)SGAs3DtwS*U$#Tk5cd%g7pXf~dk2GlLV(eNrEOBPiw+}x z#knpm7;X(K9MHF{vM%KXS|c%bjeUBSGRnwZdW*zLo(l?PqC{V4@aNwYx3D1b>`Tl| zq#5$>F^>ubfNqn`*)YN68g3TdagU0>YjU7Zp!*Qg0Cl<-L}n(Yl~B}l zIh80pZP-`zn^$K_YWREaX8G*LU5 z0vgMA|C*KF6E^tb+C$sar-pP>Z|y@8_vQb-YpeN#^K&?jDO$28yvHSB82?#N*q2~b zZ=l%0u+89ln(&xNVq2UR^+%oQq%YLn-h*jcv6hX-3>98PUALKZNpu;Y?ADxpuwJPT#XZ|M(ga<8mGv<(yls_u&kt{)wJt6#%eXr zd_!GIVTgXvImeH6{haYkyv61q*G&CqH`?KuJJ}n}O7g!5W4#}sOalK6Mhu&aUcpeb zOqoJXq3lpUcco1G%9Z2mGWWEIv0q(M??S+MNT2ha`9;nJFY z=3wrglf>{MkP^E#&4wqR$pM`re)Qp&O9o**IzyyWl--Ok8=aW++2u;^QRceauE-9! z-v0+dynq~1UjqKYS`nBy&uYX2oPL~c8TK;g)m7$l=dIaOLZh1r{1v!(S2>f`h{N`hYbrAGiRC0yzhjoRVnWM*CAB7Z0R(0>F=ZFMYv`$71B>V0{i}!)fG2A zg_b(#tdn<6sjeG(oWB40a+8qIMb&*#A$G^|M zr+od&md0ob{6*R11B(BBuw4%-6Nq$!z`K(o1O%BmW~)yDMfpVm@8A~RKUC(VY;bK@ z!q|!%x%n;pC~jI2UW8A~`m!MX9yb?r?33p{vWrSc+BejqQ2w;Fr}t6!;>WD%7RW1Y zgWeeX00J6y^l_fw>5Lc)B#+{C6w0nDEW*TdIk(`M43K{R^Nlc7R9S_{+94M7QTE0% z%R)|&A>pH?rifFSJ{wfrh;jEg6gZKly8<;`yNy4rD^|Tq9KwSF?t?A33x*L73-1L$ zYC<`r%f+E%{+2x^9+}#}cna(tNFev(Kjf`13Bz2%wgMnaEE=95%{O?u7NU2U)J6aZd7Z6!m` z?SEBxIlu6A-UF272p=Zm3xj#s_N06P1s!PhrpjH%vfkPIJ~suTIpi_9y@^iTG$LZ!wsR(MJ&1T)?vTN^$KmTfRsZ5v zbeF59q*|9`!A!Y#Fm9Gw*hZSkAhNAOq!mY%JE`DJ&qkqKw0jD``6O9gH&CTMUl<~&IsAKhzpZkm5Qz)#i$zhGtz8?3$hpfkS3~~ z9WC0D@^3P1GT=i_rf?nA)MJw7n1frCU*tR6svPi>|qOecox}g2p+dL$A z&onn(Wg*JCr~M*VRs5!Pm7*8%fPVVNFN@_NbewXtOiHi@5rVW^9lK$~+$vv{<{WRV4{@TXYZwLf>IHDAeh=gbHd$I_ zT)C7U+x{C(=2dj=&_w5n1z+}A(%OBWt`^bIvHvfR`h>A;*UGQ%NSb&%Q@2tPCSvVi zka?B2e+~U}4R9(Owq%!nB*(pG1={80^5{7IOpy2-OvJqL)~}5?9wQOpQMucfcRiY@ zrLX~K59vla)O=N>2N)QIE{#q4T$zA@S03UA*o{sG|s#{V~Zok6js=1(C-c`pAO9zs4E;lo8?mg`(zHENb^bK*UB zb0dwCFnK<}vYvFBipQYVZmY^Fk&LqN!1&vrnq}?BoU6FJ_(R>82=36OY*V1|vGVGD zpHP|4s=Yr`Pa>e+$MCcH__Mq!)a7|Kr_ot^8REfv+?}V`m*qEuij2Xv7jM!6Vefqj zI~RdTX0AqtVvO;L& z$ELA=T->lrRF2x1P#kSQFI7Ott10&t`G*2ti1owUPm@K3{z)5&6{j^i3&Hiue!d)W znfi(w$KWClZDc+i1^_*BIuxdAOG{fYC|U#fD5DdQ#oG`meftu?|KE?JA&p>zuPAS^ zIi`>3a0DJr+Iu6vb^eaIE56IhhFug9kkPZ6D>Ju_2qgqvh5lQZCKz-xF1C$6n&+9)FBa~+31tB zC+kIOn48=wnd1XD9>g)mlLR-U2h*7FWPy@@rdTPN>z0i8_Wh-ut<(z7^AEXrTlh{1 zlwmwzi7FW|*bt8=2#HyM8q%Ie;G+m@Lg2=2#UW;COi<6g>9m+r17vlie+n|YKgM+& z-_g(7jmK{e*!?~w_2wn+JfU5NPX%1B(dOA{;F?%hV-R4fCjCj>zz8(4t#J3PpODgd zOokoPwST%D!I;rNxCD|mYfG?~$gTL-9Q*q{fSfz1KfYRCh61;bUua7YK~L7+C@JAr0ekK`DZ#oEuXz@>xsEv<)8mC__l z#_jYi(Ff#MYjGaAN!G{vr>_$SMQ;V2Q!b5TBVtU~tX}?w&9_j|@X~qqlD1q-MTSo| zD~NM3|TFOdus|M;zQtm&_iYzKIY2n3u#`3_Wb7K{gSry&82G2!$tZmr2`Ulk& z1vU!}iItk*tZ2v*<51XyPI+?-D2#9>b8|H5$b;~&fMveC1a@L5_4nW@q)@&GL$kSiNvVdKS`)2#W>vmo^TG+{#yzS11|OgC|9(%sE9=m# zDSMPY0w3VcoK5~2aMj`r?p7^p4TFF4L%{J!dk4NE<~+^b5;NZf6v6VQd#>qb=S6P2 zMRwj{ZMy)PF9S9^0Z4P&@+z{Hnfzzf|GS;uv!Q< z1oy$WGN%?s>|D0snrQQ=tmThk3rv_{_0}SN3`wXQQuIdb7DD%< z#aMHb$a7&_Tu6L^n&5t7LC)t*Z^mSd?JLVYT8#hjo(J;RlKjlKCTeQ=%G`0zsEjZ# zp*itgz%*1N&*v-*j8`0}+qpcM=cwy%EeSOWJ)^H2M-G?+$>XfhmM%^C0QB6std63U z?k8@Yb|JC+eSLZ{Ddk;&LjM2rUSYXBepGE&_#mat*DgMkG8J$Sryy5xw zAGY8=ST0d{a=R%n+AU=>w!kMUWmo^%isM6G^G0_!&=VdC%J~J1$d~n zse*$U)_gS=$d84~_Qw8yAs6|S*Og$jU^brcte1)y zrwUvP^L+ZT``t!9r_XoH?_t7<#KaLCdgQBu@4c{Xy{ER*_qp&idhg|((em6{w6-%& zregA4+bmeXXM)hWTR2T>kguzE=C5p_qAOp0qnZapQ3raD-a@g7hIv+hw2}O%CX47>z3<#oCB0|7Bs432Hn;$XFW5)BLH*-q6|#lSQldWR}L?J7$mc`?2Y2pFZKPIWkH4dNzEw=QaP^ONLJ+<_(x-rW6rRqW&C zII_nK3t%2*(r&+U7*tU2DLuApUJShtgt>T2aRBhH3jCDnm$WYjmXMEaZ!Q}5G@hU1 z|C95dla_6`C(iv4&5HRMj0;~r6Ne7($-jqU+x?4QtPY21jfqFy`7ySDRp>w5E*Q?= z2_nhAL*jQ6#FWy_?uG2xn?o(1-|eD<3KeYsPg|2*FR<4JVMbaqGM~J`A7wEpJm%0zu2akyyG1JZQ>C`mmK<-4{A8q2j<~jJkPX>YERt zw&y5#UgE>{%7pKM0Y8`hTbrrfm|y8yLDDx6Wj`!%lV?>B5Q;OX=ZETDr~57Wm1F;# z41`b#5>~#EqF;TkuSJ4K+DCWc_Rk{Nb33lr^CPte{6a>Y3Nx!&`Z^ zC66*uqBiD#86O;PFh)agh$$KH`NZj zu+xfR6CV#)jtZIf?b6{)+`eE4`w*XSYsUK7kqpZR9`WICo$#<($M?J+UR0$)5^rZX zqf_54Wfja2=f2Hh7<-eaa8I%zOOj{msyO5y_6xGtB|RX+NxNWk$4Ti419s`-F@isD zA!{@`*y8h5P;VCBntDhB1)F92tJ{HI6%OcP{~DRO&UL*oA`3Fqoy7ZUl2?muCkFCdb)MurX8Kv*|6;2lltS31CU5mFs!!%TO0mO8 z_SwUoS_1_`$w`Z;@PuR5ocH%^_^Y22l9;;5Sy&twOiU zhTe8HbhR&`{QpR%Co}wbzHQEC>@?=!gD}d1(4fKr35g0+cQtbE!Rba1g-;I!Ue7^U zZ)$!TEInqtGh6_RDa!kLzcRf{S#+mv{OVVhwgU|uQp0#F_~QlLC+3Nz&Wreo(DiMS z^S3!?3j2utIW_VX76pN26zivvpe{_f+u$Flt_jR7{O(#y@HyeJqg;lyO&4K3l9EBZ z!Xw7?SC`5+D*&=4Ck0%%krWQAso%5}QHgIb>(*1{6}!^lFjX^N1c&)58a?I)(w?F@ z%IJFx;spIzVf^=S&iZ>-yt0JiiIQH)`}=fQdTdD;C4KaH6vVXy;uK7*_dj8tZ7D?f zY@I??vU`iXGVZ$0%wGOeEo>zYQ0s5{ppj+aVUByI6wo98^8BsC#k1LYOf_EX{ZEY| z00B%%;w^{1&OjP4W#k~riYh}@rgK>+Ur6kjRkqdGB`!6qAEI8%7_5|MBf-syG$K^m z+d!HmbOFxwYxq0Xiu@d;xQ5IX0~JFkZoJ`55T6;?RBFv>^JQ=^lPxD~Owbp@M$07i@20L`wm%7YyZ`P<>!4+T0vq3+&o?%Cm z8G%iqLMM)~-s^=LkIFVTqDr8{HTtb_e}2CuOfNcctVEUv>=MNr5tW}cbCEYGhd*3* zL0`-H9aqWz{}VUC(rG_pC*FvTh%Ff5IFkh*tf}}YWDcRmIGrv8?~oSDKv&Va&@9Rx z>#zC&4B4QCToEml1QN^_jQbor@q-(jg!G=#=sQKN-5gnU;Ag3yGWEJ|n;YEG5)L-O#H`${k*BC06)y9>-j8y%T*!LKZ+yyAXr z&HtW`7L~_*HbhIyx!Y_PZ3oyf_IM){Ce4kx(-_$vE z-2e(P9Qb292hTK#+xitZceU-=rjqFMbGM9|Ql6)}TTd+{nkPPhi5v_&E!E;5d=cRA zV40Nq!z>XDXIJa39y#J-$Vs^IwOY4p8_E(C(S!(p$ z#9_y1u7w(oeZA(a*BKIerl;k5-`a|51!X>Jhk@<#p=V=WUjw z?`-|-LYOQ5s(r0?9m=6=m-EWbNYBPy4kS*93q?*&XXCZMt^4hzxQc?cjUmfvQ#~Gk z(??PJV#>zCDwtPxRlfO`sd0AxLAaQXug-%Wjj8ZY?s-RaXB7H9JbPi00`T_AN|>+4 zX_|9&M?7?R@)eS^O9-3io4HYc?x!52m>Ni{Hk1!lB8@f~og#|gVOW#wc!kfJ71D8{ z`Vt9|{^UvXWcD@ z7f>Q_OC$@1XPV&|70zH_b4+TqLio0=Z3_ubltL}g6rko_&Bkw z=o7M@%RvZa7S39`!Ieiq*yKH2)W-yzpMa5TJTmR_AGp0H<^y|NfdS;Y=V2A7Cc=0s z^k{a!%neKyo!IKfv>&4l;M4er6j+9G_00g%aLV;`{mbWkehD9%b^g~2Fur{F3iC)L zd3HN)WC8(n?{9Yg#W43ppIVXZIP@8Tioog~10k zaZ%~Qp+47aLVIcNmkjFo6%Gr!0J!Gl?`@Xk^j(kmi}56hFKv;yrFN##;>QbhH}E6n zC*Ek0Tf9QQ&cP~9y#DH=CYH|J!SoVQm_>?%a7L04sD=7u?2(g-d*Wo<83!L0VF1@t zGMKc^{}3`5Dk%&23dv;*9QOZjmqGUqR19U?bmC_gmP`=2&V8CniZ@gL6Tm^Rn&?iv z^AgH!lNkq30%nm&(X=vo!Xagl9~Od5r|6=&4UF@45m($*s?uTA9Qx zF8(J?(qMuX4bN=_Czs#c`h5{I_d%Gj6TL+cmm%7Bop-oEI9ooqE;Lk#C`HaS)7zKa z43ECf_n8)@rH9FS((?ea_+KKJy$|~HJn9ixADePo9qe2wV%kA?m?K%1joT_CAr!!j z#LBe0us7v3)ZaoVJE}L|@>nY&5QM_9nxnr$Og~#R+mY3T8t}DF zTRK(c8+T{RP)X^fMIN`asJlp(38A&tIiIW^V{ONsPIEaBQo{LXf5l}YMHC9cfs9e=g_~JTfXJpE46JYKU4Y(%4O%#>+Xy1;#9Tr-xyv7U^ zSPJu_LOvO`9V`00Mxr;ZpCT!|OJuH=e(2Z->tdf^9MMKqSiVodOgf&#fYKU+SS(}lN!?0~HhvG_mMT=U%FDDvbH?O*9tfd|jfGw3PN#7RkCx8KT8O_4gD*xh#i|dP zimv(c6KXfhXOREJc0h}>$!GCj%~sHY(hjrI%bWw@n$J5#mC2l8JHF1BdbC<7uk{;T zRH$|JMbxquefvdsS{lt&)VbzE|}z?0l)p^q*4yY{7R>zmD5D-Uv3 z)+`GLG8RzoM`RFvg?pL;hBf#Jn*Og`V^JY_QSM^}QA1aQ4N!Z3UVoys{x{HDcsOzx zx+Qhcyk2hA83TYyIo2Y0m!NOb2d)_n`@Qk*)qRex)p?Ngri=6rD7QwhV0!QKcZFT! zm%tm?ZZ!Tun-t9F-?+%f3+nnOhIk4rgiqSBzABsu^fX=wkpHcYl7FaL2$y~?l@Q1V z>p_)jb7S_iaXOhT*jg)z_A|WPdy}2ycF|R2SC=&F&FXSXuW1uG?_-t8J3%`cnE-b5 zZ&QqQ2Z1rj#n#i}#4QbbP-TqT55+*x^ zll-P2T+Wy4(N>Q8JLnq*jG$cATtXeYNSfe)Xf}H>l&{%a*fxS9 zXGoq*Sp6e$$`+xQUm2DXVVZKj$Q5K3&Vux7xQ}(MO&=@tb?d!={<2U`Q#aYO%mhJV z_Thf-e}Y|oN9A+9jzFy zb?=f=1-xp-1vfyFPY3+-Vt%1MUi3baZt95* z7KuKijwx+&-elFTKmV=UR|5rmgtaq?^66)Enspu4{_2!C+_$PzG`l2{$g1fz@e$P} zm*)j6xqXHc`Zmf0pOqLc4Q?%CE-T@G27*?@zseaiZ6bo4Rv?r5@=sL$b9ONU?9Ntg z!GM5-k7XZ&Kl85mEDEwI*vwO>)PK#JWugq31D;t8 zC2erzPq_&4dfZLwbednb?DjbgmN}NgM8+lqnU6vGnWoQ@qkC>Ys%{9Jo%D5`iiql` zNO?~9lTk(Njly9VP}zQaDoEP;jh4&%Vb-htWjAajaC^of#Eork^i<)nfIj}gON~x= zjE{|_tkU#R%K!Lm@pa{qyVI?KA&zQED63n)!G4=Fsum{0y~QrkKfL^B+nO;F{bSo~ z>It@Uw2U_LD&ME%biZ2fJ>|5vsKiXA>~orWV}l@|_VEn7@Vq{Da`T{u^CLCNvruK? zA3&K4+#+@j^{vN*2=*B52G=pWMI|hiEm&eBD>K(L6qS6dW+XTbvK!9VYje06l`m+P z9qtm6>g+~i4WHvqI-NIBl;&ma9m?Ik{rlJ~ORPXifoB#1Qfh7HL1PRS zuEJfF$vZztdV@}j+7`Z0*0Aiyfg!8wynz_L+!hT?{n|n9F~19*FzGqr<6JbnS7=JL zN46{^xo*jksaHfGKVSF=a^J%L42g>y8%WuCKuh43x@y^{h`t-9)z!VuuZ(cyl6)zU_{P(4w|=|0yezAtTldTU0lMs!2pRwm+5JU*UN$)zr|8 z_kB8qIJ{*(9*JZ&!QY$l{ydu3a^Y<@DNYK{1Q`?lr-^$SxWjJrnbRSQ!$L>H1;cW| zLF93V!Cb-%4;?!J2Ex1M(1|nn8c%S95k_{M+rlK)aaZo&(b}Zz!i!_9>hhS%6(+`z zk*6+&fX(do{U(;I(oMXiu}TsoUdP&2{Ys$)+dseM_ZuPCp+uFLcguWPuFXrmdkiP| zD!7#9-~1^EFA-niqN%p$Qqwz;#$0lg0_AR$FXoA#~%ZXxP+QW}T@1u~iL=v_lmI^Sy+$y$U z!<%fMt1qj>Fbhx`^JO_!6C^$ao#3}o)NP;}Ihsrauebuea$JOm~>54E>@k>Ap zHC>=hQ6;$dPjolYA?M7Hqb7JoPnI&xc;ehlGuw0OH4E1R8AeXH<%H;%wOOgpLKJx&IO@<85_*i1jg(1(4=ihy) zK8OsnmEi=e^g$)V8Taiij_N%~I|ztR31^dHn18^PQwF#n@MNUf3D{oMk4%LOFicv4 zwoF41I+bh%${G^y)U}iL{#*GP%t(M(Yh}$PV{dvB_9x2DcDg(BT2Lu%WCR$9gLxIw z?wPDXs1z!hZ%SAi20}zDjw=v-j%NB(E&CUVr68{fzSmee-e?Q)AH55Qh>t=Pgm_Z9B^@`a!H+Hsp^RI@?E`VT|C_BUmQG|Sa@wiWpRAl)?!+Dz?v^LbQgf9^VvZI% zNBC4jZoT|lb{_wEJG^c_1B%g!7X#KjPRx`S4R~#jD$F=mS<+7~Xqc@zDeXN!&q;&R zoW$jQ6jJUNm$1AIFJ`ua)Q{(&!?in|cMR57PQvXijw%j#ZakT#!{)uL5q#mSij-Le zd?Hs;)vk*6olXwnT@c5C+gM)get>HLjH`I1wI>kw(DgqvZ)}e}1dGkgbvZA&vp6iC zABYTXTx33PGj8@q1w-6>uaou5g2wngf3)=$%jSF9mDWO*YTgO(KP0BY{1}mZVL-OF z^vZ+`r`(v~6{Z~qB4>gW%86ZS1_U&f$l_J>#$+98S|Z_x@>(K;LL&v>kt0=p3WB2f zjCPUaRjcwz)2^aQ_`~b&zHRNjcI>2g{i9`>bMsC=<)X>$!mn({=xCWHuE$56>-|5< z-aH)YFZ>%PwmZ21~C%cJ?kSvAljeXy@nIWOYQi$y95JI-GjD1k{>{(|FW62h? z$i9W&pwI96{+{Q0p6mKuSO4^OzwdMI*S(#&&w1a6Gr6+@@z28LDQt)Oi};iryW*>= z?#bj$q&~Q{>36=__i$ zI};(`yL=v(VJ?LI3G%Mn$mz5uX9{Y;N7?-w@Wx6$^bXG!x(v6#*S*Y|HI2LE%LrH^5pI1>@VP^0Vg zXP6ex4a@?Y?OLf_LT{N$+~pAL0Q4;ueh%lrX(v+?@xI)x)@C67*_cS&7rXQq5o6p+ z|1EqLnQNmOWF{ao7q2}2^ma zKF+*0usCh1cQi0HzQq?Msk1wDbNsdvOJcdhoETNg`ztQjgHcL+UMUhJS;YYD)DlO0TS3{!(x3uKwBRsc(bL=h;{X{_Hc|_bIVvbyC^fHY5c;!I_Dq# z18INUaZ6N)&9j-tc-dC<_KeCB=ZlDX1;(VMgq=y{Jrvg z)gJJ%vWM~ROgusOF0D#v&&L62=8zVU#vEk%mlhdhDJjth_V;JAy>s}?glk(J^B>)o z^VHk>&&%NCK-04y(oO6?MJ0qHAkV7jf^8BH0&h9kzg!hckWR>lbP$Gma&N3ewelFh z62Z9`z!}GXZ+O0$YwYQTn7VWaDu${T1^qcyPlJVd2!B0N!Bi{1_?_YdlqYMDqX|epY%q(qyK3w)4$Hj~-~x(OJ%R z18?H@P0PJ$*^r&IFE%zW8O7n$yeZxk!rKOvQC;mT#!UweM}Hfl`n2X8;fbWO6vtMR3#h&%?~EGkC5j;UL6 z@j6tQpgMl;C^T$W>72#yy*Bg=0}xvgwHpr;D8Q-aK+DzFacOup#9P)Qngf%fRK0Fu ze6jM*HBu!M#fDDcN1=hYL9)q@jgl;ES9@xr;MK`G<+>o3+ZFru@BxTqriyR zIzVYdkCZTtiZZdJ1rm&HzgW}r{0qnY zd!Qy+SeTk3PE>8-gO}r2Gc=Ox!n@2;_p(gh^aq+OwBKX(1TAI6D@3s-BBzyqmK%js7tWY8FmqxC z&F>-UMas0hOLK!BI)r1sn%aBd{zW=4i`G$)FK+N z+Z2my2^Q{E(`&dv3hJ62@?qezF?&R*CDw+~7Q27#q*M>32j=y*xERXPs$kut$9asy zxCDV!LZ4I)S14%rr?>U2JO=k;+deXk=KQ}v^ia&O$`DS#I1ww#6<9FhVOVJ zR$E7xM$*ka=HkcXLnq4`V)7|cL@vlCyBgOId5tUJ1#8HIV%y(02_wN$rgQQIc-`ft z$;4hELfgT}_z#c(ao%C)%UE8lE(Rt*h^ne5e(k8=WIuH2>5^ZYtv5IBgt1f6C3Feo zei$zyp6p)`k1Q#RHx6^PeL(^;`!^xR?_C9*P@nBk15&(kH0(b~x46dy#~J5^b-f2V z%)j`^5?+}G6Kj1k`Ov-lSpqn=M8MYWN#X~N%}DUZ7Y~vGApU3#^8);5;8{?wDir)3 zHZpy+GeHStjO5_QT|+*P{{mtemHM1Seu>uSd@kUNQcvWh?W!&iWUOcRw7?@tQ8=&D zYB#eR@E4cst5bwZSdjnVrsrtfS?Se~v1Xia+7B^DC6Uh9oHRK`dZU}Wq&D+Hq(40Z zIoh)1D-6Le+(fK@y6^ajDnK9I#6*Dm2{P1LSDGH?NWUxdRb*b8Ep4!tkLJ1K_skk= zwP`b<;AhM~xNgm^({O)HK@&X?kIHcG-kSei_1x!4=D?191B=jMd53Fqi^zXAaC0Ui^--B*)!jEjl~K*zlWWC3P`hW!k>w zt*v3pmKSyf&T{5c2Wo@euY9$eK1OUTc-`X?Te5nks1+p4QV2>GQm2mVmVcUesn4i} z&Ew#MkCrt#M5-94tbG!d!pfY-6?(LPre+JZL>-yqWxDsL^!2GL(Sk1+} z#&D#AR0VH|=IEb0g1<8I5lQZ?SqmAlHQdWe`ePrB>akg2259q&!N&K0?{$I${1PcgpzmNX8!jVZ%8B+*0tl6-R6c|F8r%uLsoi`JTyS zE`3DCE~ngt$F<;Ae5&**(in{LILzTSx2#FyE*$f?fve*56B2S*eFcG?aea(IwV~n%bUT^5y3pUe_ zeKb^w>`%TQE@M}rJ3ah6!Xqh<39PG-%!GFde-Q%i`L1IJsN_*GHY~Y%Vr-(8ov~cP z_CE!2uOV~F@1^r%V^ZARl3zSPUL1H1;?D;QAO5j}g@kev@nS82&u&{b)D=;V-($3N zlDZUeMzJq_uRpvwCRbxbnUahZd3hSZ3-R~v-*81lH3>U&@!**pmQ)VYDseJ7*w?jj zvJvygoO!b;t3qAk!QY~g3}D^4i#dbVY{@(W^*_-pw8k~azWPQKb{udrJuXX1zQs3^ z_;OB~7pUAIcPl?9^8JEl5M0m}Sw9Nl&idKskYA_m@&54fIpni?|5Ylr_Yb=wXNg;- zvvkkw?{C>CWu5~+D~=o0+dRnjg+-R|5${HW<0gCSaSWYp^KvH#eeE%{*2}L1ZJ+7~L_f0MN(s=)A1lK=p92DD?b4% zh2-i(j+Oc8>|)JU7mv&HWl_xd`d6AKwoIglY_iZU@!MNq(*s7gUdwjjp!>It6%3 zIwRxU7wy`zn{C>eUL~>Zn=;Ut`~*KM>ydZ;@DH|@1@ywb+vM5D*K~Sy`b%!F&SYj7 zL@-jh*&Dp6j1a$}cL7p%Y~d9LahW0><6)-J*}W{GVs&H^;uK1PiC%XpfGd?BO9)rU z9fw~c4v+8KqY7J;2V@@HScudrtxsKkhxxoUf}~rGy}~GeV*>5W5Bjdu8$1acZqRMF zOf8~ZCoTkL6In*&W@uRQIKi$w$*T7bVD2HQZ>%(83`x+Q}Bx523OCxeF&|Y`$@Fhkp5WlkOWKH@V8WDkf3;psu$j?Qx2)#OTAv43*sMH#OT{ zULdAwH@wqh7>3@*oR2=4sJ%o`E$Wl{Gc3l%lysqMmfM~bf&r^# z2fyGIq_r%TTo7rYT^OIDg0ET2?7XMUXLl!X+EDvz+H-{I}`yyGNO&0mf}N1d$LI&kZm* ziZZY6$&fa;76MH@LE3yS`V}~NYn1|)zTmQWXXeAFMGeOO#ykBA+*AG`Uz~{;syJg( znOn?AW8~pYzfZ*5F}7I2t{zI}@HDyOeMI@mTBTDD0+$g9NPBbT&vXYflInmZ2V3?x z4!-;-(|YHj2Eg`Dl6GUx zWAs@IJTSaMY`8n(ly6)jWnI1%c}LV)lK-y z_-+y_i|LV!Wi6ht0T)Nyy-6U$ov4&D7*w|2bN}<^lJ7GPL8~D*$e$kWc5b_KW7gH$ z6Z%FBRlg0>Z7e%UG7s&2+xC@LVr33-du&hUt+r2U1XK`#v8Z@mjnch zspM&&d+O^AD%&a$WxW?FPHAkwJMe9{!QjMv%Pp5uI@hoBjei@sxHUmdahG-BkXpL= z3+yuHVa$_{s~4}?zWosP=;+7L*Kf4vho4ohQuCKnuev=l8~nC+;6(cHXwg$u-uFXj ztj_s+7gIY*{gvkPK%>!ex5M=&wNI-B{twW$o#8GVtdP6*>*H_GCXO*Zi>!jk?R&G{ zJvfIXtreO{(JW0qVuewRNWv%R#fb!pRX0I^PD6U!-T5yPmxl^oQ?a(0mE9akj0c+x zJ~3;pH$?qbUATKQXX|%Uw64#nGOB6Uo%9K<>l4rbooLel6o3=iP3P`&s zRa+z$Xlj0M{bIpPyN4W>>)Olz!tp1nUQ$bcipniyuRj0Lu&r^8xuJ0|Gj_hzQO)RN zt*&q#-;L7~uD?cq3o2;8{jI_b==wO{EWAwbA@JIcUgPK6dP#XOJMJC7pH>Vlq&vL7 zz}ME=I;s9L&M*&jWd>4}%q{OF2q=NreSu0YdwT6W-8n1PmurLBV4h>alb4C&{R1+DDOY}ND7ce8Hm>3TkZME?X`LuR#T#=LjPYq&96 zN;8Q$cHsq+44!#{U@5TvRZQ2Im}WS^jWTfn|WzYvWo?p_HbRWdnu)| z!nFSh_YWSUr~;?Vt#x)sN)D&$41+C&BeN^_O>E6R>rTQr7#^vezvhsk_pKj$0U)M2 z`E*XuPG2;*`F!Lj7jzVG*?wVXn)qCCGxu#IF;@>lM%p04V^=0*cOQ%z zq!}P>G8~fJUGI+E+OgK)ppBE1R&JMA=xfOhJ|{+d|MCYJkCzGwJgfC}4?O7VJE+5$ z+W*W{i1y2<$@Rp?kuKOMbv8DXJv-Th1cG`-asu@O!v7{p_zQ&qwD)w>fruzb%xyj6 zu8WxO9I2fAhq9MOH6oN|QaF7dH1KOTZ1b!ZR?Vh*=ixF+zB3(*SnRuWEW61L+3F+g z-Y6U8ax5m?vA3`s8zyw%RJ3_pn{)c#*YfFsA(6Sa5NNo>dKW&tmRJ|g_3Fj7Va`e^}NVFQz zo%G#>=mf*igGu9f&4Y4ir$efr`dsc??X1^RA*3e#3(VUG&}(xP^DT_PfoSI`T!`{Z zAeJt=iB|-NJ_t-5NwkDG44pf{<44)X6^MBZ1WbVN#HZMHeL~k4(+!HG?Z?Sodyhpt z|D|~^4q5U(%6(UCiR)9eh~nI9F-79*ppQW^_p}!4j)k#jrqUl9sviX`pTnfvZ#-_eQ#()oc`q1Rd7is}6o>v{~ zkPQ-4L$+wExL2B*&dYW+?wZcg?XM_>*0-_my?l3}4?KLUv{dsdAE~x=Vn8Qj#X=67 z9(|_4Ki{577$<`!YA=V*_FqEITaNxd@9kW6$M|FF539gufB3-?bc$?Nko5;=J_YKwt~s?1cS!UaoeOcTDTazqtGNGW4Sk<&EBU6T#qdN6ncwBYqK zwtY3%7^W3s8s`n!m1_U)_%b({dJ}2V;ZJj(IE>%fadO~`Cp)%|7%ER0*XPP&oDzpQ z_ibx6`rKawr(9;*OVgOuKoS5N#;%a!xFIl36mbF`>3Y6;QvFgnMQ3Vy|Isje=;C)} zmv7Wo1GUvVD}2AdlW%~n-cZ@y9BCd=mDl)wEJxPEkD%+;(9*#PGmgwr5 z9Q;{|deG5Df3OGaE<|unKEH`>eu>jW9-m2o|BacfJ zuhKmMLp43Gf}_BJkd6B?Q(&%t_suAnAWf$Bi=`;_Z3NK8EE~?Dp6x$2gcUgBHUTDm zS~(9rWUIm8aS_>gD>#{r7HWFTv<84XZLn)ZKPXyfjC7RV^qAdfg#m7MK=ZTcqrzsA zI)TFq8GN0}HwIkzTRiLzhkWd0U(DOtboX_c2)e?SZj7HcTP#a-NWvDw2uiYHlT7Sz`@5}Yp7lj*>Ed5y&tXVL23+P^POQ>tY|j!3QHS1=wh| z?$9L#%j-1@Q;yopbjn+Uux|e;ur*`0dCCFmrpudn_7ZL9JymR>JE3PUWGNaD_%pRapm0w;4}OxqEyZa#!S`IqSWd zk&BJA6dW$s{3UABVtj4&2T<(}->(-WMGj&9Za#_Lv|wMGBv$#fdt`Un$8d;l!WJzq z8>FTTNEB~O2XX#qQLE){m>&1QiwDw^gAKjylOX#KgMWH&DBM!7sJXhzoPlHXd01pV zc4HYC8t2nL1YI#%NevHu*SG&kOQ@~}2J|3x?Vh*=xl!hC)-ZueNzVm%+N%~`f(~9B z8wE<-i!-lp;x*jX`%Z0kuKpdLY>Ain-5c5MtAo#$?y%6O)~958*kN$zPt{!3YSJ!0 zAR%&TqXO{px%gxVF@Whex)s{Mxl*aXN$>CUWH&3={F3|lE?V}}=Fb3pjJ-&8=pJDP$^9AA|8X_Gzd@j5F5OKg`EanicY4 zQpb8Y!95eO9fC9i^LN1f>m&e6o|-f5wuS{(L4RerB7LLN01Dzsc?Yd)bDy@oWHZrj zo$1M6B8VFkH=5@BHguabFA2q3SpV~^j4W79X@Fc2+U}{&ZX^4X4lJ_H`zCpYy6>-e z=(}PC2C=nbUuVUG`zbkm_0iTC!`3>NT5TVedL&9_Wl;nHvUl4YPXvFbL%T8|uc8&0 zfvI`Ay_2;E{UG1_&`c^Zs~nb9-3)VCVtN_;69>YPF|{g!rd8pdKX04)|bpH5C0jQ*Y&tD&^E;*KV=Z7*ntc>9C>}ZLJ{@^=j#&PiG z$)cndZyJZnSKi{CuovD-@ED@7FI>P$mw$?M(d)I13VB)fO}ef&vp>hIhXU?TI{;dV zde0FJlI1sdf20@<%N-oGqkX*Cz-+E4SE9pd|5Z9%9mel~C+>)Wcz3jj^n<6gF68q?fi|$oc2O&dS>wVl zdgKlxX8Nutr212AAdsTy83^eJD=Asv>NucgX@z?Snt8jb%5C$;4$A4^I`3k?ELHX7 ztJW{68neI3CG6F4gcim&tsFFoI+=tVxt4w@4z>LK^*I~$VFF4_>ZXp;ejrX%f*{B6 z_wH`QSH#tndR(>RzY$VqbOgM& z4+9rzdRLY8_Dg6loxX4m$-U*aDk5r|iUp4LGz6KHJ2H~J?_lMX<(z3J@(zS8x<`BLNw@7!(2}A%GWhhim)89l54GH0lP5vqQ28R8 z!bH%NhqlZm*?wfGeErvl&Q+45{~zjd-NjhrlxYob-DO`?0{#%P%IQyKo=#suT+J5U zSP13lI=jAu*r}1SPc&3M2tYB(H4B`JIxe#4b_Rl%2 zb9<{r{sLRDOXHfnVcz%d^7~AG2fn0yyP;vIliv);BFb|MW6A$58=i&&2SSnl4TyJb zKajC&xM|KM)Lr}fPQPJ&8{cZ#L9GI9Q)Bd=#mqnMIkWw}dd6^=T$)Pdi7V3JU++bM=TKFDXpahbNV{Bo~*k zzM9z2r5PiL{)4tZ)02Ol310}Xu0`Ug{tb%WZ|-tm7)R4?3bVW~+mP!;ombh^#;$8# z7gl{>^+mD<&gR9KH{7GI4Ev!qb@?bc~&|W#vi2`*lT9hWJDm*V#)G8gQ<;N9I;55HE zs+F|&toYr3gE`IiYh30<&AP2??+0KFL4o1pk7wGmI2tvxbFz}GeFlGaH5rV9U~@s8 z^_YpAz*CDNhm_WNqlRdHfHU^0GX%80Z%FytwyL=`ALy*{$c+44epF*k0m_xjyDETd zSim(i4XZ|-ElEgk8uifp77VU(N-=NV(8t=3dWdpV=V-jK@^)HSR?+fi3EBSLF(|iy zeI|g(jT5Q_z4GtT9VKwN&i{j_dp0Um+1}a9zA?_nroA*&^!^9z4|u*o21SN-dJfPC z-0(%DKAg`;Cg{!q`qwr0UAI>8J#B0Q8>Y!n{H)9L)U5}r=`q0#Z%ai?5$ z92vp!w(A?RL-Vw;s=kUm>%HY_*aWxGOm$9TRL%fP=YB)hZ?;A0AlnOADtIrv*@l7< z|D6v1o#sNG|pS|dZ<0(-FA_TonR2f3s_YOSP>4R9Nxjp5A* z#bmj@=9Bm6@bKa$Q&kCM!bDf?1jhPych7=QT$Slt-s;_i{YLGw@)B92_^@qBukmi- zhh0Jo+J4NoJ@yHYM2g9QWu$*dQ39sqYXWz!!sZ)OiWG&nl1~vSPpV!<%-U3D?BMk- z+cxtF4x0)7MpG`m+!$=TB2z_QVY(o_q(Hb}v=SaFU_=SAApL`aF;%9A+bOj|K&Ng( zWQOg4;zb$Ivdy@aIOj^H{w6X)CDC@@TaP+jZa>7cGc&npI#a)oC(+_90R0Al2IW8? z)~G;TuO*lO$EI$alYoYqUA6jFjMJ#P31?80E>Q}+ePf+vghYEnj%$O>x~2CZymnN} zlZYSUmsp7RN2>hZbDp7zsf)-icfB!224w{py9_+}#&jYpIWjG|ez@lKnrAhnQ2>XR zm`|lTc3NSR+wF|aeE1Un@r_t9Q!rZ@vFs{lBx zTs%WGML{bt9rlxEqACC3sY1j^7~{S7wd&$jpii|x)GPnE={LMZ>Orp}=L`FFlZ2^P zE}aPS2J7mT-d&W&{Z34*l5p0?doLDjHVr!^yp>;GP#+{` z{BL&Yq~=b^n&0~7K{}mz8L1)%A}{}e8Nf}N!$Lr`+A99Sibh|j4h8s3#_4e2!RNXs z?oACsonl(1cQOhOoC_bVaQ!)6hLZ`PaMPMfy8AJK)IlNZxrBf>9*p0 z_>B`eV-Q|7njL$zQFd-$IBHyVD8XuVh+U}~$4=U|;m^plgH9b+%cXFYV?@q`P3}ryutRE zN6xDa72b>BI75(<6UIE1I_E1e8*+bf3td-kbR4*QXpudw{VIU9u)KdQGyen^wf6e#FMx_t8{f4T)nXNkg4F}Amvq|YeHcGyL+yHg2` z*`-~`C-RONUn3IJsCha86h@;?>oL1l6sK%w&-L9Nn(|BA*EZ{tgt_h%IM)YO+N2U6 ziG8xoev96#07r4#AugSm`D4UXRZ_r4Z5_XikOBPj7Y&63j^*S$ATMO@RR9J4g-m*X zVt(z$DKvY@P?0&18^+%3j<490de5RyQQ5?JbV0(UreYX(>F}xFJRUw~lbNdOxZpd4 z{CQOi!Py?~qizEIO{YUMilED5s4bTY>uwtn_}e@w)hou4=K{j?Pn@zIg;RquZd;%R(NVJ?afeRAsm zbwAF#Q=3`48q5=aF1V!MDzRGNmBO->$L%F)Ag^aE_Ku&}kj5PR_8&>#`rx5oDOzv( z8=X{$nuED^;i8UWIoZtDT*U?=Vf$8&OS`kr{7w}s`iBn%{~nC(&=S&hmiOA z%|g8-Mj!P(Xw7T*L;ROm@7W*&U?;dmIEm{N4xwvk;n5F??FiqY?crCpQ=OA>?$_-H zOiPrF6Z^%T#(ix0H}nq!FRq#_g)%OjYNU>Dt=Lb;rl?`EsIW|C{NTZjBm?#OP2$xz%H*8n`ikxl97H{L4+ADJ@M4=BLfsZ)kR8wP8+56nfT6 z?09(#wM%;p5Ch=T0-tMPo}3MhcZNOR8eP&G6`0T_BPH$H=^lp$N@Q1Y5$TZcd)8M9vi3@{^^)#!}CX3#%>5Tr4EQ#%0!!1+GXEI-|1kxbQv&{VkijLm_ zZcMWwW05bkSaZyHU!+|3K(z|@d2gwzd7Qm)V2PC(rbltJcf9)AE-KrZdqqi<9SBSn zaJ{dWkT(oV#!^c8c-b3YCMA=YZ%HNG*(^ZuZ=`-XBsiH*^o^Bli@8;<|y`s z_hHKX1bJAen~}`UQm4WeIsVc)r)K+-O%e9OlVplu_1}#Az zb97dr+mD=j@9>=se+v?$Ryh9OS%58}=lEhQlKO5H82XNsZtS&x_3e{Xd}6Cop`c$S zO49{clNCSTW3=BuJ#nTWu%mwy-Ru3|Xl>e|{yQ{*?33Ur1hG_Tg|zphsWVPOj3nwu ztEJKVlAo)n+XmhM3W{rpO+eNyj^}mdK-+6^XVNkupW9Z=C65)>njxdA;1U?`^C)KA zy$e7kk|^Kd#`qxx>rd5p59ECDQ;p?(dO=?%*#3^YgRa>BH^)fWl2-6HL*(xAl#i}o zA4~*yF=z=>uYhiUv-IX4Xu^=Y<_ZS~&d8-%ZqOtcLMcJGWM}_pcP1hOvHG+#=f!{M z-hl|hI{m9QU>+G*M`HJs<;8mK8h@E3aLQr#V0Onta`l1|#p*Nryn``}{C{wF^bhA^Uo=Q?I##cEzBBsG z^sR0G5L!H(Ssem6u~QQ2eb)RN!akGGDv6hJ+E*x|yk`cjvU@eSNalI6+RG~+&V|(+ zcl~+VE|5qHfTuX?58_QsaTMD~ATT?5kyJXR+Y-=xZ-r<`y0# zX6I52SQ=0`-kw0Vm=Si4`HF5%Xr;?S(tm)JGR);IV|_GJGIqQCi|?1kSx^Gejqkcd zgSYMExuQd>+}3YOAHEHPQ2^1+#9!##kG;Frcey@>PPV-eZmPMFjK76$rh}}KBY&2B zo$wN$aX={y&BOaF`AJX9{O`wsxF(Q}a=)n|)2V#()#ALT)EAMG69H*-)zNbGseiAg z)f%t<8<-rwPO6p40~~H55X2r=j_Mu&gaL0siQIV&8iG@q^S^VDVSn0f1Nb-WIiytt zs1)?q`nB?1wFz?Zpb`jLz3d$TFZuz*vYKRbi9q0v8{`N>`f%FWg96<_m(B(Pk-8*@ z0tmmNWt@_Vh5T_`_gpRjsUT(Vu(@TpqyD*8UN)t;ptMAHbhqXh2un0dDobnDeha`` zKnuFy$zg!RA*n2PzKAvFIu206a{9YhtVqtYnNn**5O((Jd;|>AYh9k8I#<*+Z#p$U zJNV8(>TK3Yt#B+T_7F>GI!+daYX>g4N!GJJ?S#5+_{MbR{jfNN4tWi-CAb(}72(=o ztl7ywwVuz7YnoELN8`Qmy1an;pOj%BX719GFM0=uILB6y8c6QYE2-uXHo&a~A^e+9 zk7bg`+?)#Aeo3zfbPMrH015!lEzd7jyILLjeB{T!I?y-;EDQw5gm+aYj91nK1*%Ur zwjqnwY}N_>!{$;8U9BNysVV@`D+W1eg=_7XF&=(&t=(;2NcvD`UQXzZCA07LXMB!UY-Gm(`owm8Vap5 z~d=TF01{`)xmI@u#*kMF}|^ili(T+Gzr$;_KBS5*WMB9No48 zcSJN?tNYlC(uVlC0MdB^wDF{d5Rj{oG7cYZiL{yl$DR5vQCBM#@I&A-qg4{E^f)PU zkViv|v2Ewf5x8RN(MT`@ekv4une>VQ@+DhFo&BB=AJXk{WRdYKGjQ44%J4fW0x=-B z_9zcz?wX5_hiomrYu4URM>B8SqYDOI0HSH(Si#UcZ8kO4{nU`5{86_lnzx`Ia||Sw zyK3b;X@o`uwkr-)AqunXlwTg!hAh9YdB}%6Px||-%AOS;MCPB4t|;(OK1vkke$|nQp98cgMHJw)g?xwfBqBw(WQLF|dVQCUgJ^$B zI7JDCub@I3!CmkgHz{vZ?k>f}iSmg_S<*pMVCQ8*AdgTgY?jy_2YL!J>wCsO=r$Hy zlW7!~7tz&92XU+vTB)a9n@8b?o_dN)hj0KM3x?N+ySKqP@E8Q%s)Y`cMhJ5;lUhU3 z63rw@&>7V{$&XFL-@@2}C3-FFE8b!EDuwK}1gD9%O*R!8-^4;8as!;90tKDKk2%=w zegQrp8s<*UgI%{D4?X%h>+z}rR}i5krLn`S2K(aT9}_NP#M+W_@g#rDdKjWcLy@eS zkPr1%X4i1HTr(f7ESN@hYL=p5xJzUtk}Sx0G28%Pt;UbMVm+ag#D=?ty&v{P=x*c7 zN{zJS9&Zr%3MsLa>7ph@iljsPY-)TZQ6l?Y@J3gI9$|t-eE{qWfMC`bQ#an$s|hJP z08RE)*fIyXQP!!6z=Ni2^bH2~shzX6hm;8`wumLnx)?$fzDNRk$N%VQX;{_Erqrlz z%I{k@u_oUJH;JUr1tf;mUxtIkO&7)Q2h?heRUtO8M{JO?35}^&TZn^=$c~%}p^s23 zvI4I-m{3Lz`(mG=P-y6|(^HQ)tRv;FMjVgjjwTgwdMK98nN_6C{d6}U{f)MuCf+dO^sz8 z3ZV=dkb;n=g;r-jQoltDRe^~r);clxK6S!4jr%1ZW|-!aoUkm;N19k+{PLljv3^mQ zKFnLiz#Yza3`~DRin9F6ngh3R2TCZ?XTk1i(Lqb2^QR2uWnPLMaGp-;BpCCbMygvU zQoVzn#`7QxKM6)a_5VS562AT?9SNcT8{sKhC;a}=?Ty9!|Ka|BpT+;m z{QorD|CO#;`~M);Dd8yyr$YUsL;vsc{|~}baZdT2(UIUfwS_aF{#U{?uuky&-{`p6 zku5t>q|y6rPLzUG>+E;nUskr1Az7Ao8`0d6BMuU)NCU>knUr56@y)l8*>lb)&VhZQ zw+2Zc=Xa4FS?xqSjfrq!)c3ECF>eJO8IS@F>ETYcH0jZ`vBS(p?`2n0RLk#Y-xDNn zU!tOTIR5h2cj;n2RVJANi^_6Kd#l6aOmB6}vigv&SDf^e;$Ied=Zk(nU;LGpQI|5! zoydEGzmA+v#J*&y^Z<~}D7^)lJo!Oa;r|Z*CB5n~gzR;X2go$^6ToJNZ#={+t>x^= zO*tFN@kVvXB$}?Coa_@6kX9f-UGWY-#RGJ63FBiX`>s+;ck=&Kypp3!m=7h{=OX!q z`tN5C`H=h*vkd^U*Kk6H7a*3z+h82vYM-dR`}iE$rN#On5aswo$m%CpHE7~4e)1gI z<9gA@J&QB)Clf>9HEkcP3@?enh7DW30=rFT_#%Dr}+e;;GMd2p~Bk`BIG>3)7BJg$t^#{HhqZx_HK=g zEJ*UFf|jTwd;CK6vOY{v&rFOkS~$3KzQX%C1#e!4V2LuNDM!M_24f)*DJ4#0P(?!Snu{lPojm$0Snov+KA`Let~b`-xvVtL3GU)^mr(w{xVAA{OAiw^~YpEwnJC_{e1 zKd(P0b4KXfms&@yY7;ss$jHv?YnoiAJgCB^Z}$Ikn_WjCfl9d&$>^o9p|F(b`Kvcpv+wG zVf3%W%v(v}Fyaz~{sWkALnXb+#)P+e5-{FX!CUd;Hvcq(|9W)2K6b{Ng6uOleoVu^ zY@^Le$*xlrrXFTf!^=Q8pO~=SN-2NP!_NBV9NBM5q|iY!X8}|p1kdv@ffonOkSX$z7{jjP2+hR$VP0!7gXAqwLY6aIB*LKLR+>{B{|toI>;zELrsCVQ0zjAL2n5SHWn5R zx#iN?U7F@O5Pq8l^&Ub-Hq;DvWC6{O7bW|t{@RbXF7wuaq-$0RMXUx?xtT|$0kdIIKNeJE)hnlMj`Sh>Mg*Usr z&~#)E?x07b13L5nKJF!FCkU*h-D&PGw^0+s*dm*FUUNt2w_5_q$W%~kxqk@F{Tv@1 zCo`-0#CSggVSZUc-9WWldTLHM z7K(Y-hN7b&8VBCnb`$+U!K8RS@`5#VRB}0`;g$IXBvr@<186?yJD9g^@24J-4@!%q z#v=-?Dl!GdLSIRopMcX14b|~G@R6lVYIY7)*9lJG;R_AOz4(tu9M6orC{%(fHv-Dz zq_#<%<6p2E6di%6x~ zA{_%kI)*fCl+s)_KxmwWhCp9k zwToptPXR*`AkXvELu)z$*JyCieJ586JQ--v;#UGJkZX|)8?o-M|8@O}qXzZ{uwfz3LNl%*s5jec7_>dVJF zefz?)(&Gcs_y`8I;@+h2PZ*!+(;;Su7thB&s?f%#k`jhD>>Mdm$!Mn;>*97ODj~~U zeFVyd+aM3_@lXqs-6x-ZJ~hgi(JOSFbhGlQ#H11n8N?4dtv%z9$=?QX?(&s?Ap%~x z@b#u}KLNr_Q?ILxt?c9VQAv5|u(y~fsos~eN#UsCn#_2#G}3xwG*7#tvBabGK4@p5 zc#QdDk8{TH#GwS_J0tWw@}HA-OML8ka09Tb^suP z!d_l+>G#1K&RwTrnB|NcceEYt82%p#lE0+W1NJ(8Yy~iqg4S=7(EuL0m?|CJJbQED zWcKy7UOiG&g4jLP{?q_D9Y6|}Un}t3JropQEsgl_irr{v|DCIVn|72B5l5OJgA!+0 zp~81C(%;2Ou5a}>zNW-E+W|K8$7`=SMB6isxx`c|F-XY**26jMq0(2-J7p1h?}^9Z zXpa`{-Q(O7KDraPCrcmk)@`Jf^Yu@}fQn%JH?Oz2*lt{xtLN7(pYuJHI*fUEr!U<# z9Z+jlIYg5$9bJ5~6e62P^zndXoX?%s|!-QkyYY5?}+ihsi*SxS6O*`78Hb;N9J1GQeXb36Zz}s1$IX* zaXN7Q-FRaEmP~ZyR^+t4*Hp@=6(hnXL*x+aQq*Y&n{1E&>$vUeKed`Idf!s>9VbVA zcbxr7o{oW{rapPejcZH~uHQHfJ^!1vH>qLmS~6C>(m^6=1t70FuL;xz4vK+5uJ3r& z_`E9eJw_mSof2N|TtcNv<0kipfS2e#p>tx+j=8pnB<>r!KJ@~zGSGZNnCo)j0+Hz>H@>vi}+HbK>OZyk9nEv4E&x6t-)NgP4B#7mjN0+)d_ z;TfW@ldG!PB*80qCr7gD6f39WdWB1&VV85kP5c)WF49H*mqcrz$`^QLkUI=?a*w(`WHl{9WzwFlD_ggm7D2Y@V8Fw zb>gUP$<%ESsF`j7tzYz&u)df?DGWBOjcF)JCw}6@A-r&WK5+tdc$p{|!I=yMvbT_V z@e2lpWGo(kz5HpBMC=#(%BBbRrLr%`*n+mTejtHBX@!H;i<{iEu#`6pHdDbdH~q~B zRA?Xq7pKX)#{WG-v(gQcoAZl;t68|Gqh1_v2JhG_1|vf#U=~;l-R8GNBBZ>^D#-*S zj5iVT0C8n=KM9*v>mo=5g|QAlt=gbA*T7ilXW`_PO21esT65FgOgkaI7R$gb3lLH-J506TQfws z1>!2;jthzCclb}@+Nyp%%$Ben2ifJF=pJTcYI`2%>PLTkCb%(v(3G-vR?5FzqwUQO zf-3doAl_nmu@i(}>OrDYIXxPtRp;c%mW)Sg!}IOg3EUXP24c7CI(TXl`UR=?=z|9Z z=!L{YXenB0z{1#M05SG{2KJjHHn%7CKD!INI#5r!4EhSJK@CvaA#$?rkkRA z*FfJAHnsbrI_IuOJd_G_=eDVBh#hTQ3CqfaqT;Qbc*1No)e6rYz$2nL(WJNan7hUY z(h>mxS^teij7xsvI9|++CbZ`?{f6BZ3cyh-=LcbNY!M47fWAgY=3JP0Ofy0^_;*pG z38UOS!DHW`x8DP5W`*1klyD$&8$XA+UoVg?qY6-p;!0+Bk`?L~h39Ji=eo$O#UA#i zmY!qrKMmo6=#F6^)9HhC8OzA)T;CLo7eVbIxsFe~1+$p)vxrk_g`ZHnE45%xEtsX* zrruWqDWJE-hUxt_FjDP%4TZ}oMRfP|JOcqcMNZcuLg6~!T&Av5KU2z_8{^>d zQjy_RHkN5xD4saoPL-m514zV=DaYbuUoRXuOFO}lzj2q9F4&QkO4geF1Q(gddG;S8 zRX^0Cyh7c0f>>mFpz4MuVsvzUZGRO(t&TsL@6-7`S&88wy3QBZ%EP^p>k4-zih6an z{CcTv%kz%r->i=b*9!cu#7B{Wa%tj!6x%F-mjS0$kP`bbyC>&(<5Z#Nw8#s9-?Ol= zm$(g&-rS#wPRWGW zcIqTwcF!2)d4)9)dZ8$K)4H&V->~*!J$M&D_s?!V`5q_~oTp?Gw{>hPbRt$CSRX|B zkap+epC1J`LC2thn?s?NcT`uGSI-|VW$TKK4>*1l+Ln9E*LhCTuy@=dm}c4BPZwHA z3Gz2T;ixh)IKKB1#LpHF&mH#Lb9jrdblMC_ z65RPfpi&AePDK$1!Fl)5IH~5K<88-Y=JY4UmWAna-amZUSEo-C;?BDVr^d>aRQK7t z1&kaZ{6?#_-#_zDkve>#Rsj_Fv8b$M8kz4svegQm#m@uO$w05!u8a(Tk2O2{RS~gccI|F6@rZCpR7tG z4D0T5E>82xE1Z;IfmynS-SD(;F*7?|teJu_LdZKHWq8Qi@CV)0{SPm^)!SZUNBtjv zz~ro-+HFo-^cf83opLRVvka|T={>0;NAl`WnA!-p1LP9=}MTeEf6hRCyzPMdbum&O$qZcybgz zl-a0cZ>5D}iEl1*0-x z@ZJTh!BKcUs<~`|tbJ%c&Oa5 zcTnVh_h7ZQjy(^@T?ey~i#KN}d(Qly16j>eL7<)S3TU40Zk;+joUAI2AOCB9dD2)GHOX`O9WFtEUcgGaitwhL$zkcKt=@QK*ZGH0DL3_thh=@@w1CN-_cr2*{k-{79UBQd=NMTqa{Phehj9Cj%#5GAisJ{WAf;$lvC_${V>@gQ+hNF*_rZh0d-ghQm4IHl%*1S}D z*1uV)z5j1;$D%f>qF7(#WJf>}$>vql&SR@_HWtk8`z*_IMJp?K3@K9mvUmaA{cj2t#q^I1r2*Fp zdBP(k!=3`}gtJe%RewGan2BKW22vEzF)w!fC=N5woj`pha%t^o7t;T%(#1(f59P_k zl&;u-h(bg*Y5#j}JVJPP*R$;<)+eFQS4^kOS1f&%{6s0=H}Q~} zM@W0eyI>VRJq~L?)qDTm@~s|WqcjHSzEI&Yax9m-;XNYkpt@X>;vZH~6AsTjYBY=J zbs1t?*%01};`Syw07w+L5XJt&csrqadVx0mG8&JurL4>#F94n7>rmw_RvzGpwChDj7hm-0U0eZyV$hU}}c z@l&>Uzu^X#z|WGN->kL+mzFcA5;$Ene7%MW84w4!S$_YoiX|D)gy4IdN=Ck4tV6Q8ybtdnGAmu4FiPAA zTd7QkVpAthhtX74&~irsKzuun*(3*PjOVn$?J{|{rNYKYK0B)7lqbU?!6)TKL~~P0h$X8X*6{mimcH8@4K`=@nQuiP!fXKb z2M9vTUetMI3(pjhS_>*~S2-6EKbF|UPQU27-#yA~QP5*BO&(mzK~-xDX~(#r0jc-u z_*O~aiHEaHrm%&dpY7Pv3w#V_Q$$X;zCf&~6+>2{Lew$kZwt0A`VNBP?sfv~OWr^o z<@;Ay2izZL9I91PX}0XQ1lwV~smipzJ$8t^k_6? zKlVpocX3fPb|8I+8dsAW$#RuB(}@Q-GD8;DkDucK&*2A6Nvlbx79%kMDE zFh(KJ$CK*YN|SEvkBl$B)NR(N!j|SW-@?Q4_!XMBnvEr?78*$3$4yu6t&lyYP^j}7 zdszn_=};E}8gKM^R-0MDxJ>^17FE^mW&Fp21VyUhqYVI&FyKzx#M`)D{RDBH#Jt=DN zuj5$B&6&neD)KZJ%!WNlx5Kg~h;%cM%rJ(5J9EK(;3cyH1?IiTausNk@krZ;GtjpP zxOb_^*`6zWi*rrVF^XI-%gCn&O0-jUVnnItolod~G|Adu`g`ieZ1wJ(^$WQChvh<3 zPG&<|U;qS2$Xa`;U#@gw@O;9)Gfj97udF8C0>wA@-GsF=k;x*@;bJG>Jk0`{U03F^ zJttqA>Cm}kv9j~0D-37 z7H+&qkI@7(5+j{VXLIQI>eQ}HgFw~YHB)IPwZCCcZ;cyI8=0zr^%7!|)DatiX$=~H zBYs42j~=NYhM!(<{<-T@DI4;X8w9$q3!e~-_rmrp>{kXBvr+^u5R`P-X9h(9&~iA* zf;p|OY;A_4=VyIP4^&});FWfcZw{~|qwE|9Y&WNo;#+m2uqShS&!`d`JFf$1XmvX* zdvKQifx=JdB-JaHtt(cQ@%*V{->-m%GhY|j^Y@xdg%v0MM9EL(ZN>l-cI~IP*lQwSv3Ok;@D0bAUEs83^r;E8E7*T zUzMUCPQ?V6x7AY78+2awFu`v1m)d*kPB-c4G{IBKr(Ri=r>0COYsxQvK939ZYJm$I0 zRG9OYs9I*RqmjX6C{K@sc^e3HkCmu>e(yx)Q{nAG=>2F4Mz&NwFaU<8ZOXe$OjBYH zLcUSeV)l;;yVn!hfS`%G28qyYOgGHEf0b?F7sr;0SF$q-Kw|F|$d?T`d_A?tUXl_% z1FCy&-Zr|7Eckbe7fhJ@E4WffWlNEz$bb1XKXNn_Q~L~X0y+keyAE2xwBDS?<={%H z>u;9p@Py8GA~nE?F9fgYhPvC0QvGpgV(exlJ0tLexzTin zm@M}TqeH4*6ctiq0qjA?6H@hcrX@q*O;|Cl;2fAsswrd0&4LAO6m zWLj<-Z~p+mC1m}vsWN7Ne*b(9L(%U|J0Xm)j35c;1<7J1;GL$0zFSdHW^niMfawH=#~fijQ;8{4D?0zZoITXbE4xp-0J ziX*rZn1mU6&_t*`0V8G2<_PFd@uK^Oa$&}1a{$d=LjUl9#GJ_^G=8vBG+C=Ys7k2= z%0(c@HT3a=IAauRu@b5zsP;afz!~2OJ|r|&#TWy<yc9_*4LOaYRmz=q56%A42gj$k_G3v1&3z_0k!l!OXgvlfI*X+ zSV5($>&L*UqzleByp=IWTMuix1^>lD##k0_<~%y=1>Rd(%GFe`x4IDkf_Aiuz1PZb za(vY|;BD}EMzPanE`H?34{S^VuxGm+En2&}RWUe~5XUP2?k^ZBQ+#^78$2s4qYZ@G z=aB>-*M9$)35Ga~?gDxgIsARojh`Rk!|W?*4@krW7D^z>YZ}9DdKXS!TGYyvqPBAO z@hNxz@l0|ev|>=YZ__Ph5at?u2y6iM=KCaDZERJF0XL|X&z^bORo~V{b3s0=r)m4b z;`a$dC|yt6!zv)kerH&uiy@#7IMXOCeBZgs6zWsLm7+%*geHo17_Wk4pOlWtPb+Z3 zP=rIRUz49U2H;X|1*6N>ZSstuck%7$7t=&U+NU%WVF|q{l}f5Az2DFLhOVce-^l@p zVq@LpWu7-j=g61w)uWoX>|#7SY>>SWr^$jVAP;S<+>toTj}gXA&-sk%}g+mJkeNn!5433DON7jL*^0HzuMU|cK1`Y5l zWEy&O=a(`Ospr0^z^txyIsYyc?e+2DSIxM}C;V5`3T?)&3HDxZ{@aCc<9XpQTi`}# z@O(Z4%0Cd@{&=x%`}C9>U+(beHc+RLM4Leih>eh1|i61$%DN>GSfScigskyNm&*^6(%12=edG zEKIxLr-1?o#=kP2$~JDPv(x|{Mol0E2fe4xu`~V zz)DDNNB-8Z0y%zb243#(1Tl89THC^z0Tv^O6S+%rnArK5Y1u zN=(CshjX>{`Q{?lchJLD`X=;?z-rPff+}Q2JL2A)p>8`jydQEz@+pmprl+&zf7o3R z=8+E|)|H%plf#OGT4l1K;=PqU(0KM=nk!m-fwhD*e0_;guiyvR{#PhdydbMi%A@O` zoxBb1D%aZS7Iw`nDOuJ#+&GkrPyY$g&(`2=Nxcv#23UK0~J@TNHM&tOfX~ka}#6amxnLDX7jbcTW69J^&_Hh zk4%pq$NF)D{zEtV73tJXHgbF3H$ho#wy-~6q4vbPhl2I4GJYc}l4VB>7_XsaqnV$X2!_ADQxnkVO6J|T{F_V|Vv4T!zn zvm>YA5u`S~h1;4TuhOp&Ou93Yx{JAW@rpx-1diLJkvX3fRKvN}zKV&p)zfDO&0yB{ z%S*Bl(74(uFWmYF=V0p5V6RHaD} zXOo|nzjMA9goOzl*p}+zZ+7%&odQ5LY>n7ckI5u}|6dYga3)3UNycbCv!l4O=_J@iW`4q`h zgSBOaoFlzse0o|U0cS6TW%f?aF9KWU%E>_J5X+j`xwX9kpOe%4(c_Mn!j#52n`|P- zeoxFlI_bEZlVQa^lH?!UVak$RM-%*8@8j6{2!&8IWVB-$@h<{%A;2F{& zR*T%B4<@q?ev)$~ON$Bg?M*3Fe<{NdTMqj6I>~w6Z?qj;3t;`lALXsMer?dafSCFe zEFrZM_MHc>f_Poz;|d@C&PJ1tQCMG8q-@*kQDmUYCpYIj&)W8+;vM>R zeXN6mv_mY*x9<&bsriu6w*yT-E-CQWk(T!oHKTWDtjlF&U7WiRWk(i6VRBu`5q~na zDemb4>DPJI_D4~wT$4;`%ZGto?Tzuf*K->uoS`1t-hpLudb}kKtui^715=*)CjW0V zF?wa+nHx-QlXNKQW1WIfW#YXI2ktzkm@9g}#pP2m%xLD+H&VT!ai zq++#e(Ny!i<)k-YrBC4ppWY>}4qrof{pW?46&V(}vE?&E~ue^u*V=9WAYW%}>9E4Oq!q zgZGl08WomPoAz6eW-jkgUo@|s#ya{j6Inb<8m2|y%00LFD=mZ1tL>BL{$?+~XTtg* zYmmJ5VANu7^-Fk%izpRJDs$uMZibR!XOP4Y5`j`w9PCC}V=poYoG46BsO73+7hFo@ z%%qP*>{t$@?LEZ%33s|U_>%Uc4m0Lfr9e0-KkQ#3dMJTx@-`0t3z5}wX|Dj^-GpbS z7%rlc!yCk7hPp|*UXX^!dle+^#C|$A{s*;~a`Dx=UI}wVzPJ63%C_dflD8t;`js&k z=UR31M$`k$>anc_kLIepMflcpxKKTRBt7M*_e@ohKz*r2j>OUnq9}uZ;kSbhHoI`b z54KwWdOKe=C5S`?t$R13(JMkY_~B=TSPxQbWEkY2zSwRdus2d zLv_AyTEmC!W=)@b55z5>DIYeofiIBw2HhkW+u~0+C+1K;dLlvT*O~a}!KwNPtlPUA zwK28f6NR-BuPl^keKe84!+@(@z~R#;EJfjEW#O!UAn;YeKvrpr}E^*=ZS za7b9$-G$UAqdW_Wjigi5n)yhoWrDDbtE2JGF#wzkDCi9<4}Aq1U+D7W9M zI)+*F+O*r7@=QL$2sDsf*|||Jp+nXQ?v>^rY{ze zg0Et$GI|cTM~mmIj9XHS>ZQ}1jFh>EqN$P#^YYx?IiF0cgYWwFW`=`HbmFm_ZfC@7Y6n+oXZ z#ae>_u9bY)7}ZW#TaB08ZuLEEd7Y`w<28m~dKF3(_F~%;#khkb0C7t(=}IWb%PH